On 6/26/05, Fergal Daly <[EMAIL PROTECTED]> wrote:
> You have 3 situations
> 
> 1 the refs came from \&somefunc
> 2 the refs come from evaling strings of code
> 3 the refs are closures and therefore have some data associated with them
> 
> For 3, it looks like B::Deparse does't handle the data at all so even
> if the deparsed subs are identical they may behave totally
> differently.

Well, this isn't really what happens when perl is building subs. When
building things like closures (or any subroutines), perl doesn't
"associate" the data in the closed-over variables with the new sub.
For example:

sub getSetPair {
        my($default) = @_;

        my $variable = $default;
        return [sub { $variable = $_[0] }, sub { return $variable } ];
}
my($setter, $getter) = @{getSetPair(5)};

print $getter->(),"\n";
$setter->(6);
print $getter->(),"\n";

Now, this wouldn't work if perl replaced mentions of $variable in the
two closures with the value of $default. All that happens is that the
closures start checking parent scopes (in this case, a pad left over
from the invocation of getSetPair()), which, when you think about it,
is what makes these two (simpler) examples pretty much the same thing:

Example 1:
#############
sub five_wrong {
        my $five = 6;
        return sub { return $five };
}

sub five_right {
        my $five = 5;
        return sub { return $five };
}

print five_right()->();
print five_wrong()->();
#############

and, Example 2:

#############
my $five = 5;
sub five {
        return $five;
}
print five();
$five = 6;
print five();
#############

These two examples print the same thing. Would you expect five() to
decompile differently depending on when you passed it to B::Deparse
whether $five was 5 or 6? So, as you said in your post, "the deparsed
subs are identical they may behave totally differently"; do they
really behave differently, though? They both check parent scopes for
unknown variables; the only difference is where they're checking.

Collin Winter

Reply via email to