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

时间:2011-02-01 16:52:33

标签: perl glob

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?感谢。

2 个答案:

答案 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
------------------

perlmodperldata的其他文档。回到引用是Perl的一部分之前的日子里,这个习惯用法有助于将数组和哈希传递给子程序。

答案 1 :(得分:3)

凭借我对Perl的不那么精灵的了解,我会冒险回答。 *运算符分配符号表条目。据我了解,@ array,%array和$ array都引用字符串'array'的相同符号表条目,但是引用该条目中的不同字段:ARRAY,HASH和SCALAR字段。因此,赋值local *array = shift;实际上将“array”的整个本地符号表条目(包括ARRAY,HASH和SCALAR字段)分配给调用者中使用的传递。