2013-02-26 14 views
30

Sto provando a utilizzare i moduli Ruby (mixins).Ruby: modulo, richiede e include

devo test.rb:

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

class MyApp 
    include MyModule 
    self.hallo 
end 

e lib/mymodule.rb:

module MyModule 
    def hallo 
    puts "hallo" 
    end 
end 

Abbastanza semplice configurazione. Ma non funziona :(:?.

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

Dove è il mio errore

risposta

53

In breve: è necessario extend anziché include il modulo.

class MyApp 
    extend MyModule 
    self.hallo 
end 

include fornisce i metodi di istanza per la classe che mescola in.

extend fornisce i metodi di classe per la classe che mescola in.

Dare this una lettura.

3

Il codice è funzionante - ma tra cui un modulo non fa quello che pensi lo fa La classe tra cui il modulo non otterrà . metodi - gli oggetti di questa classe sarà

Quindi questo lavoro:

class MyApp 
    include MyModule 
end 

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

my_app_object è un oggetto della classe MiaApp, che ha un mixins del modulo MyModule T. dai un'occhiata a there per una spiegazione completa di moduli e mixin.

8

Il problema è che si sta chiamando hallo nella definizione della classe, mentre lo si aggiunge come metodo di istanza (include).

Così si potrebbe usare sia extend (hallo sarebbe diventato un metodo di classe):

module MyModule 
    def hallo 
    puts "hallo" 
    end 
end 

class MyApp 
    extend MyModule 
    self.hallo 
end 

O uno chiamata hallo in un'istanza di MiaApp:

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 

è lo stesso

class MyApp 
    extend MyModule 
    self.hallo 
end 

extends apre solo l'oggetto classe e include i metodi del modulo. "hallo" diventa un oggetto di classe aka. metodo statico di classe MyApp.

Così "include" inietta i metodi alle istanze del destinatario, nel tuo caso essendo "auto" NON all'oggetto stesso. "estendere" iniettare i metodi per il ricevitore nel tuo caso è "self".

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

A livello di classe "self" punta al tuo oggetto di classe che è MyApp.

Ricorda inoltre che "include" e "estendi" sono solo metodi definiti in module.rb. "include" è un metodo di oggetto classe (metodo statico) e "estendere" è un metodo di istanza.

Problemi correlati