Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

Re: sub returning undef

by adamk (Chaplain)
on May 24, 2004 at 18:53 UTC ( #356018=note: print w/replies, xml ) Need Help??

in reply to sub returning undef

Perl is filled with people offering the best way to do things, often correctly, and sometimes totally not what you expect.

But since variety is the spice of life...

There are three reasonably cohesive ways to return a list, depending on what you are doing one of them should be relevant.

Return normally as a list
The original way is to return the data as a list (returning an array does this), and for the error case just 'return', gives you 'false' in both list and scalar context, the null array in the case of a list context, and undef in scalar context. This is the simplest, but when you want to also signal an error, suffers from tricky testing. In list form, () == error, which can suck when you legally return a null array. In scalar context, well... you only get the number anyways and not the list

You also get similar problems when you 'return undef', as undef returns in list context as a single element array with an undef in it, which is probably not what you REALLY want anyways. And what if a single undef element is a legal return value?

Secondly, we get the exception method, which in perl is essentially "die"ing with the error message. You might use formal exceptions, but they just die underneath. Very clean as you don't have to test for errors everywhere, but if you don't want to be eval/try'ing all the time, or the 'policy' for the code doesn't not allow to use exceptions everywhere, this can get nasty.

Return by reference
My personal favourite, and I suspect the best answer in this situation, return just return the list by reference.

&mysub2(mysub1); sub mysub1{ # Returning something return \@data; # on error return undef; } sub mysub2{ my $result = @_; unless($result){ print "Array is not defined" #Expected out come }else{ print "Exists"; } }
You can then continue as normal.

I actually do something else, where I return defined but false for a null list, which can come in handy for something like

my $rv = getsomething(); die "Error while getting something" unless defined $rv; die "We did not find anything" unless $rv; print "Found " . scalar(@$rv) . " thing(s)\n";
Anyway, I suspect that's something like what you want.

Of course, if you DON'T return an error, I prefer to just return as a list.

For suggestions on a comprehensive return value policy that effectively covers all possible combinations of return value and error(or not), you might like to see, part of my code style policy for myself and my company.

Replies are listed 'Best First'.
Re: Re: sub returning undef
by melora (Scribe) on May 24, 2004 at 19:55 UTC
    I have a question on that notion of returning the list by reference. Would that get you into trouble, if the list you were trying to return were in a variable local to the routine doing the returning? In that case, you're providing a reference to something that is about to wink out of existence, right? Or do I misunderstand what you're saying or how it works? (I don't mean to brag, but my ignorance is vast.)
      Well, in the 'local' sense of local, I'm not sure. You should be using the 'local' keyword only to temporarily overload some global variable ( mainly anyway ).

      In the 'my' sense, which is really 'lexical' I believe, no.

      By returning by reference, you've added a second reference to the same data. The original dissapears, leaving you with 1 again. The data won't be nuked until you get to zero references to the data.
        Ah, I see. Please forgive me; I'm still just beginning to learn about references. Thanks.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://356018]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (4)
As of 2021-12-09 14:07 GMT
Find Nodes?
    Voting Booth?
    R or B?

    Results (36 votes). Check out past polls.