我正在尝试使用Ruby模块(mixins)。
我有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>'
我的错误在哪里?
答案 0 :(得分:66)
简而言之:您需要extend
而不是include
模块。
class MyApp
extend MyModule
self.hallo
end
include
为混合它的类提供实例方法。
extend
为混合它的类提供了类方法。
给this读一读。
答案 1 :(得分:11)
问题是您在类定义中调用hallo
,而将其添加为实例方法(include
)。
所以你可以使用extend
(hallo
成为一个类方法):
module MyModule
def hallo
puts "hallo"
end
end
class MyApp
extend MyModule
self.hallo
end
或者在MyApp的实例中调用hallo
:
module MyModule
def hallo
puts "hallo"
end
end
class MyApp
include MyModule
end
an_instance = MyApp.new
an_instance.hallo
答案 2 :(得分:5)
您的代码正在运行 - 但包含模块并不能达到您的预期。包含模块的类将不会获取方法 - 此类中的对象将为。
所以这会奏效:
class MyApp
include MyModule
end
my_app_object = MyApp.new
my_app_object.hallo # => hallo
my_app_object是MyApp类的一个对象,它有一个模块MyModule的混合。请查看there以获取有关模块和混合的完整说明。
答案 3 :(得分:3)
class MyApp
class << self
include MyModule
end
self.hallo
end
与
相同class MyApp
extend MyModule
self.hallo
end
extends只打开类对象并包含模块方法。 “hallo”成为了一个类对象。 MyApp类的静态方法。
所以“include”将方法注入接收者的实例,在你的情况下是“自”而不是对象本身。在你的情况下,“extend”将方法注入接收者为“self”。
self.include MyModule // inject the methods into the instances of self
self.extend MyModule // inject the methods into object self
在课程级别,“self”将指向您的类对象,即MyApp。
还要记住“include”和“extend”只是module.rb中定义的方法。 “include”是类对象方法(static-method),“extend”是实例方法。