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

Hello,

I am seeing some unexpected behaviour when nesting a function inside another.

The inner function keeps seeing the old version of variables declared in the outer function.

For example:

#!/usr/bin/perl use strict; sub outer_function { my ($v1, $v2) = @_; print STDERR "Outer \$v1: " . \$v1 . " = $v1\n"; return inner_function($v1) . ", $v2"; sub inner_function { print STDERR "Inner \$v1: " . \$v1 . " = $v1\n"; return $v1; } } print "First call: " . outer_function("A", "B") . "\n"; print "Secnd call: " . outer_function("X", "Y") . "\n";

I was expecting the (standard) output to be:

First call: A, B Secnd call: X, Y

But instead I get:

Outer $v1: SCALAR(0xa0078a8) = A Inner $v1: SCALAR(0xa0078a8) = A First call: A, B Outer $v1: SCALAR(0x9fee760) = X Inner $v1: SCALAR(0xa0078a8) = A Secnd call: A, Y

Why does inner_function() keep seeing the old version of $v1 instead of the new one that outer_function() sees?

Is there any way to prevent this, and have inner_function() see the same address as outer_function() every time they are called?

Thanks in advance!

N

PS: Perl version is "v5.10.0 built for i486-linux-gnu-thread-multi" (Debian 5.0.6, perl 5.10.0-19lenny2)

Replies are listed 'Best First'.
Re: Nested sub's beget undead variables?
by chromatic (Archbishop) on Nov 10, 2010 at 19:39 UTC

    Named functions all have the same visibility. Their bindings for lexicals get created at compilation time, so the inner function can't share the lexical bindings of the outer function. (This is a huge oversimplification, but is essentially true as far as it matters now.)

    One way to alleviate this is to introduce a lexical scope external to both function4 declarations:

    { my ($v1, $v2); sub outer_function { ... } sub inner_function { ... } }

    Otherwise you could make inner_function() an anonymous function so that it always binds those two lexicals to the current lexical scope of outer_function().

      Thanks chromatic; that explains it. Love your book, by the way.

      N

Re: Nested sub's beget undead variables?
by ikegami (Patriarch) on Nov 10, 2010 at 20:20 UTC
    Note that you would have gotten "will not stay shared" warnings if you didn't turn them off.