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

I hope this isn't a dumbass question, cuz I've already wasted 4 hours on it. The question really has nothing to do with AUTOLOADing in general, I've only mentioned it so you'll know why I don't know what the function returns.

I'm attempting to do an AUTOLOAD thing to give my API programmers access to a new feature. I want to do this transparently. So, I came up with this scheme

# this is something like the code from my AUTOLOAD # if they call the function the old way, we never # get in here... if they call the function with # _r on the end, it gets here, strips off the _r # and calls the old function. :) API->use_the_new_way $return_value = &{ $func }( @_ ); API->go_back_to_the_old_way return $return_value;

The problem is, sometimes the $func doesn't return a scalar, sometimes it might be a filehandle or a hash or something... I don't even know how to approach this problem, or how to phrase it. ... Unless I get a really good hint, I'll just keep chugging on it...

It occured to me that this might not be the best design in the whole wide world. That doesn't bother me, I still want to know how to do this (even if I never use it for anything).

Replies are listed 'Best First'.
Re: uber-reference
by merlyn (Sage) on Dec 30, 2000 at 00:35 UTC
    API->use_the_new_way; my @result; if (wantarray) { @result = $func->(@_); } else { $result[0] = $func->(@_); } API->go_back_to_the_old_way; return wantarray ? @result : $result[0];

    -- Randal L. Schwartz, Perl hacker

      update: I had no idea that wantarray was a function when I first wrote this response... I figured that was pseudo-code or something. :) Who knew (besides merlyn and everyone)?


      This is sorta what we've been thinkin' about doing, where the wantarray would get decided depending on weather or not the function was called with _r or _ra, but I really really wanted a way where we didn't have to specify the wantarray... that it would just figure it out on it's own ...

      oh well eh... *sigh*

      we were also thinkin' like:

      API->new_way; my @ret = $func->(@_); API->old_way; return @ret==1 ? $ret[0] : @ret;
      Which is a solution we just came up with a little while ago ... I can't think of any reason why it wouldn't work since it would probably work with hashes, arrays, scalars, and ... what else is there? Can you think of an reason why this method is dumb?

        But merlyn's way does figure it out automatically on its own.

                - tye (but my friends call me "Tye")
(tye)Re: uber-reference
by tye (Sage) on Dec 30, 2000 at 01:12 UTC

    I was going to propose basically what merlyn wrote above (except also preserving void context rather than transposing it into regular scalar context).

    Thinking further on it, I'd like Perl to provide more context information at some point so it'd be nice to have a solution that would forward whatever context information is available without having to add cases as Perl changes.

    Here is a solution that does that:

    sub __PACKAGE__::NewWay::new { my $class= shift; API->use_the_new_way; return bless [], $class; } sub __PACKAGE__::NewWay::DESTROY { API->use_the_old_way; } sub AUTOLOAD { ... my $newway= __PACKAGE__::NewWay->new(); goto \&$func; # or, if you want to keep AUTOLOAD in the stack trace: # return &$func( @_ ); }
    I haven't tested that so let me know if you have problems with it. ):

            - tye (but my friends call me "Tye")