blog.waterlow.work

Ruby, Rails, js, etc...

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

インスタンス変数を宣言するとその変数はselfの指すオブジェクトに属する。これも例外はない。
もし、selfがあるクラスを指していた場合、それはクラスインスタンス変数というものになる。

class Loan
  def initialize(book)
    @book = book
    @time = Loan.time_class.now    
  end

  def self.time_class
    @time_class || Time
  end
end

class FakeTime
  def self.now
    'Mon Apr 06 12:15:50'
  end
end
# for test
Loan.instance_eval { @time_class = FakeTime}
loan = Loan.new("uchu-kyodai")
p loan

インスタンスメソッド定義内では、selfはレシーバのインスタンスとなる。クラスの直下もしくはクラスメソッド定義内ではselfはクラスになる。@time_classはLoanクラスに属する。これでそのクラスだけで共通で、インスタンスや継承されたクラスから参照できない変数ができた。

ここで混乱のもと、Objectクラスのmainオブジェクトを…。

class Object
  attr_accessor :val1
end
class << self
  attr_accessor :val2
  @val3 = 3
  def self.read
    @val3
  end
end
@val4 = 4
p self.singleton_class.read
self.val1 = 1
self.val2 = 2
p self.instance_variables
obj = Object.new
obj.val1 = 1
p obj.instance_variables

トップレベルで変数を宣言するとObjectのクラスインスタンス変数になるわけではなく、mainオブジェクトのインスタンス変数になる…。