in reply to Auto-detecting returned or passed variable type

if pigs could fly...

Your challenge doesn't make sense from a Perl perspective. You are abusing the terminology.

The types of values a subroutine returns is not decided by the subroutine, but by the caller. Therefore, your challenge is meaningless. And it can never return "an array" or "a hash". It'll be a scalar or a list, depending on the context in which it's called.

-- Randal L. Schwartz, Perl hacker
Be sure to read my standard disclaimer if this is a reply.

  • Comment on •Re: Auto-detecting returned or passed variable type

Replies are listed 'Best First'.
Re^2: Auto-detecting returned or passed variable type
by richard5mith (Beadle) on Aug 19, 2004 at 20:12 UTC

    I think I'm just not explaining myself well.

    Here's a rough example...

    $result = $obj->functionA($obj->functionB());

    I want whatever function B returns to be passed as a reference to function A. I don't know what function B is going to return because that whole line is generated by a Parse::RecDescent grammar which is writing the Perl script based on the parsing of a scripting language I designed.

    If I knew functionB was always going to return a list, I could do...

    $result = $obj->functionA([ $obj->functionB() ]);

    Or if I knew it was going to be a hash...

    $result = $obj->functionA({ $obj->functionB() });

    I've thought of writing a function which takes in some values and returns a reference to them, whatever they might be...

    $result = $obj->functionA($obj->createrightreftype($obj->functionB()));

    But I can't think of any way to make createrightreftype do the right thing.

    Does that make any more sense? I'm finding it difficult to describe this.

      $result = $obj->functionA($obj->functionB());
      That's going to be calling method functionB in a list context. Therefore, the one and only answer you can have in Perl is "it is returning a list". Every other thing you think it might be doing is not happening.

      Your statement of "always going to return a list" is therefore true. Your statement of "going to be a hash" is therefore always false.

      I don't see the confusion here. It's the caller that decides what the called routine returns. It's that simple.

      -- Randal L. Schwartz, Perl hacker
      Be sure to read my standard disclaimer if this is a reply.

        My thinking is that is functionB does...

        return %myhash;

        ...then it's therefore returning a hash. In which case to pass a reference to that to functionA it would have to be...

        $obj->functionA({ $obj->functionB() });

        But if functionB did...

        return @myarray;

        Then I'd have to do...

        $obj->functionA([ $obj->functionB() ]);

        And it functionB did return...

        return $scalar or return \$ref

        Then it would be...

        $obj->functionA($obj->functionB());

        My problem is that I don't know which one of those four possibilities functionB is going to do, and therefore don't know whether to wrap it in braces (for a hash ref) or square brackets (for an array ref) or nothing (for a scalar, or if it's already a reference).

        You have got me thinking however that I should always be doing the square bracket array reference however, because functionA can always find a way to deal with that.