Shawn M Mooreさん(sartakさん)による研修「Moose入門、モダーンなオブジェクト指向システム」、とても素晴らしかったです!
前の記事で講師陣の贅沢さに触れましたが、何せMooseのCabal(中の人)による研修ということで、極めて質の高い内容となりました。
これまでのMooseの勉強は、基本的には牧さん(lestrratさん)の『モダンPerl入門』を足掛かりにして、後は実際に拙いコードを量産しながら、その場その場で疑問に思ったことを原文PODにgrepを掛けるなどという方法論でした。最近は石垣さん(charsbarさん)の翻訳に首っ引きでした。
これに対して、今回は体系立ててみっちりと学ぶことが出来たので、細切れだった知識が結びつけられて、理解がさらに深まったと思います。
研修の詳細については、以下に掲げたような、他の方々の素晴らしいリポートをご覧いただくのが良いと思います。
- lesamoureusesさんによるYAPC::Asia2009の特別研修「Moose入門、モダーンなオブジェクト指向システム」が超良かった!
- ziguzaguさんによるYAPC::Asia 2009 特別研修 - Moose 入門
ziguzaguさんの指摘する体系的に学べる素晴らしさと、lesamoureusesさんの「もっとみんな受けたらいいのに!」という思いは、まったく同感です。
一方でこの記事では、私が「入門講座」相当の内容でも知らなかったことの覚え書きや、その他全般の感想、自習の勧めなどを簡単にご紹介します。
追記 : 用語法の誤りや、書きかけでブツ切りになっていた文が多々あったので少々直しました。眠い目をこすって物を書くのは良くないですね。失礼しました。
追記 : sartakさんご自身のブログ記事が公開されました。Thank you for providing me with zeal for Moose. I love Moose.
- 自習にもおすすめ! スライドと課題を入手しよう
- 柔軟な仕組みであるロールをもっと活用しよう
- Cleaning Up Moose Droppings - ヘラジカのフンの掃除
- Traits and Metaclasses - トレートとメタクラス
- 色々な知識の補遺
- sartak先生のライブコーディング
- まとめ - 研修には是非実地で参加してください!
1. 自習にもおすすめ! スライドと課題を入手しよう
1.1. スライドと課題が公開されています
研修に参加出来なかった方々でも、スライドと課題をgit clone git://git.moose.perl.org/moose-presentations.gitして是非とも入手してください。1日の研修向けによくまとめられた内容のスライドと、冴え渡る課題コードを、自宅でいつでも触れることが出来ます。
1.2. 課題のテストがすごい!
私が特に印象に残ったのは、課題です(お題は/moose-class/exercises/READMEを参照)。完了条件はテストが全てパスすること。これだけ書くと普通のようですが、これが実は凄いのです。本当にテストがよく考えられています。
何せ、テストが通る頃には、殆ど模範解答通りのコードになるからです。Perlは同じ事をするのにもやり方が色々あって、人によってはそれが原因で敬遠していることもあるでしょう。これに対して、Mooseの決まり事に従ってコードを書くということは、オブジェクト指向のプログラムを整然と書けることを意味しています。他の技術的な研修だとこうはいきません。
これはつまり、自習するあなたのすぐ傍にsartakさんがつきっきりになってくれて、あなたのコードを適切に何度でも根気よく添削してくれることを意味しています。是非自習していただきたいと私が強く思う理由は、正にここにあります。
PerlおよびMooseのイントロスペクション(「内観」と訳されましたが、要はプログラムの実行時にオブジェクトの中身を見ることです)機能が充実していることも勿論ですが、テストコードもMooseのメタクラスオブジェクトの使い方の好例として見るべきところが多いです。
暦の上での大型連休が近付いていることもあって、秋の夜長にはMooseをものにしてみてはいかがでしょうか。
1.3. スライドを和訳しています
一式はCC-BY-SA 3.0のライセンスで公開されているので、社内で勉強会を開く際には積極的に活用したいです。
また、復習の意味も込めて、目下のところスライドを和訳しています。まだ粗訳の状態なので、石垣さん(charsbarさん)によるMooseドキュメント日本語訳での訳語を参考にするなどして改良しつつ、公開出来ればと考えています。
追記 : 取り敢えずといった水準ですが日本語訳を公開してみました。スライドの成長に伴ってページの増減がありますので、この記事でのページ番号は、記事公開当時のページ番号であることを補足しておきます。
基本的に和訳が必要ないほど分かりやすいスライドなのですが、そうはいっても英語だと敷居が高いこともあるでしょう。そうした「食わず嫌い」という勿体ない機会損失を少しでもなくしたいと思います。勿論、社内でも邦訳版を使うことになるでしょう。
1.4. スライドツールS5を始めて知った
スライドはFirefoxやIEなどのブラウザーで読めます。Arkについて発表された村瀬さん(typesterさん)など、多くの方が使われていたS5というツールによるものです。XHTML + CSS + JavaScript(jQuery)が使われています。
なお、このS5ですが、どういう名前でどこで入手出来るのか調べようと思っていてそのままになっていましたが、入手してソースを拝見させていただいたことで、思わぬ形で解決しました。技術系の話であれば、ちまちまPowerpointだとかOOo Impressだとかで書くより、こちらで書いた方が遙かに生産性が上がりますね。
上述の和訳することもとても楽です。既存のエレメントをclass="en"にして、同じ内容をclass="ja"として複製して書けばいいですし、スタイルで.en { display : none; }と指定すれば(わざわざソースから除去しなくても)原文を非表示にする(日本語のみの表示にする)ことが出来ます。
2. 柔軟な仕組みであるロールをもっと活用しよう
2.1. ロールは「取り込まれる」もの
ロールは(withでの)使用元のクラスやロールは、あたかも対象のロールをコピー&ペーストしたかのように「取り込む(consume)」という説明(スライドpp.77-79)は、大変腑に落ちました。辞書を引くと分かりますがconsumeには食べ尽くすというような意味もあり、要は「まるっと持ってくる」イメージです。
これまで継承との違いが今一つ理解出来なかったのですが、基底クラスでwithしたとしても派生クラス側で使えないことも納得です。
2.2. スーパークラスとクラスとロールでの衝突
スライドpp.81-85では、
- クラス自身とクラスで使うロールで同名メソッドがあれば、クラス側が勝つ
- クラスのスーパークラスとクラスで使うロールで同名メソッドがあれば、ロール側が勝つ
- ロールには継承関係がないので、クラスで使う複数のロールで同名メソッドがあれば、エラーになる
ということを知りました。さらに、pp.86-89の衝突回避策があることだけは知っていましたが、やみくもに回避すればよいわけではないということが印象的でした。
2.3. ロール名の言い回し
細かいところだと、命名規則の概観を知ることが出来たのも良い点です。
英語を母語としていない私のような人間では、以下のような命名はあまり自然には出て来ません。
- boolを返すメソッドやboolを意味する変数は、
is_foobar()(is Noun/is Adj.)や、$loaded(Vp)
命名絡みでは『Perlベストプラクティス』で始めて知ったような内容もあります。命名というのはとても大事で、これがしっかりしている場合とそうでない場合とでは、コードの分かり易さが天地ほども開いてしまいます。
金融ユー子のメインフレーム系SEを泣かせるのはまさにこれです。プログラム名が最大ほげ桁までなので、「じゃあ計上モジュールさんよろしく」ではなく「じゃあXXXXXXモジュールさんよろしく」などとプログラム番号のようなものを使わざるを得なかったり、変数名も(漢字を使えた場合でも)アクロバティックな略号が飛び交うなどしたり。
とにかくも命名は重要なのですが、しかしロールの命名は今一つしっくり来ていませんでした。Mooseを採用したプログラムのコードを私があまり読めていないことが理由です。今回はスライドに色々な実例が生息していました。
- 状態を持つ(つまり
hasでアトリビュートを持つ)ことが主眼になる場合、例えばCar(自動車)に対するHasEngine(have Noun、エンジンを持つ)と書ける - 上記は『モダンPerl入門』のように
Winged(Vp、翼を持つ)などとも書けるが、これは同書の例のようにインターフェースを提供することが主眼になる場合に、より適しているような気がした - 振る舞い(つまりメソッド)を提供することが主眼になる場合、例えば
Printable(V-able、表示出来る)と書ける他、CanBreakdance(can V)やIsFragile(is Adj.)などとも書ける - 広範にアトリビュートとメソッドをまとめて提供する場合、例えば
ColumnとColumnAliasに適用可能な、ColumnLike(Noun like)と書ける(クラス継承の場合にColumnBaseやColumn::Baseなどと書いていたことに相当)
自然に読める、自己説明的なコードを書くために、ロールという(コンピューター科学の分野で比較的新しめの)概念と上手にお付き合いしていきたいです。
3. Cleaning Up Moose Droppings - ヘラジカのフンの掃除
no Moose;する理由が腑に落ちました。『モダンPerl入門』p.9で「おまじない」として覚えたのですが、これまではhasなどの関数が自分のクラス内で衝突することを避けるためだと誤解していたところです。
Perlは関数もメソッドも同じsubであるので、クラスを構築するためだけに使われるシュガー(構文糖)を、クラスの外からメソッドとして呼ばれてしまうことが問題なのですね。スライドのpp.61-62の通り、MyClass->can('extends');などが真のままだと問題なのだということでした。
『モダンPerl入門』にもしっかりと「名前空間内に余計な関数が残らないようにする」と書かれていたのですが、「自分のメソッドにMooseのシュガーと被るような命名をしなければいいが、それを意識しなくても良いように防衛的に書いておく」と盛大に誤解していました。
また、Moose::Util::TypeConstraintsなど、複数のMoose系モジュールを使う際には何度もnoを書くのは辛いので、冒頭に(use Moose;の前に)use namespace::clean -except => [qw(meta)];すると1センテンスで済むので楽だということも分かりました。Pixisなどを拝見して、このこと自体は知っていたのですが、no Moose;を金科玉条として使っていたので、別の方法に手を伸ばすことはしていませんでした。
namespace::cleanだと、Mooseだけでなく他の関数インターフェース型モジュールによって名前空間にインポートされた関数も掃除出来るので、今後はこちらを使おうと思います。
4. Traits and Metaclasses - トレートとメタクラス
4.1. メタクラスではなくトレートを使おう
これまで私もMooseX::AttributeHelpersを便利に使っていたのですが、これがMooseコアに取り込まれるとのことです。また、これまでmetaclass => 'Collection::Array', provides => { push => 'add_element' },などとして使っていた構文は、基本的にtraits => [qw(Array)], handles => { push => 'add_element' }のように、トレート(trait)を使うようになるとのことでした。この内容は、2009/09/15のバージョン0.90で取り込まれました。上記の例だと、コアの名前空間にいるMoose::Meta::Attribute::Native::Arrayが機能を提供してくれています。
確かにMooseでデータ構造体を取り扱う場合には基本的にいつも使っているので、コアに入ることはとてもいいことだと思います。
metaclassと違ってtraitsでは複数のトレートを指定出来るため、基本的には後者を使うことになります。前者を使う場面は、sartakさんご自身もよく分からないということです。
4.2. 大きな変更は今後しばらくない
なお、翌日の小飼弾さんの研修(別記事で報告する予定です)の後に牧さんに質問する機会があったので、こうした比較的大きめの変更が今後どの程度あるのか、お伺いしました。すると、牧さんが認識していらっしゃる限りでは、大きな変更は今のところ予定がないとのことでした。Mooseはバージョンこそ0台ですが、牧さんが仰るように、Perlでバージョンというのはあまり大きな意味がない(本当に不安定であれば開発者向けリリースにして一般に公開しない)ので、枯れてから(開発が落ち着いてから)Mooseをキャッチアップしようと考えている人は、出来れば今すぐにでも始めた方が幸せになれると思います。
私は仕事ではMooseを使えていません(そもそも10%兼務の業務の一部でしかPerlが使えません)が、プライベートでは大いに活用させていただいています。まだMooseを触っていない方に、Perlの物書きが楽になることを少しでも早く体験していただきたいです。
5. 色々な知識の補遺
5.1. isが(ほぼ)必須になる
isがないとis => 'ro'相当になるものの、自己説明的にするため明示的にis => 'ro'と書くものと理解していましたが、
- 何も書かないとアクセッサーが生成されない
is => undefはエラーが出るので、is => 'bare'にする
という使い分けに気をつけようと思います。この辺り、バージョン0.89からMoose::Manual::Attributesの内容が増補されていました。
5.2. DEMOLISHフック
これは知りませんでした。Perlはファイルハンドルのクローズなどは自分でしてくれますが、特殊なリソースの解放やその他色々な処理は、PerlのデストラクターDESTROYではなくDEMOLISHフックを使いましょう、ということでした。
5.3. 自分でメタクラスをいじる場合
ほとんどのMoose利用クラスは__PACKAGE__->meta->make_immutableをしているので、自分でいじる場合には一旦__PACKAGE__->meta->make_mutableしてから中身を弄って、また__PACKAGE__->meta->make_immutableで不変化すると良いとのことでした。
ただ、実行時にいじらない程度であれば、実は簡単にメタクラスをいじれます。トレートもまた然り。スライドにあったような(CPANモジュールではなく、あくまで例としての)MooseX::LabeledAttributesに類することは、私も容易に行えました。私はMoose::Cookbook::Meta::Recipe2にある「それなりにいかれた開発者(sufficiently twisted developerの石垣さん訳)」というほどの域には全く達していないのですが、それでも家に帰ってからMoose::Cookbook::Meta::Recipe3も併せて読んだらすぐに作れるのです。
Mooseの拡張性(と拡張容易性)に舌を巻くと同時に、Mooseのドキュメントの充実具合にただただ感謝です。TPF支援でドキュメントの充実が図られ、JPA支援で日本語訳が行われてもいるので、リファレンス的に当たるのではなく、一度読み物としてじっくり読み込むことが大事だと思いました。
5.4. メソッドモディファイヤー
スライドp.162の継承時の実効順の図解は参考になりました。
また、argumentモディファイヤーとinner()の使い方は、ちょっと面白く感じました。埋め込み式に処理出来るので、使いどころは難しそうですが、知っているといつか役に立ちそうです。
5.5. 短いことはいいことだ
とにかく、MooseはPerl5標準では冗長になる言い回しを、宣言的(Declarative)に小気味よく書けます。バグ発生率というものは基本的にはほぼ一定なので、つまり母数であるコードの長さが短ければ短いほど、バグの総件数は減る勘定になります。
どんどん楽をしたいと思います。
6. sartak先生のライブコーディング
6.1. こんなの滅多に見られない!
sartakさんはスライドだけでなく、実際にコード素片を書きながら説明してくださり、とても地に足の着いた講義になりました。勿論スライドにもコードが書いてあるのですが、目の前でコードが書かれていく様を拝見するというのは、自分でコードを書くことの疑似体験のようにも思えるので、臨場感が増したと思います。時にはわざと「エラーになる例」を書いてくださいました。
さて、そうしたエラーメッセージが(Mooseも使っている)Carpのconfessの結果として画面に表示されたとき、sartakさんは「この使い方はおかしいです」ではなく「ここで何々は使えません」だと(内容が具体的になるので)より分かりやすいね、と改善点に言及されました。「Mooseはまだ完璧な物でないので、後で直します。誰かCPAN RTのチケットを切ってくれてもいいですよ」と仰っていたsartakさんは、何とその次の休み時間に早速その修正を始めました。滅多にお目にかかれない、sartak先生のライブコーディングです!
6.2. 自分で見つけた改善点もトラッキングシステムを使う
sartakさんは最初にRTのチケット#49680: calling immutable meta methods should report method nameを切りました。
体調不良で再びダウンされていた牧さん(lestrratさん)の代わりに監訳(通訳のNathanielさんの翻訳のサポート)してくださった石垣さん(charsbarさん)が、「RTはトラッキングのためにも使える」とすかさず解説してくださいます。
私であればせいぜいコミットログにしか対応内容を書かないところです。しかし、自分で見つけた改善点であっても、きちんとトラッキングシステムに登録することは、確かにとても大事ですね。
重大性(Severity)に最上級のCritial、コメントにaaaaaaaaaaaaaaa please fixと書かれたので、これはsartakさん一流の冗談なのかとふと思いましたが、勿論RTのチケットを切るくらいなのですからそんなことはありません。コーディングとテストもやってしまいました。
6.3. なることは出来ないが真似することは出来る
テストを実行して......盛大にエラーが出てしまいましたが、これはsartakさんの環境に入っていた(Mooseの依存モジュールである)Class::MOPが古かった所為。これを入れ直したら無事テストが通って、リポジトリへのコミットまで完了しました。
その間、わずかに10分程度。ただしその時間の大半はClass::MOPのアップグレードに伴うテスト実行時間です。これぞハッカーです。人は誰もが卓越した才能を持っている訳ではありませんが、彼らのベストプラクティスを模倣することは出来ます。積極的に真似していきたいと思います。
6.4. 筆舌に尽くしがたい体験
上記の他にも、Mooseドキュメントの石垣さん(charsbarさん)の翻訳への言及をPODのTRANSLATIONSセクションに書いたりと、正に目の前でMooseが成長していく様を目の当たりにしました。
目の前でヘラジカが大きくなっていく過程を見た熱情は、どうにも言葉にしにくいです。言葉はなんと不自由な物でしょう。上述の通り、確かにスライドと実習は自宅でも出来ますが、sartakさん直々の解説の他にも、こんな貴重な体験が出来るなんて。
7. まとめ - 研修には是非実地で参加してください!
今回はYAPC::Asia 2009に合わせて来日してくださった超大物の講師陣でした。次回以降、もしこうした機会があるならば、一般の方は是非とも実際に参加してください。こんな素晴らしい研修、本当に滅多にないですよ!
牧さんのブログ記事YAPC::Asia2009の研修、受講者絶賛募集中ですおの通り、参加者の方は多くありませんでした。これは勿体ない。牧さんの記事はかなり控えめなアピールですが、この研修の価値はとても高いものです。
前の記事で採り上げた各社の教育サービスのように、研修の概要をもう少し突っ込んで事前に紹介したり、通訳があることをコース案内や募集要項に明記したりすれば、もしかしたらもっと参加者が見込めたかも知れません。
といってもJPAというものは会員が何かを与えられるのを待つ場ではなく、企業とコミュニティーを仲立ちする場だと認識しています。従って、私の直近の使命は、参加を検討されていた人が次回の参加を検討する際の参考になるよう、参加報告をまとめることだと規定しました。拙い報告内容でエキサイティングな研修の魅力を損ねていないか不安ですが、一言で書くならば是非参加してくださいということです。
コメントする