青木峰郎さんによるRubyのお話。Rubyではprotectedなんてほとんど使わないよとか、制御構造は選り好みせずに使おうとかの話。Javaのイメージを引きずってRubyでもprotectedとか使うと残念なことになるとかsendメソッドの話とか、Rubyでプログラミングをするときに気をつけるべき点をいくつも知れて勉強になった。以下メモったこと。
Rubyでprotected使ってる?
- Rubyでprotectedを使っている人? ⇒ 使っていない
- Rubyじゃ使いません
- 95%は間違い。Railsも間違っている
- JavaやC++の人がprotected使いまくり。しかも意味がない
- JavaやC++はクラス単位。Rubyはオブジェクト単位
- 具体例 (メモれなかったけど、あとでppt見ればいいよね)
- Rubyはprivateとpublicだけ使えばOKなんです ←結論
pとpp
- p使ってる人? ⇒ 多い
- pp使ってる? ⇒ それほどでもない
- ppはpの強力版。読みやすい
- requireする。田中哲さんが作った
- pはstdoutに出力。strerrではない。inspectメソッドを実装すれば表示を変えられる
- to_sとinspectの違い: to_sはオブジェクトを文字列に変換、inspectはデバッグ用表示
unlessとuntil
- 制御構造は選り好みせずに使おう。redo以外
- if/whileで書けるから要らないよ説 → それgotoでできるよ
- プリミティブ症候群に陥らないで
- unlessの使いどころ: 前提条件
- untilの使いどころ: 終了条件をはっきり書きたいとき
クラスと名前空間
- モジュールのネストしてる? モジュールはクラスの名前空間を兼ねている
- Javaでいうパッケージ
- ネストは深くしすぎない。せいぜい3段。見た目が良くない
ファイル名とクラス名
- 最も代表的なクラスの名前をファイル名にする
- ファイル名は小文字で
- モジュールの場合はCflat::Nodeクラスだったらcflat/node.rbみたいに
- 関連するクラスはひとつのファイルにまとめる。Javaのように1クラス1ファイルにはしない
大クラス主義
- Rubyは大クラス主義。いろんな仕事をひとつのクラスにまとめて行わせる
- RubyのArrayは配列とスタックとキューを全部兼ねている
- StringはStringBuilderやStringBufferを兼ねている
- それでいいの? → OKです。うまくいってるしー
- マイクロカーネル vs. モノリシックカーネル論争に似てる?
- コンポーネントが多いとコンポーネント間の複雑性が増す。結局バランスなんです ←結論
クラス分岐をsendでやる
ここから第2部。裏世界の話。
- たくさんのクラスで別の処理をしたい → ポリモーフィズムを使う? → ひとつの処理が複数クラスに細切れになる
- Visitorパターンを使う? → 実装が面倒
- そこでsend。sendはメソッドを呼び出すメソッド
obj.send(メソッド名,引数)p 'str'.size→p 'str'.send(:size)
リフレクションでバージョン間差異を埋める
- Rubyのバージョンが1.9になって対応が面倒。そこで
- 1.9は無視する。1.9.0はテンゼロなので危ない → 現実的過ぎてむかつく
- 両方のバージョンで動かす → 非相互互換性
alias funcall send- ポイントは
- if/unless野中にclassを書ける。Cのマクロのようなことが書ける
- プログラムの実行時にメソッドを追加できる → オープンクラス。JavaやC++はクローズドクラス