处理Perl Catalyst中

时间:2016-09-03 15:40:37

标签: perl catalyst

问题

我一直在学习Catalyst Web框架,我正在尝试了解Catalyst如何将URL分发给应用程序“操作”。

似乎我可以用不明确的URL调度规则编写我的应用程序:

package Myapp::Controller::Root {
    __PACKAGE__->config(namespace => '');
    ....
    sub foo :Local {
        my ( $self, $c ) = @_;

        $c->response->body('foo action in Root controller.');
    }
}

package Myapp::Controller::Foo {
    ....
    sub default :Path {
        my ( $self, $c ) = @_;

        $c->response->body('default action in Foo controller.');
    }
}

这两个动作在不同的包中定义,但都与'/ foo / ...'路径相关联。查看上面的代码,不清楚哪个操作优先。当应用程序启动时,Catalyst或多或少随机做出这个决定。有时它是前一个动作,有时候是后者。

请注意,上面的代码是一个人为的例子,我可能不会故意创建映射到同一路径的两个不同的操作。尽管如此,我不知道如何通过查看代码来预测哪个动作最终会被调用。

问题

有没有办法指示Catalyst禁止这种含糊不清或至少提供警告?

1 个答案:

答案 0 :(得分:1)

我不确定是否有一种正式的催化剂方式可以做到这一点,但你可以尝试以下方法,从Catalyst question on how to list all actions in an app轻轻挖走

尝试在App.pm行后面的__PACKAGE__->setup()添加以下内容:

# Start the application
__PACKAGE__->setup();

# Get all known actions and store the action name and source controller
my $controller_map = {};
my @controllers = map { __PACKAGE__->controller($_) } __PACKAGE__->controllers;
for my $controller ( @controllers ) {
    my $controller_name = ref $controller;
    my @actions = $controller->get_action_methods;
    for my $action ( @actions ) {
        my $name = $action->name;
        next if $name =~ m|^_|; # _DISPATCH, _BEGIN, _AUTO, _ACTION, _END
        next if $name eq 'auto';
        next if $name eq 'begin';
        next if $name eq 'index';
        $controller_map->{ $name }->{ $controller_name }++;
    }
}

# Show all action names that come from more than 1 controller
my $bad_action_names = 0;
for my $action ( sort keys %$controller_map ) {
    my @original_controllers = keys %{ $controller_map->{ $action } };
    if ( scalar @original_controllers > 1 ) {
        $bad_action_names++;
        print "Bad Action Names for '$action' : " . join(' ', @original_controllers) . "\n";
    }
}

die "Unable to continue!!!" if $bad_action_names;