【问题标题】:Dealing with multiple-inherited constructors in Moose在 Moose 中处理多个继承的构造函数
【发布时间】:2013-02-13 02:03:32
【问题描述】:

您好,

我正在学习 Moose 并且我正在尝试使用 Moose 编写一个 CGI::Application 子类,由于 CGI-App 不是基于 Moose 的事实,这使得这变得困难。

在我的其他 CGI-App 子类中,我喜欢有一个带有 setup 方法的父类,它查看子类的符号表并自动设置运行模式。我想我可以使用 Moose 的元类工具以更简洁的方式实现相同的目标。所以这是我在父类中的内容:

use MooseX::Declare;

class MyApp::CGI 
extends Moose::Object
extends CGI::Application { 

    method setup { 
        $self->start_mode( 'main' );

        my @methods = map { $_->name } $self->meta->get_all_methods;

        $self->run_modes( map  { /^rm_(.+)$/  => $_ }
                          grep { /^rm_/ }
                          @methods
                        );
    }

}

...在我的孩子班里:

use MooseX::Declare;

class MyApp::CGI::Login 
extends MyApp::CGI { 
    method rm_main { 
        return "it works";
    }
}

我意识到我的运行模式没有正确设置的原因是因为setup 被 CGI-App 构造函数调用,而Moose::Object 在我的类中粘贴了它自己的构造函数。我试图用方法修饰符解决这个问题:

around new { 
    $self = $orig->( @_ );
    $self->CGI::Application::new( @_ );
}

这给了我

Can't call method "BUILDARGS" on unblessed reference at ...Moose/Object.pm line 21.

然而,我有一种感觉,我以完全错误的方式处理这件事,而 Moose 有更好的工具来实现我想要的,我还没有发现。

【问题讨论】:

    标签: perl oop moose mop cgiapp


    【解决方案1】:

    你已经看过Moose::Cookbook::Basics::DateTime_ExtendingNonMooseParentMooseX::NonMoose了吗?

    更新:我对 Moose 和各种技术不是很熟悉。我无法让模块一起使用MooseX::DeclareMooseX::NonMoose 进行编译。但是,这似乎可行:

    应用程序基类

    package My::App;
    
    use Moose;
    use MooseX::NonMoose;
    extends 'CGI::Application';
    
    sub setup {
        my $self = shift;
        $self->start_mode( 'main' );
    
        $self->run_modes(
            map { $_ = $_->name;
                  /^rm_ (?<rm>.+) $/x ? ( $+{rm} => $_ ) : ()
            } $self->meta->get_all_methods
        );
    }
    
    "My::App"
    

    派生类

    package My::Login;
    use Moose;
    extends 'My::App';
    
    sub rm_main { 'it works!' }
    
    "My::Login"
    

    脚本

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    # For testing on the command line
    use FindBin qw( $Bin );
    use lib $Bin;
    
    use My::Login;
    
    my $app = My::Login->new;
    
    $app->run;
    

    输出

    C:\Temp\f> t
    Content-Type: text/html; charset=ISO-8859-1
    
    it works!
    

    【讨论】:

    • 谢谢。我无法让 MooseX::NonMoose 正常工作,但我能够使用 Cookbook 中的配方让我的基类从 CGI-App 正确继承。
    • @friedo 感谢您接受我的回答。我在想一定有办法让MooseX::DeclareMooseX::NonMoose 玩得很好,但我想不通。
    猜你喜欢
    • 2011-07-06
    • 2014-04-30
    • 1970-01-01
    • 2011-05-06
    • 2021-12-08
    • 2013-10-18
    • 1970-01-01
    • 2015-01-17
    • 2015-11-08
    相关资源
    最近更新 更多