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

Odd splice behavior between perl/OS versions

by SimonSaysCake (Beadle)
on Oct 28, 2016 at 17:53 UTC ( #1174907=perlquestion: print w/replies, xml ) Need Help??

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

I was recently working with Perl's splice function and ran into an anomaly. In this case I was testing on Windows via WAMP running ActiveState Perl ver. v5.16.3. Everything looked good but when I ran the same code on one of our Linux severs (RedHat), this one running Perl ver. v5.10.1 (yes, it's old and someday it will no longer be), I got a different result which really surprised me. Here is the code in question and the different outputs:

#!/usr/local/bin/perl use strict; use warnings; my @stuff = qw(one two three four five six seven eight nine ten); print "Before:\n\n", join(",", @stuff), "\n"; splice(@stuff, $#stuff, 0, splice(@stuff, 3, 1)); splice(@stuff, $#stuff, 0, splice(@stuff, 3, 1)); splice(@stuff, $#stuff, 0, splice(@stuff, 3, 1)); print "\nAfter:\n\n", join(",", @stuff), "\n"; exit 1;

On my Windows 10 workstation with Perl v5.16.3 I get what I expect:

Before: one,two,three,four,five,six,seven,eight,nine,ten After: one,two,three,seven,eight,nine,ten,four,five,six

But on the Linux box with Perl v5.10.1 I get something else:

Before: one,two,three,four,five,six,seven,eight,nine,ten After: one,two,three,seven,eight,nine,four,five,six,ten

Our other Linux server (Ubuntu) is running Perl ver. v5.14.2 and the test script's output on that box is the same as my Windows 10/WAMP output so it would seem to be, at least in part, a Perl version issue.

I searched here and Googled around and was surprised not find anything about this. The only reference to a change in splice's behavior that I found is regarding allowing it to accept an array ref for its EXPR argument starting with 5.14. That's considered experimental behavior and doesn't apply here since I've chosen not to use refs.

Any idea why the change in behavior? Bug? Thanks for any insight you can offer.

-Simon

Replies are listed 'Best First'.
Re: Odd splice behavior between perl/OS versions
by dave_the_m (Monsignor) on Oct 28, 2016 at 19:14 UTC
    Between 5.10.0 and 5.12.0 the way $#array is handled in rvalue context changed. In lvalue context, that expression returns a magic value which, when assigned to, updates the array's length. In 5.10.0, a similar magical value was also returned in rvalue context, which delayed evaluation of the array's length until the second (left-most) split was being done. In 5.12.0 onwards, the rvalue $#array expression is evaluated immediately.

    This appears to be intentional:

    commit 02d85cc37a4acecafdc2f0b45640b03cd1f4ac71 Author: Eric Brine <ikegami@adaelis.com> AuthorDate: Fri Oct 23 19:05:40 2009 -0400 Avoid adding magic with rvalue $#a

    Dave.

Re: Odd splice behavior between perl/OS versions (undefined)
by tye (Sage) on Oct 28, 2016 at 19:14 UTC

    The behavior depends on the order in which different parts of the operation are done. If this were C code, then it would be labeled "undefined behavior". Since it is Perl code, the strict meaning of that phrase from the C standard doesn't quite apply. But it is the type of behavior that is the most likely to end up changing when mundane maintenance is done on Perl's source code, including optimizations.

    I believe the crux of the difference is whether you get the value of $#stuff passed to the outer instance of splice from before or after the inner instance of splice has removed $stuff[3]. Though I can also imagine more complex ways that a simple optimization, bug fix, or just reworking of Perl's code could cause your code to behave differently.

    Avoid changing @stuff in multiple ways in a single expression and using values like $#stuff from within an expression where that value is changed.

    - tye        

Re: Odd splice behavior between perl/OS versions
by BrowserUk (Patriarch) on Oct 28, 2016 at 19:00 UTC

    If it helps, 5.10.1 on windows produces the same results as on linux:

    C:\test>perl #!/usr/local/bin/perl use strict; use warnings; my @stuff = qw(one two three four five six seven eight nine ten); print "Before:\n\n", join(",", @stuff), "\n"; splice(@stuff, $#stuff, 0, splice(@stuff, 3, 1)); splice(@stuff, $#stuff, 0, splice(@stuff, 3, 1)); splice(@stuff, $#stuff, 0, splice(@stuff, 3, 1)); print "\nAfter:\n\n", join(",", @stuff), "\n"; exit 1; ^Z Before: one,two,three,four,five,six,seven,eight,nine,ten After: one,two,three,seven,eight,nine,four,five,six,ten

    Which is different from 5.22 on the same machine:

    C:\test>\perl22\bin\perl.exe #!/usr/local/bin/perl use strict; use warnings; my @stuff = qw(one two three four five six seven eight nine ten); print "Before:\n\n", join(",", @stuff), "\n"; splice(@stuff, $#stuff, 0, splice(@stuff, 3, 1)); splice(@stuff, $#stuff, 0, splice(@stuff, 3, 1)); splice(@stuff, $#stuff, 0, splice(@stuff, 3, 1)); print "\nAfter:\n\n", join(",", @stuff), "\n"; ^Z Before: one,two,three,four,five,six,seven,eight,nine,ten After: one,two,three,seven,eight,nine,ten,four,five,six

    So it seems to be down to version alone rather than platform.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (3)
As of 2022-10-06 01:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My preferred way to holiday/vacation is:











    Results (26 votes). Check out past polls.

    Notices?