Learning Ruby: Setter and Getter Methods
This article assumes that you have a basic understanding of instance variables. Setter and getter methods are important for attribute access outside of the class creation. In the instance that you need to access, say, the name of a Person object, you need a getter method defined within the class, or in simpler terms, you need a method that can access that particular attribute, and print it on the screen for you. Getter methods are typically defined by the attribute name. For example:
class Person
def name
@name = "Bao"
end
end
Whereas getter methods allow you to access attributes, setter methods, as the name implies, allows you to set or assign attributes.
class Person
def name=(name)
@name = name
end
end
bao = Person.new
bao.name = "Bao"
bao.name
[1] pry(main)> load "setter_getter_methods.rb"
NoMethodError: undefined method `name' for #<Person:0x007fca14b22790 @name="Bao">
Did you mean? name=
from: setter_getter_methods.rb:23:in `<top (required)>'
Take a look at the code above. The setter method allows you to assign “Bao” to the name attribute of the bao object. The setter method in this example is the name= method that passes through a string as a parameter. Notice how we get a NoMethodError right at the bottom of the code snippet. That’s because we don’t have a getter method! Which means we won’t be able to access the name attribute.
Now that you’ve seen what setter and getter methods are, we’ll go into how to create these methods, as well as alternative and awesome ways to shortcut the creation of the setter and getter methods.
How to Set Setter and Getter Methods
This is the easy part! Actually learning how to set the setter and getter methods, it’s understanding how they work that was hard, but now that you get a sense of how they work from the previous section, this should be relatively easy. Let’s start with setter methods. There’s two ways to do setter methods:
1. Defining the Setter Method:
Class Person
def initialize(new_name)
@name = new_name
end
def name=(name)
@name = name
end
end
2. attr_writer:
class Person
attr_writer :name
def initialize(new_name)
@name = new_name
end
end
As you can see in the second example, the attr_writer, usually seen at the top by the class name, is shorthand for the setter method. Let’s take a look at the getter method, which works similarly!
1. Defining the Getter Method
class Person
def initialize(name)
@name = name
end
def name
@name
end
end
2. attr_reader:
class Person
attr_reader :name
def initialize(name)
@name = name
end
end
In the getter methods, attr_reader replaces the getter method. Now why is this important to note, and why should you use the attr_reader and attr_writer notations instead of defining each setter and getter method separately? Let’s take a look at some code, but this time, with more than just the name attribute.
class Person
def initialize(name)
@name = name
end
def name
@name
end
def name=(name)
@name = name
end
def age
@age
end
def age=(age)
@age = age
end
def hair_color
@hair_color
end
def hair_color=(color)
@hair_color = color
end
def eye_color
@eye_color
end
def eye_color=(color)
@eye_color = color
end
end
vs….
class Person
attr_writer :name, :age, :hair_color, :eye_color
attr_reader :name, :age, :hair_color, :eye_color
def initialize(name)
@name = name
end
end
I don’t think an explanation is needed as to why you should use attr notations over setter and getter methods. attr notation saves a lot of screen space and makes the code look cleaner. Ruby further simplifies the attr notations by combining BOTH attr_reader and attr_writer into attr_accessor. Check it out:
class Person
attr_accessor :name, :age, :hair_color, :eye_color
def initialize(name)
@name = name
end
end
We’ve effectively simplified that massively long Person class down to just 4 lines of code, which makes it a lot easier to look at, without all those unnecessary lines of code!
That pretty much concludes what I’ve learned about setter and getter methods! I hope this has helped you. Let me know if something is incorrect or if anything was unclear, and I’ll make sure to address it.