You’ll love module_function

Sven Winkler
<pretty/code>
Published in
1 min readDec 15, 2015

Ever had the problem of exposing methods as instance methods and module level methods? You’ll love module_function.

You can use module_function on a method-to-method basis:

module X
def foo
'bar'
end
module_function :foo
end
$ X.foo
=> 'bar'

When given no arguments all subsequent methods are made module functions:

module X
module_function
def foo
'huhu'
end
end
$ X.foo
=> 'huhu'

All instance counterparts of methods exposed by module_function are private by default.

Even better, the module level methods are copies of their instance parts, so monkey patching one of them is not going to affect the other.

Why should I be using this?

When you’re adopting a more functional style of programming and your methods become independent of internal object state they get useful in other contexts.

Have a look at Erb::Util where this principle is applied. We can get a hold of the modules methods like we are used to:

require 'erb'class X
include ERB::Util
def call
url_encode 'http://www.google.com'
end
end
$ X.new.call
=> 'http%3A%2F%2Fwww.google.com'

Or we can just use the provided module function:

require 'erb'class Y
def call
ERB::Util.url_encode 'http://www.google.com'
end
end
$ Y.new.call
=> 'http%3A%2F%2Fwww.google.com'

Thanks to module_function you are now able to use url_encode without littering your inheritance chain. This pattern is used extensively throughout the ruby codebase.

--

--

Sven Winkler
<pretty/code>

Ruby, Rails, CoffeeScript & Vim » breaking things with passion since 1983