在解釋有這段代碼在test1.rbRuby爲什麼會用類和函數污染全局名稱空間,但不能變量?
my_var = 42
def my_func()
42
end
class MyCLS
attr_accessor :prop
def initialize()
@prop = 42
end
end
然後我需要它在IRB
> require './test1.rb'
> MyCLS.new().prop
=> 42
> my_func()
=> 42
> my_var
NameError: undefined local variable or method `my_var' for main:Object
我很困惑,紅寶石好像很樂意與污染類全局命名空間和函數,但拒絕對my_var做同樣的事情?我想這是爲了避免名稱衝突和錯誤。但問題只是部分解決,因爲它仍然存在於類和函數中。也許只是不太容易發生?
所以現在想象第二個文件test2.rb
def my_func()
43
end
class MyCLS
attr_accessor :prop
def initialize()
@prop = 43
end
end
然後執行它
> require './test1.rb'
> require './test2.rb'
> MyCLS.new().prop
=> 43
> my_func()
=> 43
這是正常的,以前的全局MyCLS和my_func,並將得到提示的覆蓋?這是不是很可能會破壞一個軟件,因爲寶石決定在某處添加/重命名類或函數?所有這些看起來非常脆弱和危險。
我知道模塊的,我想他們,但收效甚微(彆扭,和他們再次是全局)
是否有辦法防止這種情況或減輕什麼似乎是一個語言的設計缺陷?
編輯:另一個例子
# test1.rb
def my_func()
42
end
# test2.rb
puts my_func()
# test3.rb
class Example
require './test1.rb'
end
class AnotherExample
require './test2.rb'
end
# command line
$ ruby test3.rb
42
這不是一個缺陷,它是一個功能。 :)您正在查看「打開類」,這是您修改類定義(即「猴子修補」)的機制。定義被合併;但在你的情況下,你已經重新定義了一個方法,所以後者會覆蓋第一個方法。 – 2015-06-29 19:59:42