On 2/12/08, Robert K. [email protected] wrote:
And then
irb(main):026:0> class Oink
irb(main):027:1> include Foo
irb(main):028:1> def initialize
irb(main):029:2> super
irb(main):030:2> @x = 10
irb(main):031:2> end
irb(main):032:1> end
=> nil
irb(main):033:0> Oink.new.var
=> 10
You have to be careful here, since it relies on invoking super in the
initialize method, and since the initialize method in the module
doesn’t do this, it can break under the right conditions:
class A
attr_reader :a_var
def initialize
@a_var = :a_var
end
end
module M
attr_reader :m_var
def initialize
@m_var = :m_var
end
end
class B < A
include M
end
B.new.instance_variables # => [“@m_var”]
Note that the A instance didn’t get an @a_var instance variable.
The solution here is to invoke the superclass’ initialize, which also
works for subclasses which don’t have an initialize method themselves:
class A
attr_reader :a_var
def initialize
@a_var = :a_var
end
end
module M
attr_reader :m_var
def initialize
super
@m_var = :m_var
end
end
class B < A
include M
end
class C
include M
end
B.new.instance_variables # => [“@a_var”, “@m_var”]
C.new.instance_variables # => [“@m_var”]
But this is hard to do in general when the initialize methods take
different parameters.
module M
attr_reader :m_var
def initialize(*a, &b)
super
@m_var = :m_var
end
end
class D
include M
def initialize(d_val)
@d_var = d_val
super
end
end
D.new(10).instance_variables # =>
~> -:13:in `initialize’: wrong number of arguments (1 for 0)
(ArgumentError)
~> from -:13:in `initialize’
~> from -:30:in `initialize’
~> from -:35:in `new’
~> from -:35
–
Rick DeNatale
My blog on Ruby
http://talklikeaduck.denhaven2.com/