Carmel を読む
5/20 に 吉祥寺.pmミニ Carton/Carmelのコードリーディング が行われるので事前にCarmelを読んどく。
結論
読むなら Carmel::Setup/Runtime あたり!
Carmel の基本的な使い方
ほとんど Carton と同じにように使える。つまり cpanfile に依存を書いて、carmel install でインストールし、carmel exec で実行。
$ echo "requires 'Plack';" > cpanfile $ carmel install ---> Installing new dependencies: Plack ... ---> Complete! 1 cpanfile dependencies. 20 modules installed. $ carmel exec perl -V ... @INC: Carmel::Runtime::FastINC=HASH(0x7fbe120a45a8) /Users/skaji/.carmel/5.20.2-darwin-2level/builds/Apache-LogFormat-Compiler-0.32/blib/lib /Users/skaji/.carmel/5.20.2-darwin-2level/builds/POSIX-strftime-Compiler-0.41/blib/lib ... $ carmel exec plackup --version Plack 1.0034
実際のところ
Carmel と Carton は module の保持の仕方、それをどのように使わせるかにおいてかなり違う。
Caton は local/ 以下に module をインストールし、実行時は単に PERL5LIB に local/ を追加していた。
一方 Carmel は中央 repository (~/.carmel/perl-version/builds) に module を "個別" に保持し、実行時に @INC を巧みにいじり、require させている。
Carmel は @INC をどのように扱っているのか
中央 repository に個別にmodule を保持しているためたくさんの依存があった場合は、その数だけ @INC に追加しなくてはいけない。
初期の Carmel は環境変数 PERL5LIB にこれを追加していた。 PERL5LIBは相当な長さになり、これはちょっと、という感じがあった。
現在の Carmel は .carmel/MySetup.pm という設定ファイルに @INC をはじめとする依存moduleの情報を保存し、実行時はそれを require するようになった。
そして、ここからが興味深いところで Carmel は その設定ファイル .carmel/MySetup.pm の情報を単に @INC に追加するのではなく、Carmel::Runtime::FastINC クラスのインスタンスを作り、それを @INC に差し込んでいる。
名前の通り、Carmel::Runtime::FastINC は素早くmoduleを読み込むための仕掛けである。 実装詳細はコードを見てもらえばわかるが、とにかくこのあたりがかっこいい!
その他
- 依存モジュールを recursive に解決するコードがかっこいい。
- binstub の意味は?
my($self, $arg) = @_
のmy
と(
の間にスペースを書かない流儀 は誰が発祥か知りたい。- carmel package で configure deps などがコピーされない。
- https://github.com/miyagawa/Carmel/blob/master/lib/Carmel/Runner.pm#L31
ここは PERL5OPT ではなくて PERL5LIB=local/lib/perl5 だと思うが自信がない。-> やはりそのままであってた。 - 開発環境での使い方は?
perl -MCarmel::Setup ...
がいい? - 本番環境での使い方は?
carmel rollout
してPERL5LIB に local を設定する、がいい? - 会社で HTML::Tidy module を使っているのだが、これは先にAlien::Tidyp module を入れておかないとインストールに失敗する。 このようなmoduleをcpanfileで管理するのに苦労している。 何かいい解決法はないか。