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

PerlMonks, I have a question for you.

What is the most elegant way to propagate the calling context of a function into another function?

Here's the ugly way:
sub inner_func { if (wantarray) { print "ARRAY CONTEXT\n"; } elsif (defined wantarray) { print "SCALAR CONTEXT\n"; } else { print "VOID CONTEXT\n"; } } sub outer_func { my @result; if (wantarray) { # propagate context @result = inner_func(); } elsif (defined wantarray) { $result[0] = inner_func(); } else { inner_func(); } # do some other stuff return (wantarray ? (@result) : $result[0]); } my @r = outer_func(); my $r = outer_func(); outer_func();

Note that doing
sub outer_func { inner_func() }
doesn't count, since I need to do some work after calling inner_func but before returning the results.

Replies are listed 'Best First'.
Re: Propagating calling context
by merlyn (Sage) on Aug 22, 2000 at 05:25 UTC
    I'd just be straightforward, nearly as you had done, but with less smoke, fewer mirrors:
    sub middle_function { if (wantarray) { my @result = inner_function(); # modify @result as needed @result; } else { my $result = inner_function(); # modify $result as needed $result; } }

    -- Randal L. Schwartz, Perl hacker

      Lemme guess, untested code? :-)

      I wrote the same thing, tried it with his test and realized that he differentiated between scalar and void context. FWIW my first try involved:

      push my @result, wantarray ? &inner_func() : scalar &inner_func();
      then I realized the problem, and came up with:
      sub outer_func { my @result; defined(wantarray) ? (push @result, wantarray ? &inner_func() : scalar &inner_func()) : &inner_func(); # do some other stuff return (wantarray ? (@result) : $result[0]); }
      Ick. :-( There are times you should be verbose. This is one of them...

      Personally I think your approach of separating the cases is cleaner. But honestly I have never once encountered a situation where I needed to propagate context in this manner...

        Personally I think your approach of separating the cases is cleaner. But honestly I have never once encountered a situation where I needed to propagate context in this manner...
        Oddly enough, I did. In the ill-fated chat2.pl. {grin}

        -- Randal L. Schwartz, Perl hacker