2013-04-10 5 views
10

私は、Perlでは、与えられたモジュールのシンボルテーブルがモジュール名と一致するハッシュに格納されていることを知りました。例えば、架空のモジュールFoo::Barのシンボルテーブルは%Foo::Barです。デフォルトシンボルテーブルは%main::に格納されています。Perlシンボルテーブルの印刷できない文字は何を表していますか?

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

を出力はこのように見えた:ちょうど好奇心のために、私は私が行ったように、それらをプリントアウトし、ハッシュ内の各キー/値のペアを通じて反復、私は%main::にあったものを見たいと思ったことを決めました:

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

私は私がした非ASCII文字を見て期待していなかったものを... STDOUTとSTDERRファイルハンドルを見て期待し、そしておそらく@INCと%ENVた...は、どのようなコードブロック出力の3行目が実際に印刷できない文字を示すグリフを持っているということです。

私は、スクリプトを実行し、次のようにパイプ:

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のシンボルテーブルにやってない文字は何ですか?それらのシンボルは何ですか?

+0

わかりませんが、印刷不可能なすべてのキーが同じ値を持つように見えますが、 '* main ::'。 –

+0

実際、これは単なる人工物です。私がStackOverflowにペーストしたときにコントロール文字のグリフが削除されたという事実。上のコードを実行してみてください。あるいは、ilmariの印刷不可能な文字の変換を含むコードの方が良いでしょう。そして、シンボルテーブルの値が何であるかが明らかになります。 –

+0

おっと、そうです。私は印刷できない文字のキーをチェックしましたが、値はチェックしませんでした! –

答えて

10

達人は正しい軌道に乗っている。具体的には、答えは述べていた、perlvarで発見される:

「Perlの変数名も数字の配列、または単一句読点や制御文字かもしれません。これらの名前はすべて、Perlによる特別な使用のために予約されています;例えば、全桁の名前は、正規表現の一致後に後方参照によって取得されたデータを保持するために使用されます。たとえば、記号$^W(ドル記号のキャレットW)は、1文字のコントロール-Wという名前のスカラー変数です。あなたのプログラムにリテラルコントロール-Wをタイプします。

Perl 5.6以降では、Perlの変数名は、制御文字で始まる英数字の文字列(より良い意味では、キャレット)でもかまいません。これらの変数は、${^Foo}の形式で記述する必要があります。中括弧はオプションではありません。 ${^Foo}は、名前がcontrol-Fで2つのoが続くスカラー変数を示します。これらの変数は、^_(control-underscoreまたはcaret-underscore)で始まるものを除いて、Perlによる今後の特別な使用のために予約されています。 ^_で始まる制御文字の名前は、Perlの将来のバージョンでは特別な意味を持ちます。したがって、そのような名前はプログラムで安全に使用できます。しかし、$^_自体は予約されています。あなたが読みやすいように、それらの名前を印刷したい場合は、「

することは、あなたのコードに次のような行を追加することができます。

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

$keyの最初の文字が制御文字である場合、これが置き換えられますキャレットに続けて対応する文字が続きます(制御-Aの場合は^A、制御-Bの場合は^Bなど)。

+0

翻訳コードを含めていただきありがとうございます。これは問題のより神秘的な部分の1つ、つまり* main :: \ 027ARNING_BITSに答えました。これは* main ::^WARNING_BITSになります。 –

+0

ちょうど '$ key =〜s/^([\ 0- \ x1F])/ '^'($ 1^'@')/ e;' –

+0

@ブラッド:まあまあ同じことです。 –

1

Perlには、$",$,,$/,$\などの特殊変数があります。これらはすべてあなたが見ているシンボルテーブルの一部です。また、@INC、%ENVもシンボルテーブルで見ることができます。

関連する問題