jack daniel
jack daniel

Reputation: 31

Ruby modules methods

I was going through an online tutorial on Ruby module extends where the teacher explains the code with this

module Tracking
  def create(name)
    object = new(name)
    instances.push(object) # note this line
    return object
  end

  def instances
    @instances ||= []
  end
end



class Customer
  extend Tracking

  attr_accessor :name
  def initialize(name)
    @name = name
  end

  def to_s
    "[#{@name}]"
  end
end

This was the output

puts "Customer.instances: %s" % Customer.instances.inspect
puts "Customer.create: %s" % Customer.create("Jason")
puts "Customer.create: %s" % Customer.create("Kenneth")
puts "Customer.instances: %s" % Customer.instances.inspect

Output:

Customer.instances: [] 

Customer.create: [Jason]

Customer.create: [Kenneth]

Customer.instances: [#<Customer:0x007f2b23eabc08 @name="Jason">, #<Customer:0x007f2b23eabaf0 @name="Kenneth">]

I got an understanding on how extends works but what I dont get is this method

def create(name)
        object = new(name)
        instances.push(object)
        return object
end

Specifically the line, instances.push(object)

Shouldn't it be @instances.push(object)

instances is a method in the module, how can we push objects to methods, it is not an array, it contains an array.

What is going on?

Please, I am new to Ruby, I will really appreciate simple answers.

Upvotes: 2

Views: 42

Answers (1)

kiddorails
kiddorails

Reputation: 13014

instances returns @instances which is an array, that's why when you are pushing things inside it, you are pushing it in @instances (variable) and not instances(method) .

calling instances will create the @instances with blank array if not present and return it, thereby, giving you a placeholder to keep stuff in.

For your understanding, you can even do this:

module Tracking
  def create(name)
    object = new(name)
    @instances ||= [] # NOW note this line
    @instances.push(object) # using @instances
    return object
  end

  def instances
    @instances # just a getter now
  end
end



class Customer
  extend Tracking

  attr_accessor :name
  def initialize(name)
    @name = name
  end

  def to_s
    "[#{@name}]"
  end
end


2.4.1 :098 > puts "Customer.instances: %s" % Customer.instances.inspect
Customer.instances: [#<Customer:0x007f9772187d40 @name="Jason">]
 => nil
2.4.1 :099 > puts "Customer.create: %s" % Customer.create("Jason")
Customer.create: [Jason]
 => nil
2.4.1 :100 > puts "Customer.create: %s" % Customer.create("Kenneth")
Customer.create: [Kenneth]
 => nil
2.4.1 :101 > puts "Customer.instances: %s" % Customer.instances.inspect
Customer.instances: [#<Customer:0x007f9772187d40 @name="Jason">, #<Customer:0x007f9772037080 @name="Jason">, #<Customer:0x007f977223d690 @name="Kenneth">]

Upvotes: 1

Related Questions