Creating practically private methods in mixed-in Ruby modules

Module injection in Ruby is cool. It allows you to flexibly compose an object’s behavior (those it’s not composition; it’s multiple inheritance), while still leveraging the data/code coupling power of objects. However, it comes with its own set of complications.

A particular module might want to reduce its namespace footprint by exposing a small interface and hiding implementation functions. Take a look at the code in this gist. Both modules define an aptly-named private_method, but once they’re both included in the class, the second private method overwrites the first.

Ruby’s private keyword does not do what I want here, as methods defined within it share a namespace with all other included methods. You do not want a module’s private methods to have to compete for namespace, as no other parts of your code should even know they exist! This is a strong dependency.

There is an easy, common solution, but I have to admit that it feels hacky, and is certainly not semantic. By which I mean, this solution would never occur to me. But here: effectively private methods can be hidden within classes or modules defined within your original module, like in this gist. The idea is summarized as follows:

module MyFirstModule
  def first_public_method(my_string)
    return "#{my_string} #{PrivateMethods.private_method}"
  end

  module PrivateMethods
    def self.private_method
      1
    end
  end
end

This module can be included in your model classes, and Bob’s your uncle! The module exposes a public interface which makes use of private methods which truly do not effect anything else. It’s not too complicated, but don’t you agree that it’s a bit gross?

This doesn’t solve every problem of module injection, but it allows you to reduce surface area and make necessary dependencies more obvious. I’m currently trying to figure out how to prevent modules from being so easily able to call and depend on each other in inexplicit, unobvious ways. Like in this gist.

Advertisements

Leave a comment

Filed under Uncategorized

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s