Mixin objectvariables

Hi,

i tried to replace methods and variables common to many classes by a
mixin. I attached the file that contains the module as well as the file
where the module is mixed in. Here is a short schematic version of what
i want to do.

module m
@array = []
def add x
array.push x
end
end

class inner
include m
end

class outer
inner.new.add x
end

Here is the original error output.
./updatepaintmodule.rb:21:in addElement': undefined methodpush’ for
nil:NilClass (NoMethodError)
from ./layeredbg.rb:7:in initialize' from ./game.rb:35:innew’
from ./game.rb:35:in initialize' from ./main.rb:5:innew’
from ./main.rb:5

I think i saw an example where instance variables were mixed in. So, why
would they be nil?

On Mon, Nov 26, 2012 at 1:09 AM, Michael S. [email protected]
wrote:

array.push x

I think i saw an example where instance variables were mixed in. So, why
would they be nil?

Attachments:
http://www.ruby-forum.com/attachment/7897/updatepaintmodule.rb

That does not work. You define instance variables of the module and
not of instances of classes which include the module.

You have basically two options

  1. use lazy initialization via an accessor

module UpdatePaintModule
def updatables
@updatables ||= []
end

def addUpdatable updatable
updatables.push updatable
end

def update
updatables.each { |updatable| updatable.update if
updatable.respond_to? :update}
end

end

  1. write a constructor

module UpdatePaintModule
def initialize(*a, &b)
super
@updatables = []
end
end

Note, for option 2 to work your class needs to invoke super properly
in it’s #initialize:

class X
def initialize(a, b)
super()
@a = a
@b = b
end
end

Btw, Ruby convention is to write #add_updatable instead of
#addUpdatable.

Kind regards

robert

Thank you Robert for explaining and providing a solution. That was a
very good answer.