2007年 10月 05日

ruby, クラスのインスタンス変数と、クラス変数

なにがちがうんだって思ったらリファレンスマニュアルに書いてあった……

  • サブクラスから参照/代入が可能
  • インスタンスメソッドから参照/代入が可能
http://www.ruby-lang.org/ja/man/index.cgi?cmd=view;name=%CA%D1%BF%F4%A4%C8%C4%EA%BF%F4

サブクラスからの参照/代入が大きな違いかな。クラスのインスタンス変数はあくまでそのクラスにしか属さないから、サブクラスからは頑張って superclass 探すしかアクセスする術がない。

無駄だけど以下のようにすればだいたいクラス変数と同じことがクラスのインスタンス変数でできる。

class Hoge
	@@test = :CV_test
	@test = :IV_test

	def hoge
		[
			@@test,
			self.class.ancestors.find {|c|
				c.instance_variables.include?("@test")
			}.instance_variable_get(:@test)
		]
	end

end

p Hoge.new.hoge #=> [:CV_test, :IV_test]
p Hoge.new.hoge #=> [:CV_test, :IV_test]

class Fuga < Hoge
end

p Fuga.new.hoge #=> [:CV_test, :IV_test]
p Fuga.new.hoge #=> [:CV_test, :IV_test]

サブクラスからはアクセスされたくない場合だけクラスのインスタンス変数をつかうべきかな (具体的にはどういうケースだろう)