2016-03-09 88 views
0

假設我有以下幾點:通過ruby模塊包含的變量和方法的範圍是什麼?

module MyModule 
    module SubModule 
    Var = 'this is a constant' 
    var = 'this is not a constant' 
    def hello_world 
     return 'hello world!' 
    end 
    end 
end 

在同一個文件,我只能似乎訪問MyModule::SubModule::Var,但沒有任何常量或方法。如果我現在創建一個類,包括以不同的方式,這些模塊,我得到更多奇怪的現象:

class MyClass 
    include MyModule 
    def initialize() 
    puts SubModule::Var 
    end 

    def self.cool_method 
    puts SubModule::Var 
    end 
end 

在這種情況下,我可以再次只能訪問Var,而不是其他兩個。 SubModule::varSubModule::hello_world不起作用。最後:

class MyClass 
    include MyModule::SubModule 
    def initialize() 
    puts Var 
    puts hello_world 
    end 
    def self.cool_method 
    puts Var 
    puts hello_world 
    end 
end 

在這種情況下,我現在可以同時訪問Var和方法hello_world但不var,並且,最奇特的地方,就是hello_world似乎已經成爲一個實例方法!也就是hello_worldinitialize的作品,但self.cool_method沒有。這是非常奇怪的,考慮到Var似乎已被列爲一類變量,因爲外面的課,我一定要像這樣訪問他們:

MyClass::Var 
x = MyClass.new 
x.hello_world 

所以,我有幾個重大問題。

  1. 關於Varvar有什麼關係?看起來大寫變量名稱不僅僅是一個慣例。
  2. include模塊,什麼樣的東西被傳遞給包含類,以及在什麼範圍?
  3. 有沒有辦法做相反的事情?也就是說,使用include來包含一個實例變量或一個類方法?
+0

答案的一部分是要直接訪問模塊方法,它們必須是,那麼,模塊方法,而不是實例方法。所以你需要定義'def self.hello_world ...'來獲得MyModule :: SubModule.hello_world =>「hello world!」'。或者,您可以將'hello_world'保留爲一個實例方法,並在'SubModule'的末尾添加'extend self'行,以將'hello_world'作爲模塊方法(以及實例方法)。 –

回答

3

關於Var vs var的背後是怎麼回事?看起來大寫變量名稱不僅僅是一個慣例。

是的,當然,這不是一個約定。以大寫字母開頭的變量是常量,以小寫字母開頭的變量是局部變量。兩者完全不同。

include一個模塊,什麼樣的東西被傳遞給包含類,以及在什麼範圍?

什麼都不會傳遞到任何地方。 include ingin mixin只是簡單地將它混入到你所在類的超類中。就這樣。然後其他的一切就像班級一樣工作。

有沒有辦法做相反的事情?也就是說,使用include來包含一個實例變量或一個類方法?

我不明白這個問題。實例變量與mixin或類沒有任何關係。它們屬於實例,這就是爲什麼它們被稱爲「實例」變量的原因。

Ruby中沒有「類方法」這樣的事情。 Ruby只知道一種方法:實例方法。當Rubyists彼此交談時,他們有時會使用「類方法」這個術語來表示「碰巧是一個類的對象的單例方法」,但他們這樣做確實知道類方法實際上並不存在,它是隻是談話中的簡寫。 (當然,單例方法也不存在,它們只是說「單例類的實例方法」的便利方式。)