2012-05-06 13 views
2

シンボリックリンクを使用せずにこの状況で変数の名前を知る方法はありますか?Perl:リスト内の変数の名前を知る方法はありますか?

use strict; 
... 
for ($var1, $var2, $var3) 
{ 
    die "NAME_OF_VAR is not defined" if !defined $_; 
} 

出力VARが定義されていない場合:

「VAR [123]で定義されていません...」

+0

私はそれを(あなたがそれを行うことができ、そのリストが 'for($ var1、undef、$ var2){...')であったとすればどういう意味でしょうか?しかし、Perlで何かができるとは思っていなかったし、間違っていたことが何度もありました。 – mob

答えて

2

ここでは、未定義の変数の致命的な警告を得るための一つの方法です:

my ($var1, $var2, $var3) = 1..2; 

{ 
    use warnings FATAL => 'all'; 
    my $test = "$var1 $var2 $var3"; 
} 

出力:

T上記のブロック内でエラーが発生すると、スクリプトは停止します。この場合:

Use of uninitialized value $var3 in concatenation (.) or string at ... 

Iは、定義済みかのテストとして連結を選んだが、それは未定義の変数が使用されている警告を引き起こす任意の操作であってもよいです。

2
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 
0

私はあなたがそれを言っている自分自身を考えて、あなたはシンボリック参照文献を必要としています。これらは悪ではないことを覚えておいてください、彼らはただ普通はあなたが望むものではありません。この特定のケースでは、あなたはメタプログラミングの一種をしています、あなたは変数の名前を気にします。したがって、これを行うことができます。

use strict; 
... 
for (qw/var1 var2 var3/) 
{ 
    no strict 'refs'; 
    die "$_ is not defined" if !defined ${$_}; 
} 
0

はPadWalkerモジュールを考えてみましょう:あなたは、あなたのシステム上のCPANコマンドラインツールを使用して、それをインストールする必要がありますので、

#!/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は、デフォルトではインストールされません。

もちろん、PadWalkerは狂っているし、あなたがやろうとしていることをするための最良の方法ではないかもしれませんが、しばらくのうちにばかげているのは間違いありません。

2

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); 

利回りは何かになることを出力サブルーチン内で、我々はWALに必要なのに対し、forループ内var_name(0, ...を指定する必要があるか

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

はご注意:このようなkをvarname(1, ...を使用して追加レベルを1つ戻します。

given/whenステートメントではエイリアシングが使用されていますが、そのように見えることもあります。したがって、PadWalkerはgiven(...)で指定された変数にトレースバックできません。

関連する問題