[Pdx-pm] New DA question - sub return'd values

Ovid curtis_ovid_poe at yahoo.com
Thu Jan 8 10:13:48 CST 2004


--- "Roderick A. Anderson" <raanders at acm.org> wrote:
> Sometimes I feel like Red (from "That 70's Show) is talking to me!
> 
> When I use 'return N;' -- where N is a number -- in a sub(routine) is
> N
> returned as as a number or a string?

Neither.  In Perl, typing is based around data structures, not data
types.  When you return something in Perl, you're returning one of
three things:  nothing (a bare return), a scalar, or a list.

Assuming you return a scalar, it will behave either as a number or a
string, depending upon whether or not you wish to use it as a number or
a string.  Here's what happens if you return a scalar.

  sub foo {
    # do a bunch of stuff
    return $x;
  }

  my $result = foo(4) + 3; 

For the above snippet, the return value of foo() will be converted to a
number.  If it's undef (or nothing), it will convert it to zero and
$result will be set to four.  If you have warnings enabled, you'll be
warned about "use of uninitialized value in addition".

If the return value is really a number, $result will be set to that
number plus 3.  If the return value is a string, it's a bit odd.  Perl
will try and convert the string to a number and then add three.  Most
strings will be converted to the number zero and get added to three. 
You'll most like get a warning similar to "argument 'bar' isn't numeric
in addition".  If, however, the string begins with a number, you'll get
the same warning, but Perl will use the scalar as if it's that number
and then add three to it.  (note that none of these operations change
the perceived value of the scalar, though, despite what Perl does).

  sub foo {
    return "3apples";
  }
  my $apples = foo();
  print $apples + 2;  # prints 5 and issues a warning if enabled
  

> I ask because I'm having some issues using the values in a (faked)
> switch 
> construct.
> 
> $_ = typeofcust($username, $password);
> 
> CASE: {
> 
>    /1/ and do { ... ;
> 	last CASE; };
>    /2/ and do { ... ;
> 	last CASE; };
>    /3/ and do { ... ;
> 	last CASE; }
>    blow_chunks;
> 
> }
> 
> If typeofcust() returns a value from 1, 2 or 3 is $_ treated as a
> string
> or number by the match operation?

In this case, because you're using a regular expression, the $_ is
automatically treated as a string (regexes do not operate on numbers). 
I might, however, add a "local" statement to the assignment:

  local $_ = typeofcust($username, $password);

If you don't do that and any other place in your code is using $_, you
just altered their value.  That can be a nasty bug to track down.

Also, check out Switch.pm
(http://search.cpan.org/~dconway/Switch-2.09/Switch.pm).  It's more
robust:

  use Switch;

  switch ($val) {
    case 1          { print "number 1" }
    case "a"        { print "string a" }
    case [1..10,42] { print "number in list" }
    case (@array)   { print "number in list" }
    case /\w+/      { print "pattern" }
    case qr/\w+/    { print "pattern" }
    case (%hash)    { print "entry in hash" }
    case (\%hash)   { print "entry in hash" }
    case (\&sub)    { print "arg to subroutine" }
    else            { print "previous case not true" }
  }

Cheers,
Ovid

=====
Silence is Evil            http://users.easystreet.com/ovid/philosophy/indexdecency.htm
Ovid                       http://www.perlmonks.org/index.pl?node_id=17000
Web Programming with Perl  http://users.easystreet.com/ovid/cgi_course/



More information about the Pdx-pm-list mailing list