Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initializing instance variables in Mixins

Tags:

ruby

mixins

Is there any clean way to initialize instance variables in a Module intended to be used as Mixin? For example, I have the following:

module Example

  def on(...)   
    @handlers ||= {} 
    # do something with @handlers
  end

  def all(...)
    @all_handlers ||= []
    # do something with @all_handlers
  end

  def unhandled(...)
    @unhandled ||= []
    # do something with unhandled
  end

  def do_something(..)
    @handlers     ||= {}
    @unhandled    ||= []
    @all_handlers ||= []

    # potentially do something with any of the 3 above
  end

end

Notice that I have to check again and again if each @member has been properly initialized in each function -- this is mildly irritating. I would much rather write:

module Example

  def initialize
    @handlers     = {}
    @unhandled    = []
    @all_handlers = []
  end

  # or
  @handlers  = {}
  @unhandled = []
  # ...
end

And not have to repeatedly make sure things are initialized correctly. However, from what I can tell this is not possible. Is there any way around this, besides adding a initialize_me method to Example and calling initialize_me from the extended Class? I did see this example, but there's no way I'm monkey-patching things into Class just to accomplish this.

like image 923
John Ledbetter Avatar asked Sep 25 '12 15:09

John Ledbetter


1 Answers

Perhaps this is a little hacky, but you can use prepend to get the desired behavior:

module Foo
  def initialize(*args)
    @instance_var = []
    super
  end
end

class A
  prepend Foo
end

Here is the output from the console:

2.1.1 :011 > A.new
 => #<A:0x00000101131788 @instance_var=[]>
like image 174
Max Avatar answered Sep 27 '22 01:09

Max