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'
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.