Ruby の "shadowing outer local variable" という警告について
ブロックパラメータを指定する際は, ローカル変数と同じ名前ではないか気をつける必要があります.
例えば次のような Ruby コードがあります:
# example.rb
n = 0
arr = [1, 2, 3]
arr.each do |n|
n *= 2
puts n
end
puts "Local variable n: #{n}"
そしてそれを ruby -w
で警告があれば表示するという設定で実行すると:
ruby -w example.rb
このような警告が発せられます:
example.rb:5: warning: shadowing outer local variable - n
2
4
6
Local variable n: 0
これはどういうことかと言いますと example.rb
の 5 行目:
arr.each do |n|
のブロックパラメータの n
が 3 行目:
n = 0
の n
を見えなくしてしまって, その元々の 3 行目の n
をブロック内で参照することができなくなってしまったという内容の警告です.
また Local variable n: 0
という結果を見てもわかるように, ブロックパラメータでローカル変数と同じ名前の n
を使用したからといって, 元々のローカル変数 n
が n *= 2
による代入によって上書きされるということはありません.
もし上書きされていれば, Local variable n: 0
という結果ではなく Local variable n: 6
となっていたはずです.
なので shadowing
(影で覆う) という警告になるわけです.
修正方法
このようにエラーではないのですが, 警告ということなので直してあげる必要があります .
その場合, ローカル変数 n
, もしくはブロックパラメータ n
のどちらかを別の名前に変更する必要があります.
なので次のような二通りの修正方法があります:
ローカル変数
n
を別の名前に変更する:num = 0 arr = [1, 2, 3] arr.each do |n| n *= 2 puts n end puts "Local variable num: #{num}"
ブロックパラメータ
n
を別の名前に変更する:n = 0 arr = [1, 2, 3] arr.each do |num| num *= 2 puts num end puts "Local variable n: #{n}"
まとめ
プロックパラメータを指定する時は, ブロックの外側のローカル変数と名前が同じにならないか注意する必要があります.
また同じになってしまってもどちらかの変数名を変えてあげればいいので, 比較的簡単に修正できます.
ただエラーではなく警告なので, ruby -w
を実行するまで気づけなかったということがあるかもしれません.
なので使用しているエディタがそのような警告を出してくれる機能が付いているといいのでしょう.
僕は Vim を使っているので Syntastic というリンターのプラグインにお世話になっています.
Vim を使われている方は Syntastic はおすすめです.
最後までお読みくださいましてありがとうございました.
関連記事
Ruby の正規表現を備忘録としてまとめてみた2018.08.30
Ruby のブロック, Proc, Lambda の違い2018.06.21
Ruby の関数プログラミングでオイラー積を計算してみた2018.07.02
Ruby のグローバル変数をそれぞれ調べてみた2018.06.12
Vim プラグイン ri.vim で Ruby のドキュメントを Vim の中でも見れてしまう2018.09.13