変数のイメージを図で掴もう
まずは「変数とは何か」を図で理解していきましょう。
変数とは
Rubyの変数は、オブジェクトに紐付けることができる名札のような存在として機能します。
例えば、りんご1個の値段が100円だとします。
りんごの値段を数値オブジェクトとして表す場合は、100
と記述しますよね。
この100
は、「りんご1個の値段」と記述した本人は理解することができます。
しかし、次のように他の人からすると100
だけでは何を意図しているのかわかりません。
そこで、オブジェクトに結べる名札(変数)を利用します。
次のように「apple_priceと書いた名札」を100
に結びつけることで、他の人にもオブジェクトの意図を把握させることができます。
名札(変数)とオブジェクトが紐付くと、名札はオブジェクトを指し示すことになります。
そのため、名札に書いてある名前(変数名)を記述すれば、オブジェクトを参照することができます。また、一時的に保存されている状態なので、何度でも参照可能です。
変数のイメージが掴めたところで、次はRubyを使って変数を学ぼう
変数の定義
変数を使うには、まず変数を定義する必要があります。
変数の定義とは、変数を作成することです。
Rubyで名札(変数)を作成し、オブジェクトに紐付ける方法を学んでいきましょう。
変数の宣言と代入
Rubyで変数を定義するには、以下のように記述します。変数名は「名札に書く名前」で、オブジェクトは「名札と結び付けるオブジェクト」です。
1
変数名 = オブジェクト
上記により、変数(名札)が作成されて右辺のオブジェクトが結び付きます。
=
という記号は「等しい」という意味ではありません。
Rubyにおいて=
は、左辺の変数に右辺のオブジェクトを結び付けることを意味しており、これを「代入」と呼びます。
「変数にオブジェクト(値)を代入する」という表現がよく使われるよ
前述の例を使って変数を定義すると、以下のようになります。
1
apple_price = 100
上記により、apple_price
という変数を作成し、apple_price
に数値オブジェクト100
を代入することができます。
変数を定義してみよう
それでは、Rubyで変数を定義してみましょう。
apple_price = 100
と打ち込み、Enterキー(returnキー)を押しましょう。そうすると、エラーが発生することなく変数の定義ができます。
変数の使い方で詳しく説明しますが、定義した後に変数名(apple_price
)を実行すると、紐付いたオブジェクトを参照することができます。
変数の種類と命名規則
Rubyの変数には、以下のように4つの種類が存在します。
変数の種類は、変数名の先頭1文字目がどんな文字種かによって決まります。
- ローカル変数(
name
) - インスタンス変数(
@name
) - クラス変数 (
@@name
) - グローバル変数(
$name
)
この章で変数と呼ばれているものは、全て「ローカル変数」のことを指しています。他の変数については、後の章で説明させて頂きます。
ローカル変数の命名規則を確認してみよう
ローカル変数は、以下の決まりに従って名前を付けます。
- 先頭1文字目は小文字のアルファベットか
_
が使える - 2文字目以降は英数文字や
_
が使える - 予約語は使うことができない
それでは、実際にirbで各挙動を確認していきましょう。
1
name = "ぴっかちゃん"
1
user_name = "ぴっかちゃん"
1
bell_2000 = "晩御飯のお知らせ"
ここまでは、エラーが発生することなく変数を定義することができましたね。
次は誤った変数名を付けて実行してみます。変数名の1文字目は、小文字のアルファベットか_
だけ使うことができます。
1
1_name = "ぴっかちゃん"
また変数名にスペースが入ると、エラーが発生します。
1
user name = "ぴっかちゃん"
- 先頭1文字目を数字にして変数を定義したときに、エラーが発生することを確認
- 変数名にスペースが入ると、エラーが発生することを確認
最後に予約語(用途が決められた文字列)は変数名に使うことができません。
Rubyの予約語は、以下の通りです。
1
2
3
4
5
6
7
BEGIN class ensure nil self when
END def false not super while
alias defined? for or then yield
and do if redo true __LINE__
begin else in rescue undef __FILE__
break elsif module retry unless __ENCODING__
case end next return until
do
を変数名にして、変数を定義してみましょう。1
do = 1
実行すると、動画のようにエラーが発生します。
このように変数名を付ける際にはいくつかルールがあるので、注意しましょう。
変数の使い方
オブジェクトと紐付いた名札(変数)の使い方について学んでいきましょう。
変数の値を参照する
変数に代入するオブジェクトのことを「変数の値」と呼びます。
変数を定義した後は、変数名を記述すると「変数の値」が書かれたものとして扱われます。これを「変数の値を参照する」と呼びます。
変数は、変数を定義した後でないと使うことができません。
プログラムは上から順番に実行されるので、以下のようにage = 18
の定義前にage
を使うことができません。
age
を使ってみましょう。1
puts age
実行すると、動画のように「NameError」というエラーメッセージが表示されます。
さらに括弧を読んでみると、ageのことを「定義されていないローカル変数またはメソッド」というエラーが出ています。
変数を使う場合は、まず変数を定義するということを覚えておこう!
変数の値を変更する
変数を定義した後は、代入した変数の値を変更することができます。
すでに値が代入された変数に、別の値を代入することを「再代入」と呼びます。
変数の値を変更(再代入)するには、その変数に別の値を代入します。
1
2
age = 18
age = 20 #ageに別の値を代入する(再代入)
それでは、irbで変数age
へ再代入してみましょう。
最後age
の値を参照したときに、18
ではなく再代入した20
が上書きされています。
再代入した値を参照できる範囲を確かめてみよう
プログラムは上から順番に実行されるので、変数に再代入した値を参照できる範囲は以下のように再代入した後になります。
例えば、putsは指定した値を出力できるメソッドですが、再代入前と後では同じputs age
を記述しても出力する値が変わります。
1
2
3
4
age = 18
puts age
age = 20
puts age
上記を実行すると、動画のような結果となります。irbを起動している場合はexit
と入力して、起動を終了させてから、rubyコマンドで実行しましょう。
18
の後に20
が出力されましたね。これはプログラムが上から実行されるので、再代入前のageと再代入後のageがそれぞれ参照された結果です。
1
2
3
4
age = 18
puts age #=> 18 と出力される
age = 20
puts age #=> 20 と出力される
自身に代入する
変数は、変数に対して行った演算結果を同じ変数に代入することができます。これを「自己代入」と呼びます。
例えば、変数sum
の値に対して3
を加算する場合は、以下のように記述します。
1
2
3
4
sum = 0
sum = sum + 3 #自己代入する
puts sum #=> 3 と出力される
自己代入しない場合は、以下のようにsum
の値を参照して加算しただけなので、sum
は0
のままです。
1
2
3
4
sum = 0
sum + 3 # sumの値を参照しているだけ
puts sum #=> 0 と出力される
自己代入してみよう
それでは、実際に自己代入して挙動を確かめてみましょう。
1
2
3
4
5
6
sum = 0
puts sum
sum = sum + 150
puts sum
sum = sum - 35
puts sum
上記を実行すると、以下のような結果となります。
0
、150
、115
が出力されましたね。これはプログラムが上から実行されるので、同じputs sum
でも自己代入後は参照する値が変わります。
1
2
3
4
5
6
sum = 0
puts sum #=> 0 と出力される
sum = sum + 150
puts sum #=> 150 と出力される
sum = sum - 35
puts sum #=> 115 と出力される
自己代入演算子を使ってみよう
Rubyには、自己代入演算子という自己代入専用の演算子が用意されています。
式には、数値オブジェクトなどが入ります。
1
2
3
変数 = 変数 + 式
# 上記は自己代入演算子+=を使って、以下のように記述できる
変数 += 式
+=
と-=
を使って書き換えて、rubyコマンドでプログラムを実行して挙動が同じか確かめてみましょう。1
2
3
4
5
6
sum = 0
puts sum
sum = sum + 150
puts sum
sum = sum - 35
puts sum
1
2
3
4
5
6
sum = 0
puts sum
sum += 150
puts sum
sum -= 35
puts sum
式展開を利用する
変数は、式展開を利用して文字列中に変数の値を埋め込むことができます。
式展開とは、ダブルクォート(”
)で囲んだ文字列の中に#{}
と変数を記述すると、変数の値が展開されます。
1
2
name = "ぴっかちゃん"
puts "名前は#{name}です。"
上記の実行結果は、以下の通りです。
式展開を使う場合の文字列は、シングルクォート('
)ではなくダブルクォート(”
)で囲う必要があります。
以下のようにシングルクォートにした場合は、変数の値は展開されません。
1
2
name = "ぴっかちゃん"
puts '名前は#{name}です。'
上記の実行結果は、以下の通りです。
式展開を試してみよう
それでは、irbで式展開を試してみましょう。
1
2
year = 2022
puts "今年は#{year}年です。"
式展開には変数だけではなく、式(何らかの値を持つ)も記述することができます。
例えば、以下は20%5
が実行時に計算されて0
が文字列の中に展開されます。
1
puts "20を5で割った余りは#{20%5}です。"
以前のカリキュラムで算術演算子の+
を使って文字列と数値.to_sを連結させました。
1
"今年で" + 20.to_s + "歳になります。"
数値はオブジェクトの種類が違うので、to_sメソッドで文字列に変換する必要がありましたが、式展開を使うと以下のように記述することができます。
irbで実行してみましょう。
1
2
age = 20
puts "今年で#{age}歳になります。"
このように式展開を使うことで、文字列の連結を使わなくても文字列の中に変数や式を埋め込むことができます。
変数を使う際の注意点
これまで説明してきたローカル変数を使う際の注意点を確認していきましょう。
ローカル変数は参照を保持している
ローカル変数は、オブジェクトへの参照を保持しています。
例えばname1
に文字列を代入し、name2
にname1
を代入した場合で考えてみます。
1
2
3
4
5
name1 = "pikawaka"
name2 = name1
puts name1 #=> "pikawaka"と出力される
puts name2 #=> "pikawaka"と出力される
上記を実行すると、name1
とname2
は同じ文字列オブジェクトを指します。
そのため、片方の変数の値を破壊的に変更すると、もう片方の変数の値も変更されるので注意が必要です。
例えば、破滅的メソッド(オブジェクト自身の値を変更する)を使う場合が挙げられます。
以下のようにname2
にupcase!メソッド(大文字に置き換えた文字列を返す)を使うと、name1
の値まで変わってしまいます。
1
2
3
4
5
6
name1 = "pikawaka"
name2 = name1
puts name1 #=> "pikawaka"と出力される
name2.upcase! #破壊的メソッドを使う
puts name1 #=> "PIKAWAKA"と出力される
upcase!メソッドは、オブジェクト自身の値を変更する破滅的メソッドなので、name1
とname2
が参照する"pikawaka"
が"PIKAWAKA"
に変わります。
name1
の値が変更されているかirbで確かめてみましょう。このようにローカル変数はオブジェクトへの参照を保持しているので、変数の値を破壊的に変更すると、意図しない挙動をすることがあります。
変数はなぜ必要か
冒頭で変数を使うことで、オブジェクトの意図を把握させられるという可読性の部分について触れましたが、他にも「繰り返し利用できる」「保守性が上がる」などが挙げられます。
- 繰り返し利用できる
- 可読性が上がる
- 保守性が上がる
例えば、テストの合計と平均点を求めるとします。(数学80点、英語50点、理科70点)
変数を使わない場合は、以下のように記述できます。
1
2
puts 80 + 50 + 70 #テストの合計
puts (80 + 50 + 70) / 3 #テストの平均点
しかし、上記の場合は以下のような問題点があります。
- 同じ数値を何度か入力するので、打ち間違えてしまう可能性がある
- 点数を後から変えるときに全ての部分を変える必要がある
- 他の人がコードを見たときに、数値の意味が分からない可能性がある
そこで変数を利用すれば、以下のように問題点を解決できるよ
1
2
3
4
5
6
7
8
9
mathematics_score = 80
english_score = 50
science_score = 70
total_score = mathematics_score + english_score + science_score
average_score = (mathematics_score + english_score + science_score) / 3
puts total_score
puts average_score
合計点や平均点も変数に代入することで、繰り返し利用することができますね。
一見するとコードの量が増えてたので、「変数を使わない方が良いのではないか」と感じる方もいるかもしれません。しかし、短いコードよりも他の人から見て理解しやすいコードがプログラムを作る上で重要なことです。
定数
定数は、変数と同様にオブジェクトに紐付けることができる名札のような存在として機能します。変数名の先頭1文字目は大文字という決まりがあります。
ただし、定数は大文字だけで書くスタイルを採用するところが多いです。
1
定数名 = オブジェクト
1
SITE_NAME = "Pikawaka"
Rubyでは定数も結局は再代入が可能です。
1
2
3
SITE_NAME = "Pikawaka"
SITE_NAME = "ぴかわか" # 警告は出るが、再代入できる
上記を実行すると、以下のように定数に再代入することができます。
このように定数は変数と同様に再代入できますが、値が変わらないものであれば定数として宣言しておくとコードの可読性が高まります。
この記事のまとめ
- 変数は、オブジェクトに紐付けることができる名札のような存在として機能する
- この章で説明した変数は「ローカル変数」のことを指す
- ローカル変数は、オブジェクトへの参照を保持している
この記事で学んだことをTwitterに投稿して、アウトプットしよう!
Twitterの投稿画面に遷移します