🦔
[Bug #19990] Could we reconsider the second argument to Kernel#load?
[Bug #19990] Could we reconsider the second argument to Kernel#load?
-
#load
は他のファイルのコードを読み込んできて実行する機能になる
# b.rb
def hoge
"hoge"
end
class C
end
X = 42
# a.rb
load "./b.rb", false
pp hoge # => "hjoge"
pp C # => C
pp X # => 42
- また
#load
メソッドにtrue
を渡すことで『グローバルな名前空間を汚染』を抑制することができる
# a.rb
# #load の第二引数に true を渡すと無名モジュールに b.rb のトップレベルが定義される
load "./b.rb", true
pp hoge # error
pp C # error
pp X # error
- ただし、以下のように
::
を付けて定義した場合は無名モジュールではなくてトップレベルのオブジェクトとして定義される
# b.rb
# :: を付けてクラスや定数を定義する
class ::C
end
::X = 42
# a.rb
load "./b.rb", true
pp C # => C
pp X # => 42
- このように
#load
の第二引数によって制御されたりされなかったりする事があるのでドキュメントを見直したり、機能を見直したり、機能自体を削除したほうがいいんじゃないか、という旨のチケット- 元のドキュメントだと
protecting the calling program
と書かれているが、実際にはそうではない、という点が起点
- 元のドキュメントだと
- 他にもロードする側で次のようにクラウを再オープンしてメソッドを定義している場合に
true
を渡した場合とそうでない場合で挙動が変わる
# b.rb
class String
def foo
end
end
"hoge".foo
# load "./b.rb" => OK
# load "./b.rb", true => undefined method `foo' for "hoge":String (NoMethodError)
- エッジケースではあるけど細かい挙動を付いていくといろいろと問題がありそうだなあ…
- 個人的には
#load(file, true)
はつかったことはない
- 個人的には
Discussion