I have a module that needs to set a few instance variables on the instances it is used with, during initialization.
I wrote a library that did this a while ago, and I really thought it was working fine when I left it. It had code like this:
module Foo
attr_reader :foo
def initialize
@foo = 'foo'
super
end
end
class Bar
include Foo
attr_reader :bar
def initialize
@bar = 'bar'
end
end
b = Bar.new
p b.foo
...but Foo#initialize is not being called. Am I wrong? Did I leave my library in a broken state, despite calling it 1.0.3 and releasing it and using it? Or did the above used to work? (In 1.8.1 or 2 or so?)
Anyhow, I cobbled the following together, and it works, but...is there a better/cleaner way to do the following:
module Foo
attr_reader :foo
def self.included( klass )
klass.instance_eval{
alias_method :_pre_foo_initialize, :initialize
define_method( :initialize ){ |*args|
_setup_foo
_pre_foo_initialize( *args )
}
}
end
def self.extended( obj )
obj.instance_eval{ _setup_foo }
end
private
def _setup_foo
@foo = 'foo'
end
end
class Bar
attr_reader :bar
def initialize( bar )
@bar = bar
end
include Foo
end
class Cow
attr_reader :cow
def initialize
@cow = 'cow'
end
end
b = Bar.new( 'bar' )
p b.bar
p b.foo
c = Cow.new
c.extend( Foo )
p c.cow
p c.foo
···
--
(-, /\ \/ / /\/