[oak perl] newbie array question

Steve Fink sfink at reactrix.com
Wed Jan 5 12:22:59 CST 2005


Sandy Santra wrote:
> Hi, I'm a very new newbie learning arrays.  Apologies for
> the length of this--it's all just a little hard to grasp
> at this point. 
> 
> I have a perlintro document that says don't bother using
> 
> $#array + 1
> 
> for determining the number of items in an array, implying
> there's a shortcut.  But it doesn't really give me a simple(r)
> way of doing it. 

Usually the easier way is by using @array in scalar context.

my $count = @array;
print "array has $count elements\n";

> I just want the print command to produce the number of items,
> but none of the following work: 
> 
> print @arrayname;
> print '@arrayname';
> print "@arrayname";

print takes a list of arguments, so its arguments are in list context. 
You need scalar context. So any of these will work:

print scalar(@arrayname); # forcing scalar context
print 0+ at arrayname; # addition wants a scalar from both sides
print "". at arrayname; # the . operator wants two scalars too
print @arrayname . " elements in array\n";

The number of occasions when you need to force scalar context through 
one of these tricks is fairly limited (that was the point of the last 
example -- as long as you're not just printing out the length and 
nothing else, it's easy to use a . somewhere and get what you want.)

> I was hoping at least the first of those would, since I
> thought something without quotes usually implied same was
> a number, and Perl is supposed to give me a number when
> it sees @arrayname in a scalar context, right? 

Yep, but print gives its arguments list (aka array) context.

> Seems longer than
> 
> print $#array + 1;
> 
> (if that even works)

It does. But it "smells" wrong. $#array means that index of the last 
element in the array. Yes, you can add one to it and it'll be the same 
as the length, but that's one little logical step that you don't want to 
force the readers of your code to make. That's not to say that you 
should never use $#array. Say you have two parallel arrays and want to 
iterate through them:

   my @names = ('Bob', 'Bruce', 'Bonehead', 'Bob');
   my @ages = (12, 20, 13, 20);

   for my $i (0..$#names) {
     print "$names[$i] is $args[$i] milliseconds old.\n";
   }

Not the greatest data structure for this particular problem, but I find 
myself using parallel arrays reasonably frequently.


More information about the Oakland mailing list