G
Gavin Kistner
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
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