gpt4 book ai didi

perl - 使用已发布的 Moo API 动态修改 Moo 中的方法

转载 作者:行者123 更新时间:2023-12-02 02:46:44 25 4
gpt4 key购买 nike

我试图坚持使用已发布的 API 来动态修改 Moo 中的方法, 并没有提出一个通用的解决方案。

首先,一些代码:

package R1 {
use Moo::Role;
sub r1 { say __PACKAGE__ }
}

package C1 {
use Moo;
sub c1 { say __PACKAGE__ }
}

use Scalar::Util qw[ blessed ];
use Moo::Role ();

my $c = C1->new;
Moo::Role->apply_roles_to_object( $c, 'R1' );

角色申请将说明一种方法的失败。

我尝试了两种方法。

第一个使用 Class::Method::Modifiers :

use Class::Method::Modifiers qw[ install_modifier ];
install_modifier( blessed( $c ),
before => r1 =>
sub { say "BEFORE r1" }
);
$c->r1;

并且工作正常:

% perl test.pl
BEFORE r1
R1

Moo 的内部代码 _install_modifier子例程非常相似,但还执行额外的 Moo 特定操作,因此这种方法并不完全等同。

我尝试的下一个方法是直接使用 $c 可用的 before 修饰符,从而获得额外的 Moo 特殊调味汁:

$c->can('before')->( r1 => sub { say "BEFORE r1" } );
$c->r1;

但是……

% perl test.pl
The method 'r1' is not found in the inheritance hierarchy for class C1 at [...]/lib/site_perl/5.28.0/Class/Method/Modifiers.pm line 42.
Class::Method::Modifiers::install_modifier("C1", "before", "r1") called at /[...]/lib/site_perl/5.28.0/Moo/_Utils.pm line 44
Moo::_Utils::_install_modifier("C1", "before", "r1", CODE(0x5590bb800360)) called at [...]/lib/site_perl/5.28.0/Moo.pm line 84
Moo::before("r1", CODE(0x5590bb800360)) called at test.pl line 25

修饰符似乎是为原始 C1 类生成的,并且在应用 R1 角色时没有更新。以下令人震惊的骇客“修复”了:

use Import::Into;
Moo->import::into( blessed $c );

$c->can('before')->( r1 => sub { say "BEFORE r1" } );
$c->r1;

结果是:

% perl test.pl
BEFORE r1
R1

那么,有没有一种方法可以仅使用已发布的 Moo API 来实现我的目标?

谢谢!

最佳答案

你可以通过应用另一个角色来修改方法(它甚至不必是 Moo::Role 除非你正在处理属性):

use Role::Tiny;
before r1 => sub { say "BEFORE r1" };

只需确保在组成 r1 方法的角色之后应用此角色,或在角色中包含一个虚拟 sub r1 {}(如果已经存在,它将被忽略)。

关于perl - 使用已发布的 Moo API 动态修改 Moo 中的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54391782/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com