メタプログラミングRuby読みメモ 1
1章 頭文字M
- 多くのプログラミング言語では、コンパイラ後は変数やメソッドは実体を失う
- メモリ上に配置されるだけの存在となる
- 一方Rubyのような言語は、言語要素が残る
- 言語要素について尋ねることもできる
- これはイントロスペクションと呼ばれる
Object#class
やObject#instance_variables
などActiveRecordではイントロスペクションを用いてクラス名を調べ、同名のテーブルへのマッピングなどの機能を実現している
メタプログラミングとは、言語用添えお実行時に操作するコードを記述することである
2章 オブジェクトモデル
- 全ての言語要素はオブジェクトモデルの中に存在する
- このメソッドはどのクラスに所属するものなのか
- このモジュールをインクルードしたらなにが起こるのか
オープンクラス
- Ruby ではクラスの定義の中に入ったときに初めてクラスが定義される
- 定義されているクラスをもう一度記述すると再オープンとなり、既存のクラスに記述されたメソッドなどを追加する
- いつでも既存のクラスを再オープンし、修正できる。この技法をオープンクラスと呼ぶ
オープンクラスの問題点
- メソッドを追加しようとして同名の既存のメソッドを書き換えてしまう可能性がある
- このような既存メソッドの書き換えをモンキーパッチと呼ぶ
オブジェクトモデルの内部
- インスタンス変数
- メソッド
- クラスの真相
- モジュール
- Class クラスのスーパークラスは Moduleである
- つまり全てのクラスは"new, allocate, superclass"を継承したモジュールである
- どこかでインクルードするときはモジュールを選択し、生成や継承をするときはクラスを選択する
- クラスはオブジェクトであり、クラス名は定数である
- Class クラスのスーパークラスは Moduleである
- 定数
メソッドの呼び出し
- メソッド探索
- オブジェクトのクラスを探索してメソッドを発見している
- レシーバのクラスから継承チェーンを上りながら探索する
- Kernel
- Rubyにはどこからでも呼び出せるメソッドがある(print など
- これはKernelモジュールのprivateメソッドである
- ObjectクラスがKernelモジュールをインクルードしているので全てのオブジェクトの継承チェーンに挿入されている
- メソッドの実行
- メソッドを実行するには発見したメソッドが誰から呼び出されたか知っている必要がある
- それがレシーバでありこれを参照するキーワードがself
- レシーバを明示しないメソッド呼び出しは全てselfに対する呼び出しとなる
トップレベル
クラス定義とself
- クラスやモジュール定義の内側では、selfはクラスやモジュールそのものになる
private
- private は二つのルールに従っている
- 自分以外のオブジェクトのメソッドを呼び出すにはレシーバを明示的に指定する必要がある
- private はレシーバを指定できない
self."privateなメソッド"
な呼び方も明示的にselfを指定しているので呼び出すことができない
- この二つのルールを合わせるとprivateのついたメソッドを呼び出すのは自分しかできなくなる
Refinements
- クラスの修正をする時の問題点は、変更がグローバルに及ぶこと
- refine をつけるとusingメソッドを使って明示的に有効化しないと有効にならないようにできる
using "モジュール"
を呼び出した時点から有効化される- Refinements はモジュール定義の終わりまで有効