Ruby:模块,需求和包含

时间:2013-02-26 19:47:14

标签: ruby module mixins

我正在尝试使用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>'

我的错误在哪里?

4 个答案:

答案 0 :(得分:66)

简而言之:您需要extend而不是include模块。

class MyApp
  extend MyModule
  self.hallo
end

include为混合它的类提供实例方法。

extend为混合它的类提供了类方法。

this读一读。

答案 1 :(得分:11)

问题是您在类定义中调用hallo,而将其添加为实例方法(include)。

所以你可以使用extendhallo成为一个类方法):

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”是实例方法。