2

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.

0

1 Answer 1

1

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">] 
Sign up to request clarification or add additional context in comments.

4 Comments

Ok. So it means whatever method returns we can directly manipulate them as well, which means in the original code, I can also do, i = instances; i.push(object);. This is what is actually happening?
indeed. i= instances will hold the same reference of array
Got that. But why was I downvoted, I am learning? Was there something wrong with the question? I did made sure to read on How to ask questions.
I'm not sure. I didn't downvote you. It's a fair question for a learner, and I appreciate that you came with the code, phrased the question correctly and had genuine curiosity about the internals. Personally, that's how I learnt it as well. Here, take my upvote on question; and keep up with learning ;)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.