はじめに
Ruby Goldのお勉強中によく分からない挙動をしていたので手元で動かしてみた。
特異クラス内のインスタンス変数
まずはこのコード
class A @a = 1 def call_a p @a end class << self @a = 2 def call_a p @a end end end
Aクラスの中でインスタンス変数@aに1を代入&特異クラス内で@aに2を代入
メソッドを呼んでみる
A.new.call_a => nil A.call_a => 1
A.new.call_a
がnilになるのは分かる(initialize
でインスタンス変数に値がセットされてない)けど、A.call_a
で2じゃなくて1になるのがよく分からなかった...
けど、手を動かしてみるとなるほどなという結果
class << self
の中でself
を呼んでみる
class A @a = 1 def call_a puts @a end class << self @a = 2 p self # => #<Class:A> def call_a puts @a end end end
#<Class:A>
はA
クラスの特異クラス。
つまり@aは特異クラス内のインスタンス変数ということなので、特異クラス内に特異クラスを作りレシーバーを特異クラスにしてメソッドを定義すれば取ってこれる(何言ってるか謎)
class A @a = 1 def call_a puts @a end class << self @a = 2 def call_a puts @a end class << self def call_a_from_singleton_class puts @a end end end end A.singleton_class.call_a_from_singleton_class # => 2
singleton_class
は自身の特異クラスを返すので、それをレシーバーにしてもう一つネストの深い特異クラスのスコープの中でメソッドを定義する。
まとめ
そもそも特異クラスのスコープの中にインスタンス変数を定義するのかどうか分からない。
自分は見たことがない。
まぁまたちょっとRubyに詳しくなったのでヨシ✋