1

The example code and output can be found here:

module A
  def self.included(base)
    base.include InMethods
  end

  module InMethods
    def mem
      @mem ||= []
    end

    def add(n)
      mem += n
    end
  end
end

class Help
  include A
end

h = Help.new
h.add(1)
# in `add': undefined method `+' for nil:NilClass (NoMethodError)

Basically, I am included one module which includes a submodule, but the real problem is with the methods and the instance variable. this is a common pattern for me, but since i am trying to do it from a module i've included, i'm having trouble.

0

1 Answer 1

2

This actually has nothing to do with modules/inclusion/inheritance/whatever. You get the same error in a regular class.

class Help
  def mem
    @mem ||= 0
  end

  def add(n)
    mem += n
  end
end

Help.new.add(1)
# test.rb:16:in `add': undefined method `+' for nil:NilClass (NoMethodError)

When you use the syntactic sugar mem +=, Ruby actually expands this into mem = mem +. The first problem is that this is interpreted left-to-right, so the mem = defines a local variable mem that masks your method. So then the second mem references a defined-but-unset local variable and you get nil.

The second problem is that you didn't define a setter mem= method, so it can't change @mem at all!

To fix both problems, you could do

attr_writer :mem

def add(n)
  self.mem += n
end
Sign up to request clarification or add additional context in comments.

1 Comment

True, my wording is wrong. I meant "unset" for the second one. A weird artifact of how Ruby defines local variables.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.