in reply to Sliced Perl

It Slices! It Dices! It makes Julian fries!

The main trick I learned from this obfuscation is, if the subscripts in a slice go from a negative number to a positive number the resulting list elements "wrap around". So the slice could end up longer than the original array! (Bird does this several times.)

Here are two superfluous example of slices that "wrap"

@a = 0..4; # a simple 5 element array print @a[-2..1], "\n"; # 3 4 0 1 print @a[-5..4], "\n"; # 0 1 2 3 4 0 1 2 3 4

In the "de-obfuscated" code below (I'm not sure it is any clearer than the original(but there are a lot more comments)) I use two different notations in the comments for lists. The first notation uses single quotes and commas to show the list the way you might write the list when writing perl code. The second notation is more compact. It shows the list as it might look after you it through

join '-', @list
. The first method shows a space at the beginning or end of a list clearly the second just shows a dash at the beginning or end when there is a space there.

@j=@a=@p=@h= qw/ J u s t A n o t h e r P e r l H a c k e r . /; # scalar @j == 22; print ( ( ( ( ( @j )[-22..21],q, , # doubles the array & adds a space at the end. )[-45..44] # doubles the double. )[0,23,47,70,44] # Gets 1st char from 1st array, 2nd from 2nd, +etc. ), # 'J','u','s','t',' ' ( ( ( ( ( ( @a # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 )[-7..10] # H-a-c-k-e-r-.-J-u-s-t-A-n-o-t-h-e-r )[-18..17] # Doubles it ),q, , # Add a space at the end )[-8..-1] # last 8 characters ), # 'A','n','o','t','h','e','r',' ' ( ( ( ( ( @p # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 )[-8..11] # l-H-a-c-k-e-r-.-J-u-s-t-A-n-o-t-h-e-r-P )[0,-1] # P-l )[-2..1] # P-l )[1,2] # P-l ) # TRICKY! This is subscript into A-n-o-t-h-e-r +-P-l # The subscript -5..4 gets the 'e','r', in ano +ther )[-10..-2,-5..-4,-1], # 'A','n','o','t','h','e','r',' ','P','e','r', +'l' ( ( ( ( ( ( @h ),q, , # Add a space at the end # 0 1 2 3 4 5 6 7 8 9 0 1 )[11..22] # P-e-r-l-H-a-c-k-e-r-.- # 0 1 2 3 4 5 6 7 8 9 0 )[-8..2] # H-a-c-k-e-r-.- -P-e-r )[9,10,6,7,0..3] # e-r-.- -H-a-c-k )[-5..2] # ' ','H','a','c','k','e','r','.' ) );

So my quesion is, how does perl know I want "-2 -1 0 1" from print -2..1, "\n";, and "3 4 0 1" from print ((0..4)[-2..1]), "\n";?

<shudder>

Or, is this realy some deep magic in the Range Operator?

Replies are listed 'Best First'.
Re: Sliced Perl
by Abigail-II (Bishop) on Jul 31, 2002 at 17:10 UTC
    $, = ", "; $\ = "\n"; print -2 .. 1; print 0 .. 4; print +(0 .. 4) [-2, -1, 0, 1]; __END__ -2, -1, 0, 1 0, 1, 2, 3, 4 3, 4, 0, 1
    (list) [-2] gives you the last but one element of the list, (list) [-1] gives you the last, (list) [0] gives the first, (list) [1] the second.

    Abigail

Re: Re: Sliced Perl
by Bird (Pilgrim) on Jul 31, 2002 at 17:57 UTC
    Nice desconstruction!! I wasn't sure if anyone would take the time to do that. ;)

    I think Abigail already answered your question, but no, there's no deep magic going on. Just make sure you don't lose track of which range of values are your values and which range of values are your subscripts. The range operator results in a list of values in either case, it's just a matter of what you do with that list.

    -Bird