14

私は少しだけ perl を知っていますが、次を理解するには十分ではありません。

perldelta 5.18を読んで、5.18 で既に無効になっている次のコードを見つけました。これを数えなくても、それがどのように機能するかを理解したい.

ここにコードがあり、コメントには私が理解しているものがあります

%_=(_,"Just another "); #initialize the %_ hash with key=>value   _ => 'Just another'
$_="Perl hacker,\n";    #assign to the $_ variable with "Perl..."
s//_}->{_/e;            # darkness. the /e - evauates the expression, but...
print

それは印刷します:

Just another Perl hacker,

私は試しました、perl -MO=Deparseそして次を取得します

(%_) = ('_', 'Just another ');   #initializing the %_ hash
$_ = "Perl hacker,\n";           # as above
s//%{'_';}/e;                    # substitute to the beginning of the $_ - WHAT?
print $_;                        # print the result
japh syntax OK

(少なくとも私にとって)奇妙なことは、「逆解析された」コードを実行しても元の結果が得られず、次のように出力されることです。

1/8Perl hacker,

とてもうれしくなる:

  1. 誰かがコードを説明できれば、特に誰かがヘルパー コードを (追加の手順で) 書くことができれば、それがどのように機能するかを理解するのに役立ちます - 何が起こるか.
  2. デパースさ​​れたコードが元の結果を出力しない理由を説明してください。

%{'_';}デパースさ​​れたコードの はどういう意味ですか?

4

1 に答える 1

14

置換演算子によって実際に実行されるコードは、おそらく実際には次のようなものです

my $code = "do { $repl_expr }";

したがって、置換式が の_}->{_場合、次が実行されます。

do { _}->{_ }

_単純に文字列を返します_(strict がオフになっているため)。

do { "_" }->{_}

これはと同じです

"_"->{_}

そこにあるのは、参照がシンボリック参照(つまり、実際の参照ではなく文字列)であるハッシュ要素の逆参照です。通常は strict によって禁止されていますが、これは動作中のシンボリック参照の例です:

%h1 = ( id => 123 );
%h2 = ( id => 456 );
print "h$_"->{id}, "\n"
   for 1..2;

つまり、

"_"->{_}    # Run-time symbol lookup

と同じです

$_{_}       # Compile-time symbol lookup

同様のトリックは、ワンライナーでよく使用されます。

perl -nle'$c += $_; END { print $c }'

に短縮できます

perl -nle'$c += $_; }{ print $c'

-nを使用したときに実際に実行されるコードは、

my $code = "LINE: while (<>) { $program }";

%{'_';}

非常に奇妙な書き方です

%{'_'}

これはハッシュ逆参照です。繰り返しますが、ここでの参照はシンボリック参照です。と同等です

%_

スカラー コンテキストでは、現在のハッシュは、そのハッシュの内部に関する情報を報告する値 (空の場合は false 値) を返します。代わりにキーの数を返すように変更するという提案がありました。

于 2013-06-01T19:47:37.993 に答える