2013-04-10 15 views
10

Właśnie dowiedziałem się, że w Perlu tabela symboli dla danego modułu jest przechowywana w haszowniku, który pasuje do nazwy modułu - tak, na przykład, tablica symboli dla fikcyjnego modułu Foo::Bar byłaby %Foo::Bar. Domyślna tabela symboli jest przechowywana w %main::. Właśnie ze względu na ciekawość, postanowiłem, że chciałem zobaczyć, co było w %main::, więc powtórzyć za pośrednictwem każdej pary klucz/wartość w tablicy asocjacyjnej, drukując je jako Poszedłem:Co oznaczają znaki niedrukowalne w tabeli symboli Perla?

#! /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'"; 
} 

Wyjście wyglądał następująco :

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

spodziewałem się zobaczyć stdout i STDERR uchwytów plików, a może @ INC i% ENV ... co ja nie spodziewałem się zobaczyć było znaków spoza ASCII ... co blok kodu powyżej nie pokazuje, że trzecia linia wyjścia rzeczywiście zawierała glif wskazujący na niedrukowalną postać.

wpadłem skryptu i rurami go w następujący sposób:

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

Wyjście wyglądał następująco:

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 

Więc jakie są niedrukowalne znaków robi w tablicy symboli Perl? Po co są te symbole?

+0

Nie wiem, ale wygląda na to, że wszystkie klucze niedrukowalne mają tę samą wartość, '* main ::'. –

+0

W rzeczywistości jest to po prostu artefakt o f fakt, że glify znaków kontrolnych zostały usunięte po wklejeniu do StackOverflow. Spróbuj uruchomić mój kod powyżej lub jeszcze lepiej kod zawierający tłumaczenie znaków niedrukowalnych autorstwa ilmari, a stanie się jasne, jakie wartości znajdują się w tabeli symboli. –

+0

Ups, masz rację. Sprawdziłem klucze dla znaków niedrukowalnych, ale nie wartości! –

Odpowiedz

10

Guru jest na właściwej drodze: konkretnie, że odpowiedź można znaleźć w perlvar, który mówi:

„Nazwy zmiennych Perl może być również sekwencja cyfr lub pojedynczy znak interpunkcyjny lub kontrola. Wszystkie te nazwy są zarezerwowane dla specjalnych zastosowań przez Perl, na przykład wszystkie cyfry są używane do przechowywania danych przechwyconych przez odsyłacze wstecz po dopasowaniu wyrażenia regularnego Perl ma specjalną składnię dla nazw jednokierunkowych: Rozumie ^X (caret X) oznacza znak kontrolny X. Na przykład notacja $^W (znak W znaku dolara) jest skalarną zmienną, której nazwa jest pojedynczym znakiem-W. To jest lepsze han wpisując literalną kontrolkę-W do twojego programu.

Od Perla 5.6, nazwy zmiennych Perla mogą być ciągami alfanumerycznymi, które zaczynają się od znaków kontrolnych (lub jeszcze lepiej, karetki). Te zmienne muszą być napisane w postaci ${^Foo}; szelki nie są opcjonalne. ${^Foo} oznacza zmienną skalarną, której nazwa to control-F, a po niej dwie o. Zmienne te są zarezerwowane dla przyszłych zastosowań specjalnych przez Perl, z wyjątkiem tych, które zaczynają się od ^_ (podkreślenie kontrolne lub podkreślenie znaku podkreślenia). Żadna nazwa znaku kontrolnego zaczynająca się od ^_ nie zyska specjalnego znaczenia w żadnej przyszłej wersji Perla; dlatego nazwy takie mogą być bezpiecznie używane w programach. $^_ sam w sobie jest jednak zarezerwowany."

Jeśli chcesz wydrukować te nazwy w czytelny sposób, można dodać taką linię do kodu:

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

Jeśli pierwszy znak $key jest znak kontrolny, to zastąpić to z karetką, a następnie odpowiednią literą (^A dla kontroli-A,dla kontroli-B, itp.).

+0

Dzięki za uwzględnienie kodu tłumaczenia; który faktycznie odpowiedział na jedną z bardziej tajemniczych części problemu, a mianowicie * main :: \ 027ARNING_BITS, która staje się * main ::^WARNING_BITS. –

+0

Co powiecie na '$ key = ~ s/^ ([\ 0- \ x1F])/'^'. ($ 1^'@')/e;' –

+0

@Brad: Oczywiście, to robi dokładnie to samo. –

1

Perl ma specjalne zmienne, takie jak $", $,, $/, $\ i tak dalej. Wszystko to jest częścią tablicy symboli, którą widzisz. Powinieneś również widzieć @INC,% ENV w tabeli symboli.

Powiązane problemy