Rubyの変数の定義について、今回はクラス変数
前回までにローカル変数とインスタンス変数について書きました。
そして今回はクラス変数について書こうと思います。
命名規則
- 先頭は@@をつける
- 変数の構成は英数字と_が使える
@@student = 'Taro'
warning: class variable access from toplevel ##なぜかwarningが出る
=> "Taro"
@@_STUDENT_2 = 'Jiro'
=> "Jiro"
@@1_STUDENT_3 = 'Sabu' #@@のすぐ後ろに数字は定義できない
SyntaxError:`@@1' is not allowed as a class variable name
@@student5 #クラス変数に何も値を代入しないとエラーになる
NameError: uninitialized class variable @@student5 in Object
class Students
puts @@student
end
Taro
ちなみに
warning: class variable access from toplevel
が毎回でるのはなんででしょうか??
これはObjectクラスに直下書きはよくないよってことらしいです。
詳しくはまた後日まとめます。
##スコープ
そのクラスの全インスタンスから参照することができる
class Students
@@student = 'Taro'
def greet
puts "Hi,#{@@student}"
end
end
a = Students.new
a.greet
Hi,Taro
=> nil
となります。
クラス変数はインスタンスメソッド外部で定義されているクラス変数を、インスタンスメソッド内で参照できる。
ではインスタンス変数で同様なコードで検証してみる。
class Students
@student = 'Taro'
def greet
puts "Hi,#{@student}"
end
end
a = Students.new
a.greet
Hi,
=> nil
@studentがnilになっている。
インスタンスの外で定義されているので参照できないというのがインスタンス変数との違いです。
また他にもクラス変数を使うと
class Students
@@student = 'Taro'
def greet
puts "Hi,#{@@student}"
end
def replace=(name)
@@student = name
end
end
class MedicalStudents < Students
end
a = Students.new
a.greet
Hi,Taro
=> nil
a.replace = 'Jiro'
a.greet
Hi,Jiro
=> nil
#さならにここからが面白い
b = MedicalStudents.new
b.greet
b.replace = 'Hanako'
b.greet
Hi,Hanako
=> nil
a.greet
Hi,Hanako
=> nil
というかんじで何故か全くちがくインスタンスや親クラスを操作できてしまいまいます。
一見便利ですが、例えばユーザーを作成するときは1つ1つインスタンスを作成してデータを管理する場合、クラス変数で定義するとインスタンスを作成するごとにすべてのインスタンスに変更を加えるので危険ですね。
とうわけでクラス変数のまとめでした。
ちなみにRuby技術者認定試験のシルバーではこのあたりが狙われるので注意ですね!!