Search code examples
perlpromisesyntaxmojoliciouscoderef

Perl Mojolicious: Passing arguments to a code ref


In my Mojolicious Controller, I have:

my @promise;
foreach my $code (\&doit1, \&doit2,) {
    my $prom = Mojo::Promise->new;
    Mojo::IOLoop->subprocess(
    sub {
        my $r = $code->("Hello");
        return $r;
    },
    sub {
        my ($subprocess, $err, @res) = @_;
        return $prom->reject($err) if $err;
        $prom->resolve(@res);
    },
    );
    push @promise, $prom;
}

Mojo::Promise
    ->all(@promise)
    ->then(
    sub {
    my ($result1, $result2) = map {$_->[0]} @_;
    });

This works, and I can pass arguments (e.g. Hello) to my sub.

Now I converted doti1() and doit2() as helpers. So the code looks like:

foreach my $code (sub {$self->myhelper->doit1("Goodbye")},
                  sub {$self->myhelper->doit2("Good night")},
    ) {
    my $prom = Mojo::Promise->new;
    Mojo::IOLoop->subprocess(
    sub {
        my $r = $code->("Hello"); # this is ignored?
        return $r;
    },
    sub {
        my ($subprocess, $err, @res) = @_;
        return $prom->reject($err) if $err;
        $prom->resolve(@res);
    },
    );
    push @promise, $prom;
}

How can I continue to pass the same set of arguments inside the loop (e.g. Hello), without having to specify them in each code ref (i.e. avoid Goodbye & Good night)? I like the idea of passing the same arguments for each code ref: $code->("Hello")


Solution

  • Now I converted doti1() and doit2() as helpers. So the code looks like:

    foreach my $code (sub {$self->myhelper->doit1("Goodbye")},
                      sub {$self->myhelper->doit2("Good night")},
        ) {
        #....
    }
    

    Yes but you are calling the helpers from another anonymous sub,

    How can I continue to pass the same set of arguments inside the loop (e.g. Hello), without having to specify them in each code ref

    so to recover the argument and pass it on the the helper, you just do:

    foreach my $code (sub {my $arg = shift; $self->myhelper->doit1($arg)},
                      sub {my $arg = shift; $self->myhelper->doit2($arg)},
    ) {...}
    

    or more generally as @Dada pointed out in the comments:

    foreach my $code (sub {$self->myhelper->doit1(@_)},
                      sub {$self->myhelper->doit2(@_)},
    ) {...}