2013-07-11 125 views
1

我在動態定義模塊中的類方法時遇到問題。見下面的代碼。當試圖在模塊中引用另一個類方法時,我得到一個NameError: undefined local variable or method。似乎這可能是一個範圍或上下文問題,但我至今還沒有弄清楚。Ruby:動態定義模塊中的類方法

module Bar 

    def self.included(base) 
    base.extend ClassMethods 
    end 

    module ClassMethods 

    def fruits 
     ["apple", "orange", "banana"] 
    end 

    def example_function(string) 
     string.upcase 
    end 

    fruits.each do |fruit| 
     method_name = fruit.to_sym 
     define_method(method_name) { example_function(fruit) } 
    end 

    end 

end 

class Foo 
    include Bar 
end 

puts Foo.apple 
puts Foo.orange 
puts Foo.banana 

我希望能夠調用:

puts Foo.apple => "APPLE" 
puts Foo.orange => "ORANGE" 
puts Foo.banana => "BANANA" 

目前,當我嘗試任何這些,我得到以下錯誤: NameError: undefined local variable or method 'fruits' for Bar::ClassMethods:Module

此外,類方法在酒吧:: ClassMethods應該可以提供給Foo,所以我應該可以打電話:

puts Foo.fruits => ["apple", "orange", "banana"] 

系統要求:

  1. 所有代碼都在一個模塊中。
  2. 該模塊允許混合實例和類方法(下面的文章)。
  3. 目標方法是動態定義的。

閱讀 「包括VS延長紅寶石」(特別是標題爲 「A常見的成語」 一節)http://www.railstips.org/blog/archives/2009/05/15/include-vs-extend-in-ruby/

幫助,這是非常感謝!

回答

2

問題是,fruits方法被定義爲一個實例方法,但您在ClassMethods上沒有實例的情況下調用它。只要定義它是這樣的:

def self.fruits 
    ["apple", "orange", "banana"] 
end 

而你的代碼的作品。

編輯: 要使fruits方法上Foo一個類的方法訪問過,你必須聲明fruits陣列的方式,是可以訪問,而ClassMethods模塊內。一種方法是將數組聲明爲類變量,並將其用於fruits方法和each塊中。請看下面的代碼:

module Bar 

    def self.included(base) 
    base.extend ClassMethods 
    end 

    module ClassMethods 
    @@fruits = ["apple", "orange", "banana"] 

    def fruits 
     @@fruits 
    end 

    def example_function(string) 
     string.upcase 
    end 

    @@fruits.each do |fruit| 
     method_name = fruit.to_sym 
     define_method(method_name) { example_function(fruit) } 
    end 
    end 
end 

class Foo 
    include Bar 
end 

puts Foo.apple 
puts Foo.orange 
puts Foo.banana 
puts Foo.fruits 
+0

嘿馬里奧,你的代碼沒有解決我最初的例子,但我忘了澄清,我希望能夠訪問Foo.fruits,看到更新後的版本。根據所使用的模塊模式,Bar :: ClassMethods模塊中的所有內容都應該是Foo中的有效類方法,即使沒有使用self來定義函數。 – mayatron

+0

@mayatron我更新了我的答案。希望這可以按照你的意圖工作。 – mario

相關問題