user1934428
user1934428

Reputation: 22366

Defining a module_function in Ruby

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

Answers (1)

K M Rakibul Islam
K M Rakibul Islam

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

Related Questions