Perl在非严格模式下解除引用

时间:2014-09-08 21:59:13

标签: perl dereference perldoc perlop

在Perl中,如果我有:

no strict;
@ARY = (58, 90);

要操作数组的元素,比如第二个,我会写(可能是更大表达式的一部分):

$ARY[1]  # The most common way found in Perldoc's idioms.

虽然出于某种原因这些也有效:

@ARY[1]
@{ARY[1]}

导致所有人都在同一个对象中:

print (\$ARY[1]);
print (\@ARY[1]);
print (\@{ARY[1]});

输出:

SCALAR(0x9dbcdc)
SCALAR(0x9dbcdc)
SCALAR(0x9dbcdc)

启用此类构造的语法规则是什么?用这些结构中的每一个构建可靠的程序代码到多远,或者将它们全部混合在一起?这些表达方式如何互换? (总是在非严格的背景下讲话)。

关于如何证明我是如何进入这个问题的,我同意“使用严格”作为一种更好的做法,我仍然对积累非严格表达的一些知识感兴趣。

为了找到自己对这种不安的一些帮助,我来到了:

  • 关于“不严格”的概念不抱怨未申报的 变量和怪癖语法。
  • 前缀取消引用的优先级高于subindex [](perldsc§“优先级警告”)。
  • 关于何时使用@而不是$(perldata§“Slices”)的澄清。
  • Perl的运算符(perlop)中缺少“[]”(数组下标/切片)描述,这让我觉得它不是 操作员...(但它必须是别的东西。但是,什么?)。

根据我所学到的,这些提示中的任何一个都没有让我更好地理解我的问题。

提前致谢。

4 个答案:

答案 0 :(得分:4)

来自perlfaq4的报价:

  

$array[1]@array[1]之间的区别是什么?

     

不同之处在于sigil,即数组名称前面的特殊字符。 $ sigil表示"恰好是一个项目",而@ sigil表示"零个或多个项目"。 $会为您提供单个标量,而@会为您提供一个列表。

请参阅:What is the difference between $array[1] and @array[1]?

答案 1 :(得分:2)

@ARY[1]确实是一个切片,实际上只是一个成员的切片。不同之处在于它创建了一个列表上下文:

@ar1[0] = qw( a b c );    # List context.
$ar2[0] = qw( a b c );    # Scalar context, the last value is returned.
print "<@ar1> <@ar2>\n";

输出:

<a> <c>

除了使用strict外,还可以启用warnings。您将收到以下警告:

Scalar value @ar1[0] better written as $ar1[0]

在perlop中,您可以阅读&#34; Perl的前缀解除引用运算符的类型为:$,@,%和&amp;。&#34;标准语法是SIGIL { ... },但在简单的情况下,花括号可以省略。

请参阅Can you use string as a HASH ref while "strict refs" in use?了解no strict refs的一些乐趣以及严格的模拟。

答案 2 :(得分:1)

扩展choroba's回答,检查特定情境,您可以使用wantarray

sub context { return wantarray ? "LIST" : "SCALAR" }

print $ary1[0] = context(), "\n";
print @ary1[0] = context(), "\n";

输出:

SCALAR
LIST

答案 3 :(得分:1)

除了隐藏您的错误

之外,您所做的一切都不需要no strict;
@ARY = (58, 90);

什么时候应该完成

my @ARY = (58, 90);

以下内容返回数组的单个元素。由于EXPR将返回单个索引,因此将在标量上下文中对其进行评估。

$array[EXPR]

e.g。

my @array = qw( a b c d );
my $index = 2;
my $ele = $array[$index];   # my $ele = 'c';

以下内容返回LIST标识的元素。由于LIST要返回0个或更多元素,因此必须在列表上下文中对其进行评估。

@array[LIST]

e.g。

my @array = qw( a b c d );
my @indexes ( 1, 2 );
my @slice = $array[@indexes];   # my @slice = qw( b c );

\( $ARY[$index]   )  # Returns a ref to the element returned by $ARY[$index]
\( @ARY[@indexes] )  # Returns refs to each element returned by @ARY[@indexes]

${foo}       # Weird way of writing $foo. Useful in literals, e.g. "${foo}bar"
@{foo}       # Weird way of writing @foo. Useful in literals, e.g. "@{foo}bar"
${foo}[...]  # Weird way of writing $foo[...].

大多数人甚至不知道你可以在字符串文字之外使用它们。