Chinaunix首页 | 论坛 | 博客
  • 博客访问: 471916
  • 博文数量: 142
  • 博客积分: 4126
  • 博客等级: 上校
  • 技术积分: 1545
  • 用 户 组: 普通用户
  • 注册时间: 2008-02-22 10:03
文章分类

全部博文(142)

文章存档

2011年(8)

2010年(7)

2009年(64)

2008年(63)

我的朋友

分类:

2009-04-24 11:29:41

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 => \&currency_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 测试程序

阅读(655) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~