代码之家  ›  专栏  ›  技术社区  ›  viraptor

在另一个包中设置变量

  •  1
  • viraptor  · 技术社区  · 14 年前

    我想在另一个包中用选定的名称设置一个变量。我怎么能这么容易?

    类似于:

    $variable_name = 'x';
    $package::$variable_name = '0';
    # now $package::x should be == '0'
    
    3 回复  |  直到 14 年前
        1
  •  1
  •   Eugene Yarmash    14 年前

    既然如此 $variable_name 已验证,您可以执行以下操作:

    eval "\$package::$variable_name = '0'";
    
        2
  •  2
  •   jira    14 年前

    你可以这样做,但是你必须禁用这样的限制:

        package Test;
    
        package main;
    
        use strict;
    
        my $var_name = 'test';
        my $package = 'Test';
    
        no strict 'refs';
        ${"${package}::$var_name"} = 1;
    
    print $Test::test;
    

    所以我不推荐。最好用杂凑。

        3
  •  2
  •   Eric Strom    14 年前
    use 5.010;
    use strict;
    use warnings;
    
    {
        no warnings 'once';
        $A::B::C::D = 5; # a test subject
    }
    
    my $pkg = 'A::B::C';
    my $var = 'D';
    
    # tearing down the walls (no warranty for you):
        say eval '$'.$pkg."::$var"; # 5
    
    # tearing down the walls but at least feeling bad about it:
        say ${eval '\$'.$pkg."::$var" or die $@}; # 5
    
    # entering your house with a key (but still carrying a bomb):
        say ${eval "package $pkg; *$var" or die $@}; # 5
    
    # using `Symbol`:    
        use Symbol 'qualify_to_ref'; 
        say $${ qualify_to_ref $pkg.'::'.$var }; # 5
    
    # letting us know you plan mild shenanigans
    # of all of the methods here, this one is best
    {
        no strict 'refs';
        say ${$pkg.'::'.$var}; # 5
    }
    

    如果你能理解以下内容,请继续:

    # 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
    

    当然,您可以指定这些方法中的任何一种,而不是 say 他们。