Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Ruby Ruby Modules Store Inventory Using Modules Stock Counts

Erik Nuber
Erik Nuber
20,629 Points

Just offering link to help understand better Getters/Setters and Virtual Attributes.

Seems like the course is skipping things without explaining them overly well. Spent a lot of time trying to find out whats really going on with the module

module Inventoryable

  def stock_count #getter
    @stock_count ||= 0
  end

  def stock_count=(number) #setter
    @stock_count = number
  end

  def in_stock?
    stock_count > 0
  end

end

specifically the setter portion of this as it was new and not explained much at all.

Here is a link to the best explanation I was able to find that finally gave the Uh-Huh moment of understanding.

https://rubymonk.com/learning/books/4-ruby-primer-ascent/chapters/45-more-classes/lessons/110-instance-variables

Roland Cedo
Roland Cedo
21,261 Points

Hey Erik, thanks for the post. I was a bit confused on why he declared a setter as well.

So let me know if I'm understanding this right: we declared a setter in the example because we created an instance variable inside of a module? Otherwise, if it were a class we declared the instance variable in, we'd use attr_reader/ attr_writer / attr_acessor, correct?

1 Answer

Erik Nuber
Erik Nuber
20,629 Points

From my understanding the setter portion of this is equivalent to the attr_writter allowing you to write or overwrite what a variable is equal to. However, the setter must be used in combination with a getter. Also, I agree that we are creating an instance variable in this case.

class User < ActiveRecord::Base

  # This is Getter
  def full_name
    [first_name, last_name].join(' ')
  end

  # This is the Setter
  def full_name=(name)
    split = name.split(' ', 2)
    self.first_name = split.first
    self.last_name = split.last
  end
end

I found the example above on another site, unfortunately I didn't make myself a note as to where I found it but, here the Getter method gets the first_name and last_name values and joins them together with a space between them. Then, the setter takes the full name and splits the passed in value into two where the space actually is. It then takes the split name and assigns it to the correct values. I think this example isn't the greatest as far as coding goes, it would make a lot more sense to pass and set the names inside the getter but, it is just being used to explain the concept.

Just in case, the attr_writer method does the following but, just in the background without us having to actually type it out.

def methodName=(arg1)
  @arg1=arg1
end

I found another examle at ruby-doc.com

class Song

  def durationInMinutes
    @duration/60.0   # force floating point
  end

  def durationInMinutes=(value)
    @duration = (value*60).to_i
  end
end

aSong = Song.new("Bicylops", "Fleck", 260)
aSong.durationInMinutes »  4.333333333
aSong.durationInMinutes = 4.2
aSong.duration  »  252

This is just a little different. They have used attribute methods to create a virtual instance variable. durationInMinutes seems to be an attribute but internally there is no corresponding instance variable. This is because the getter and setter are being used simply for calculations.

I am currently going back thru all the ruby lessons so, when I get back to this particular section, I will recheck my answer here and see if I can offer anything further.