Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re^2: Can't understand function returning undefs

by rg0now (Chaplain)
on Sep 24, 2010 at 20:43 UTC ( #861880=note: print w/ replies, xml ) Need Help??


in reply to Re: Can't understand function returning undefs
in thread Can't understand function returning undefs

Thanks. Not that I like this behavior but I think I'll have to live with it.

But if we are at it. My problem is that I have a function that returns two values when data is available to it and when no data remained it returns undef.

sub recv_data{ if(read_some_data){ return($stuff1, $stuff2); } else { return; } }
What I would like to do is to call this function in a while until all data is consumed. I tried to do this first by
while(($x, $y) = recv_data){ ... }
which failed due to the above reasons (i.e., the while block always executed since ($x, $y) = recv_data always evaluates to true even if the function returns undef).

I still have the option to write

while(1){ my($x, $y) = recv_data; last unless defined $x; ... }
but I fail to see this as elegant.

How to organize this code so that I obtain the required behavior in an elegant and readable way?


Comment on Re^2: Can't understand function returning undefs
Select or Download Code
Re^3: Can't understand function returning undefs (explicit)
by tye (Cardinal) on Sep 24, 2010 at 21:01 UTC
    while( defined( ( ($x,$y)= recv_data() )[0] ) )

    But I'd rather do that like:

    my( $x, $y )= recv_data(); while( defined $x ) { ... ( $x, $y )= recv_data(); }

    - tye        

Re^3: Can't understand function returning undefs
by AnomalousMonk (Abbot) on Sep 24, 2010 at 21:24 UTC
    sub recv_data{ if(read_some_data){ return($stuff1, $stuff2); } else { return; } }

    The function in your example returns an empty list, not undef, in list context when there is no more data available.

    If your real function actually returns undef in list context (which is 'supplied' to the function by the  ($x, $y) sub-expression in your example code), then the list will always have at least a single item (i.e., undef) and will always evaluate as true; only the empty list or array is false. See the code below for the difference between
        return;
    and
        return undef;

    >perl -le "use warnings FATAL => 'all'; use strict; ; my @pairs1 = qw(1 2 3 4); ; sub S1 { return if not @pairs1; return pop @pairs1, pop @pairs1; } ; my ($x, $y); while (($x, $y) = S1()) { print qq{$x $y}; } ; my @pairs2 = qw(5 6 7 8); ; sub S2 { return undef if not @pairs2; return pop @pairs2, pop @pairs2; } ; while (($x, $y) = S2()) { print qq{$x $y}; } " 4 3 2 1 8 7 6 5 Use of uninitialized value $x in concatenation (.) or string at ...
      The function in your example returns an empty list, not undef, in list context when there is no more data available.
      Thanks for this update. I never actually thought these two cases are different.

      And I thought I knew Perl...

Re^3: Can't understand function returning undefs
by ikegami (Pope) on Sep 24, 2010 at 21:55 UTC

    But if we are at it. My problem is that I have a function that returns two values when data is available to it and when no data remained it returns undef.

    It should return an empty list when no data remains. Compare

    my @a = qw( a b c d ); my $i = sub { @a ? splice(@a, 0, 2) : () }; while (my ($x,$y) = $i->()) { print("$x:$y\n"); }
    with
    my @a = qw( a b c d ); my $i = sub { @a ? splice(@a, 0, 2) : (undef,undef) }; while (my ($x,$y) = $i->()) { print("$x:$y\n"); }

    Update: Added missing semicolons.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (8)
As of 2014-11-27 08:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My preferred Perl binaries come from:














    Results (182 votes), past polls