blog.waterlow.work

Ruby, Rails, js, etc...

【Ruby】Goldリベンジするぞ-メタプロRuby4.1クラス定義

メタプロRubyをしっかり読んで理解していこうと思います。

メタプログラミングRuby

メタプログラミングRuby

*** 4.1.2カレントクラス Rubyにはカレントオブジェクト(self)カレントクラスなるものがある。これらのパラメータは常に存在してる。たとえば以下の超単純なコードだと

|ruby| def chk_current self end puts Object.private_methods.detect {|e| e == :chk_current}

=> :chk_current

p chk_current

=> main

||< カレントオブジェクトはメソッドの呼び出し側(と考えて良い)。カレントクラスはメソッドを定義した時にそのメソッドが格納されるクラス(と考えて良い)。この場合カレントオブジェクトはmain、カレントクラスはObjectである。(mainに関しては他のクラス定義と異なり少し特殊。)

もう一つ例を見る。カレントクラスとカレントオブジェクトの挙動が少し異なる例。

|ruby| class MyClass def m_1 p self def m_2; "hello"; end end end

class MyClass2 < MyClass end

obj = MyClass.new obj2 = MyClass2.new obj2.m_1 #=>#<MyClass2:0x007fc43a9f6608> p obj.public_methods(false) # [:m_1, :m_2] p obj2.public_methods(false) # [] ||< サブクラスのオブジェクトからメソッドを定義する内容を含むメソッドを呼ぶ。 カレントクラス→MyClass、カレントオブジェクト→MyClass2 この辺を知るとやはりRubyは複雑だなと思いますね…。

class_evalを使うとカレントクラスをいじれます。

|ruby| def add_method_to(a_class) a_class.class_eval do def m "hello" end end end

add_method_to String p "a".m #=> "hello" ||< 正確にはカレントクラスとselfを、全体の辻褄を合わせる形で変更します。 カレントクラスを意識した変数、クラスインスタンス変数(Classクラスのインスタンスとしてのインスタンス変数?)に関してはこの次に!