文字列に基づいて Perl 変数名を作成するにはどうすればよいですか?
-
21-09-2019 - |
質問
Perl では、文字列に基づいてグローバル変数を作成できますか?
たとえば、次のような関数があるとします。
sub create_glob_var {
my ($glob_var_str) = @_;
# something like this ( but not a hash access).
our ${$glob_var_str};
};
そして私はそれを次のように呼びました:
create_glob_var( "bar" );
どうすれば変更できますか create_glob_var
というグローバル変数を実際に作成するには $bar
?
私のプロジェクトは perl 5.8.5 を使用しています。
編集
以下は機能しません:
use strict;
BEGIN {
sub create_glob_var {
my ($glob_var_str) = @_;
no strict 'refs';
$$glob_var_str = undef; # or whatever you want to set it to
}
create_glob_var("bah");
};
$bah = "blah";
生産物:
Variable "$bah" is not imported at /nfs/pdx/home/rbroger1/tmp2.pl line 12. Global symbol "$bah" requires explicit package name at /nfs/pdx/home/rbroger1/tmp2.pl line 12. Execution of /nfs/pdx/home/rbroger1/tmp2.pl aborted due to compilation errors.
注記 グローバル変数を使用すると、 オゾン層破壊と男性型脱毛症. 。グローバル変数の使用によってすでに完全に感染しているレガシーコードをクリーンアップしようとしています。リファクタリングは一度に 1 つずつ...
解決
あなたは古いコードをクリーンアップしようとしている場合は、必要な変数(複数可)をエクスポートするモジュールを書くことができます。たびは、create_glob_var
を呼び出す代わりに、このパッケージに変数を追加し、インポートリストにそれを配置する必要性を感じています。
これは、あなたが上に行くとどのように変数が使用されているものを追跡するのに役立ちます。
package MyVars;
use strict; use warnings;
use Exporter 'import';
our($x, %y, @z);
our @EXPORT_OK = qw( $x %y @z );
スクリプトます:
#!/usr/bin/perl
use strict;use warnings;
use MyVars qw( $x %y @z );
$x = 'test';
%y = (a => 1, b => 2);
@z = qw( a b c);
use Data::Dumper;
print Dumper \($x, %y, @z);
出力:
$VAR1 = \'test'; $VAR2 = { 'a' => 1, 'b' => 2 }; $VAR3 = [ 'a', 'b', 'c' ];
他のヒント
sub create_glob_var {
my ($glob_var_str) = @_;
no strict 'refs';
$$glob_var_str = undef; # or whatever you want to set it to
}
no strict 'refs'
が有効である場合は、 use strict
は、それが常にあるべき、必要なだけである。
補遺ます:
サブルーチンcreate_glob_var
を書くための方法がある場合は、求めている場合は、次のコードが成功することをます:
use strict;
create_glob_var("bar");
$bar = "whatever";
...その後答えは「いいえ」でありますしかし、Perlのvars
プラグマは、あなたがやりたいだろう。
use strict;
use vars qw($bar);
$bar = "whatever";
しかし、これは古いスタイルのPerlコーディングの一種です。今日では、1は、一般的にこれを行うだろう。
use strict;
our $bar = "blah";
our
また、単に自由に後で使用できるグローバル変数を宣言することができます:
our ($foo, @bar, %baz);
# ...
$foo = 5;
@bar = (1, 2, 3);
%baz = (this => 'that');
この質問を見て試してみてください。 PerlはPHPのような動的変数を持っていますか?の
簡単に言えば、あなたが$$glob_var_str = "whatever";
を行うことができるはずのように思える。
あなたはeval
を使用する必要がありますが、それは一般的に悪と考えられています。ような何かます:
eval("$glob_var_str = \@_;");
の編集の
ちょうどあなたが唯一my
なしとno strict refs
でこれを行うことができますことを確認します。
の vars
pragma は、あなたが望むことのために重労働をすでに行っているので、それを動作させます。
#! /usr/bin/perl
use warnings;
use strict;
use vars;
BEGIN { vars->import(qw/ $bah /) }
$bah = "blah";
print $bah, "\n";
スペルを書きたい場合は、 create_glob_var
, 、次に使用します
#! /usr/bin/perl
use warnings;
use strict;
use vars;
sub create_glob_var { vars->import("\$$_[0]") }
BEGIN { create_glob_var "bah" }
$bah = "blah";
print $bah, "\n";
いずれにせよ、出力は次のとおりです
blah
これらの変数を次のように宣言するのではなく、なぜこのようにしたいのか知りたいです。 our
. 。はい、すべてを検出するには数回の反復が必要になるかもしれませんが、いずれにせよ、これらは短期的な修正ですよね?
一般に、変数を変数名として使用できます (「 perlref の「シンボリック参照」)でも、あなたは本当に、本当に、 本当に それはしたくない:を有効にする strict 'refs'
pragma はこの機能を無効にします。
ラファエル・ガルシア・スアレスは、「あなたの元の問題が何なのかは知りませんが、ハッシュを使用することをお勧めします。」と書いて、優れた知恵を示しました。
以下も参照してください。
シナンÜnürによって回答は確かに最高です。しかし、これは私の好奇心を選んだので、私は読書のビット(はperldoc perlmodを)を行なったし、パッケージの名前空間にアクセスするための方法として、「パッケージ名::」のハッシュを学びました。
次のコードは、メイン::パッケージのシンボルテーブルにレコードを追加します:
use strict;
my $name = "blah";
my $var = "sss";
$main::{$name} = \$var;
print "$main::blah\n";
この印刷物 "SSS" ます。
しかし、私はまだだまされていない「厳格な使用」ので、print文にパッケージ名を追加する必要がありました。私が探しておこう - VARSを使用することは現時点で動作するようには思えない。
。