符号引用包中的sub,试图理解

时间:2013-12-31 09:13:35

标签: perl

use strict;
use warnings;

package Foo::Bar;
sub baz { print "$_[0]\n" }

package main;
{ # test 1
my $quux = "Foo::Bar::baz";
no strict 'refs';
&$quux(1);
}
{ # test 2
my $qux = 'Foo::Bar';
my $quux = "$qux\::baz";
no strict 'refs';
&$quux(2);
}
{ # test 3
my $qux = 'Foo::Bar';
my $quux = "$qux::baz";
no strict 'refs';
&$quux(3);
}

输出:

Name "qux::baz" used only once: possible typo at test31.pl line 21.
1
2
Use of uninitialized value $qux::baz in string at test31.pl line 21.
Undefined subroutine &main:: called at test31.pl line 23.

为什么test 2有效,为什么反斜杠必须完全放在那里?

为什么test 3不起作用,到目前为止,语法是否来自test 1

我尝试将该字符串写为"{$qux}::baz",但它也不起作用。

我看到了Image::Info发布的来源。

2 个答案:

答案 0 :(得分:3)

$qux::baz引用包baz中的标量qux

"$qux::baz"是该标量的字符串化。

"$qux::baz"是撰写$qux::baz.""的另一种方式。

Curlies可用于指示变量的结束位置。

"$foo bar"表示$foo." bar"

"${f}oo bar"表示$f."oo bar"

因此,

"${qux}::baz"是撰写$qux."::baz"的另一种方式。

"$qux\::baz"是一种可爱的$qux."::baz"方式,因为\无法出现在变量名称中。

答案 1 :(得分:2)

变量名可以是简单的$foo,也可以是完全限定的名称(在包变量的情况下)。这样一个完全限定的名称看起来像$Foo::bar。这是包$bar中的“全局”变量Foo

如果插值变量后跟双冒号::并且该变量不应被解释为完全限定的包变量名,那么您可以:

  • 使用字符串连接:$qux . "::baz"
  • 使用反斜杠终止变量名称:"$qux\::baz"
  • 用大括号括起变量名(不是sigil),就像名称是符号引用一样:"${qux}::bar"