Perl中的插值有什么缺点吗?

Jas*_*own 12 perl interpolation

我刚刚开始使用Perl(字面意思是今天),我正在阅读免费在线版的Beginning Perl.在早期,该书提到双引号字符串将被插值.但是,在每个使用print函数的例子中(到目前为止......我在第66页左右),作者将标量变量作为列表参数传递.也许我正在跳枪,这将在后面解释,但有没有理由选择方法A而不是方法B?

方法A:

$myVar = "value";
print "Current value is ", $myVar, "\n";
Run Code Online (Sandbox Code Playgroud)

方法B:

$myVar = "value";
print "Current value is $myVar\n";
Run Code Online (Sandbox Code Playgroud)

在我看来,方法B更方便.社区中是否有首选方式?或者也许一些隐藏的陷阱使一种方法比另一种方法更安全?

TIA

Ian*_*and 14

肯定有隐藏的陷阱 - perl将处理简单的变量名称和表达式

"$array[$subscript]"
Run Code Online (Sandbox Code Playgroud)

"$hashref->{key}"
Run Code Online (Sandbox Code Playgroud)

没有任何问题.但是,随着表达式变得越来越复杂,最终perl将无法判断表达式停止的位置以及字符串的其余部分是否开始.

本文中有大量的血腥细节在双引号字符串中的可变插值(原来在这里,但现在下来)


Eth*_*her 12

在一个简单的例子中,没有..但是考虑是否$myVar实际上更复杂,例如深度解引用散列引用或方法调用.有些东西在字符串内插入(大多数对象引用都有),但方法调用没有.当直接打印出来并插入字符串时,数组也会做不同的事情.

PS.欢迎来到Perl; 请享受旅程!:)


mob*_*mob 12

'问题:

$owner = "John";
$item = "motorcycle".
print "This is $owner's $item.\n";  # Oops, parsed as $owner::s
Run Code Online (Sandbox Code Playgroud)

但上面的内容可以安全地写成

print "This is ${owner}'s $item.\n";
Run Code Online (Sandbox Code Playgroud)


bri*_*foy 12

插值有几点需要注意,虽然一旦你了解它们,你几乎不会错误地做它们.

将变量名称放在有效标识符文本旁边.Perl找到最长的有效变量名称,并不关心它是否先前已定义.您可以使用大括号将变量名称部分设置为显式:

  my $p = 'p';
  print "Mind your $ps and qs\n";  # $ps, not $p

  print "Mind your ${p}s and qs";  # now its $p
Run Code Online (Sandbox Code Playgroud)

现在,在那个例子中,我忘记了撇号.如果我添加它,我有另一个问题,因为撇号曾经是过去的包分隔符,它仍然有效.括号也在那里工作:

  my $p = 'p';
  print "Mind your $p's and q's\n";  # $p::s, not $p

  print "Mind your ${p}'s and q's";  # now its $p
Run Code Online (Sandbox Code Playgroud)

Perl还可以插入对哈希和数组的单个元素访问,因此将索引字符放在变量名称旁边可能会执行您不需要的操作:

 print "The values are $string[$foo]\n";  That's the element at index $foo
 print "The values are $string{$foo}\n";  That's the value for the key $foo
Run Code Online (Sandbox Code Playgroud)

当您想要字符串中的电子邮件地址时,您可能会忘记Perl插入数组.除非你逃脱了Perl,Perl过去常常会犯这个致命的错误@:

 print "Send me mail at joe@example.com\n";  # interpolates @example

 print "Send me mail at joe\@example.com\n";
Run Code Online (Sandbox Code Playgroud)

由于Perl使用反斜杠来转义某些字符,因此当您需要字面值时,需要将它们加倍:

 print "C:\real\tools\for\new\work";      # not what you might expect

 print "C:\\real\\tools\\for\\new\\work"; # kinda ugly, but that's life
 print "C:/real/tools/for/new/work";      # Windows still understands this
Run Code Online (Sandbox Code Playgroud)

尽管有这些小问题,但如果我必须使用另一种语言,我真的很想念在Perl中构造字符串的难易程度.

  • 如果您不小心写了"print"joe@example.com"`并发出警告,还会有一个特定的警告"可能是@example的意外插值".除非你不幸在范围内有一个数组`@ example`,否则无论如何. (2认同)