简体   繁体   English

MooseX :: NonMoose类中mixins的问题

[英]Problem with mixins in a MooseX::NonMoose class

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. 因为当我尝试use CGI :: Application :: Plugin :: *类时,它希望我在编译时继承CGI::Application 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. 插件类试图在我的类上调用add_callback作为类方法,但不能,因为我的@ISA尚未设置。

What's the best way to solve this? 解决这个问题的最佳方法是什么? Would tweaking @ISA manually in a BEGIN block interfere with MooseX::NonMoose ? BEGIN块中手动调整@ISA会干扰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. 关于Moose内部人员我不知道(或任何事情,真的)知道这是不是一个好主意。

I don't find use base 'CGI::Application'; extends 'CGI::Application'; 我找不到use base 'CGI::Application'; extends 'CGI::Application'; use base 'CGI::Application'; extends 'CGI::Application'; to be terribly ghastly because it does precisely what you need: 非常可怕,因为它完全符合你的需要:

  • At compile-time, @ISA contains 'CGI::Application' , which exactly satisfies the usage requirements of CGI::Application::Plugin::* 在编译时,@ @ISA包含'CGI::Application' ,它完全满足CGI :: Application :: Plugin :: *的使用要求
  • At runtime, your class is a Moose descendant of CGI::Application , with all the ensuing benefits (being able to design the composition of your class with Moosey meta goodness). 在运行时,您的类是CGI :: ApplicationMoose后代,具有所有后续的好处(能够使用Moosey meta goodness设计您的类的组合)。 It's only after the extends 'CGI::Application' line is encountered that any work is done (ie methods are called on your class) that rely on the work done by the extends statement: that your class descends from Moose::Object and you have a meta-class installed. 只有在遇到extends 'CGI::Application'行之后才会完成任何工作(即在你的类上调用方法),这些工作依赖于extends语句所做的工作:你的类来自Moose::Object而你安装了一个元类。

That said, jrockway's solution should also work: 也就是说,jrockway的解决方案也应该有效:

BEGIN { extends 'CGI::Application' }

...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 and use MooseX::NonMoose in order to define extends . ...在你需要的时候,你可以提前获得所有Moosey meta goodness,并且它不应该超出预定时间,前提是你已经调用了use Mooseuse MooseX::NonMoose来定义extends

(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. eg something like if Moose.pm declared use compiletime qw(extends) . It would be a nice piece of syntactic sugar for sure.) (附录:现在我正在思考创建强制在编译时强制解析关键字的能力的复杂性,这些解析是立即解析的,例如它们是否包含在BEGIN块中。例如,如果Moose.pm声明use compiletime qw(extends) 。肯定会是一段很好的语法糖。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM