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

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.