Oh, Most Monkilicious Monks:

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.

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 with preceding access to $common variable:
>perl t_create_f_PM.pl param: hi there common: fooble private: xpto function return: `hi there;fooble;xpto'
Output without preceding access to variable:
>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

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.