在this question中,海报询问如何在一行中执行以下操作:
sub my_sub {
my $ref_array = shift;
my @array = @$ref_array;
}
根据我对Perl基本魔法的了解,我会通过简单地使用类似的东西来避免:
sub my_sub {
my $ref_array = shift;
for (@$ref_array) {
#do somthing with $_ here
};
#use $ref_array->[$element] here
}
然而在this answer SO的当地僧侣之一tchrist建议:
sub my_sub {
local *array = shift();
#use @array here
}
我问的时候
试图学习中级Perl 魔术,我可以问,你是什么 正在设置到这里?你是 将@array的引用设置为 传入的arrayref?怎么样 你知道你创建@array和 不是%array或$ array?我可以在哪里 了解这个*运营商的更多信息 (perlop中?)。谢谢!
我被建议将其作为一个新帖子,尽管他确实提供了很好的参考。无论如何,这里呢?有人可以解释什么被分配给什么以及如何创建@array而不是%array或$ array?感谢。
答案 0 :(得分:22)
分配给一个glob
*glob = VALUE
包含一些魔法,它取决于VALUE
的类型(即,Scalar::Util::reftype(VALUE)
的返回值)。如果VALUE
是对标量,数组,散列或子例程的引用,则仅符号表中的条目将被覆盖。
这个成语
local *array = shift();
#use @array here
在子例程的第一个参数是数组引用时记录。如果第一个参数是标量引用,那么只有$array
而不是@array
会受到分配的影响。
一个小小的演示脚本,看看发生了什么:
no strict;
sub F {
local *array = shift;
print "\@array = @array\n";
print "\$array = $array\n";
print "\%array = ",%array,"\n";
print "------------------\n";
}
$array = "original scalar";
%array = ("original" => "hash");
@array = ("orignal","array");
$foo = "foo";
@foo = ("foo","bar");
%foo = ("FOO" => "foo");
F ["new","array"]; # array reference
F \"new scalar"; # scalar reference
F {"new" => "hash"}; # hash reference
F *foo; # typeglob
F 'foo'; # not a reference, but name of assigned variable
F 'something else'; # not a reference
F (); # undef
输出:
@array = new array $array = original scalar %array = originalhash ------------------ @array = orignal array $array = new scalar %array = originalhash ------------------ @array = orignal array $array = original scalar %array = newhash ------------------ @array = foo bar $array = foo %array = FOOfoo ------------------ @array = foo bar $array = foo %array = FOOfoo ------------------ @array = $array = %array = ------------------ @array = orignal array $array = original scalar %array = originalhash ------------------
perlmod
和perldata
的其他文档。回到引用是Perl的一部分之前的日子里,这个习惯用法有助于将数组和哈希传递给子程序。
答案 1 :(得分:3)
凭借我对Perl的不那么精灵的了解,我会冒险回答。 *运算符分配符号表条目。据我了解,@ array,%array和$ array都引用字符串'array'的相同符号表条目,但是引用该条目中的不同字段:ARRAY,HASH和SCALAR字段。因此,赋值local *array = shift;
实际上将“array”的整个本地符号表条目(包括ARRAY,HASH和SCALAR字段)分配给调用者中使用的传递。