Question

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.

Was it helpful?

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.

OTHER TIPS

No need to eval, you can

use warnings;
sub f (&) {
    my ($func) = @_;
    $func->(); # better than &$func
}

eval on the other hand returns only last element in the list given by $f as it is a same thing as writing eval scalar $func->();, so @b ends up with one element => 4

From perldoc -f eval

the return value of EXPR is parsed and executed as if it were a little Perl program. The value of the expression (which is itself determined within scalar context) is first parsed, and if there were no errors, executed as a block within the lexical context of the current Perl program.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top