Search code examples
arraysperlreferencereturn-valueperl-data-structures

prototype: return either array or scalar


I am having trouble understanding how to return an array using a subroutine prototype. Here's an example

sub f (&@) {
        my ($func) = @_;        
        eval &$func;
}

my $a = f {return 1};
my @b = f {return (2,1,1,4)};

print "a = ".$a."\n";
print "b = ".scalar(@b)."\n";

This outputs a = 1 and b = 1, but I expect @b to have length four.

I also tried to return the reference \ eval &$func in function f. I can then dereference the scalar ($$a is 1) , but when dereferencing the array (@$b) perl tells me that it is not an array reference.


Solution

  • Prototypes have no effect on whether a subroutine returns a scalar or a list. Use wantarray if you want to know in what context a subroutine was called.

    eval &$func;
    

    The line above first calls the subroutine referred to by $func, in scalar context, then converts its return value into a string and executes that string as a Perl program.

    sub f (&) {
        my ($func) = @_;
        eval { &$func }
    }
    

    This will do what you apparently want (call the subroutine referenced by $func, in the same context (scalar or list) in which f itself was called, within an eval block to catch runtime errors).

    sub f (&) {
        my ($func) = @_;
        eval { $func->(@_) }
    }
    

    This is more modern style, with the -> operator.