我有一个角色声明它需要一个方法(requires
)。
我正在尝试通过在类的符号表中直接定义它来安装该方法。
但是,在某些情况下它可以正常工作,而在其他情况下则不然。
在下文中,WORKS表示没有报告错误,不工作意味着我收到错误:'arole' requires the method 'finddepth' to be implemented by 'aclass'
package arole;
use Moose::Role;
requires 'finddepth';
package anexporter;
sub import {
no strict 'refs';
*{ "aclass::finddepth" } = sub {};
}
package anexporter2;
sub import {
eval "sub aclass::finddepth {}";
}
package aclass;
use Moose;
# WORKS:
# sub finddepth { }
# WORKS:
# BEGIN { *{finddepth} = sub {} };
# DOESN'T WORK:
# use File::Find qw(finddepth);
# DOESN'T WORK:
# BEGIN { anexporter->import };
# WORKS:
# BEGIN { no strict 'refs'; *{ "aclass::finddepth" } = sub { }};
# WORKS:
# BEGIN { anexporter2->import };
with 'arole';
1;
答案 0 :(得分:3)
问题在于,Moose非常努力地追踪方法的来源,以便本地包中未定义的任何内容都不会被意外地视为方法。
如果不是使用原始glob,而是使用Moose元协议来注入导入,这将起作用,因为Moose会知道你正在尝试显式添加方法。
package anexporter {
sub import {
aclass->meta->add_method(finddepth => sub {})
}
}
然而,这确实意味着需要包装CPAN上的任何内容(如File :: Find的finddepth)。由于通常不希望将出口称为方法,因此无论如何都可能需要进行出口。
答案 1 :(得分:0)
您的角色正在寻找名为finddepth的方法;只是从一些其他包中导入它不是一个方法make。我将它包装在一个方法中,因为你的角色方法无论如何都需要将finddepth称为方法,以使所有内容都能正确解析。
# in package aclass
use File::Find;
sub finddepth { shift; File::Find::finddepth(@_) }
这有几个优点:这并不奇怪,它并不神奇,一切都按预期工作。