views:

454

answers:

2

Say I'm writing a mixin module that adds functionality to a third-party class. Obviously some of the methods and instance variables I want to make accessible to the third-party class and its clients. These constitute the public interface of the mixin module.

But I want certain other methods and instance variables to be encapsulated. I don't want them to be accessible to the class I'm mixing into, and in particular I don't want them to accidentally override, shadow, conflict, or otherwise interfere with the mixee class's methods or instance variables -- either those that may currently exist, or those that may be created in the future if the third-party modifies the class I'm mixing into.

What precautions do I need to take, if any, to make sure my mixin is "hygienic" in this way?

+1  A: 

Create a separate object to encapsulate your functionality and instance variables, and have the mixin delegate the publically accessible methods to that object. Now you only need to associate a single instance variable with your object. You could even dodge that by storing a {Mixee => Delegate} Hash in the module and doing a lookup at the start of each mixed in method.

rampion
+1  A: 

Perhaps you could create a sub-module to contain all the utility methods.

module Foo
  module Utils
    def self.answer
      42
    end
  end
  def helpme
    "the answer is #{Utils.answer}"
  end
end
include Foo
puts helpme
glenn jackman