概要
Rubyまわりの復習のため、下記Rubyプログラムを実行した際、コンソールに表示される内容を予測する。
def rename(name)
name = "#{name}エンジニア"
return name
end
name = "Samurai"
rename(name)
puts name
予測
先述のRubyプログラムを実行すると・・・
Samuraiエンジニア
上記のような結果が返ってくる。
結果
Samurai
Rubyプログラムを実行したところ上記のような結果が返ってきた。
理由
def rename(name)
name = "#{name}エンジニア"
return name
end
上記でrenameメソッドを定義している。rename(name)とあるので「nameという変数を用いてrenameというメソッドを実行せよ」という内容になる。
なぜ“Samuraiエンジニア”ではなく“Samurai”と表示されたのか
ポイントは変数の種類、そして変数のスコープという考え方である。
スコープとは、変数を参照できる有効範囲のこと。スコープの範囲外からはその変数を見ることが出来ないため、参照しようと思っても出来ないのだ。
スコープは変数の種類ごとに異なる。
- グローバル変数・・・スコープはプロジェクト全体。例)$global
- インスタンス変数・・・スコープはインスタンス内。同一オブジェクトであればずっとデータを保持し続けることができる。例)@name
- クラス変数・・・スコープはクラス内。同一クラスのオブジェクト内であればOK。思わぬ上書きが発生する可能性あり。例)@@name
- ローカル変数・・・スコープはその変数が定義されたメソッド内。狭い。例)name
さて、ここで問題になっているプログラムを見てみると・・・
def rename(name)
name = "#{name}エンジニア"
return name
end
name = "Samurai"
rename(name)
puts name
ここで登場するnameはローカル変数、つまりスコープは定義されたメソッド内である。
メソッドrename(name)の中でname= "#{name}エンジニア"と定義されてはいるものの、このnameはメソッド内でしか参照されない。
よって、後半部分の・・・
name = "Samurai"
rename(name)
puts name
上記におけるrename(name)は出力結果に一切影響を及ぼさない。
結果は非常にシンプルで、puts nameによってname = "Samurai"が呼び出されるだけなのである。
補足
ちなみに、当初の私の予想通りSamuraiエンジニアと表示させたい場合、下記のようにプログラムを書き換えればOKである。
def rename(name)
name = "#{name}エンジニア"
return name
end
name = "Samurai"
name = rename(name)
puts name