シンボリックリンクを使用せずに、この状況で変数の名前を知る方法はありますか?
use strict;
...
for ($var1, $var2, $var3)
{
die "NAME_OF_VAR is not defined" if !defined $_;
}
varが定義されていない場合の出力:
「var[123]は...で定義されていません。」
use strict;
use warnings;
my ($var1, $var2, $var3) = 1..2;
for( qw($var1 $var2 $var3) ) { print "$_ is undefined\n" if !defined eval($_) }
このmy
行はTLPの例から借用しており、次の出力があります。
$var3 is undefined
未定義の変数の致命的な警告を取得する 1 つの方法を次に示します。
my ($var1, $var2, $var3) = 1..2;
{
use warnings FATAL => 'all';
my $test = "$var1 $var2 $var3";
}
出力:
上記のブロック内でエラーが発生すると、スクリプトは終了します。この場合:
Use of uninitialized value $var3 in concatenation (.) or string at ...
定義のテストとして連結を選択しましたが、未定義の変数が使用されたときに警告が発生するのは、どの操作でもかまいません。
PadWalkerは、エイリアスを解明するための答えです。ただし、PadWalker が答えであるほとんどすべての状況で、それは間違った質問に対する答えである可能性があります。これは、デバッグに使用するか、自分自身を隅に追いやった後に抜け道を見つけるために使用するモジュールの 1 つです。悪い設計からの出口として使用されている場合は、設計を再考する方が良いかもしれません。あなたの場合、答えはおそらくすでに言及されているものです:警告を失敗に引き上げます。
それにもかかわらず、モジュールは存在し、機能し、楽しく遊べます。
質問はエイリアスの解明または検査について具体的に尋ねられたため、 PadWalker がエイリアスをカットスルーして元の変数に戻すことができる 2 つの例を次に示します。
use strict;
use warnings;
use PadWalker qw( var_name );
my( $var1, $var2, $var3 ) = ( undef, undef, undef );
for ($var1, $var2, $var3) {
warn var_name( 0, \$_ ) . ' is not defined in "for" loop'
if !defined $_;
}
sub foo {
warn var_name( 1, \$_[0] ) . ' is not defined in sub foo()'
if !defined $_[0];
}
foo( $var1 );
得られる出力は次のようになります。
$var1 is not defined in "for" loop at mytest.pl line 13.
$var2 is not defined in "for" loop at mytest.pl line 13.
$var3 is not defined in "for" loop at mytest.pl line 13.
$var1 is not defined in sub foo() at mytest.pl line 19.
var_name( 0, ...
ループ内で指定する必要があることに注意してfor
ください。一方、サブルーチン内では、 を使用してさらに 1 レベル戻る必要がありますvarname( 1, ...
。
また、given/when
ステートメントがエイリアシングを使用しているように見えますが、エイリアシングを使用していないことも興味深い点です。その結果、PadWalker は で指定された変数まで遡ることができませんgiven(...)
。
あなたは自分で言ったと思いますが、シンボリック参照が必要です。覚えておいてください、これらは悪いことではなく、通常はあなたが望むものではないということです. この特定のケースでは、一種のメタプログラミングを行っており、変数の名前を気にしています。したがって、これを行うことができます。
use strict;
...
for (qw/var1 var2 var3/)
{
no strict 'refs';
die "$_ is not defined" if !defined ${$_};
}
PadWalker モジュールを考えてみましょう:
#!/usr/bin/env perl
use warnings;
use strict;
use PadWalker qw(var_name);
my $foo = 123;
print var_name(0, \$foo), "\n"; # prints "$foo"
PadWalker はデフォルトではインストールされないため、cpan コマンド ライン ツールを使用してシステムにインストールする必要があります。
もちろん、PadWalker はクレイジーで、何をしようとしても最適な方法ではないかもしれませんが、たまにいじってみるのは確かに楽しいものです。