3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

MojoliciousAdvent Calendar 2013

Day 13

Mojo::Homeの挙動を探る

Last updated at Posted at 2013-12-11

今朝、といってもこれを書いているのは12日の早朝なのですが.. Mojolicious 4.60 がリリースされ CPANにおいてのリリースオーサーがMarcus Ramberg氏 になっていてちょいと驚いている僕です。まーPOD見るとProject Founderのはいつも通りのSebastian Riedel氏なので特に内紛があったとかそういうのじゃないでしょうねw そこらの事情に詳しい人いましたら是非Advent Calendarを書いていただきたいです。

追記

miyagawaさんからこんなツイートを頂きまして... ようはリリースオーサーが変わることは特に目新しいことじゃない!とのことですね。

@yusukebe there were released made by one of core developers in the past, nothing new.

===

さて、MojoliciousのWebアプリに限らず そのプロジェクトのトップ=いわゆるホームディレクトリ へのパスを取得して ごにょごにょ したいという要望は結構あります。例えば、前日・前々日と

という記事が本Advent Calendarで投稿されたのですが、本文中のコード中にそれぞれ違うやり方でプロジェクト・ホームへのパスを探っています。前者はPath::Classを使った方法、もう後者はAmon2::Utilを模倣しFile::Specを内部で利用しています。こうしたやり方はMojo/Mojoliciousネームスペースに依存しないという意味ではよいかと思われます。が、ある程度自作しているので、もしカジュアルに使うとかMojo/Mojoliciousの機能をフルに使いこなしたい場合は Mojo::Home というその名もズバリなモジュールがMojoliciousディストリビューションの中に同封されMojolicious.pmなどで使われています。その挙動に興味があったのでソースコード見ながら使ってみました。

例えば、LiteでないMojoliciousアプリをつくってControllerの中で呼んでみましょう。プロジェクト・ホーム直下の log ディレクトリのへのパスを取得するには以下のコードでまかなえます。

lib/MyApp/Web/Example.pm
package MyApp::Web::Example;
use Mojo::Base 'Mojolicious::Controller';
use Mojo::Home;

sub welcome {
    my $self = shift;
    my $home = Mojo::Home->new();
    $home->detect( ref $self );
    my $log_dir = $home->rel_dir('log');
    $self->render( text => "project directory is '$log_dir'" );
}

1;

Mojo::Homeモジュールのインスタンスで detect メソッドを一度発行するのですが、その際に呼び出し元のパッケージ名を ref 関数で取得して渡しているのがポイントですね。一度 detect メソッドを実行したら rel_dir などで相対パスをこの場合「log」と指定して log ディレクトリへのパスを キチンと 取得しています。

ちなみにController以外の場所でも use Mojo::Home してパス解決をさせることは可能です。

lib/MyApp/Logic/SomeThing.pm
package MyApp::Logic::SomeThing;
use Mouse;
use Mojo::Home;
use Cwd qw/abs_path/;

sub project_dir {
    my $self = shift;
    my $home = Mojo::Home->new;
    $home->detect( ref $self );
    my $project_dir = $home->rel_dir('.');
    return $project_dir;
}

__PACKAGE__->meta->make_immutable();

無駄にMouseを使っていますがw project_dir メソッドを実行すると今回はプロジェクト・ホームへの絶対パスを文字列で得ることが出来ます。

ちなみに、と、いいますが… もっと早く言ってくれよ! って感じかも知れませんが、 Mojolicious.pm のメソッドに home というのものがありそれを使うのが一番短く楽に書けるので、実際はそうしましょう。Controllerから呼び出す場合は

lib/MyApp/Web/Example.pm
package MyApp::Web::Example;
use Mojo::Base 'Mojolicious::Controller';

sub welcome {
    my $self = shift;
    my $log_dir = $self->app->home->rel_dir('log');
    $self->render( text => "log directory is '$log_dir'" );
}

1;

これだけでOK!

で、本来ならソースコード見たのでもう少しネタはありますが、内部実装の話になっちゃうのでこの程度にとどめておきます。まーControllerや MyApp::Web からならば使う機会はありそうですよね!!

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?