Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Well I ran into this construct that doesn't do what I expect. Is Perl's behavior justified? If so, please help me understand.
#!/local/bin/perl -w use warnings; use strict; # Runs the sub reference in arg #1 sub Doit { &{$_[0]}; } # Start of a big block - don't want to pollute { my $x = 777; my $y = 222; print "Initialized, what's the values?"; print " x = $x\n"; print " y = $y\n\n"; sub mysub { print " Start of subroutine\n"; print " what's x? (forget y for now)\n"; print " x = $x\n\n"; print " Going to child block\n"; print " let's inspect the variables again:\n"; { Doit( sub { print "x = $x\n\n"; print " y = $y\n\n"; } ); } } } # Big Block mysub();
---------------------- output:
>perl perlbug.pl
Initialized, what's the values? x = 777
 y = 222

  Start of subroutine
    what's x? (forget y for now)
    x = 777

    Going to child block
     let's inspect the variables again:
x = 777

Use of uninitialized value in concatenation (.) or string at perlbug.pl line 31

      y =
(This behavior has been checked on Perl 5.6.1 and 5.8.8)

Replies are listed 'Best First'.
Re: Lexical Scoping and Anonymous Subroutines Passed To Functions
by jdporter (Paladin) on Jun 15, 2007 at 21:30 UTC

    Yeah, it's a known quirk. Perl doesn't think it needs to bind $y in the inner sub because it needn't in the outer sub, whereas it did have to bind $x in the outer sub. (btw - that inner bare block, around the Doit call, is superfluous; removing it doesn't change the behavior, and, I think, clarifies the situation somewhat.)

    A word spoken in Mind will reach its own level, in the objective world, by its own weight
Re: Lexical Scoping and Anonymous Subroutines Passed To Functions
by Anonymous Monk on Jun 15, 2007 at 21:49 UTC
    I think my previous example was perhaps too involved. Here's something simpler that shows the same behavior:
    #!/local/bin/perl -w use warnings; use strict; # Start of a big block - don't want to pollute { my $y = 222; my $x = 777; print "Initialized, what's the values?"; print " x = $x\n"; print " y = $y\n\n"; sub mysub { print " Start of subroutine\n"; print " what's x? (forget y for now)\n"; print " x = $x\n\n"; print " Going to child block\n"; print " let's inspect the variables again:\n"; my $sr = sub { print "y = $y\n\n"; print "x = $x\n\n"; }; &$sr; } } # Big Block mysub();
      This bug is fixed in perl 5.9.0

      Dave.

Re: Lexical Scoping and Anonymous Subroutines Passed To Functions
by ambrus (Abbot) on Jun 16, 2007 at 15:30 UTC