处理 Moose 中的多重继承构造函数

发布于 2024-07-25 21:27:24 字数 1436 浏览 5 评论 0原文

您好,

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

在我的其他 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";
    }
}

我意识到我的运行模式未正确设置的原因是因为 CGI-App 构造函数调用了 setup ,并且 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 有更好的工具来实现我想要的东西,而我还没有目前尚未发现。

Greetings,

I'm learning Moose and I'm trying to write a CGI::Application subclass with Moose, which is made difficult by the fact that CGI-App is not based on Moose.

In my other CGI-App subclasses, I like to have a parent class with a setup method that looks at the child class's symbol table and automatically sets up the runmodes. I figure I can use Moose's metaclass facilities to achieve the same thing in a cleaner way. So here is what I have in my parent class:

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
                        );
    }

}

...and in my child class:

use MooseX::Declare;

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

I realized that the reason my runmodes were not getting setup properly is because setup is called by the CGI-App constructor, and Moose::Object is sticking its own constructor in my class. I tried to solve this with a method modifier:

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

This gives me

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

I have a feeling, however, that I'm going about this in completely the wrong way, and Moose has a much better facility for achieving what I want, which I have not as yet discovered.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

春夜浅 2024-08-01 21:27:24

您是否已经看过 Moose::Cookbook::Basics::DateTime_ExtendingNonMooseParent MooseX::NonMoose

更新:我对驼鹿和各种技术不太熟悉。 我无法同时使用 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!

Have you already looked at Moose::Cookbook::Basics::DateTime_ExtendingNonMooseParent and MooseX::NonMoose?

Update: I am not very familiar with Moose and assorted techniques. I was not able to get the modules to compile using MooseX::Declare and MooseX::NonMoose together. However, here is something that seems to work:

Application Base Class

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"

Derived Class

package My::Login;
use Moose;
extends 'My::App';

sub rm_main { 'it works!' }

"My::Login"

Script

#!/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;

Output

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

it works!
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文