Ruby Journal

How to Consolidate Module Functions?

| Comments

If you have touched module before, you would know that function can be called with module as receiver or as instance method when mixed in class. Today I am going to show you a nitfy trick to consolidate your module function so it can be used for both purposes at same time by using Module#module_function.

Concept

Instance functions

Module functions can be mixed into classes and thus are invoked as instance methods for the object of that classes. For example:

1
2
3
4
5
6
7
8
9
10
11
module MyLibrary
  def hello
    puts "Hello world"
  end
end

class Greeter
  include MyLibrary
end

Greeter.new.hello # => Hello world

Module functions

Module functions can be invoked with module as receiver. For example:

1
2
3
4
5
6
7
module MyLibrary
  def self.hello
    puts "Hello world"
  end
end

MyLibrary.hello # => Hello world

I want both, how?

Well, you can, here is my ugly version:

1
2
3
4
5
6
7
8
9
module MyLibrary
  def self.hello
    puts "Hello world"
  end

  def hello
    MyLibrary.hello
  end
end

As you can see from the code above, we reference hello method to module function MyLibrary.hello.

It looks duplicating, isn’t it? Thanks to Ruby, there is an alternative:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
module MyLibrary
  def hello
    puts "Hello world"
  end

  module_function :hello
end

class Greeter
  include MyLibrary
end

Greeter.new.hello # => Hello world
MyLibrary.hello # => Hello world

Ruby gives us Module#module_function which takes the method name and automatically generate the module function that is equivalent to MyLibrary.hello for us.

Comments