7
#!/usr/bin/perl
my $var_a;
$sub_a = "a";
$var_a = "a";
print ${var_."$sub_a"},"\n";


$sub_b = "b";
$var_b = "b";
print ${var_."$sub_b"},"\n";

__DATA__

b

a ではなく b が表示されるのはなぜですか? これは私には非常に予期しない動作のように思えます。

名前が置換された変数を使用しようとしています。実際には、代入が forloop で行われているため、変数を宣言しないことはできず、したがってレキシカル スコープが異なります。

4

3 に答える 3

9

これは、変数を使用して他の変数の名前を含めるという事実とは何の関係もないことに注意してください。

これが機能しない理由は${"var_a"}、実際にはコンストラクトがパッケージ レベルの変数を参照しているためです$main::var_a

$var_aはレキシカル変数として宣言されているため、異なる識別子であり、したがってundef${"var_a"}です。

my $var_aに変更するとわかりますour $var_a

our $var_a="a";
my $var_b="b";
$var_c="c";

print ${"var_a"},"\n";
print ${"var_b"},"\n";
print ${"var_c"},"\n";

######## RESULTS:
a

c

他の人が指摘したように、あなたがやろうとしていることがうまくいかない理由については良い説明がありますが、あなたがしていることは間違ったアプローチである可能性があります. 他に良い方法がない限り、この方法は絶対に使用しないでください。あなたの問題がなければ、より良い方法が何であるかは明らかではありませんが、TLPの答えが言うようにハッシュになる可能性が最も高いです.

于 2012-08-02T19:00:26.483 に答える
4

シンボリック参照が必要な場合は、ハッシュを使用します。

my %user_vars = (var_a => 'what ever');
my $sub_a = 'a';
print $user_vars{"var_$sub_a"};


Output: 'what ever'

シンボリック参照は不要であり、質問のコンテキストでは非常に有害である可能性が高いため、この目的でシンボリック参照を使用しないでください。詳細については、「変数を変数名として使用するのはなぜ愚かなのか」を参照してください。. ほとんどの場合、これを行うためのより良い方法があります。1 つの方法は、sub_avar_a配列を作成することsub_aですvar_aインジェクション攻撃を防ぐためにハッシュを使用していないときは、常にハッシュをロックすることをお勧めします。次に例を示します。

use strict;
use warnings;
use Hash::Util qw(lock_hash unlock_hash);

my @sub_a;
my %var_a;
lock_hash(%var_a);

@sub_a = qw(a b c);          # the keys

unlock_hash(%var_a);
%var_a = (a => 'Value for a', b => 'Value for b', c => 'Value for c');
lock_hash(%var_a);

print $var_a{$sub_a[0]};     # 'Value for a'
print $var_a{'banana'};      # Fatal error when accessing data for banana.
于 2012-08-02T18:56:18.210 に答える
0

strict文字列を参照として使用すると、常に使用する必要があるプラグマに違反します。適切に行いたい場合は、ハッシュを使用することをお勧めします。

use strict;
use warnings;

my %hash;

$hash{"var_a"} = "a";
print $hash{"var_a"},"\n";
于 2012-08-02T18:57:49.517 に答える