- クラス変数とクラスインスタンス変数とインスタンス変数の違いについて
を読んで、クラスメソッドとインスタンスのメソッドを組み合わせたときクラス変数、クラスインスタンス変数、インスタンス変数が参照できるのかどうかよく理解してないことに気がついたのでサンプルを書いてみることにしました。
- class MyClass
- @@class_var = true
- @class_instance_var = true
- def initialize
- @instance_var = true
- end
- # Class Variableを取得
- def self.class_method
- return @@class_var, @class_instance_var, @instance_var
- end
- # Instance Variableを取得
- def instance_method
- return @@class_var, @class_instance_var, @instance_var
- end
- end
- # 派生クラス
- class Derived < MyClass; end
- p MyClass.class_method # => [true, true, nil]
- p Derived.class_method # => [true, nil, nil]
- p MyClass.new.instance_method # => [true, nil, true]
- p Derived.new.instance_method # => [true, nil, true]
これを日本語でまとめると..
- クラスインスタンス変数
- 定義の仕方は@name_of_variable。インスタンス変数とは定義する場所が違う(クラスの中、メソッドの外)。
- 継承先のクラスから参照できない
- インスタンスから参照できない
- クラス変数
- 常に参照できる
- インスタンス変数
- インスタンスからのみ参照できる
それでなんだか定義の記述が同じで場所が違うだけのクラスインスタンス変数とインスタンス変数の違いがなんだか分からなくなった。
- class MyClass
- @class_instance_var = 0
- def initialize(fnum)
- @class_instance_var = fnum
- end
- # Class Variableを取得
- def self.class_method
- @class_instance_var
- end
- # Instance Variableを取得
- def instance_method
- @class_instance_var
- end
- end
- m = MyClass.new 1
- p m.instance_method # => 1
- d = Derived.new 2
- p d.instance_method # => 2
- p m.instance_method # => 1
- p MyClass.class_method # => 0
- p Derived.class_method # => nil
- クラスインスタンス変数
- インスタンスから参照した場合、インスタンス変数がそのインスタンスのスコープでクラスインスタンス変数を上書く
- クラスメソッドから参照した場合、定義したクラスからのみ参照可能
というわけで、クラスインスタンス変数は継承されるときに継承先にコピーされないんだろうと理解したけど、このあたり本当のところご存知の方いらっしゃいます?
.