脳汁portal

アメリカ在住(だった)新米エンジニアがその日学んだIT知識を書き綴るブログ

[Ruby]if文やfor文はスコープを作らない

Rubyでコーディングする際のはまりポイントしてスコープの範囲がありますが、Rubyのif文はスコープを作りません。

確認

if true
  a = 1
end

puts a #===> 1
  • 上記のコードは問題なく動きます。
  • これはif文がスコープを作らないため、if文内で宣言された変数aが有効なためです。


test_array = [1, 2, 3]

test_array.each do |i|
  a = 1
end

puts a
#===> if.rb:7:in `<main>': undefined local variable or method `a' for main:Object (NameError)
  • こちらは動きません。
  • eachはスコープを作るので、each内で宣言された変数をスコープの外で使うことは出来ません。

対応策としては

対応策1
for文を使う

test_array = [1, 2, 3]

for i in test_array do
  a = 1
end

puts a #===>1
  • each文と違い、for文はスコープを作りません。
  • ちなみに他の繰り返し文のtimes等はスコープを作ります



対応策2
あらかじめスコープ外で宣言しておく

test_array = [1, 2, 3]

a = 0
test_array.each do |i|
  a = 1
end

puts a #===>1
  • あらかじめスコープ外宣言しておけば使えます



対応策3
インスタンス変数を使う

test_array = [1, 2, 3]

test_array.each do |i|
  @a = 1
end

puts @a #===>1
  • インスタンス変数として宣言すればスコープ外でも使用できます。



追記

  • スコープを作らない:case, if, for, while
  • スコープを作る : loop, each, times