PerlBroker has asked for the wisdom of the Perl Monks concerning the following question:

This is SSCCE example code. At the position (A) in the code, I am asking subroutine check_mobiletype to find the ID, and phone number. It does find the ID and phone, at position (B). I don't know why, but at position (C) it says: "Use of uninitialized value $phone in say"...

So, I get kind of dizzy feeling, and trying to find a solution.

#!/usr/bin/perl my $destination = '+123'; if($destination eq 'show') { $show = 1; $destination = shift @ARGV; utf8::decode($destination); $sms = join(" ", @ARGV); # POSITION (A) my ($id, $phone) = check_mobiletype($destination) || die "ID not f +ound"; # POSITION (C) print $id, $phone, "\n"; # ID is not printed } else { $sms = join(" ", @ARGV); die "No text" unless $sms; my ($id, $phone) = check_mobiletype($destination) || die "ID not f +ound"; print $id, ' ', $phone, "\n"; } exit; sub check_mobiletype { my $destination = shift; if($destination =~ /^\+/ && $destination !~ /^\+{1}.*\D/) { print "Type phone number\n"; my $id = get_contacts_id_by_mobilephone($destination) || retur +n 0; my $phone = get_mobilephone($id) || return 0; # POSITION (B) print $id, ' ', $phone, "\n"; # ID and phone are printed return ($id, $phone); } elsif($destination =~ /\d/ && $destination !~ /\D/) { #say "Type ID"; my $id = $destination; my $phone = $tcrm->get_mobilephone($id) || return 0; return ($id, $phone); } } sub get_mobilephone { return '+49121212121'; } sub get_contacts_id_by_mobilephone { return 123456; }

Replies are listed 'Best First'.
Re: refuses to return me 2 values from subroutines
by ikegami (Patriarch) on Jan 18, 2016 at 14:29 UTC
    sub check_mobiletype { my $destination = shift; if($destination =~ /^\+/ && $destination !~ /^\+{1}.*\D/) { my $id = get_contacts_id_by_mobilephone($destination) or return; my $phone = get_mobilephone($id) or return; return ($id, $phone); } elsif($destination =~ /\d/ && $destination !~ /\D/) { my $id = $destination; my $phone = $tcrm->get_mobilephone($id) or return; return ($id, $phone); } return; } my ($id, $phone) = check_mobiletype($destination) or die "ID not found";

    By using or instead of ||, you're checking the result of the assignment (the number of elements returned by its RHS) instead of the result of check_mobiletype. Returning an empty list from check_mobiletype will therefore trigger throwing the exception.

Re: refuses to return me 2 values from subroutines
by Anonymous Monk on Jan 18, 2016 at 13:57 UTC

    Ah, this is a "fun" list issue :-)

    The problem is your use of the || operator. It puts its left hand side in scalar context. The left hand side is the list ($id, $phone). A list in scalar context returns its last element, in this case $phone, which in the calling code gets assigned to $id, and $phone gets nothing (undef). (BTW, you would have come closer to identifying this issue if you had printed $id as well.)

    The fix is two parts: change || to the lower-precedence or, and change the return 0 statements in the sub to plain return; statements. The reason for the latter is that in list context, it will return the empty list. If you continued to return 0, then the returned list still has one element, and the error would not be detected.

    Of course, another, probably better possibly better fix is to make your code more explicit:

    my ($id, $phone) = some_func(); die "oops" unless defined $id; # or whatever the error condition is
      Deeply thankful.