in reply to Re: What I am missing here
in thread What I am missing here

Interestingly, if I pass pop a slice, it seems to operate on the last element in the slice, popping the last element from the array to which that element is a reference. If I pass it a slice of ordinary scalars (not array references) it errors. All this is since version 5.14, by the way; prior to that pop simply demands an array as the first argument. Also, perldoc -f pop says this is experimental behavior, so it'd probably be best to keep dereferencing for now and not count on this.

#!/usr/bin/env perl use Modern::Perl; use Data::Dumper; my @cards = ([qw[0 1 2 3]], [qw[4 5 6 7]], [qw[8 9 A B]], [qw[C D E F]], ); say pop @cards; # pop the last array element [C D E F] say pop @cards[0,1]; # pop from a two-element slice, gets 7 from @$ca +rds[1]; say pop @cards[0]; # pop from a one-element slice, gets 3 from @$ca +rds[0], throws warning say pop $cards[0]; # pop from a scalar array reference, gets 2 from + @$cards[0] say Dumper @cards; # see what's left in the array my @list = (0..15); say pop @list[3..5]; # error, not an ARRAY reference

Aaron B.
My Woefully Neglected Blog, where I occasionally mention Perl.

Replies are listed 'Best First'.
Re^3: What I am missing here
by heatblazer (Scribe) on Mar 21, 2012 at 17:14 UTC

    My only vision of the things here ( and I am a Perl noob) is that pop @ar0,1 is possible by poping index1 and index0 sequentially, the problem with pop @ar0..3 is that you try to pop a list probably, that`s my assumption tho, it may be completely wrong. The problem with pop is more verbal than system, it`s hard for us humans to read than the compiler to turn to 0s and 1s, when I say:

    pop($storage[0]);

    I actually want a scalar variable, but I have to know that $storage[0] is a index to an array from which I`ll pop something. It`s tricky and definitely not a noob-friendly, so noobs like me should read Perl books 2 times more cautiously.

      I guess that you have code that works to your satisfaction. But I thought I'd point this out if you haven't realized it yet.... A Perl 2D structure is very similar to a dynamically built 2D structure in C (not what the compiler does for a static 2D declaration).

      In C I would malloc an array of pointers (the number of rows), then for each row, malloc an array for the data and set the row pointer for that row to point to that array of data. Perl works the same way. @cards is an array of pointers to array.

      You can use the $card[$i][$j] syntax just like in C, card[i][j]. There is no need here to be "popping" anything. You have a mix of Perl ideas with C ideas and this combination creates some confusing code!

      As you write more Perl code, you will find that C style "for" loops are rare. The dreaded "off by one error", which statistically is there most common programming error by many studies, is much less likely in Perl because under most circumstances you don't have to explicitly specify array index bounds like in C. This is a major advantage to Perl.

      There is other "magic" in Perl, for example, the core module Data::Dumper which can dump any data structure of arbitrary complexity - there is no equivalent in C.

      #!/usr/bin/perl -w use strict; use Data::Dumper; my @deck = deck_maker(); print Dumper \@deck; sub deck_maker { my @deck = (); #the deck for returning my @types = ('spades', 'hearts', 'diamonds', 'clubs'); my @cards = ( [2,3,4,5,6,7,8,9,10,'J','Q','K','A'], [2,3,4,5,6,7,8,9,10,'J','Q','K','A'], [2,3,4,5,6,7,8,9,10,'J','Q','K','A'], [2,3,4,5,6,7,8,9,10,'J','Q','K','A'] ); for ( my $i=0; $i < 4; $i++) { for ( my $j=0; $j < 13; $j++) { my $newcard = "$cards[$i][$j] of $types[$i]";##### push(@deck, $newcard); } } return @deck; #return the new deck }
      As previously mentioned, I wouldn't write the code this way, but for example, this is possible:
      #!/usr/bin/perl -w use strict; use Data::Dumper; my @deck = deck_maker(); print Dumper \@deck; sub deck_maker { my @deck = (); #the deck for returning my @types = ('spades', 'hearts', 'diamonds', 'clubs'); for ( my $i=0; $i < 4; $i++) { my @cards = ( 2,3,4,5,6,7,8,9,10,'J','Q','K','A'); while (my $card = pop @cards) { my $newcard = "$card of $types[$i]"; push(@deck, $newcard); } } return @deck; #return the new deck }
      Every time Perl sees "my", you get a "new" one. Perl will re-use the same memory if it can. The syntax that you wound up with generates a run-time error. Why get more complicated than necessary? No need to use a multidimensional structure when a 1D structure will work. Note that in my "while" loop, I don't have to know how many cards are there.