3

こんにちは私はコントローラーで同じコードを繰り返したくないので、メインのMyAppパッケージにサブを作成しました:

sub do_stuff {
    my $input = shift;

    do something
}

でもそれならコントローラーで使いたいMyApp::Controller::Foo

sub test : Chained('base') Args(0) {
    my ($self, $c) = @_;

    my $test = do_stuff($c->request->params->{s});

    do something more
}

次のエラーが発生します:

MyApp :: Controller :: Foo-> testで例外が発生しました"未定義のサブルーチン&MyApp :: Controller :: Foo::do_stuffが/home/student/workspace/MyApp/script/../lib/MyApp/Controller/Fooで呼び出されました。午後24行目、1000行目。」

すべてのCatalystコントローラーでグローバルを使用するためのサブルーチン/関数を作成するにはどうすればよいですか?

4

2 に答える 2

4

原則として、メインで使用されたすべてのモジュールですでに使用可能ですMyApp

ただし、メインパッケージで定義されている場合は、その名前空間(mainまたはMyApp名前空間)内から呼び出すか、現在のパッケージ名前空間にインポートする必要があります。

定義された場所に応じて、これらの方法のいずれかを使用します。

my $test = main::do_stuff($c->request->params->{s});
my $test = MyApp::do_stuff($c->request->params->{s});

別の方法は、各パッケージの名前空間にインポートすることです。

package MyApp::Controller::Foo;
if (defined &MyApp::do_stuff) {
  *do_stuff = *MyApp::do_stuff;
}

を使用definedすると、サブルーチンが存在するかどうかを確認できます。


別の注意点として、このサブはExporterdo_stuffを持つ別のモジュール内に配置する方が適切かもしれません。必要なすべてのコントローラーまたは他のモジュールで使用でき、Exporterが独自に名前空間にインポートします。

于 2012-09-28T11:35:14.943 に答える
1

$cCatalystのほとんどのメソッドに渡すコンテキストオブジェクト( )は、すでにタイプのオブジェクトでMyAppあるため、

$c->do_stuff($c->request->params->{s})

呼び出すのと同じです

MyApp::do_stuff($c, $c->request->params->{s});

グローバルサブルーチンがこのコンテキストオブジェクトを利用することを期待する場合は、それらをメソッドとして記述することを検討する必要があります(つまり、最初の引数が常にパッケージのインスタンスであるパッケージ内のサブルーチン)。

# to be called like   $c->do_stuff("s")  to do something with form input "s"
sub do_stuff {
    my ($c, $param) = @_;

    ... do something with $c->request->param($param) ...
}
于 2012-09-28T14:44:51.427 に答える