6

なぜこれは42を出力するのですか:

$answer = 42;
$variable = "answer";

print ${$variable} . "\n";

しかし、これはしません:

my $answer = 42;
my $variable = "answer";

print ${$variable} . "\n";
4

4 に答える 4

15

シンボリック参照を介してターゲットにできるのは、パッケージ変数 (最初の例で宣言された種類) のみです。レキシカル ( my) 変数は使用できません。これが、2 番目の例が失敗する理由です。

Perl の 2 つの別々の変数システムがどのように動作するかについては、優れた記事Coping with Scopingを参照してください。また、なぜそれがばかげているのかについては、なぜ変数変数名を使用するのがばかげているのかという優れたものも参照してください。:)

于 2010-02-25T23:32:29.343 に答える
6

Perl には、最初の例のようにパッケージ変数と、2 番目の例のようにレキシカル変数という、完全に独立しているがほぼ互換性のある 2 つの変数システムがあります。それぞれができることはいくつかありますが、もう一方はできません。

パッケージ変数は、次のことができる唯一のものです。

  1. ローカライズ (でlocal)
  2. シンボリック参照のターゲットとして使用されます(OPの2番目の例が機能しない理由)
  3. ベアワードとして使用 (サブ定義、ファイル ハンドル)
  4. 型グロブと一緒に使用されます (これは、シンボルが実際にボンネットの下にあるためです)

レキシカル変数は、閉じることができる唯一のものです (レキシカル クロージャで使用されます)。

strict を使用すると、パッケージ変数を で宣言することが強制されour、違いが明確になります。

Perl でシンボリック参照が役立つ場合がいくつかありますが、そのほとんどはシンボル テーブルの操作に集中しています (import使用するのではなく、独自のモジュールを記述したりExporter、実行時にモジュールにモンキー パッチを適用したり、その他のさまざまなメタプログラミング タスクを実行したりするなど)。これらはすべて高度なトピックです。

他のタスクについては、通常、ハッシュなどを使用するより良い方法があります。一般的な経験則はuse warnings; use strict;、プラグマの一部を無効にする以外に方法がないことがわかっていない限り、常に実行することです (no strict 'refs';できるだけ小さなスコープで使用するなど)。

于 2010-02-25T23:27:06.467 に答える
5

問題は、シンボリック参照を使用してレキシカル変数を参照できないことです。両方の例${$variable}で を探してい$main::answerます。最初の$answerはグローバルなパッケージであり、 の略で$main::answerあるため、リファレンスはそれを見つけます。2 番目$answerはレキシカル変数であり、どのパッケージにも存在しないため、参照はそれを見つけることができません。

詳細については、シンボリック参照の見出しの下のperlrefを参照してください。

于 2010-02-25T23:29:19.630 に答える
5

シンボリック参照は、パッケージ変数でのみ機能します。シンボルテーブルはレキシカル変数を追跡しません (これがレキシカルであることの要点です:)。

于 2010-02-25T23:34:01.680 に答える