in reply to Re: check for wantarray?
in thread check for wantarray?

    The answer is that only by running the program you can answer your question.

OK, but how can I answer this by running??? 

I'm calling different subs in list context. Some return a reference 
of an array, others return an array by list.

How can I distinguish both if the the array has only one element, 
a reference of an array?

Even calling both a second time in scalar context doesn't help.

Replies are listed 'Best First'.
Re^3: check for wantarray?
by ikegami (Patriarch) on Dec 26, 2008 at 12:02 UTC

    [ Please don't use <pre>. All you have to do is put <p> in front of every paragraph. ]

    I don't think CountZero meant to imply that it's possible by running the program, only that it can be impossible without running the program. Such is the nature of dynamic languages such as Perl.

    How can I distinguish both if the the array has only one element, a reference of an array?

    By reading the docs. There's no way to know programatically.

Re^3: check for wantarray?
by bageler (Hermit) on Dec 27, 2008 at 00:46 UTC
    If this is a problem you can call all subroutines in array context and examine the first and possible remainder of the array elements for expected return values.
    @ret = somesub(); if (ref $ret[0] eq 'HASH') { .... } elsif (ref $ret[0] eq 'ARRAY') { .... }
    etc. Messy but would take care of the problem. This is how I handle some XML data structures deparsed from API calls to certain applications that can return an array of hashrefs, an arrayref of hashrefs, a single hashref or undefined.

      If this is a problem you can call all subroutines in array context

      It's called list context. Arrays have nothing to do with it.

      Messy but would take care of the problem.

      Not necessarily.

      sub f { return @_ } sub g { return [ @_ ] } my $d = []; my @f = f($d); printf("%d element(s), first=%s\n", 0+@f, $f[0]); my @g = g($d); printf("%d element(s), first=%s\n", 0+@g, $g[0]);
      1 element(s), first=ARRAY(0x235f6c) 1 element(s), first=ARRAY(0x236020)

      This is how I handle some XML data structures deparsed from API calls to certain applications that can return an array of hashrefs, an arrayref of hashrefs, a single hashref or undefined.

      Let's hope not since your code can't differentiate between list of hashrefs and a single hashref. The latter is just a short list of hashrefs. (I presumed you meant "list of hashref" when you said "array of hashref" since it's impossible to return an array.)

Re^3: check for wantarray?
by CountZero (Bishop) on Dec 28, 2008 at 14:48 UTC
    You will have to examine the return value(s).
    • If more than one value is returned, the sub returned a list, you will then have to examine each element (see next bullet point).
    • If only one value is returned, the ref function can help you to determine what kind of value was returned.
    • From the docs:
      ref EXPR ref
      Returns a non-empty string if EXPR is a reference, the empty string otherwise. If EXPR is not specified, $_ will be used. The value returned depends on the type of thing the reference is a reference to. Builtin types include:
      • SCALAR
      • ARRAY
      • HASH
      • CODE
      • REF
      • GLOB
      • LVALUE
      If the referenced object has been blessed into a package, then that package name is returned instead. You can think of ref as a typeof operator.

      CountZero

      A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

      IMHO missed the OP's crucial question:

      How can I distinguish both if the the array has only one element, a reference of an array?

        One cannot, for the simple reason that no array is ever returned by a sub. A sub returns a list and a single element list is indistinguishable from a scalar (and as you know a scalar can also contain a reference or an object, which is just a blessed reference). IMHO the question is therefore irrelevant.

        CountZero

        A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James