Perl Mojolicious:将参数传递给代码引用

huangapple go评论64阅读模式
英文:

Perl Mojolicious: Passing arguments to a code ref

问题

In Mojolicious Controller, you can continue to pass the same set of arguments ("Hello") inside the loop without specifying them in each code reference by using a closure. Here's how you can modify your code to achieve this:

my @promise;
my $common_arg = "Hello"; # Define the common argument outside the loop

foreach my $code (
    sub { $self->myhelper->doit1($common_arg) },
    sub { $self->myhelper->doit2($common_arg) },
) {
    my $prom = Mojo::Promise->new;
    Mojo::IOLoop->subprocess(
        sub {
            my $r = $code->(); # Call the code reference without arguments
            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] } @_;
        }
    );

By defining $common_arg outside the loop and then using it inside the code references, you can pass the same argument "Hello" to each code reference without specifying it explicitly in each one.

英文:

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")

答案1

得分: 5

> 我现在已将 doti1()doit2() 转为辅助函数。所以代码看起来像这样:

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

但是你正在从另一个匿名子例程中调用这些辅助函数,

> 如何在循环中继续传递相同的一组参数(例如 Hello),而不必在每个代码引用中都指定它们

所以为了恢复参数并将其传递给辅助函数,你只需这样做:

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

或者更一般地,如评论中 @Dada 指出的:

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

> 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(@_)},
) {...}

答案2

得分: 3

以下是已翻译好的部分:

只是一个注释...

先前建议如下:

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

也可以这样写:

for my $method (qw( doit1 doit2 )) {
   ...
   $self->myhelper->$method( "Hello" )
   ...
}

这是一个不太通用的解决方案,但更简单且更快速。

甚至可以考虑将获取帮助程序单独提取出来。

my $myhelper = $self->myhelper;

for my $method (qw( doit1 doit2 )) {
   ...
   $myhelper->$method( "Hello" )
   ...
}
英文:

Just a comment...

The following was previously suggested:

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

It could also be written as follows:

for my $method (qw( doit1 doit2 )) {
   ...
   $self->myhelper->$method( "Hello" )
   ...
}

It's a less general solution, but it's simpler and faster.

You might even want to factor out obtaining the helper.

my $myhelper = $self->myhelper;

for my $method (qw( doit1 doit2 )) {
   ...
   $myhelper->$method( "Hello" )
   ...
}

huangapple
  • 本文由 发表于 2023年6月1日 12:00:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/76378581.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定