module Test
def self.model_method
puts "this is a module method"
end
end
class A
include Test
end
A.model_method
this will be error with:
undefined method `model_method' for A:Class (NoMethodError)
But when I use metaclass of A. it works:
module Test
def model_method
puts "this is a module method"
end
end
class A
class << self
include Test
end
end
A.model_method
Can someone explain this?
To answer your question, you can use self to define your method as a class method inside your module, and without self to define the method as instance method and it depends on your need and usecase that when you want what type of behaviour from your module methods. Follow this answer to receive notifications.
Class Method Self A class method is a method that refers only to that class in all contexts, but not to any individual instances of that class. A class instance method is a method that applies to all instances of that class, but not for the class object itself.
module_function can be used in a way similar to private : module Something def foo puts 'foo' end module_function def bar puts 'bar' end end. That way, you can call Something.
If you want to have both class methods and instance methods mixed into a class when including a module, you may follow the pattern:
module YourModule
module ClassMethods
def a_class_method
puts "I'm a class method"
end
end
def an_instance_method
puts "I'm an instance method"
end
def self.included(base)
base.extend ClassMethods
end
end
class Whatever
include YourModule
end
Whatever.a_class_method
# => I'm a class method
Whatever.new.an_instance_method
# => I'm an instance method
Basically to over-simplify it, you extend
to add class methods and you include
to add instance methods. When a module is included, it's #included
method is invoked, with the actual class it was included in. From here you can extend
the class with some class methods from another module. This is quite a common pattern.
See also: http://api.rubyonrails.org/classes/ActiveSupport/Concern.html
Including a module is analogous to copying its instance methods over.
In your example, there are no instance methods to copy to A
. model_method
is actually an instance method of Test
's singleton class.
Given:
module A
def method
end
end
This:
module B
include A
end
Is analogous to this:
module B
def method
end
end
When you think of it this way, this makes perfect sense:
module B
class << self
include A
end
end
B.method
Here, the methods are being copied to the B
module's singleton class, which makes them the "class methods" of B
.
Note that this is exactly the same thing as:
module B
extend A
end
In reality, the methods are not being copied; there is no duplication. The module is simply included in the method lookup list.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With