1.1.1 提出问题
你想在字符串里面进行函数调用或者表达式扩展。这将可以让你建立比起字符串里面内插简单的标量更加复杂的模板。
1.1.2 解决方案
把你的表达式分割成几个部分再连起来:
$answer = $var1 . func( ) . $var2; # 只可以是标量
|
或者使用略现“滑头”的@{[ LIST EXPR ]} 或 ${ \(SCALAR EXPR ) }扩展:
$answer = "STRING @{[ LIST EXPR ]} MORE STRING"; $answer = "STRING ${\( SCALAR EXPR )} MORE STRING";
|
1.1.3 讨论
这个代码表达了2种技术,第一行表达的是连接(concatenation)技巧,第二行表达的是扩展技巧:
$phrase = "I have " . ($n + 1) . " guanacos."; $phrase = "I have ${\($n + 1)} guanacos.";
|
第一种技术通过连接短字符串,避免了字符串内插,但是结果是一样的。因为print函数也只是把它的整个参数列表连接起来, 在这里如果我们只想打印$phrase,我们只需这样写:
print "I have ", $n + 1, " guanacos.\n";
|
如果你肯定要用内插的话,你需要像上面解决方案里面那样进行特殊符号内插。在双引号和其他大多数反引号里面只有@,$,\是特别的字符。(像m//,s///,qx()等这样的如果使用了单引号的定界符,那么它们不能像跟双引号引用那样进行扩展。比如:$home = qx'echo home is $HOME';这行代码最后会打印出shell环境变量$HOME,而不是Perl的变量$HOME),所以,要进行强制进行表达式扩展的唯一方法是使用${ } 或者 @{ }内带一个引用进行扩展。
例如:
$phrase = "I have ${\( count_em( ) )} guanacos.";
|
由于${\( )} 中的括号提供的依然是列表环境。所以,如果count_em这个函数返回列表的话,它仍然是在处于列表上下文,如果要使用标量上下文就这样:
$phrase = "I have ${\( scalar count_em( ) )} guanacos.";
|
再比如:
print "start \tat ${\( localtime() ) }\n"; #将打印返回列表的元素数
print "start \tat ${\(scalar localtime() ) }\n"; #打印时间值
|
在完成字符串里面的内插后,并不仅仅只能用来赋值,你可以把它当成一个一般的字符串使用,下面这个例子把内插扩展后的字符串传给了一个函数:
some_func("What you want is @{[ split /:/, $rec ]} items");
|
你还可以内插到这文档,比如:
die "Couldn't send mail" unless send_mail(<<"EOTEXT", $target); To: $naughty From: Your Bank Cc: @{ get_manager_list($naughty) } Date: @{[ do { my $now = `date`; chomp $now; $now } ]} (today)
Dear $naughty,
Today, you bounced check number @{[ 500 + int rand(100) ]} to us. Your account is now closed.
Sincerely, the management EOTEXT
|
扩展反引号是更加的困难而有趣,因为你一般会以一个伪造的换行符结尾. 就像上面最后一个例子中做的那样,在@{[]}这个匿名数组引用中通过在符号@后建立一个大括号块,你可以建议私有的变量。
通过使用这些技术,简单的把你的工作分割成很多步奏,或者保存每一件事情在对于读者很清晰的临时变量中。
CPAN提供的Interpolation模组是一个更加合适的选择. 例如, 下面使散列%E的元素等价于子函数的返回值:
use Interpolation E => 'eval'; print "You bounced check number $E{500 + int rand(100)}\n";
|
或者制作一个命名的散列去来调用你选择的合适的子函数:
use Interpolation money => \¤cy_commify;
print "That will be $money{ 4 * $payment }, right now.\n";
#将得到像下面这样的结果:
# $>That will be $3,232.421.04, right now.
|
1.2.4 参考
参考perlref(1)和大骆驼书的第八章。
1.2.4 测试程序
阅读(691) | 评论(0) | 转发(0) |