A Perl Chicken-and-egg problem
Richard Dice
rdice-e+AXbWqSrlAAvxtiuMwx3w at public.gmane.org
Sat Jun 21 18:58:33 UTC 2008
Hi Paul,
my @A = myobj::files::list(params); // same declaration as in the docs
> foreach $x (@A) {
> print "$x\n";
> }
>
First, I take it that somewhere on the disk you have a file called myobj/
files.pm and there is a "sub list {...}" within it? Also, "params" should
be written "@params".
Also, please make sure you "use strict;" and "use warnings;" in your
programs, and then you will need to lexicalize your 'foreach' loop iteration
variables, making it "foreach my $x ( ... ) { ... }".
On to your ultimate code example:
> my @A = myobj::files::list(params);
> foreach $x (@A) {
> for ($i = 0; $i < 16; $i++) {
> for $j = 0; $j < 16; $j++) {
> print "$x->[$i][$j]\n";
> }
> }
> }
>
> This kind of works. I get the output I expect, except for one thing. I
> don't know the array size, so I am hard-coding the upper limit of the
> loops. $#x to find the size doesn't work, since (1) $x merely points to
> an array, and (2) the array is two dimensional. Any suggestions?
There are two ways to cope with this.
First, you _can_ continue to work with the C-style approach you have written
above and improve it by using the $#ARRAY syntax, but you need to give the
$#ARRAY syntax what it needs in order to work.
my @A = myobj::files::list(@params);
foreach $x (@A) {
for ($i = 0; $i < $#{@$x}; $i++) {
for $j = 0; $j < $#{@{$x->[$i]}; $j++) {
print "$x->[$i][$j]\n";
}
}
}
Here's a small program that might make the technique a bit more explicit.
#!perl
use warnings;
use strict;
my $a = [ 'a' .. 'z', [10 .. 15] ];
print $#{@$a} . "\n";
print $#{@{$a->[$#{@$a}]}} . "\n";
print $a->[ $#{@$a} ][ $#{@{$a->[ $#{@$a} ]}} ] . "\n";
exit 0;
$a is a reference to an array, so it would be analogous to a single element
within your @A array.
I stuff it with the characters 'a' through 'z', which is 26 elements, though
the final element has array element index 25 (since arrays start at index
0). Then I tack on a 27th element (array index 26), which is itself a
reference to an array which contains the integers 10, 11, 12, 13, 14, 15.
This is a list of 6 elements, so its last index has a value 5.
The output of the program is three lines. The first line is "26". The
second line is "5". The third line is "15".
This is the old C-style of doing things. Unless you actually need to know
array indices for some other reason then it's not what I would recommend.
Here's a much simpler Perl-style approach.
my @A = myobj::files::list(@params);
foreach my $x ( @A ) {
foreach my $y ( @$x ) {
foreach my $z ( @$y ) {
print "$z\n";
}
}
}
Other simplifications exist, which may or may not be appropriate to your
situation. Here are some that would work with this (admittedly myopic)
example:
foreach my $x ( myobj::files::list(@params) ) {
foreach my $y ( @$x ) {
print "$_\n" foreach @$y;
}
}
In much the same way that it's possible to program FORTRAN in any language,
it's possible to program C in Perl. I recommend programming Perl in Perl.
:-) An excellent book if you are interested in getting more into the idioms
of programming Perl-as-Perl is "Perl Cookbook", 2nd Edition, by Torkington
and Christiansen, published by O'Reilly.
http://oreilly.com/catalog/9780596003135/
Cheers,
- Richard
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://gtalug.org/pipermail/legacy/attachments/20080621/e1c33fd9/attachment.html>
More information about the Legacy
mailing list