揭秘 Perl glob (*)

发布于 2024-10-15 05:12:59 字数 938 浏览 1 评论 0原文

这个问题中,发帖者询问如何在一行中执行以下操作:

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
}

但是在这个答案中,SO的当地僧侣之一tchrist 建议:

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

当我问时

在尝试学习中级Perl 魔法,我可以问一下,你那是什么? 这里设置什么?你是 设置对 @array 的引用 arrayref 已传入?如何 你知道你创建了 @array 并且 不是 %array 或 $array?我在哪里可以 了解有关 * 运算符的更多信息 (珀洛普?)。谢谢!

有人建议我将其作为新帖子提出,尽管他确实提供了很好的参考资料。不管怎样,就这样吧?有人可以解释一下什么被分配给什么以及如何创建 @array 而不是 %array 或 $array 吗?谢谢。

In this question the poster asked how to do the following in one line:

sub my_sub {
    my $ref_array = shift;
    my @array = @$ref_array;
}

which with my knowledge of the basic Perl magic I would avoid by simply using something like:

sub my_sub {
    my $ref_array = shift;
    for (@$ref_array) {
      #do somthing with $_ here
    };

    #use $ref_array->[$element] here
}

However in this answer one of SO's local monks tchrist suggested:

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

When I asked

In trying to learn the mid-level Perl
magic, can I ask, what is it that you
are setting to what here? Are you
setting a reference to @array to the
arrayref that has been passed in? How
do you know that you create @array and
not %array or $array? Where can I
learn more about this * operator
(perlop?). Thanks!

I was suggested to ask it as a new post, though he did give nice references. Anyway, here goes? Can someone please explain what gets assigned to what and how come @array gets created rather than perhaps %array or $array? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

温折酒 2024-10-22 05:12:59

对 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 一部分之前的日子里,这个习惯用法对于将数组和散列传递到子例程中很有帮助。

Assignment to a glob

*glob = VALUE

contains some magic that depends on the type of VALUE (i.e., return value of, say, Scalar::Util::reftype(VALUE)). If VALUE is a reference to a scalar, array, hash, or subroutine, then only that entry in the symbol table will be overwritten.

This idiom

local *array = shift();
#use @array here

works as documented when the first argument to the subroutine is an array reference. If the first argument was instead, say, a scalar reference, then only $array and not @array would be affected by the assignment.

A little demo script to see what is going on:

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

Output:

@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
------------------

Additional doc at perlmod and perldata. Back in the days before references were a part of Perl, this idiom was helpful for passing arrays and hashes into subroutines.

尾戒 2024-10-22 05:12:59

诚然,我对 Perl 的了解还不够丰富,我将冒险给出一个答案。 * 运算符分配符号表条目。据我了解,@array、%array 和 $array 都引用字符串“array”的相同符号表条目,但引用该条目中的不同字段:ARRAY、HASH 和 SCALAR 字段。因此,分配 local *array = shift; 实际上将“array”的整个本地符号表条目(包括 ARRAY、HASH 和 SCALAR 字段)分配给调用者中传递的使用内容。

With my admittedly less-than-wizard knowledge of Perl, I'll venture an answer. The * operator assigns the symbol table entry. As I understand it, @array, %array, and $array all refer to the same symbol table entry for the string 'array', but to different fields in that entry: the ARRAY, HASH, and SCALAR fields. So assigning local *array = shift; actually assigns the entire local symbol table entry for 'array' (including the ARRAY, HASH, and SCALAR fields) to what was passed used in the caller.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文