我刚刚了解到,在Perl中,给定模块的符号表存储在与模块名称匹配的哈希中 - 例如,虚构模块Foo::Bar
的符号表将为{{ 1}}。默认符号表存储在%Foo::Bar
中。只是为了好奇,我决定我想看看%main::
中的内容,因此遍历散列中的每个键/值对,在我去的时候将它们打印出来:
%main::
输出看起来像这样:
#! /usr/bin/perl
use v5.14;
use strict;
use warnings;
my $foo;
my $bar;
my %hash;
while( my ( $key, $value ) = each %:: ) {
say "Key: '$key' Value '$value'";
}
我期待看到STDOUT和STDERR文件句柄,也许@INC和%ENV ...我不期望看到的是非ascii字符......上面的代码块没有显示是输出的第三行实际上有一个表示不可打印字符的字形。
我运行脚本并按如下方式管道:
Key: 'version::' Value '*main::version::'
Key: '/' Value '*main::/'
Key: '' Value '*main::'
Key: 'stderr' Value '*main::stderr'
Key: '_<perl.c' Value '*main::_<perl.c'
Key: ',' Value '*main::,'
Key: '2' Value '*main::2'
...
输出看起来像这样:
perl /tmp/asdf.pl | grep '[^[:print:]]' | while read line
do
echo $line
od -c <<< $line
echo
done
那么Perl符号表中的不可打印字符是什么?它们的符号是什么?
答案 0 :(得分:10)
Guru走在正确的轨道上:具体来说,答案可以在perlvar找到,其中说:
“Perl变量名称也可以是数字序列或单个标点符号或控制字符。这些名称都保留给Perl的特殊用途;例如,所有数字名称用于保存后向引用捕获的数据正则表达式匹配.Perl具有单控制字符名称的特殊语法:它将
^X
(插入符号X)理解为控制-X字符。例如,符号$^W
(美元) -sign caret W)是标量变量,其名称是单个字符控件-W。这比在文本中输入文字控件-W更好。从Perl 5.6开始,Perl变量名可能是以控制字符开头的字母数字字符串(或者更好的是插入符号)。这些变量必须以
${^Foo}
的形式写出;大括号不是可选的。${^Foo}
表示标量变量,其名称为control-F,后跟两个o。这些变量保留给Perl将来的特殊用途,但以^_
(控制下划线或插入符号 - 下划线)开头的变量除外。没有以^_
开头的控制字符名称将在任何未来的Perl版本中获得特殊含义;因此,这些名称可以安全地用于程序中。但是,$^_
本身是保留的。“
如果您想以可读的方式打印这些名称,可以在代码中添加这样的行:
$key = '^' . ($key ^ '@') if $key =~ /^[\0-\x1f]/;
如果$key
的第一个字符是控制字符,则会将其替换为插入符后跟相应的字母(^A
表示控件-A,^B
表示控件-B,等)。
答案 1 :(得分:1)
Perl具有特殊变量,例如$"
,$,
,$/
,$\
等。所有这些都是符号表的一部分,这就是你所看到的。此外,您还应该能够在符号表中看到@ INC,%ENV。