1

I know there is should be a way to initialize class instance variable that added by a module via extend example:

module MyModule
  def self.included(base)
    base.extend ClassMethods
    base.send :include, InstanceMethods
  end

  module ClassMethods
    attr_accessor :count

    def self.count
      @count = 0
    end

    count
  end

  module InstanceMethods
    def register
      # self.class.count = 0 if self.class.count.nil?
      self.class.count += 1
    end
  end
end

class Foo
  include MyModule

  private

  def initialize
    register
  end

end

In ClassMethods should be a way to initialize count, but i always catch error "undefined method `+' for nil:NilClass" When i perform

f = Foo.new

No problem in module InstanceMethods if i uncomment line

# self.class.count = 0 if self.class.count.nil?

Work correctly!

5
  • 1
    attr_accessor :count defines attributes acces for instance variables. Commented Aug 29, 2017 at 9:20
  • 2
    If you're using a recent ruby, include is no longer a private method. Which means, no need to send it. Just base.include InstanceMethods Commented Aug 29, 2017 at 9:36
  • 1
    initialize is by default private, so you can omit the explicit private in Foo. Commented Aug 29, 2017 at 10:01
  • @Stefan: I'll be damned, it IS private. It hasn't occurred to me until now :) Commented Aug 29, 2017 at 10:38
  • Sergio thanks for the tip about base.include :-) Commented Aug 31, 2017 at 3:54

2 Answers 2

5

You could move the variable initialization into the included callback:

module MyModule
  def self.included(base)
    base.extend ClassMethods
    base.include InstanceMethods
    base.count = 0
  end

  module ClassMethods
    attr_accessor :count
  end

  module InstanceMethods
    def register
      self.class.count += 1
    end
  end
end
Sign up to request clarification or add additional context in comments.

1 Comment

That's a possibility, yes.
3

One bit too many self in your code. You already extend your ClassMethods module. extend uses instance methods, not class methods. So your module should look like this (rest of the code unchanged).

module ClassMethods

  def count
    @count ||= 0
  end

  attr_writer :count
end

Then it works

Foo.count # => 0
Foo.new
Foo.count # => 1

2 Comments

I got this: NoMethodError: undefined method `+' for nil:NilClass
@D.K.S Must be you didn't copy my code exactly. Or you changed something else in the other code.

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.