Initializing perl variables using eval

前端 未结 3 1819
暖寄归人
暖寄归人 2021-01-05 06:18

I\'m guessing this should be something obvious to those knowing Perl, but I simply don\'t get it.. I also guess it has to do with problems described in Perl scoping « darkne

相关标签:
3条回答
  • 2021-01-05 07:07

    jjolla, you can use require $filename; or require "filename"; to include a file that has perl syntax. this would declare any variables you need as globals. But as always, be careful with Globals.

    0 讨论(0)
  • 2021-01-05 07:15

    It has everything to do with scoping. The variables are declared with my inside the eval expression. This makes them local to the eval statement and not accessible once the eval statement exits. You can declare them first, though:

    my ($varA, $varB, $varC);  # declare outside the eval statement
    
    my $tvars = "\$varA = 1;
    \$varB = 2;
    \$varC = 3;
    ";
    
    eval $tvars;
    # local $varA, $varB, $varC variables are now initialized
    

    or as you suggest, you can use global variables. The easiest (though not necessarily the "best" way) is to prepend :: to all variable names and get them in the main package.

    my $tvars = "\$::varA = 1;
    \$::varB = 2;
    \$::varC = 3;
    ";
    
    eval $tvars;
    print "A=$::varA, B=$::varB, C=$::varC\n";
    

    Now when you tried our variables in your example, you actually were initializing package (global) variables. But outside the eval statement, you still need to qualify (i.e., specify the package name) them in order to access them:

    $tvar = "our \$foo = 5";
    eval $tvar;
    
    print $main::foo;    # ==> 5
    
    0 讨论(0)
  • 2021-01-05 07:17

    The problem is that when you do eval $string, $string is evaluated as its own subroutine which has its own lexical scope. From perldoc -f eval:

    In the first form [in which the argument is a string], the return value of EXPR is parsed and 
    executed as if it were a little Perl program. The value of the expression (which is itself 
    determined within scalar context) is first parsed, and if there were no errors, executed in the 
    lexical context of the current Perl program, so that any variable settings or subroutine and format 
    definitions remain afterwards.
    

    So, in other words, if you have:

    use strict;
    use warnings;
    eval "my $foo=5;";
    print "$foo\n";
    

    you'll get an error:

    Global symbol "$foo" requires explicit package name at -e line 3.
    Global symbol "$foo" requires explicit package name at -e line 4.
    

    However, if you initialize your variables first, you're fine.

    use strict;
    use warnings;
    my $foo;
    eval "\$foo=5;";
    print "$foo\n"; #prints out 5, as expected.
    
    0 讨论(0)
提交回复
热议问题