Что представляют собой символы, не подлежащие печати в таблице символов Perl?

Я только что узнал, что в 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 символов... то, что код выше, не показывает состоит в том, что на третьей строке вывода на самом деле был глиф, указывающий на непечатаемый символ.

Я запустил script и передал его следующим образом:

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? Для чего они предназначены?

Ответ 1

Гуру находится на правильном пути: в частности, ответ можно найти в perlvar, в котором говорится:

"Имена переменных Perl также могут быть последовательностью цифр или одним символом пунктуации или управления. Эти имена зарезервированы для специальных целей Perl, например, имена всех цифр используются для хранения данных, захваченных обратными ссылками после регулярное выражение соответствует. Perl имеет специальный синтаксис для имен с одним управляющим символом: он понимает ^X (caret X) как символ управления X. Например, обозначение $^W (знак доллара в кадре W ) - это скалярная переменная, имя которой является единственным символьным контролем -W. Это лучше, чем ввести в вашу программу буквенный элемент управления-W.

Так как Perl 5.6, имена переменных Perl могут быть буквенно-цифровыми строками, которые начинаются с управляющих символов (или, еще лучше, каретки). Эти переменные должны быть записаны в виде ${^Foo}; фигурные скобки необязательны. ${^Foo} обозначает скалярную переменную, имя которой является элементом управления-F, а затем двумя o. Эти переменные зарезервированы для будущих специальных применений Perl, за исключением тех, которые начинаются с ^_ (control-underscore или caret-underscore). Имя управляющего символа, начинающееся с ^_, приобретает особое значение в любой будущей версии Perl; такие имена могут поэтому безопасно использоваться в программах. $^_ сам, однако, зарезервирован.

Если вы хотите напечатать эти имена читаемым способом, вы можете добавить в код такую ​​строку:

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

Если первый символ $key является управляющим символом, он заменит его каретой, за которой следует соответствующая буква (^A для управления-A, ^B для элемента управления-B и т.д.).

Ответ 2

Perl имеет специальные переменные, такие как $", $,, $/, $\ и так далее. Все это часть таблицы символов, которую вы видите. Кроме того, вы также должны увидеть @INC,% ENV в таблице символов.