Create A Module Of Utility Functions in Ruby

The Module class offers a powerful tool called module_function. It serves a dual purpose: it copies methods as singleton methods (class methods) on the module itself, while simultaneously setting them as private instance methods for any class that includes the module.

Let's see this in action by starting with a module of markdown utility functions.

module MarkdownHelpers
  module_function

  def heading(text, level = 1)
    ("#" * level) + " #{text}"
  end

  def link(text, href)
    "[#{text}](#{href})"
  end

  def image(alt_text, href)
    "!#{link(alt_text, href)}"
  end
end

Similar to private and protected, module_function is a scope gate that applies to all method definitions that follow, modifying their visibility. This is what transforms them into these "dual-use" functions.

We can now call these utility functions directly with the module as the receiver:

$ ruby -r ./markdown_helpers.rb -e 'puts MarkdownHelpers.link("Click here", "https://example.com")'
[Click here](https://example.com)

Next, let's see how this behaves when we mix the module into a class, such as Post.

class Post
  include MarkdownHelpers

  def build(title, cover_image, content)
    <<~MD
      #{heading(title)}

      #{image(cover_image.name, cover_image.url)}

      #{content}

      To read more like this, #{link("subscribe to my newsletter", "https://...")}.
    MD
  end
end

Those markdown helpers are available to instances of the Post class, functioning just like any other private method declared in the class itself. Notice that each of them is used in turn in the build method.

Here are some lines I appended to the bottom of the file to demonstrate that this works:

require "ostruct"

cover_image = OpenStruct.new(name: "City Sunset", url: "https://unsplash.com/123_city_sunset")

full_post =
  Post.new.build(
    "Latest Update",
    cover_image,
    "This is the body of the post."
  )

puts full_post

When executing the file, we see the following output:

# Latest Update

![City Sunset](https://unsplash.com/123_city_sunset)

This is the body of the post.

To read more like this, [subscribe to my newsletter](https://...).

Notice, however, that these utility functions are private to the including class. While they can be called internally, they cannot be called with an explicit receiver (part of the public interface).

ruby -r ./post.rb -e 'puts Post.new.link("Click here", "https://example.com")'
-e:1:in '<main>': private method 'link' called for an instance of Post (NoMethodError)

This is the cleanest way to namespace a set of utility functions and make them available directly in a class without expanding the public interface of that class. While a similar effect is achievable with tricks like extend self, that approach leaves included methods public.

module_function is the specific tool designed to create this strictly private utility pattern. I've found this pattern to be particularly helpful in Rails apps as a way to define reusable helpers and to share logic across controllers.

Tell us about your project

We build good software through good partnerships. Reach out and we can discuss your business, your goals, and how VisualMode can help.