In preparing a reply to Making variables visible between calls. by ambs, I came across an
odd bit of behavior. Someone else posted essentially the same idea
first, so I never posted my reply. However, the problem that slowed
me down is the subject of this post.
I have tested this with ActiveState Win32 Perl 5.6.1 and 5.8.2.
The intent was to add another little feature to the mix: a variable commonly accessible to all functions defined via create_f(). This variable could have its own get/set methods for global access as needed. The problem is that in the code below, the variable $common in the closure of the function create_f() does not have a defined value within the string eval statement in the function unless preceded by some kind of access to the variable. (Any of the access statements shown will do the trick.) Note that in the absence of any preceding access, the variable is in scope within the eval statement, just not defined!
I cannot see how this could be syntactically correct behavior. If it is, I would be very interested to know an explanation!
Many thanks for any insight my fellow monks may offer.
Output with preceding access to $common variable:use warnings; use strict; BEGIN { # closure: data in scope only to create_f() function my $common = 'fooble'; sub create_f { my ($user_source, # required: string: user source code ) = @_; my $private = 'xpto'; # ??? makes $common variable defined in eval ??? # any of these statements do the trick. # except as noted, tested in both 5.6.1 and 5.8.2 # print "in create_f(): common: $common \n"; # $common .= ''; map defined, $common; # note: not tested with 5.6.1 my $coderef = eval qq{ sub { $user_source } }; return $coderef; # code reference undefined if eval failed } } # end closure: create_f() function # NOTE: single quotes on here-doc tag below: no interpolation. my $function = create_f(<<'USER_CODE'); my $param = shift; print "param: $param common: $common private: $private \n"; return join ';', $param, $common, $private; USER_CODE my $freturn = $function->('hi there'); print "function return: `$freturn' \n";
Output without preceding access to variable:>perl t_create_f_PM.pl param: hi there common: fooble private: xpto function return: `hi there;fooble;xpto'
>perl t_create_f_PM.pl Use of uninitialized value in concatenation (.) or string at (eval 1) +line 2. param: hi there common: private: xpto Use of uninitialized value in join or string at (eval 1) line 3. function return: `hi there;;xpto'
In reply to Non-definition of lexical referenced in string eval by AnomalousMonk
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |