揭开Perl glob(*)的神秘面纱

揭开Perl glob(*)的神秘面纱,perl,glob,Perl,Glob,在海报中,有人问如何在一行中执行以下操作: 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_arr

在海报中,有人问如何在一行中执行以下操作:

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
}
然而,在苏的一位当地僧侣身上,克瑞斯特建议:

sub my_sub {
  local *array = shift();
  #use @array here
}
当我问起

在尝试学习中级Perl时 魔术师,我能问你,你是怎么想的吗 你在这里设定什么?你是吗 将对@array的引用设置为 已传入的arrayref?怎么 你知道你创建了@array和 不是%array还是$array?我能去哪里 了解有关此*运算符的详细信息 (perlop?)。谢谢


有人建议我把它作为一个新的帖子来问,尽管他给了我很好的推荐信。不管怎么说,是这样吗?有人能解释一下分配给什么的是什么,以及为什么创建@array而不是%array或$array吗?谢谢。

无可否认,我对Perl的知识还不太了解,我将大胆地给出一个答案。*运算符指定符号表条目。据我所知,@array、%array和$array都引用了字符串“array”的同一符号表条目,但指向该条目中的不同字段:数组、哈希和标量字段。所以赋值
local*array=shift实际将“数组”的整个本地符号表项(包括数组、散列和标量字段)分配给调用程序中使用的传递内容。

分配给全局

*glob = VALUE
包含一些取决于
值的类型的魔法(例如,
标量::Util::reftype(值)
)。如果
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 ------------------ @数组=新数组 $array=原始标量 %数组=原始哈希 ------------------ @数组=原始数组 $array=新标量 %数组=原始哈希 ------------------ @数组=原始数组 $array=原始标量 %array=newhash ------------------ @数组=foo-bar $array=foo %数组=foooo ------------------ @数组=foo-bar $array=foo %数组=foooo ------------------ @排列= $array= %排列= ------------------ @数组=原始数组 $array=原始标量 %数组=原始哈希 ------------------
额外的文件在和。早在引用成为Perl的一部分之前,这个习惯用法有助于将数组和散列传递到子例程。

不要忘记,当typeglob赋值的RHS既不是typeglob,也不是引用,而是字符串时会发生什么。还可以考虑当<代码> *>代码> SIGIL的操作数是一个字符串而不是BalWord时会发生什么。最后,考虑<代码>本地< /代码>。正如这个答案所示,分配给一个GOLB会根据引用类型填充不同的时隙。您可以简洁地确保您具有正确的类型,如:
local*array=\@{shift@}
。如果ref是一个数组,那么reference/dereference pair
\@
是透明的,但如果不是,则会抛出错误。我仍在尝试阅读tchrist在问题注释中发布的链接中的一些内容,但是,这很好地回答了我的实际问题。谢谢我想我至少了解了要引导的符号表的一些基本知识!你可能会从中收集到一些关于类型glob的重要见解,这里还没有涉及到这些见解;否则就更复杂了。实际上,它更复杂,因为符号表条目就像一个“glob变量”,它包含一个“glob值”,赋值设置值部分,而不是变量本身。