MooseX::NonMoose 类中 mixin 的问题
请考虑以下事项:
package MyApp::CGI;
use Moose;
use MooseX::NonMoose;
use Data::Dumper;
extends 'CGI::Application';
BEGIN {
print "begin isa = " . Dumper \@MyApp::CGI::ISA;
};
print "runtime isa = " . Dumper \@MyApp::CGI::ISA;
...
编译时的输出是:
begin isa = $VAR1 = [
'Moose::Object'
];
runtime isa = $VAR1 = [
'CGI::Application',
'Moose::Object'
];
为什么我关心?因为当我尝试使用
CGI::Application::Plugin::* 类时,它期望我在编译时已经从 CGI::Application
继承。插件类尝试调用 add_callback
作为我的类上的类方法,但不能,因为我的 @ISA
尚未设置。
解决这个问题的最佳方法是什么?在 BEGIN
块中手动调整 @ISA
会干扰 MooseX::NonMoose
吗?
编辑
以下内容似乎有效,但我发现它令人反感:
package MyApp::CGI;
use Moose;
use MooseX::NonMoose;
use base 'CGI::Application';
extends 'CGI::Application';
我对 Moose 内部结构的了解不够(或任何东西,真的),不知道这是否是一个好主意。
Consider the following:
package MyApp::CGI;
use Moose;
use MooseX::NonMoose;
use Data::Dumper;
extends 'CGI::Application';
BEGIN {
print "begin isa = " . Dumper \@MyApp::CGI::ISA;
};
print "runtime isa = " . Dumper \@MyApp::CGI::ISA;
...
The output when this compiles is:
begin isa = $VAR1 = [
'Moose::Object'
];
runtime isa = $VAR1 = [
'CGI::Application',
'Moose::Object'
];
Why do I care? Because when I try to use
a CGI::Application::Plugin::* class, it expects me to be inheriting from CGI::Application
at compile-time already. The plugin class tries to call add_callback
as a class method on my class, but can't, because my @ISA
isn't set up yet.
What's the best way to solve this? Would tweaking @ISA
manually in a BEGIN
block interfere with MooseX::NonMoose
?
Edit
The following appears to work, but I find it offensive:
package MyApp::CGI;
use Moose;
use MooseX::NonMoose;
use base 'CGI::Application';
extends 'CGI::Application';
I don't know enough (or anything, really) about Moose internals to know if this is a good idea.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我找不到 use base 'CGI::Application'; extends 'CGI::Application'; 非常可怕,因为它正是您所需要的:
@ISA
包含'CGI::Application' ,它完全满足 CGI::Application::Plugin::* 的使用要求。
extends 'CGI::Application'
行之后,依赖于extends
声明:您的类源自Moose::Object
并且您安装了一个元类。也就是说,jrockway 的解决方案也应该有效:
...您可以在需要时提前一点获得所有 Moosey 元优点,而且不应该提前太多,前提是您已经调用了
use Moose
和use MooseX::NonMoose
来定义extends
。(附录:现在我正在思考创建在编译时强制解析关键字的能力的编译复杂性,这些关键字会立即解析,例如如果它们被包装在
BEGIN
块中例如,如果 Moose.pm 声明了usecompiletime qw(extends)
这肯定是一个很好的语法糖。)I don't find
use base 'CGI::Application'; extends 'CGI::Application';
to be terribly ghastly because it does precisely what you need:@ISA
contains'CGI::Application'
, which exactly satisfies the usage requirements of CGI::Application::Plugin::*extends 'CGI::Application'
line is encountered that any work is done (i.e methods are called on your class) that rely on the work done by theextends
statement: that your class descends fromMoose::Object
and you have a meta-class installed.That said, jrockway's solution should also work:
...where you get all the Moosey meta goodness just a little ahead of schedule from when you need it, and it shouldn't be too ahead of schedule, provided you already called
use Moose
anduse MooseX::NonMoose
in order to defineextends
.(Addendum: Now I'm pondering the complilational complexities of creating the ability to force the parsing of a keyword at compile-time that are parsed immediately such as if they were wrapped in a
BEGIN
block. e.g. something like if Moose.pm declareduse compiletime qw(extends)
. It would be a nice piece of syntactic sugar for sure.)