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

hi guys ! I have a function that returns a scalar if it found one match or an array if it found more then one match (I didn't write it). Is there a short way to know what I got from it(a scalar or array) ?
I can always do:
my @tmp = &someonesFunc(); if (@tmp > 1) { # got an array # do something } else { # got a scalar # do something else }
But I'm sure there's a better way, am I right?

Hotshot

Replies are listed 'Best First'.
Re: array or scalar, that's the question
by Juerd (Abbot) on Jan 01, 2002 at 21:48 UTC
    In list context, every sub returns a list. In scalar context, every sub returns a scalar.
    That's because return "knows" the context the sub is in.
    With @tmp = func(), func() will always return a list. It could be a list with just one item, but it's still a list.

    Note: a sub never returns an array (it could return a list with a reference to an array in it, though)

    Think about rewriting someonesFunc to return a reference, or to use wantarray.

    2;0 juerd@ouranos:~$ perl -e'undef christmas' Segmentation fault 2;139 juerd@ouranos:~$

Re: array or scalar, that's the question
by Aristotle (Chancellor) on Jan 01, 2002 at 23:56 UTC
    All the above certainly is good advice, but what I'm puzzled about is the big picture.

    What do you want to know the difference for? I'm asking because I'm sensing an un-Perlish way of doing things in your approach. I believe you're better served if you tell us why you need this information so we can advise you on your overall approach, not just part of it.

    (To the more versed people: I would also inquire if f.ex I came across someone wanting to use eof - in Perl, it's almost always possible and better to avoid it.)
Re: array or scalar, that's the question
by Parham (Friar) on Jan 01, 2002 at 21:38 UTC
    well it seems like no matter what you do... you're going to end up with an array cuz that's what your returning from &someonesFunc() (you don't need the ampersand on that btw). I think the solution you already have is a very good one and i can't see why you'd want to even change it.

    In both cases though, you're always going to have an array, either with one or more elements.
      to clear things up a little. the function I use (someonesFunc() in the last post) is something from the format:
      if ($x) { return $foo; # returns scalar }else{ return @bar; # returns array }
      I just thought there's a better way then mine to know what it returned, but if you suggest that what I did is good then what that's good enough for me.
      Thanks.

      Hotshot
        Differentiating between a "scalar" and an "array" is meaningless here. When you say "return @bar" Perl flattens @bar into a list.
        $foo = 3; @bar = (1, 2, 3); return $foo; # (3) return @bar; # (1, 2, 3)

        In a scalar context, both of these versions will return 3 (the last element in the list returned). In a list context, you get 3 or 1, 2, 3. Just returning @bar, though, is sufficient for both cases, because it's your calling code that would want to act on the results. Make sense?

        If you're wanting to return a real solid array (so that you can return @foo, @bar without flattening it into one big list), you need to return references to each array.

        return (\@foo, \@bar); ... my ($fooref, $barref) = your_function();
Re: array or scalar, that's the question
by count0 (Friar) on Jan 01, 2002 at 22:26 UTC
    Well, Parham and Juerd summed up the most common ways to do it. But for the sake of tmtowtdi, here is YAW (yet another way ;)

    Rewrite the return portion of someonesFunc() to always return a scalar, either a string/number or an array refrence.
    my $tmp = someonesFunc(); if ($ref $tmp eq 'ARRAY') { # use @$tmp as an array } else { # use $tmp as a scalar }