🌊
[Bug #21662] 意図せず変数が書き換えられてしまうバグ報告
[Bug #21662] Variables other than those in the conditional score are replaced.
- 以下のようなコードを実行した際に
bar = ''がbar.nameまで書き換えてしまうというバグ報告
class Bar
attr_accessor :name
end
class Foo
attr_accessor :bar
def initialize(bar=nil)
@bar = bar || Bar.new
end
def bug!
# Bar 以外の場合は bar = '' する
# Bar の場合は if bar.name == 'bar' で更に条件分岐する
if !bar.is_a?(Bar)
bar = ''
elsif bar.name == 'bar'
end
end
end
# error: undefined method 'name' for nil (NoMethodError)
Foo.new.bug!
- 上記のコードを実行した場合、
barはBar.newが割り当てられているのでbar = ''の処理は呼ばれずにif bar.nameの分岐処理が呼ばれる - なので
bar.nameはBar#nameが呼ばれることを期待しているが実際にはnil.nameが呼ばれエラーになってしまう - これなんですが Ruby では変数が定義される構文があれば実行時にその処理が呼ばれなくても『変数が定義されている状態』になる
if false
# ここは実行時に呼ばれない
a = 42
end
# しかし、変数が定義されているように振る舞う
# 初期値は nil になっている
p a
# => nil
- これにより提示されているコードでは
bar = ''によって#barメソッドが隠蔽されbar.nameが意図する呼び出しにならない - Ruby になれていないと結構ぎょっとしまうねえ
Discussion