在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 的工作方式,它引用单词,不进行插值。不过,您不必将 qwuse 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,因为不需要使用qwqw 只是创建字符串列表的一种方法,对您的需求不是特别有用。

my @prefixes;  BEGIN { @prefixes = qw( one two ... twenty ); }
my @suffixes;  BEGIN { @suffixes = 1..50; }

use vars map { my $p = $_; map { '$'.$p.'_'.$_ } @suffixes } @prefixes;