0

Given the code below:

class Man
  def self.noise=(noise)
    @@noise = noise
  end
end

puts Man.noise = ("YO")

I have used the setter method self.noise, but not actually used the getter method and it worked. I'm curious to know whether class variables requires getter and setter methods to work?

The confusing element in all of this is that instance variables seem to need both getter and setter methods to be accessed. If you only have a setter method to access instance variables, the variable simply will not get returned, if you call the setter method.

My question is that for class variables, can you only have a setter method and call it, without a getter method to access the class variable? In this case, the getter method would be:

self.noise
  @@noise
end 
developer098
  • 773
  • 2
  • 10
  • 18
  • Does http://stackoverflow.com/questions/8737421/trying-to-learn-understand-ruby-setter-and-getter-methods - which asks basically the same question but about instance variables - help clarify things? In particular answer http://stackoverflow.com/a/8737438/117424 may be helpful. – Ben Gribaudo Nov 05 '16 at 01:43
  • I fully understand that instance variables need to use both getter and setter methods, wondering the same thing about class variables. Whether it is necessary to have both in order for the program to work. – developer098 Nov 05 '16 at 01:46

2 Answers2

3

You're not calling the "getter" method here since Man.noise is on the left side of the assignment operator. That makes a call to Man.noise= and you've defined that.

If you try calling it you get this:

Man.noise
#! NoMethodError: undefined method `noise' for Man:Class

You can do things like this to make your life easier:

class Man
  class << self
    attr_accessor :noise
  end
end

Man.noise = 'Hello world!'
Man.noise
# => "Hello world!"

In the Rails environment you have cattr_accessor for classes and mattr_accessor for modules which does this for you without the need for class << self and such.

One thing to note is to use regular instance variables whenever possible. There's no need to use @@ here.

tadman
  • 208,517
  • 23
  • 234
  • 262
  • I understand that I have used a "setter" method in this class variable case, but it seems to be functioning without the "getter" method. This is compared to instance variables, where if I called the "setter method" directly without a "getter" method, the instance variable would not be returned. Just wanted to confirm whether I had the right understanding that you don't need both getter and setter methods to access class variables (just setter in this case), as opposed to instance variables. Is that true? – developer098 Nov 05 '16 at 18:47
  • It's unusual to have a setter (mutator) only. Normally you create these in pairs so you can read *and* write. In your case you defined only a mutator, not a reader, so you've only done half the work. It's basically a write-only class property. – tadman Nov 06 '16 at 00:00
  • I realize that have both reader and writer methods is better. Just wanted to confirm that you can for class variables (if you wanted) get away with just having a setter method and calling it to access the class variable? – developer098 Nov 06 '16 at 00:30
0

Writing the class variable is done properly. You can read them as follows:

class Man
  def self.noise=(noise)
    @@noise = noise
  end
  def self.noise
     @@noise ||= nil
  end
end

puts "Hello world!"
puts Man.noise
puts Man.noise = ("YO")
puts Man.noise

Output:

Hello world!

YO
YO 

However, you should be very careful when it comes to inheritance.

class Man
  def self.noise=(noise)
    @@noise = noise
  end
  def self.noise
     @@noise ||= nil
  end
end


class Man1 < Man

end

Man.noise = ("YO")
Man1.noise = ("XYZ")
puts Man1.noise
puts Man.noise

Output:

XYZ
XYZ

Note that changing noise of the child class also changes noise of the parent class.

maij
  • 4,094
  • 2
  • 12
  • 28