tags:

views:

820

answers:

4

I'm looking at the following code snippet:

my @ret = <someMethod>
return (undef) if( $DB_ERROR );
return (undef) unless ($#ret >= 0);

Does $# just give you a count of elements in a array?

+22  A: 

$#arrayname gives you the index of the last element, so if array @ret has 2 elements then $#ret is 1.

And, as noted by Barry Brown, an empty array gives -1.

To get the length you can use the array in scalar context:

print scalar @ret;
Ed Guiness
Also, if @ret has nothing in it, $#ret will return -1.
Barry Brown
+5  A: 

Be aware that the $#array expression will return -1 when array has zero elements.

Quantum Omega
+19  A: 

edg is correct, but the original code is unnecessarily obtuse. In most cases, $#foo is a red flag that the code could be written more simply using scalar @foo.

return (undef) unless ($#ret >= 0);

unless foo >= bar is difficult to puzzle out. First, turn it into a positive statement.

return (undef) if ($#ret < 0);

When is $#ret < 0? When it's -1. A $#ret of -1 is an array of length 0. So the above can be written much more simply as...

return (undef) if scalar @ret <= 0;

But you can't have a negative length array, so...

return (undef) if scalar @ret == 0;

And == is in scalar context, so that "scalar" is redundant...

return (undef) if @ret == 0;

But that's just a wordy way of saying "if @ret is false".

return (undef) if !@ret;

Which I think for simple statement modifiers is better expressed with unless.

return (undef) unless @ret;

Isn't that easier to follow?

As a final side-note, return undef is discouraged because it does the wrong thing in list context. You get back a list containing one undef element, which is true. Instead, just use a blank return which returns undef in scalar context and an empty list in list context.

return unless @ret;
Schwern
And one place where $#foo isn't a red flag would be in an array slice... my @five_to_end = @foo[ 5 .. $#foo ];
draegtun
Mighty fine simplification!
fatcat1111
Re: `return undef` being discouraged. In some cases, you do want to return an explicit `undef` even in list context. It depends on how the function is usually used. It's not that you shouldn't use `return undef`, it's just that you shouldn't use it without thinking "why am I using `return undef` here?" If you have a good answer, then go ahead and do it.
cjm
A: 

To summarize everyone else, that code is much more legible if written like this:

my @ret = someMethod();
return if $DB_ERROR;
return unless @ret;
Rob Van Dam