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

basically, i'm doing this: (full cod below)$test{ shift @array } = \@array; to set up a little hash, which works fine and outputs this (no, CGI::Pretty isn't broken, i changed this slightly to save screen space =):

<TABLE><TR> <TD>1</TD> <TD>2</TD> <TD>3</TD> <TD>4</TD> <TD>5</TD> <TD>6</TD> <TD>7</TD> <TD>8</TD> <TD>9</TD> </TR> </TABLE>

I realize I only want a few members of the array so change it to: $test{ shift @array } = \@{ [ @array[0,1,2] ] }; which makes the output:

<TABLE><TR> <TD>1</TD> <TD>1</TD> <TD>2</TD> <TD>3</TD> </TR> </TABLE>

Is it just me or should 1 no longer be in @array?

full script with funky line:

use strict; use warnings; use CGI; use CGI::Pretty; my %test; my @array = qw(1 2 3 4 5 6 7 8 9); my $q = new CGI; $test{ shift @array } = \@{ [ @array[0,1,2] ] }; print $q->start_table(-border=>"1"); print map { $q->Tr($q->td($_),$q->td($test{$_})) } keys %test; print $q->end_table(), "\n\n";
"A man's maturity -- consists in having found again the seriousness one had as a child, at play." --Nietzsche

Replies are listed 'Best First'.
Re: i thought i understood shift...
by merlyn (Sage) on Jan 06, 2001 at 00:23 UTC
    Don't use something that alters @array on the left side of the same assignment as accessing @array on the right. Order of execution is not guaranteed. And your taking a reference to a dereference of a reference made from a list constructed from something that was already a list (whew!) has me dizzy.

    Also, learn to use the shortcuts of CGI.pm. Even Lincoln avoids the object-oriented form for short programs.

    Some code:

    my @array = qw(1 2 3 4 5 6 7 8 9); my %test; my $where = shift @array; $test{$where} = [splice @array, 0, 2]; ...
    Don't put the shift in the same expresssion as the splice. Order of execution not guaranteed. One other way to do it:
    $test{$_} = [splice @array, 0, 2] for shift @array;
    which is nice because it eliminates the intermediate variable. Even weirder:
    $_ = [splice @array, 0, 2] for $test{shift @array};
    which still works because we know the shift has to happen before the splice.

    -- Randal L. Schwartz, Perl hacker

Re: i thought i understood shift...
by chipmunk (Parson) on Jan 06, 2001 at 00:26 UTC
    The right-hand side of an assignment is always evaluated before the left-hand side. (This is what allows for chained assignments, like $x = @y = 7.) In your first snippet, you create a reference to an array, then shift the first value off the same array. In the second snippet, however, you create a new array with the first three elements of the original array, and then shift the first value off the old array.

    I think this situation is not best handled with a single line of code:

    my $key = shift @array; $test{$key} = [ @array[0,1,2] ];
    BTW, \@{ [ LIST ] } creates a reference to an anonymous array, dereferences the reference to the anonymous array, and then creates a new reference to the anonymous array. That's a bit silly... :)