Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

This is really a Perl BUG with my?! Need some advice...

by gmpassos (Priest)
on Jan 24, 2004 at 04:10 UTC ( [id://323782]=perlquestion: print w/replies, xml ) Need Help??

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

When I was making some tests of Class::HPLOO, where multiple documents are filtered in the same process, I found a very strange bug, that only happens if you use my and recursivity in a strange way.

Soo, I tried to isolate the bug and make sample of it:

{ package RecMy ; use strict ; sub rec { my $n = shift ; return if !$n ; rec( --$n ) ; my $local = "[$n] set" if ($n/3) !~ /\./ ; $local .= ' append' ; print "<$n> $local\n" ; } for(1..5) { print "--------------------- $_\n" ; rec(4); } }
The BUGGED output is:
--------------------- 1 <0> [0] set append <1> append <2> append <3> [3] set append --------------------- 2 <0> [0] set append <1> append append <2> append append <3> [3] set append --------------------- 3 <0> [0] set append <1> append append append <2> append append append <3> [3] set append --------------------- 4 <0> [0] set append <1> append append append append <2> append append append append <3> [3] set append --------------------- 5 <0> [0] set append <1> append append append append append <2> append append append append append <3> [3] set append
But the right output should be:
--------------------- 1 <0> [0] set append <1> append <2> append <3> [3] set append --------------------- 2 <0> [0] set append <1> append <2> append <3> [3] set append --------------------- 3 <0> [0] set append <1> append <2> append <3> [3] set append --------------------- 4 <0> [0] set append <1> append <2> append <3> [3] set append --------------------- 5 <0> [0] set append <1> append <2> append <3> [3] set append
And to produce the right output I have just changed one line of the code:
## changed from (bugged): my $local = "[$n] set" if ($n/3) !~ /\./ ; ## to (fine): my $local ; $local = "[$n] set" if ($n/3) !~ /\./ ;

Soo, why this happens? It seems that my() creates the same scalar 2 times? Or the scalar is not destroied after end the scope of the sub? Or this is a optimization bug? I think that this is a reference count bug, but I haven't looked the Perl CORE yet to really say that.

Note that the bug only happens if the interpolation exists, that is made by:

... if ($n/3) !~ /\./ ;
I saw the bug first on Perl-5.6.1, than I saw it on Perl-5.8.2 and Perl-5.8.3 too. Soo, wasn't patched yet!

I will wait some advices from the monks before send it to perlbug...

Graciliano M. P.
"Creativity is the expression of the liberty".

Replies are listed 'Best First'.
Re: This is really a Perl BUG with my?! Need some advice...
by thelenm (Vicar) on Jan 24, 2004 at 04:39 UTC
    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: This is really a Perl BUG with my?! Need some advice...
by davido (Cardinal) on Jan 24, 2004 at 07:36 UTC
    This is not a bug. If Perl behaved in a way contrary to defined behavior, that's a bug. But failure to behaive how you expect, having not read (or remembered) the perldocs, doesn't constitute a bug.

    From perlsub:

    NOTE: The behaviour of a my statement modified with a statement modifier conditional or loop construct (e.g. my $x if ...) is undefined. The value of the my variable may be undef, any previously assigned value, or possibly anything else. Don't rely on it. Future versions of perl might do something different from the version of perl you try it out on. Here be dragons.

    The way it does behaive when attached to an 'if' modifier is simply a side-effect of how my is implemented, but as the perldocs state, it's a side effect that you should not count on, and a construct that you shouldn't use; "Here be dragons."


    Dave

      If I recall correctly, there has been talk about fixing this so my $x ... if ... acts like my $x; $x ... if .... I originally had a negative reaction to that, since the my $x if 0 had been advocated by some as a valid way to produce a semi-static variable, but now, given that that warning has been in the doc since 5.8.0, I think its a good idea. People mess themselves up by accident too much to care about those intentionally doing it. (The doc warning should probably be added to 5.6.2, also.)
Re: This is really a Perl BUG with my?! Need some advice...
by asarih (Hermit) on Jan 24, 2004 at 04:37 UTC
    I don't think this is a bug at all.

    When $n/3 does not contain a dot, that statement is not executed at all, thus preserving the value of $local from the previous iteration.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://323782]
Approved by neuroball
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (5)
As of 2024-04-16 04:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found