我一直在学习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禁止这种含糊不清或至少提供警告?
答案 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;