From: Robert Klemme Date: 2012-11-26T21:12:05+09:00 Subject: Re: mixin objectvariables On Mon, Nov 26, 2012 at 1:09 AM, Michael Sas wrote: > 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 method `push' for > nil:NilClass (NoMethodError) > from ./layeredbg.rb:7:in `initialize' > from ./game.rb:35:in `new' > from ./game.rb:35:in `initialize' > from ./main.rb:5:in `new' > from ./main.rb:5 > > 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 2. 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 -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/