perl - 需要帮助理解脚本的一部分(全局和引用)

标签 perl

我正在审核 this question ,尤其是 response来自埃里克·斯特罗姆先生,并有一个关于其中更“神奇”元素的一部分的问题。请查看上下文的链接问题,因为我只是想了解此块的内部部分:

for (qw($SCALAR @ARRAY %HASH)) {
    my ($sigil, $type) = /(.)(.+)/;
    if (my $ref = *$glob{$type}) {
        $vars{$sigil.$name} = /\$/ ? $$ref : $ref
    }
}

因此,它循环遍历三个单词,将每个单词分成两个变量,$sigil$type . if {}块是我不理解的。我怀疑 ( .. ) 里面的部分正在获得对 $glob{$type} 中内容的符号引用...一定有一些“魔法”(我还不了解的底层机制的一些深奥元素)依赖于那里来确定“指向”数据的类型?

下一行也部分令人困惑。在我看来,我们正在分配给 vars 哈希,但是 rhs 在做什么?我们没有分配给 $_在最后一个操作中(分配了 $ref),所以与 /\$/ 中的比较堵塞?我的猜测是,如果我们正在处理一个标量(尽管我无法辨别我们是怎么回事),我们会取消引用 $ref var 并将其直接存储在哈希中,否则,我们存储引用。

所以,只是寻找这三行中发生的事情的一个小故事。非常感谢!

最佳答案

您遇到了 Perl 语言中最神秘的部分之一,我最好通过将您推荐给 Symbol Tables and Typeglobs 来解释。来自 brian d foy的优秀掌握 Perl。另请注意,页面底部还有对 Perl 自身文档相关部分的进一步引用,其中最相关的是 Typeglobs and Filehandlesperldata .

本质上,perl 符号表的工作方式是每个包都有一个“stash”——一个“符号表哈希”——其名称与包相同,但带有一对尾随分号。所以默认包的存储 main被称为 %main:: .如果你运行这个简单的程序

perl -E"say for keys %main::"

您将看到所有熟悉的内置标识符。

stash 元素的值是对 typeglobs 的引用,它们也是散列,但具有对应于不同数据类型的键,SCALAR , ARRAY , HASH , CODE等等以及引用具有该类型和标识符的数据项的值。

假设您定义了一个标量变量 $xx ,或更完整的是,$main:xx
our $xx = 99;

现在是 main 的藏匿处包裹是%main:: , 以及标识符为 xx 的所有数据项的 typeglob由 $main::{xx} 引用所以,因为 typeglobs 的印记是一颗星 *就像标量标识符有美元 $ 一样,我们可以将其取消引用为 *{$main::{xx}} .获取对具有标识符 xx 的标量变量的引用,这个类型团可以用 SCALAR 索引字符串,给 *{$main::{xx}}{SCALAR} .再一次,这是对我们所追求的变量的引用,所以要收集它的值,它需要再次取消引用,如果你写
say ${*{$main::{xx}}{SCALAR}};

然后你会看到99 .

用单个语句编写时,这可能看起来有点复杂,但拆分后却相当简单。您问题中的代码具有变量 $glob设置为对 typeglob 的引用,这对应于 $main::xx
my $type = 'SCALAR';
my $glob = $main::{xx};
my $ref  = *$glob{$type};

现在如果我们say $ref我们得到 SCALAR(0x1d12d94)或类似的,这是对 $main::xx 的引用和以前一样,打印 $$ref将显示 99正如预期的那样。

@vars 的后续分配是简单的 Perl,我认为一旦你理解包符号表是 typglob 的存储,或者实际上只是散列的散列这一原则,你应该不会有任何问题。

关于perl - 需要帮助理解脚本的一部分(全局和引用),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26282512/

相关文章:

perl - 这个perl代码可以简化吗?

arrays - 对配对数字数组进行排序并删除重复或重叠?

mysql - Perl 和 MySql 中的 utf8 编码

找不到带有 uuid_t typedef 的 unistd.h

perl - Facebook黑客杯: Studious student problem

regex - Perl 正则表达式对带或不带引号的项目进行分组并忽略空格

perl - 如何将 ItemFilters 与 eBay::API::Simple::Finding 结合使用?

arrays - 如何引用hashmap数组中的值?

perl - 如何在 Perl 中更改、删除或插入文件中的一行,或附加到文件的开头?

Perl 随机字符串,但在浏览器中使用时似乎不那么随机