Rubyを学習している時に、変数の違いや種類などで悩んだことはありませんか?
自分で書いたコードに合っている変数なのか?
迷ってしまうこともありますよね。
そこで、ここではRubyで使われている代表的な変数の特徴や違いなどをまとめました。よく使われる変数の中にはスコープが分かりづらかったり、紛らわしいものもあるので、学習中の方にもわかりやすく説明していきます!
変数とは
変数とは、プログラムで使用する値を予め格納しておいたり、演算結果で得られた値を格納する用途で使われる箱のようなものです。
Rubyにおける代表的な変数は以下の通りです。
- ローカル変数
- 定数
- グローバル変数
- ブロック変数
- インスタンス変数
- クラス変数
- クラスインスタンス変数
スコープという言葉が度々でてきますが、スコープとはその変数が使用可能な範囲のことです。そのため、変数の種類によってスコープ(参照できる範囲)が異なるので注意が必要です。
次項よりそれぞれの変数についての使い方やスコープについて説明していきます
ローカル変数
ローカル変数は変数の中で一番よく使われます。基本となる変数なのでしっかり理解しておくようにしましょう!
宣言
変数名には英数字と_(アンダーバー)を使うことができます。ただし、先頭に数字を使うことはできません。また、宣言と初期化を同時に行う必要があります。
慣習として、全て小文字を使います。
samurai = "ruby" # アルファベットの小文字 samurai_1 = "ruby" # 数字もOK #数字で始めてはいけない 1_samurai = "ruby" #=> SyntaxError #宣言のみはエラーとなる samurai #=> NameError: undefined local variable or method `samurai' for main:Object
スコープ
メソッド、クラスなどの定義された場所の範囲内でのみ使用可能です。クラスやメソッドを超えての参照はできないので定義された場所以外から参照をするとエラーになります。
class Cat name = "ねこ" def catName puts name end end cat = Cat.new cat.catName
[実行結果]
undefined local variable or method `name'
定数
宣言
ルールはローカル変数と一緒ですが、アルファベット大文字を用います。慣習として、定数は全て大文字で宣言をします。
最初の文字だけ大文字にする「キャメルケース」はクラス名などに用います。
SAMURAI = "ruby" Samurai = "ruby" # クラス名と紛らわしいので定数としては使われない
一般的なプログラミング言語では、定数は変更不可の値ですが、Rubyの定数は警告を出すだけで値の変更は可能です。
SAMURAI = "ruby" SAMURAI = "change value"
[実行結果]
(pry):2: warning: already initialized constant SAMURAI (pry):1: warning: previous definition of SAMURAI was here => "change value"
変更不可の値にしたい場合は、オブジェクトに限りfreezeメソッドを使うことで可能になります。
スコープ
定義されたクラスやモジュール内やクラスを継承しているクラスなどで参照できます。
SAMURAI = 3.14 puts SAMRAUI
[実行結果]
3.14
クラスの中で定義可能なので同じ定数名でもクラスごとに違う値を持つことができます。定数はメソッドの中では定義できません。
グローバル変数
宣言
変数名の一番初めに「$」をつけることでグローバル変数は宣言できます。
$global = "ruby"
スコープ
ローカル変数の逆で、メソッドやクラスを超えて参照できる変数です。定義した場所にとらわれず、プログラムのどこからでも参照や変更ができます。そのため、名前を付ける際には重複しないように注意が必要です。
$global = "global" def greet p $global end greet
[実行結果]
"global"
ブロック変数
宣言
ブロック内「{}(ブレース)またはdo ~ end内」で「|」で囲むことで宣言できます。
言葉で説明すると少しわかりにくいかもしれませんが、下の例の「iとx」のことを指します。
3.times do |i, x| # 複数行で書く場合 end [1, 2, 3].inject {|sum, n| sum + n} # 1行で書く場合
スコープ
ブロック実行の際にブロック内で使われる一時的な変数です。繰り返しなどの処理をする際、この「ブロック変数」に値を代入しながら処理をします。ブロック内からのみ参照可能な変数なのでブロック専用の変数と言えます。
a = 99 3.times do |i, x=a| a = i*10 p x end
[実行結果]
10 10 11
インスタンス変数
宣言
変数の初めに「@」をつけることで宣言を行うことができます。
@name = "ruby"
スコープ
インスタンスメソッド内でのみ使用できる変数です。インスタンスごとに異なる値を持つことができ、メソッドを超えて参照することができます。
class User def initialize(name) @name = name end def put_name p @name end end user1 = User.new("taroo") user2 = User.new("hanako") user1.put_name user2.put_name
[実行結果]
"taroo" "hanako"
クラス変数
宣言
変数目の初めに「@@」をつけることで宣言できます。
@@samurai = "ruby"
スコープ
定義されたクラス内で共有する値を扱うことのできる変数です。他のインスタンスで使用しても同じクラス内であれば共通の値として扱われるのでクラス内では一つの値しか扱うことができません。クラスを継承したクラスからも参照可能です。
class Samurai @@samurai = 1 def foo puts @@samurai end end person1 = Samurai.new person1.foo
[実行結果]
1
class Bushi < Samurai def hoge puts @@samurai end end person2 = Bushi.new person2.hoge
[実行結果]
1
このようにSamuraiクラスを継承したBushiクラスでもきちんとクラス変数にアクセスできています。
クラスの継承がどういうことなのかわからない方はこちらの記事を参考にしてみてください。
クラスインスタンス変数
宣言
インスタンス変数と同じく「@」ではじまりますが、定義される場所によりインスタンス変数と区別されます。
@class_instance_var = "ruby"
スコープ
クラス変数と同様にクラス内で定義し、定義されたクラス内でしか参照することができません。
インスタンス変数と同じく@を前置しますが、クラスで定義されている場合はクラスインスタンス変数、インスタンス内で定義されている場合はインスタンス変数と定義されている場所で区別します。
クラスを継承したクラスからは参照できないのがクラス変数との違いです。
class MyClass @class_instance_var = "ruby" def self.class_instance_var puts @class_instance_var end def class_instance_var puts @class_instance_var end end instance = MyClass.new instance.class_instance_var
[実行結果]
インスタンスメソッド内では、インスタンス変数として認識されるので、クラスインスタンス変数にはアクセスできません。
class MyClass @class_instance_var = "ruby" def self.class_instance_var puts @class_instance_var end def class_instance_var puts @class_instance_var end end MyClass.class_instance_var
[実行結果]
ruby
クラスメソッドの場合はクラスインスタンス変数にアクセスできます。
class SubClass < MyClass def self.class_instance_var_again puts @class_instance_var end end SubClass.class_instance_var_again
[実行結果]
継承したクラスからはクラスインスタンス変数にアクセスできません。
まとめ
いかがでしたか?この記事では、変数の扱い方について解説しました。
- ローカル変数
- 定数
- グローバル変数
- ブロック変数
- インスタンス変数
- クラス変数
- クラスインスタンス変数
と変数の種類は多いので、それぞれの役割やスコープをしっかりと区別できるようにしておきましょう。また特に、インスタンス変数、クラス変数、クラスインスタンス変数の3つは混同しやすいのでもう一度復習しておいてください。
もし変数の扱い方について忘れてしまったらこの記事を確認してくださいね!
関連記事