使用@_将单个参数传递给Perl子例程时遇到了一个奇怪的错误。传入子程序的值在进入子程序后立即更改。
代码示例:
my $my_def = 0;
print "my_def = $my_def \n";
@someResult = doSomething($my_def);
sub doSomething {
my $def = @_;
print "def = $def \n";
...
}
这返回:
> my_def = 0
> def = 1 # instead of "0"
另一个奇怪的事情是代码在几个月前就已正常工作。
当我将其更改为:
时,问题得以解决sub doSomething {
my $def = $_[0];
有人能说出可能导致问题的原因吗?使用@_传递单个参数是否有任何限制?
谢谢!
答案 0 :(得分:13)
你得到了正确的行为,虽然这不符合你的预期。
从子例程中的参数获取局部变量的简单经验法则是始终在my (...)
声明中的变量列表周围使用括号:
sub do_something
{
my ($def) = @_;
...
}
区别在于列表上下文和标量上下文。在标量上下文中,所有数组都返回数组中的元素数:在您的情况下为1。当你写my $def = @_
时,你提供了标量上下文。当您使用my $def = $_[0]
时,您显式访问了数组的元素零,这是一个标量(因此$
sigil),所以它再次起作用。
在一般情况下,您可能有:
sub do_something_else
{
my ($arg1, $arg2, $arg3, @the_rest) = @_;
...
}
现在你有三个标量局部变量$arg1
,$arg2
和$arg3
,以及一个数组@the_rest
,它收集传递的任何额外参数。
答案 1 :(得分:1)
当分配给标量值的数组返回数组中的元素数时,答案很简单
答案 2 :(得分:1)
这完全取决于背景。这是一个例子:
@data = (0, 1, 2);
$count = @data; # imply in scalar context
### $count: 3
$count = scalar @data; # same as above, but force scalar context
### $count: 3
$first = $data[0]; # both sides are in scalar context
### $first: 0
($first) = @data; # both sides are in list context
### $first: 0
$first = shift @data; # get the first, but @data was modified
### $first: 0
### @data: (1, 2)
($second, $third) = @data;
### $second: 1
### $third: 2