Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Re: Can't understand function returning undefs

by jettero (Monsignor)
on Sep 24, 2010 at 20:21 UTC ( [id://861878]=note: print w/replies, xml ) Need Help??


in reply to Can't understand function returning undefs

if( ()=(0,0) ) { print "sometimes you're counting the things in the list and getting +2.\n" } if( (0,0) ) { print "sometimes you're applying the comma operator and getting und +ef (last)\n"; }

if is going to boolean test, so it's rather like this:

use Data::Dumper; print Dumper({ test1=>scalar( 7,13 ), test2=>scalar( ()=(7,13) ) }), " +\n";

Replies are listed 'Best First'.
Re^2: Can't understand function returning undefs
by rg0now (Chaplain) on Sep 24, 2010 at 20:43 UTC
    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?

      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...

      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        

      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
Domain Nodelet?
Node Status?
node history
Node Type: note [id://861878]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (7)
As of 2024-04-19 15:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found