2013-02-26 81 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”是一个实例方法。