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?
is the same as
extends just opens the class object and include the module methods. "hallo" becomes a class object aka. static method of class MyApp.
So "include" inject the methods to the instances of the receiver, in your case being "self" NOT to the object itself. "extend" inject the methods to the receiver in your case being "self".
At class level "self" will point to your class object which is MyApp.
Also remember that "include" and "extend" are just methods defined in module.rb. "include" is a class object method (static-method) and "extend" is an instance method.
In short: you need to
extend
instead ofinclude
the module.include
provides instance methods for the class that mixes it in.extend
provides class methods for the class that mixes it in.Give this a read.
Your code is working - but including a module does not do what you think it does. The class including the module will not get the methods - the objects from this class will.
So this will work :
my_app_object is an object of class MyApp, which has a mixins of module MyModule. Take a look there for a complete explanation of modules and mixins.
The issue is that you are calling
hallo
in the class definition, while you add it as an instance method (include
).So you could either use
extend
(hallo
would become a class method):Or either call
hallo
in an instance of MyApp: