Modular Code Organization

In many functional languages, it is possible to group together your related functions using a module. However, we typically think of something different when we think of modules in Ruby:

class A

  include Enumerable

  def initialize(arr)
    @arr = arr
  end

  def each
    @arr.each { |e| yield(e) }
  end

end

>> A.new([1,2,3]).map { |x| x + 1 }
=> [2, 3, 4]

Here, we’ve included the Enumerable module into our class as a mixin. This enables shared implementation of functionality between classes, but is a different concept than modular code organization in general.

What we really want is a collection of functions unified under a single namespace. As it turns out, Ruby has that sort of thing, too! Although the Math module can be mixed into classes similar to the way we’ve used Enumerable here, you can also use it on its own:

>> Math.sin(Math::PI / 2)
=> 1.0
>> Math.sqrt(4)
=> 2.0

So, how’d they do that? One way is to use module_function:

module A
  module_function

  def foo
    "This is foo"
  end

  def bar
    "This is bar"
  end
end

We can now call these functions directly on the module, as you can see here:

>> A.foo
=> "This is foo"
>> A.bar
=> "This is bar"

You won’t need anything more for most cases in which you want to execute functions on a module. However, this approach does come with some limitations, because it does not allow you to use private functions:

module A
  module_function

  def foo
    "This is foo calling baz: #{baz}"
  end

  def bar
    "This is bar"
  end

  private

  def baz
    "hi there"
  end
end

Though it ...

Get Ruby Best Practices now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.