J'essaie d'utiliser Ruby modules (mixins).
J'ai test.rb:
#!/usr/bin/env Ruby
require_relative 'lib/mymodule'
class MyApp
include MyModule
self.hallo
end
et lib/mymodule.rb:
module MyModule
def hallo
puts "hallo"
end
end
Configuration assez simple. Mais cela ne fonctionne pas :(:
Ruby test.rb
test.rb:8:in `<class:MyApp>': undefined method `hallo' for MyApp:Class (NoMethodError)
from test.rb:6:in `<main>'
Où est mon erreur?
En bref: vous devez extend
au lieu de include
le module.
class MyApp
extend MyModule
self.hallo
end
include
fournit des méthodes d'instance pour la classe qui la mélange.
extend
fournit des méthodes de classe pour la classe qui la mélange.
Donnez ceci une lecture.
Le problème est que vous appelez hallo
dans la définition de classe, tandis que vous l'ajoutez en tant que méthode d'instance (include
).
Vous pouvez donc soit utiliser extend
(hallo
deviendrait une méthode de classe):
module MyModule
def hallo
puts "hallo"
end
end
class MyApp
extend MyModule
self.hallo
end
Ou appelez hallo
dans une instance de MyApp:
module MyModule
def hallo
puts "hallo"
end
end
class MyApp
include MyModule
end
an_instance = MyApp.new
an_instance.hallo
Votre code fonctionne - mais l'inclusion d'un module ne fait pas ce que vous pensez qu'il fait. La classe incluant le module n'obtiendra pas les méthodes - les objets de cette classe le seront.
Cela fonctionnera donc:
class MyApp
include MyModule
end
my_app_object = MyApp.new
my_app_object.hallo # => hallo
my_app_object est un objet de classe MyApp, qui a un mixins de module MyModule. Jetez un oeil là pour une explication complète des modules et mixins.
class MyApp
class << self
include MyModule
end
self.hallo
end
est le même que
class MyApp
extend MyModule
self.hallo
end
étend ouvre simplement l'objet classe et inclut les méthodes du module. "hallo" devient un objet de classe aka. méthode statique de la classe MyApp.
Donc, "include" injecte les méthodes dans les instances du récepteur, dans votre cas étant "self" PAS à l'objet lui-même. "étendre" injectez les méthodes au récepteur dans votre cas étant "auto".
self.include MyModule // inject the methods into the instances of self
self.extend MyModule // inject the methods into object self
Au niveau de la classe "self" pointera vers votre objet de classe qui est MyApp.
Souvenez-vous également que "include" et "extend" ne sont que des méthodes définies dans module.rb. "include" est une méthode d'objet de classe (méthode statique) et "extend" est une méthode d'instance.