SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Webアプリケーションフレームワーク「Catalyst」入門

初めてのCatalyst入門(3)
処理の入り口はアクション

コントローラのURLパスとアクションの定義方法

ローカルな正規表現(:LocalRegex)

 :Pathアトリビュートでは、登録できるパス文字列は固定でしたが、もっと柔軟に正規表現で定義することもできます。正規表現で定義するためのアトリビュートは2種類あり、ネームスペースに結びつけられる「:LocalRegex」と、グローバルに定義可能な「:Regex」があります。

 :LocalRegexの引数に正規表現でパス部分を定義します。例として次のようなURLを考えてみましょう。

  • http://<ホスト名またはIPアドレス><:Port>/foo/bar/item<数値>/comment<数値>

 「item」と「comment」の後には何らかの数値が入りますが、この値は固定ではなく、さまざまな値が入るものとします。このURLにマッチするアクションは次のように定義します。

[リスト9]Bar.pmのローカルな正規表現定義
package HelloC::Controller::Foo::Bar;

# 省略

#(1)foo/bar/item<数値>/comment<数値>にマッチする定義
sub localregex_path :LocalRegex('^item(\d+)/comment(\d+)$') {
  my ( $self, $c ) = @_;
  #(2)itemの後の数値
  my $msg = 'item:' . $c->req->captures->[0];
  #(3)commentの後の数値
  $msg .= ', comment:' . $c->req->captures->[1];
  $c->response->body( $msg );
}

 :LocalRegexアトリビュートを付加した「localregex_path」アクションは次のように定義しています。

(1)ローカルな正規表現定義

 Perlで定義可能な正規表現については詳しくは説明しませんが、ここで登場する正規表現は次のような意味になります。

「^item(\d+)/comment(\d+)$」に現れる正規表現
正規表現 意味
^item 先頭が「item」から始まる
(\d+) 1つ以上の数値が入り、グループとして保持
/comment 「/comment」という文字列にマッチ
$ 末尾にマッチ

(2)itemの後の数値を取得

 正規表現のグループにマッチする値を取得するには、コンテキストのリクエストオブジェクト「$c->request」または「$c->req」の「captures」から取得します。「captures」には配列の参照として値が格納されています。「item」の後の数値を取得するには、0番目の値を取得します。

 以前のCatalystでは、「$c->req->snippets」を使っている例が紹介されており、現在でも使用できます。ただし互換性のために残されているだけで、現在は非推奨となっています。

(3)commentの後の数値を取得

 「item」の場合と同様に、「comment」の後の数値を取得するには、「$c->req->captures->[1]」で値を取得します。このアクションでは、itemとcommentの後の数字を表示させています。次のURLをWebブラウザで表示させた場合の例を示します。

  • http://<ホスト名またはIPアドレス><:Port>/foo/bar/item12/comment34
「foo/bar/item12/comment34」を表示した画面
「foo/bar/item12/comment34」を表示した画面

 正規表現の先頭で「^」を指定していますが、これは先頭にマッチするという意味があります。この「^」を取り除くと、ネームスペース「foo/bar」と「item<数値>/comment<数値>」の間に、スラッシュ「/」を含む0個以上の文字列を含めることもできます。例えば、次のURLが呼び出された場合にもアクションにマッチさせることができるようになります。

  • http://<ホスト名またはIPアドレス><:Port>/foo/bar/any/path/item12/comment34

 もし、ネームスペースと「item」の間の文字列(「any/path/」)を取得したい場合には、次のような正規表現を定義すれば、「captures」配列の0番目の値として取得できます。

[リスト10]itemより前の文字列を取得するローカル正規表現定義
package HelloC::Controller::Foo::Bar;

# 省略

sub localregex_path2 :LocalRegex('(.*)item(\d+)/comment(\d+)$') {
  my ( $self, $c ) = @_;
  my $msg = 'prefix:' . $c->req->captures->[0];
  $c->response->body( $msg );
}

グローバルな正規表現(:Regex)

 :Regexでも:LocalRegexと同様に正規表現でパスを定義しますが、ネームスペースに結びつけられず、グローバルにマッチさせることができます。

 例として、次のようなURLを考えてみましょう。

  • http://<ホスト名またはIPアドレス><:Port>/user/<文字列>

 ここでは、userの後にユーザー名などの文字列が入るものとします。このURLにマッチするアクションは次のように定義します。

[リスト11]Bar.pmのグローバルな正規表現定義
package HelloC::Controller::Foo::Bar;

# 省略

sub regex_path :Regex('^user/(\w+)$') {
  my ( $self, $c ) = @_;
  my $msg = 'user:' . $c->req->captures->[0];
  $c->response->body( $msg );
}

 「:Regex」アトリビュートを付加した「regex_path」では、「user/」の後に1つ以上の文字列(アルファベットや数字)が入り、その文字列はグループとして保持され、「$c->req->captures」で参照できます。

 このアクションでは、userの後の文字列を表示させています。次のURLをWebブラウザで表示させた場合の例を示します。

  • http://<ホスト名またはIPアドレス><:Port>/user/suzuki01
「user/suzuki01」を表示した画面
「user/suzuki01」を表示した画面

 正規表現の先頭に「^」を指定した場合にはベースの直下に結びつけられますが、「^」を指定しない場合には、このパターンにマッチするURLであれば、ネームスペースなどに関係なくどこでもマッチさせることができます。

 例えば、「:Regex('user/(\w+)$')」を指定した場合には、次のようなパスにマッチします。

「^user/(\w+)$」にマッチするパス
パス 説明
/user/suzuki01 ベース直下に現れる場合
/foo/bar/user/suzuki01 既存のネームスペース以下に現れる場合
/any/path/user/suzuki01 存在しないネームスペース以下に現れる場合
/someuser/suzuki01 スラッシュではない文字列の後に現れる場合

 このように:Path:Regexなどでネームスペースに関係ないパスを定義できますが、Catalystでは、リクエストされたパスが複数の定義にマッチする場合には、一致部分が最も長いアクションに処理が割り当てられます。

次のページ
プライベート(:Private)

この記事は参考になりましたか?

Webアプリケーションフレームワーク「Catalyst」入門連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 花田 善仁(ハナダ ヨシヒト)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/4444 2009/10/30 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー