Reputation: 22366
Note: This question has been posted already at Ruby-Forum without getting an answer
Consider this module:
module MM
def f
end
def self.g
end
module_function :f
end
Both, f
and g
, are module functions, and can be called as
MM::f
MM::g
Is it just a matter of taste, or might there be good reasons to choose one way of defining a module function over the other?
I am aware, that there is a difference, when I am using the module as a mixin:
class CC
include MM
end
In this case, f
is available also as an instance method within CC
, while
g
is not. However, this doesn't look to me as a particularily
interesting feature: If I design a module to be used as a mixin to a
class, I don't see why I would use module_function. Are there other
reasons why I would favorize either self.FUNCTION
or module_function
when defining a module function?
Upvotes: 4
Views: 1042
Reputation: 34336
From the Doc:
module_function creates module functions for the named methods. These functions may be called with the module as a receiver, and also become available as instance methods to classes that mix in the module. Module functions are copies of the original, and so may be changed independently. The instance-method versions are made private. If used with no arguments, subsequently defined methods become module functions.
Basically, module_function is a way of using module methods without mix-in the module into a class.
The difference is that if you mix-in a module which uses module_function
, the mixed-in methods will become private instance methods (but they will be public class methods of the declaring module). So, in your example, f
becomes private instance method when module MM
is mixed-in to the class CC
, but can also be used as: MM.f
.
When you have:
module MM
def f
end
module_function :f
end
then you can use MM.f
without mix-in the MM
module into the CC
class. But, if you don't use:
module_function :f
You can always mix-in the module MM
into the CC
class using:
class CC
include MM
end
and can use method f
as an instance method of the objects of CC
class.
IMO, you don't really have any better reason to use module_function
in general. If you want to have your module methods as instance methods of a class, then just include the module into the class (mix-in the module into the class) as shown in the above example.
And, for defining static
/utility
methods, you should do:
module MM
def self.g
end
end
or, you can even do this:
module MM
extend self
def g
end
end
and then use the method like this: MM.g
without mix-in the module. So, you don't really need to use module_function
.
Upvotes: 2