首页 文章

Perl符号表中的不可打印字符代表什么?

提问于
浏览
10

我刚刚了解到,在Perl中,给定模块的符号表存储在与模块名称匹配的散列中 - 因此,例如,虚构模块 Foo::Bar 的符号表将是 %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'";
}

输出看起来像这样:

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'
...

我期待看到STDOUT和STDERR文件句柄,也许@INC和%ENV ...我不期待看到的是非ascii字符...上面的代码块没有显示的是输出的第三行实际上有一个表示不可打印字符的字形 .

我运行脚本并将其管道如下:

perl /tmp/asdf.pl | grep '[^[:print:]]' | while read line
do 
    echo $line
    od -c <<< $line
    echo
done

输出看起来像这样:

Key: '' Value '*main::'
0000000   K   e   y   :       ' 026   '       V   a   l   u   e       '
0000020   *   m   a   i   n   :   : 026   '  \n
0000032

Key: 'ARNING_BITS' Value '*main::ARNING_BITS'
0000000   K   e   y   :       ' 027   A   R   N   I   N   G   _   B   I
0000020   T   S   '       V   a   l   u   e       '   *   m   a   i   n
0000040   :   : 027   A   R   N   I   N   G   _   B   I   T   S   '  \n
0000060

Key: '' Value '*main::'
0000000   K   e   y   :       ' 022   '       V   a   l   u   e       '
0000020   *   m   a   i   n   :   : 022   '  \n
0000032

Key: 'E_TRIE_MAXBUF' Value '*main::E_TRIE_MAXBUF'
0000000   K   e   y   :       ' 022   E   _   T   R   I   E   _   M   A
0000020   X   B   U   F   '       V   a   l   u   e       '   *   m   a
0000040   i   n   :   : 022   E   _   T   R   I   E   _   M   A   X   B
0000060   U   F   '  \n
0000064

Key: ' Value '*main:'
0000000   K   e   y   :       '  \b   '       V   a   l   u   e       '
0000020   *   m   a   i   n   :   :  \b   '  \n
0000032

Key: '' Value '*main::'
0000000   K   e   y   :       ' 030   '       V   a   l   u   e       '
0000020   *   m   a   i   n   :   : 030   '  \n
0000032

那么在Perl符号表中做什么不可打印的字符呢?它们的符号是什么?

2 回答

  • 1

    Guru走在正确的轨道上:具体来说,答案可以在_1793790中找到,其中说:

    “Perl变量名称也可以是数字序列或单个标点符号或控制字符 . 这些名称都保留给Perl的特殊用途;例如,全数字名称用于保存常规后反向引用捕获的数据表达式匹配.Perl具有单控制字符名称的特殊语法:它理解^ X(插入符号X)表示控制-X字符 . 例如,符号$ ^ W(美元符号插入符号W)是标量变量,其名称是单个字符控件-W . 这比在文件中键入文字控件-W更好 . 从Perl 5.6开始,Perl变量名称可能是以控制字符开头的字母数字字符串(或者更好的是,插入符号)这些变量必须以$ {^ Foo}的形式写出;大括号不是可选的 . $ {^ Foo}表示标量变量,其名称为control-F,后跟两个o . 这些变量保留用于将来的特殊用途通过Perl,除了以^ _开头的那些(控制下划线o r caret-underscore) . 没有以^ _开头的控制字符名称将在任何未来的Perl版本中获得特殊含义;因此,这些名称可以安全地用于程序中 . 但是,$ ^ _本身是保留的 . “

    如果要以可读的方式打印这些名称,可以在代码中添加如下所示的行:

    $key = '^' . ($key ^ '@') if $key =~ /^[\0-\x1f]/;
    

    如果 $key 的第一个字符是控制字符,则将其替换为插入符后跟相应的字母( ^A 表示control-A, ^B 表示control-B等) .

  • 10

    Perl有特殊变量,如 $"$,$/$\ 等 . 所有这些都是符号表的一部分,这就是你所看到的 . 此外,您还应该能够在符号表中看到@ INC,%ENV .

相关问题