我正在审核 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 Filehandles在 perldata
.
本质上,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/