Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Slice Madness

by japhy (Canon)
on Nov 09, 2005 at 15:14 UTC ( [id://507091]=perlmeditation: print w/replies, xml ) Need Help??

Someone on #freenode::perl just asked if $array[2..4] would return a list of elements. Their mistake was the '$' instead of a '@', but I opened a can of worms by saying that the code as shown would return $array[0] or $array[1], but I couldn't know which.

Then I said that $array[2..4] behaves differently from ($x,$y) = (2,4); $array[$x..$y]. Just for kicks, I post this here. Who knows why the two behave differently?

# given: my @array = qw( A B C ); my ($x, $y, $z) = (0, 1, 2); # explain: $array[0..1] $array[0..2] $array[1..2] $array[$x..$y] $array[$x..$z] $array[$y..$z] $array[$z..$x]
Hint here:

Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart

Replies are listed 'Best First'.
Re: Slice Madness
by pg (Canon) on Nov 09, 2005 at 18:11 UTC

    Doesn't matter whether your explanation is precise. If one uses warnings (like everyone says here), there are plenty of warnings to make one think whether things are right:

    use Data::Dumper; use strict; use warnings; my @array = qw( A B C ); my ($x, $y, $z) = (0, 1, 2); my @a = $array[0..1]; print Dumper(\@a); @a = $array[$x..$y]; print Dumper(\@a);

    Which gives:

    Use of uninitialized value in range (or flip) at math1.pl line 8. Use of uninitialized value in range (or flop) at math1.pl line 8. $VAR1 = [ 'B' ]; Argument "" isn't numeric in array element at math1.pl line 10. $VAR1 = [ 'A' ];

    With all the warnings, one starts to fix things:

    use Data::Dumper; use strict; use warnings; my @array = qw( A B C ); my ($x, $y, $z) = (0, 1, 2); my @a = @array[0..1]; print Dumper(\@a); @a = @array[$x..$y]; print Dumper(\@a);

    Which gives the slice one wanted:

    $VAR1 = [ 'A', 'B' ]; $VAR1 = [ 'A', 'B' ];
      Glad to see that. I was wishing this was a syntax error, but at least it's a warning.
Re: Slice Madness
by duff (Parson) on Nov 09, 2005 at 15:51 UTC

    Nice one japhy but I think you give too much of a hint in your first paragraph :-)

    This is another one of those nodes that I wish I could ++ more

Re: Slice Madness
by Anonymous Monk on Nov 09, 2005 at 18:39 UTC
    *sigh*

    Why do we have to have nasty things like this in our language? :-(

    From perlop: Binary ".." is the range operator, which is really two different operators depending on the context. (emphasis mine)

    I always felt this was a point of needless confusion in perl. If the operator is really two operators, why not create two operators? Just make a range operator (array context only), and a flip flop operator (scalar context only), and report an error if the wrong one is used in the wrong context? That would eliminate this kind of error altogether, and make life easier to all concerned.

    Wouldn't that have been wiser? Is it too late to fix it? Will Perl6 have the same mistake?

    Me, I don't like the flip-flop operator; I didn't understand it when I first ran across it, and now that I do, I still prefer to write my conditionals more verbosely. But I'd put up with it to appease the sed people (if the are any left), and create a range operator (or function), rather than deal with this kind of ugliness for newcomers (or for me when I'm sick, overtired, or called into work in the middle of the night).

    Even a function called "range" that returned a list from the first argument to the last argument would probably do.

    Given that I can write this:

    @range = $x .. $y; @slice = @x[ @range ];
    it shouldn't be that much more confusing to write this:
    @range = range($x,$y); @slice = @x[ @range ];
    and leave the .. for the flip flop.

    Just a thought... --
    Ytrew

      Yes, it's fixed in Perl 6. In fact, it's already fixed in Pugs:

          pugs> say ~(1..10)
          1 2 3 4 5 6 7 8 9 10

      But your solution is bad Huffman coding. Range objects are much more useful than flipflops, and therefore should get the .. operator.
        Yes, it's fixed in Perl 6. In fact, it's already fixed in Pugs:

        Yay! Three cheers for fixing stuff! :-)

        But your solution is bad Huffman coding. Range objects are much more useful than flipflops, and therefore should get the .. operator.

        Either way works for me; I was trying to be charitable to the opposing position. :-) I'll always prefer the solution that lets me keep my favourite syntax (i.e. the range operator), but I didn't know if there were a ton of hidden ex-sed and awk lurkers out there ready to gripe at me if I suggested the range operator be used instead. :-)
        --
        Ytrew

      Perl got where it is via evolution*. Evolution begets cruft. It strikes me as particularly ivory-tower-minded of people to wring their hands over these little throwbacks, particularly considering that Perl was never intended to be elegant. I trust you know where to find Ruby.

      It's not like this thing is something that's constantly tripping people up and making Perl painful to use. It's more of a wart that adds some amusing character. Yes, it's a flaw. What is there to do about it? Break backward-compatibility? That would be a worse flaw. And that's why evolution begets cruft.

      *You were thinking maybe intelligent design?


      Caution: Contents may have been coded under pressure.
        You were thinking maybe intelligent design?

        Yup! Larry certainly designed most of Perl intelligently enough. In some ways, it makes the areas where he didn't more jarring, because they're unexpected, and thus confusing. And by the way, thanks, Larry! :-)

        It's a small nit, but the nits add up. The more of them we can clean up, the better.

        Yes, it's a flaw. What is there to do about it? Break backward-compatibility? That would be a worse flaw.

        Yup. It doesn't have to be a flaw: we can deprecate the feature, like we've done in the past.

        Just add a warning like: "$x .. $y better written as flip_flop($x,$y)" for flip flops. Put in an explanation that flip flops must be written explictly so that they're not confused with the range operator, and in a few years, we could remove the feature entirely.

        Remember, effort at development time is easy. Until the program is put in production, it can be changed without impacting end users. Effort at mainenance time is hard; any change to the program will have to be analysed for it's impact on the end users. Fixing bugs is easy; finding bugs is hard. Giving the users one less bug is worth it, IMHO.

        --
        Ytrew

        Ruby is much perfect as we Japaness are made for perfection. We are made to lead the world to its perfection even it means pain to our own nation and people.

      I just had this exact same thought in Ruby terms today. The idea of the flip-flop operator is ... well ... dumb. It's syntactic sugar that's overloading a rather useful operator (the range) and should be banned. IMNSHO, of course.

      My criteria for good software:
      1. Does it work?
      2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Slice Madness
by itub (Priest) on Nov 09, 2005 at 16:32 UTC
Re: Slice Madness
by Aristotle (Chancellor) on Nov 10, 2005 at 03:26 UTC
    #!/usr/bin/perl use strict; use warnings; sub context { print wantarray ? "list" : defined( wantarray ) ? "scalar" : "void" ; print "\n"; } $_ = $_[ context() ]; @_ = @_[ context() ]; __END__ scalar list

    Makeshifts last the longest.

Re: Slice Madness
by Animator (Hermit) on Nov 09, 2005 at 18:46 UTC

    I think you didn't wrote backwards compatible code...

    Running something that uses these statements on v5.6.1 produces a different result then running the same thing on v5.8.7...

    It returns this on v5.6.1:

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (3)
As of 2024-03-28 18:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found