http://qs1969.pair.com?node_id=161836

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

I've got an object method which digs into a hash of arrays of arrays and pulls out the last element of each stored array. Here's my code:
sub whatever { my $self = shift; # ... do stuff to set ar_data... # Slice out the last element of each stored array into a new array my @last_elements; push @last_elements, $_->[$#_] for @{$ar_data}; return \@last_elements; }
After grabbing some water, I walked back and realized that @last_elements is (uh-oh) a transitory variable. (and wouldn'tcha know it, I try to look up on the web why transitory variables are bad, and I can't find anything. Dang; I'm sure dominus wrote about this somewhere. Or maybe this is hard water I'm drinking.) So, with a vague idea that some variables are "good" and others are "bad", I wanted to re-write my method to just return the list of @last_elements without actually storing into a list. (Sidenote: or is this foolish? Am I just inviting bogarts into my code?)

After a bit of toying, I realized that there are other ways to iterate over a list than by using for. Enter sort, map, and grep.


#!/usr/bin/perl use strict; use warnings; # fill the 2-d array my @data; for ( 0..2 ) { push @data, [qw 'a bc def' ]; } # try extracting last element from each stored array my @for_data = slice_with_for ( @data ); my @map_data = slice_with_map ( @data ); my @sort_data = slice_with_sort ( @data ); my @grep_data = slice_with_grep ( @data ); # show the y-axis slices print "for : @for_data\n"; print "map : @map_data\n"; print "sort: @sort_data\n"; print "grep: @grep_data\n"; exit; sub slice_with_for { my @slice_me = @_; my @last_fields; push @last_fields, $_->[2] for @slice_me; @last_fields; } sub slice_with_map { my @slice_me = @_; return map { $_->[2] ? $_->[2] : () } @slice_me; } sub slice_with_sort { my @slice_me = @_; sort { $a->[2] cmp $b->[2] } @slice_me; } sub slice_with_grep { my @slice_me = @data; grep { $_->[2] } @slice_me; } exit;
Prints:
for : def def def
map : def def def
sort: ARRAY(0x80fad5c) ARRAY(0x810c844) ARRAY(0x810c7c0)
grep: ARRAY(0x80fad5c) ARRAY(0x810c844) ARRAY(0x810c7c0)

My questions:
1. What other ways are there to iterate over the list besides for, sort, map, and grep?
2. Why don't my slice_with_grep and slice_with_sort functions return what I'm expecting?
3. Am I drunk, or is the water? That is, have I invented this whole notion of a "transitory variable", or is it really something that exists (albeit momentarily) and should be avoided?

blyman
setenv EXINIT 'set noai ts=2'