在perl中使运行时变量名全局化
making runtime variable names global in perl
好吧,我仔细研究并尝试了无数变体来让它工作。我需要 perl 专家的帮助。
首先,我知道,我知道,不要使用动态变量名!好吧,我想在这种情况下我需要这样做。我正在修复 inherited 脚本。它有一组由 prefix
+ "_"
+ suffix
组成的变量。这开始很小,但现在前缀是大约 20 个和大约 50 个后缀的列表——一千个不同的变量。
脚本在某些情况下循环遍历这些变量,使用 eval
检索单个值等。这一切都有效。问题是,在整个脚本中对不同变量的所有使用,无论是在前缀 and/or 后缀的循环内还是只是硬编码使用,都假设这些变量是 globalized使用 use var qw($varname)
。 use vars
硬编码语句的数量已经失控。而且,过去有数千个使用全局语法初始化这些变量的输入配置文件,所有这些都需要继续工作。
我希望我可以通过在循环中执行 globalization 步骤来提高可维护性,一次动态创建一个变量名,然后使用 use vars
将它们全球化或 our
。这是一些代码来显示我所追求的。我在这里展示了几个选项,但每个选项实际上都是一个单独的试验。我尝试了其他变体,但无法再保持笔直。
my @prefixes = ("one", "two", ..., "twenty");
my @suffixes = ("1", "2", ..., "50");
my $globalvars = "";
for my $suffix (@suffixes) {
for my $prefix (@prefixes) {
# option 1 -- remainder of #1 outside of loop
# NOTE: 1.a (no comma); 1.b (include comma between vars)
$globalvars .= "$$prefix\_$suffix, ";
# option 2
eval "use vars qw($$prefix\_$suffix)";
# option 3
my $g = "$prefix\_$suffix";
eval ("use vars qw($$g)");
# option 4
eval ("our $$g");
}
}
# option 1.a
use vars qw($globalvars);
# or option 1.b
my (eval "$globalvars");
:
:
:
# now use them as global variables
if ($one_1 eq ...) {
if ($one_10) {
似乎"use vars"的问题(除了不鼓励)是qw里面的字符串必须是实际的变量名,而不是动态变量名。我认为 'eval' 选项不起作用,因为范围仅存在于 eval 本身。
有没有办法在 perl 中做到这一点?
string inside qw has to be the actual variable name, not a dynamic variable name
这就是 qw
的工作方式,它引用单词,不进行插值。不过,您不必将 qw
与 use vars
一起使用。
#! /usr/bin/perl
use warnings;
use strict;
my @global_vars;
BEGIN { @global_vars = qw($x $y) }
use vars @global_vars;
# strict won't complain:
$x = 1;
$y = 2;
这里需要BEGIN,因为use vars
在编译时运行,我们需要@global_vars已经填充。
不需要eval EXPR
,因为不需要使用qw
。 qw
只是创建字符串列表的一种方法,对您的需求不是特别有用。
my @prefixes; BEGIN { @prefixes = qw( one two ... twenty ); }
my @suffixes; BEGIN { @suffixes = 1..50; }
use vars map { my $p = $_; map { '$'.$p.'_'.$_ } @suffixes } @prefixes;
好吧,我仔细研究并尝试了无数变体来让它工作。我需要 perl 专家的帮助。
首先,我知道,我知道,不要使用动态变量名!好吧,我想在这种情况下我需要这样做。我正在修复 inherited 脚本。它有一组由 prefix
+ "_"
+ suffix
组成的变量。这开始很小,但现在前缀是大约 20 个和大约 50 个后缀的列表——一千个不同的变量。
脚本在某些情况下循环遍历这些变量,使用 eval
检索单个值等。这一切都有效。问题是,在整个脚本中对不同变量的所有使用,无论是在前缀 and/or 后缀的循环内还是只是硬编码使用,都假设这些变量是 globalized使用 use var qw($varname)
。 use vars
硬编码语句的数量已经失控。而且,过去有数千个使用全局语法初始化这些变量的输入配置文件,所有这些都需要继续工作。
我希望我可以通过在循环中执行 globalization 步骤来提高可维护性,一次动态创建一个变量名,然后使用 use vars
将它们全球化或 our
。这是一些代码来显示我所追求的。我在这里展示了几个选项,但每个选项实际上都是一个单独的试验。我尝试了其他变体,但无法再保持笔直。
my @prefixes = ("one", "two", ..., "twenty");
my @suffixes = ("1", "2", ..., "50");
my $globalvars = "";
for my $suffix (@suffixes) {
for my $prefix (@prefixes) {
# option 1 -- remainder of #1 outside of loop
# NOTE: 1.a (no comma); 1.b (include comma between vars)
$globalvars .= "$$prefix\_$suffix, ";
# option 2
eval "use vars qw($$prefix\_$suffix)";
# option 3
my $g = "$prefix\_$suffix";
eval ("use vars qw($$g)");
# option 4
eval ("our $$g");
}
}
# option 1.a
use vars qw($globalvars);
# or option 1.b
my (eval "$globalvars");
:
:
:
# now use them as global variables
if ($one_1 eq ...) {
if ($one_10) {
似乎"use vars"的问题(除了不鼓励)是qw里面的字符串必须是实际的变量名,而不是动态变量名。我认为 'eval' 选项不起作用,因为范围仅存在于 eval 本身。
有没有办法在 perl 中做到这一点?
string inside qw has to be the actual variable name, not a dynamic variable name
这就是 qw
的工作方式,它引用单词,不进行插值。不过,您不必将 qw
与 use vars
一起使用。
#! /usr/bin/perl
use warnings;
use strict;
my @global_vars;
BEGIN { @global_vars = qw($x $y) }
use vars @global_vars;
# strict won't complain:
$x = 1;
$y = 2;
这里需要BEGIN,因为use vars
在编译时运行,我们需要@global_vars已经填充。
不需要eval EXPR
,因为不需要使用qw
。 qw
只是创建字符串列表的一种方法,对您的需求不是特别有用。
my @prefixes; BEGIN { @prefixes = qw( one two ... twenty ); }
my @suffixes; BEGIN { @suffixes = 1..50; }
use vars map { my $p = $_; map { '$'.$p.'_'.$_ } @suffixes } @prefixes;