`instance_eval`の話

今日の夜は、うさぎのらーめんだった。うさぎのらーめんを食べはじめてもうすぐ1年になる。
あの頃とは自分が何か違うかんじがする。だけど、うさぎのらーめんは、なにひとつ変わらない。

人間がRubyのオブジェクトだと考える。
だれかが定義したクラスがある。そこからインスタンス化される。
ruby
params = {
name: "Keisuke KITA",
sex: :male,
# ...
}
kitak = Human.new(params)

これが人間が生まれるということなんだろう。
オブジェクトには色々な属性があって、それはインスタンス変数(@から始まるやつだ)に代入されている。
人に知られても構わない属性もあれば、困る属性もある。
基本的にインスタンス変数は外からは見えない。
だから、必要なものだけattr_readerとかattr_accessorをつかって、インスタンス変数を参照したり書き換えるためのメソッドを生やす。

インスタンス変数はメソッドを通してしか原則変えることはできない。メソッドのコールがヒュンヒュンとあちこちで行われて僕たちの属性は変化していく。

ただし、これには裏口がある。instance_evalだ。
instance_evalに渡されたブロックのコンテキストはレシーバになる。

kitak.instance_eval do
  # この中では
  # kitakのインスタンス変数が参照できる
  # プライベートなメソッドが呼べる
  puts @age # => 23
end

ろくでもないことだと理解しているけれど、ときどき、instance_evalが欲しくなるような経験をする。

思うに、うさぎのらーめんはオブジェクトの世界ではなく、関数の世界にあるのだと思う。あの世界では、同じ入力には、必ず同じ出力が得られる。
オブジェクトの世界が嫌になるときがある。だけど、基本的に全てはオブジェクトなのだ。
オブジェクト同士が互いに参照しあって、泥沼になっているのならば、どちらかが参照をやめるしかない。
状態をもったり、参照しあったりする泥臭い世界でヒュンヒュンと相変わらずメソッドをレシーブしたりコールし続けないといけない。

どこからも参照されなくなり、ガベージコレクタに消されるまで。

15