in reply to Re^2: Dereferenced Arrays
in thread Dereferenced Arrays
You might like PerlTidy. It doesn't do comments, but it does do a good job of normalizing your code layout. It has reasonable defaults which you can override if you prefer some other style. It formats your code as:
poo( [ 1 .. 4 ], [ "goo", "doo", "moo" ], [ 6 .. 9 ] ); sub poo { my ( $first, $second, $third ) = @_; my @array = @{$second}; my $second = shift(@array); my $length = length($second); print( "@array", " $second", " $length\n" ); @array = @{$first}; my $first = shift(@array); my $length1 = length($first); print( "@array", " $first", " $length1\n" ); @array = @{$third}; my $third = shift(@array); my $length2 = length($third); print( "@array", " $third", " $length2\n" ); my $result = $length + $length1 + $length2; print("$result\n"); }
Not much different, but very easy to do.
I would use strict and warnings. If you did, you would see warnings like the following:
"my" variable $second masks earlier declaration in same scope at test. +pl line 9. "my" variable $first masks earlier declaration in same scope at test.p +l line 13. "my" variable $third masks earlier declaration in same scope at test.p +l line 17. test.pl syntax OK
These are warnings, not errors, but I generally code to avoid such warnings. In this case, you could simply omit the my on the indicated lines.
Then I would add some white space to make the structure of your subroutine a little easier to see:
sub poo { my ( $first, $second, $third ) = @_; my @array = @{$second}; $second = shift(@array); my $length = length($second); print( "@array", " $second", " $length\n" ); @array = @{$first}; $first = shift(@array); my $length1 = length($first); print( "@array", " $first", " $length1\n" ); @array = @{$third}; $third = shift(@array); my $length2 = length($third); print( "@array", " $third", " $length2\n" ); my $result = $length + $length1 + $length2; print("$result\n"); }
For each array in the input you are printing all the elements of the array, with what was the first element after the last element, all followed by the length of the first element. In addition, you are summing the lengths of the first elements. For this, I would use something like the following:
sub poo { my ( $first, $second, $third ) = @_; my $total_length = 0; foreach my $array_ref (@_[1,0,2]) { print join(' ', @$array_ref[1..$#$array_ref,0]), ' ', length($array_ref->[0]), "\n"; $total_length += length($array_ref->[0]); } print "$total_length\n"; }
Or, a little more tersely:
sub poo { my $total_length = 0; foreach (@_[1,0,2]) { print join(' ', @$_[1..$#$_,0]), ' ', length($_->[0]), "\n"; $total_length += length($_->[0]); } print "$total_length\n"; }
Or perhaps a little more verbosely and less efficient (copying data), but easier to read (at least for me):
sub poo { my $total_length = 0; foreach my $array_ref (@_[1,0,2]) { my ($first, @rest) = @$array_ref; my $length = length($first); print "@rest $first $length\n"; $total_length += $length; } print "$total_length\n"; }
And, finally, if the order in which the array details were printed didn't matter, I would not bother with the array slice in the foreach loop, leaving:
sub poo { my $total_length = 0; foreach my $array_ref (@_) { my ($first, @rest) = @$array_ref; my $length = length($first); print "@rest $first $length\n"; $total_length += $length; } print "$total_length\n"; }
update: This last version will accept a variable number of arguments (array references). Those using the array slice will produce errors if there are fewer than three and ignore anything after the first three. Whether this is good or bad depends on your requirements.
|
|---|