Perl 在另一个包中设置变量

Perl 在另一个包中设置变量,perl,Perl,我想在另一个包中设置一个具有选定名称的变量。我怎样才能轻松做到这一点 比如: $variable_name = 'x'; $package::$variable_name = '0'; # now $package::x should be == '0' 您可以这样做,但必须禁用以下限制: package Test; package main; use strict; my $var_name = 'test'; my $package = 'Te

我想在另一个包中设置一个具有选定名称的变量。我怎样才能轻松做到这一点

比如:

$variable_name = 'x';
$package::$variable_name = '0';
# now $package::x should be == '0'

您可以这样做,但必须禁用以下限制:

    package Test;

    package main;

    use strict;

    my $var_name = 'test';
    my $package = 'Test';

    no strict 'refs';
    ${"${package}::$var_name"} = 1;

print $Test::test;

所以我不建议这样做。最好使用散列。

您可以这样做,但您必须禁用如下限制:

    package Test;

    package main;

    use strict;

    my $var_name = 'test';
    my $package = 'Test';

    no strict 'refs';
    ${"${package}::$var_name"} = 1;

print $Test::test;

所以我不建议这样做。最好使用散列。

如果验证了
$variable\u name
,则可以执行以下操作:

eval "\$package::$variable_name = '0'";

假定已验证
$variable\u name
,您可以执行以下操作:

eval "\$package::$variable_name = '0'";
如果以下内容对您有意义,请参加聚会:

# with a recursive function:
    sub lookup {
        @_ == 2 or unshift @_, \%::;
        my ($head, $tail) = $_[1] =~ /^([^:]+:*)(.*)$/;
        length $tail
            ? lookup($_[0]{$head}, $tail)
            : $_[0]{$head}
    }
    say ${ lookup $pkg.'::'.$var }; # 5

# as a reduction of the symbol table:
    use List::Util 'reduce';
    our ($a, $b);

    say ${+ reduce {$$a{$b}} \%::, split /(?<=::)/ => $pkg.'::'.$var }; # 5
#具有递归函数:
子查找{
@_==2或取消移位@\%:;
我的($head,$tail)=$\[1]=~/^([^::+:*)(.*)$/;
长度$tail
?查找($\u0]{$head},$tail)
:$\u0]{$head}
}
说${lookup$pkg.':'.$var};#5.
#作为符号表的缩减:
使用列表::Util'reduce';
我们的(a美元,b美元);
说${+reduce{$$a{$b}}\%:,split/(?$pkg.':'.$var};#5
当然,您可以指定这些方法中的任何一种,而不是
say
ing它们

如果以下内容对您有意义,请参加聚会:

# with a recursive function:
    sub lookup {
        @_ == 2 or unshift @_, \%::;
        my ($head, $tail) = $_[1] =~ /^([^:]+:*)(.*)$/;
        length $tail
            ? lookup($_[0]{$head}, $tail)
            : $_[0]{$head}
    }
    say ${ lookup $pkg.'::'.$var }; # 5

# as a reduction of the symbol table:
    use List::Util 'reduce';
    our ($a, $b);

    say ${+ reduce {$$a{$b}} \%::, split /(?<=::)/ => $pkg.'::'.$var }; # 5
#具有递归函数:
子查找{
@_==2或取消移位@\%:;
我的($head,$tail)=$\[1]=~/^([^::+:*)(.*)$/;
长度$tail
?查找($\u0]{$head},$tail)
:$\u0]{$head}
}
说${lookup$pkg.':'.$var};#5
#作为符号表的缩减:
使用列表::Util'reduce';
我们的(a美元,b美元);
说${+reduce{$$a{$b}}\%:,split/(?$pkg.':'.$var};#5

当然,您可以为这些方法中的任何一个赋值,而不必说它们。

修补另一个包变量是不礼貌的。Perl允许这样做,但您对另一个包的设计造成了暴力。当然,有一个警告:如果该变量由包导出(不推荐,但肯定可行),则您可能拥有使用它的权限,然后您不必做任何事情,只需分配给它。@Jonathan:我需要更新一些旧代码。以前,它确实
需要magic\u config\u file.pl;
(从绝对路径)当它需要配置时。我将它切换到一个可以读取正确本地配置文件的模块,但为了向后兼容,我需要设置
%main::SOME_DB=(主机=>'blah',用户=>'blah'…
@Jonathan Leffler:一个更大的警告:如果有文档记录,您可以(例如Data::Dumper,Text::Wrap等)@ysth:当然-但是如果允许你修改变量,你就不必通过扭曲来使用它。Perl允许你打破另一个包周围的保护墙,但它经常出现(但我不是说“总是”!)强行进入另一个包的内部是个坏主意。包不是真正的“防护墙”。它们只是用来组织事物,使它们不会都生活在书架上的同一个书架上。包是用来共享的,因为它们——以及它们的内容——都有众所周知的名字,任何人都可以使用。相反,有一个范围是不共享的,因为没有名字。也就是说,它被认为是相当糟糕的不喜欢玩未经宣传的东西,采取这样的态度,“天哪,如果你不摆弄它,它就不会公开,对吧?”从长远来看,这类事情本身就是一种惩罚。修补另一个包变量是不礼貌的。Perl允许这样做,但你正在对另一个包的设计施加暴力。当然,有一个警告:如果变量由包导出(不推荐,但肯定可行),则您可能拥有使用它的权限,然后您不必做任何事情,只需分配给它。@Jonathan:我需要更新一些旧代码。以前,它确实
需要magic\u config\u file.pl;
(从绝对路径)当它需要配置时。我将它切换到一个可以读取正确本地配置文件的模块,但为了向后兼容,我需要设置
%main::SOME_DB=(主机=>'blah',用户=>'blah'…
@Jonathan Leffler:一个更大的警告:如果有文档记录,您可以(例如Data::Dumper,Text::Wrap等)@ysth:当然-但是如果允许你修改变量,你就不必通过扭曲来使用它。Perl允许你打破另一个包周围的保护墙,但它经常出现(但我不是说“总是”!)强行进入另一个包的内部是个坏主意。包不是真正的“防护墙”。它们只是用来组织事物,使它们不会都生活在书架上的同一个书架上。包是用来共享的,因为它们——以及它们的内容——都有众所周知的名字,任何人都可以使用。相反,有一个范围是不共享的,因为没有名字。也就是说,它被认为是相当糟糕的不喜欢玩未经宣传的东西,采取这样的态度,“天哪,如果你不摆弄它,它就不会公开,对吧?”从长远来看,这类事情本身就是一种惩罚。要做到这一点,你真的不需要求助于
eval STRING
。要做到这一点,你真的不需要求助于
eval STRING
。当你在运行时更改包中的值时,这不起作用,它只能获取init state。当你在运行时更改包中的值,它只能获取init状态