Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type of arg 1 must be block or sub {} (not subroutine entry)

the following Python code demonstrates what I want to do in Perl:

def runner(cmd, arg):
    print("runner:", arg)
    cmd()

def run_hooks1(arg):
    def work():
        print("work", arg)

    if (arg):
        work()
    else:
        runner(work, "hello")

run_hooks1(True)
run_hooks1(False)

Output:

work True
runner: hello
work False

I thought it would be simple enough to port this to Perl. So I started with this code:

sub runner(&$) {
    my $cmd = shift;
    my $arg = shift;
    print STDOUT "runner: $arg\n";
    &{$cmd}();
}

sub run_hooks1($) {
    my $arg = shift;

    sub work() {
        print STDOUT "work: $arg\n";
    }

    if ($arg) {
        work();
    } else {
        runner \&work, "hello";
    }
}

run_hooks1(0);
run_hooks1(1);

Unfortunately, this results in:

Variable "$arg" will not stay shared at test.pl line 17.
runner: hello
work: 0
work: 0

Due to this warning, I rewrote run_hooks like this:

sub run_hooks1($) {
    my $arg = shift;

    my $work = sub {
        print STDOUT "work: $arg\n";
    };

    if ($arg) {
        &{$work}();
    } else {
        runner &work, "hello";
    }
}

But now I'm getting:

Type of arg 1 to main::runner must be block or sub {} (not subroutine entry) at test.pl line 23, near ""hello";"
Execution of test.pl aborted due to compilation errors.

I tried multiple other ways to pass the work function to runner but to no avail.

What am I missing?

like image 258
josch Avatar asked Dec 03 '25 14:12

josch


1 Answers

Did you try:

runner \&$work, "hello";

Or just stop using prototypes and do:

runner $work, "hello";

Prototypes in Perl are for when you want some type of magical parsing of calls to your sub, like some builtins get. They are ill suited for just parameter checking such as other languages have.

like image 73
ysth Avatar answered Dec 05 '25 15:12

ysth



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!