50

I'm trying to use Ruby modules (mixins).

I have test.rb:

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

class MyApp
  include MyModule
  self.hallo
end

and lib/mymodule.rb:

module MyModule
  def hallo
    puts "hallo"
  end
end

Quite simple setup. But it does not work :( :

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

Where is my error?

4

4 に答える 4

77

つまり、モジュールextendの代わりに行う必要があります。include

class MyApp
  extend MyModule
  self.hallo
end

includeそれを混合するクラスのインスタンスメソッドを提供します。

extendでそれを混合するクラスのクラスメソッドを提供します。

これを読んでください。

于 2013-02-26T19:58:39.667 に答える
13

hallo問題は、インスタンス メソッド ( ) として追加しているときに、クラス定義で呼び出していることですinclude

したがって、次のいずれかを使用できますextendhalloクラスメソッドになります):

module MyModule
  def hallo
    puts "hallo"
  end
end

class MyApp
  extend MyModule
  self.hallo
end

またはhallo、MyApp のインスタンスを呼び出します。

module MyModule
  def hallo
    puts "hallo"
  end
end

class MyApp
  include MyModule
end

an_instance = MyApp.new
an_instance.hallo
于 2013-02-26T20:04:06.993 に答える
9

コードは機能していますが、モジュールをインクルードしても、思ったとおりに動作しません。モジュールを含むクラスはメソッドを取得しません - このクラスのオブジェクトは取得します。

したがって、これは機能します:

class MyApp
  include MyModule
end

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

my_app_object は、モジュール MyModule のミックスインを持つクラス MyApp のオブジェクトです。モジュールとミックスインの完全な説明については、そこをご覧ください。

于 2013-02-26T19:54:56.220 に答える
5
class MyApp
  class << self
    include MyModule
  end
  self.hallo
end

と同じです

class MyApp
  extend MyModule
  self.hallo
end

extends はクラス オブジェクトを開き、モジュール メソッドをインクルードするだけです。「ハロー」は別名クラスオブジェクトになります。クラス MyApp の静的メソッド。

したがって、「インクルード」はメソッドをレシーバーのインスタンスに注入します。あなたの場合は、オブジェクト自体ではなく「自己」です。「拡張」は、「自己」の場合にレシーバーにメソッドを注入します。

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」はクラスオブジェクトメソッド(静的メソッド)で、「extend」はインスタンスメソッドです。

于 2014-02-08T07:26:02.827 に答える