メタプログラミングRuby 5章メモ
https://scrapbox.io/files/6599eda8173c1e00254bf9dc.png
Ruby Goldの模試でも出てくる難しい部分。class_evalの使い方や特異クラスについて理解が合っているか確認しよう。
classもコードを実行している
試しにselfとか書くと、戻り値になる
code:ruby
class A
def m1
def m2
end
end
end
p A.instance_methods.include?(:m2) # false
p A.new.m1
p A.instance_methods.include?(:m2) # true
まじか...
すごい
オブジェクトを操作するなら4章のinstance_eval(要復習)、それ以外ならclass_eval
クラスインスタンス変数
クラスのインスタンスからも、サブクラスからもアクセスできない。
クラス変数ならできる。
本ではinstance_evalをMockを使う際に活用していた。なるほど。
特異メソッド
Stringクラスにモンキーパッチするには影響が大きいメソッドを特異メソッドとして実装する
def str.title? みたいにするか、Object#define_singleton_methodを使う
クラスマクロ
attr_accesorみたいなやつ
特異クラス
Object#singleton_classかclass << objの構文でselfを返すと見ることができる
P129 の図をよく見るべきだが、class C < D の関係があれば、それはシングルトンクラスにも適用される
instance_eval
code: ruby
class Dog
def initialize
@sound = "Woof!"
end
private
def private_bark
end
end
dog = Dog.new
# instance_evalを使用してインスタンス変数にアクセス
sound = dog.instance_eval { @sound }
puts sound
# => "Woof!"
# instance_evalを使用してプライベートメソッドにアクセス
bark = dog.instance_eval { private_bark }
puts bark
# => "Private bark: Woof!"
インスタンスを開く(selfを切り替える)みたいな感じか
クラスのアトリビュートは特異クラスに住んでいる(?)
まだ理解が甘い
アラウンドエイリアス
requireを再定義することで、本来の挙動と違う処理を処理後(前?)にラップしていると解釈した
なのでアラウンド
オーバーライドだとダメなのだろうか
元の処理が消えるからダメか
そもそもmoduleの話だし
prependは、アラウンドエイリアスと違って必要な部分を入れてラップできるから、元に影響でない
本当か?メリデメまだうまく説明できない