2013-02-26 80 views
30

我試圖使用Ruby模塊(mixins)。Ruby:模塊,要求包括

我有test.rb:

#!/usr/bin/env ruby 
require_relative 'lib/mymodule' 

class MyApp 
    include MyModule 
    self.hallo 
end 

和lib/mymodule.rb:

module MyModule 
    def hallo 
    puts "hallo" 
    end 
end 

很簡單的設置。但它不工作:(:?

ruby test.rb 
test.rb:8:in `<class:MyApp>': undefined method `hallo' for MyApp:Class (NoMethodError) 
     from test.rb:6:in `<main>' 

哪裏是我的錯誤

回答

53

總之:您需要extend而不是include該模塊。

class MyApp 
    extend MyModule 
    self.hallo 
end 

include提供實例方法爲混合它的類。

extend提供混合了它在類的類方法。

this讀。

3

您的代碼工作 - 但其中一個模塊不會做你認爲它包括模塊類不會得到。方法 - 從這個類將對象

所以這將工作:

class MyApp 
    include MyModule 
end 

my_app_object = MyApp.new 
my_app_object.hallo # => hallo 

my_app_object是類MyApp的,其具有模塊MyModule的的混入的物體T。請看一下there以獲取模塊和mixin的完整說明。

8

問題在於,您在類定義中調用hallo,而將其作爲實例方法(include)添加。在MyApp的實例

module MyModule 
    def hallo 
    puts "hallo" 
    end 
end 

class MyApp 
    extend MyModule 
    self.hallo 
end 

或任一電話hallo

所以,你既可以使用extendhallo將成爲一個類的方法)

module MyModule 
    def hallo 
    puts "hallo" 
    end 
end 

class MyApp 
    include MyModule 
end 

an_instance = MyApp.new 
an_instance.hallo 
1
class MyApp 
    class << self 
    include MyModule 
    end 
    self.hallo 
end 

是一樣的

class MyApp 
    extend MyModule 
    self.hallo 
end 

擴展只是打開類對象幷包含模塊方法。 「hallo」成爲一個類對象。類MyApp的靜態方法。

所以「include」將方法注入接收者的實例,在你的情況下是「self」而不是對象本身。在你的情況下,「擴展」將方法注入到接收器中是「自我」的。

self.include MyModule // inject the methods into the instances of self 
self.extend MyModule // inject the methods into object self 

在類級別「自我」將指向您的類對象,它是MyApp。

還要記住,「include」和「extend」只是在module.rb中定義的方法。 「include」是一個類對象方法(static-method),「extend」是一個實例方法。