How getter/setter methods work in Ruby

Ronald Walker
Jun 29, 2017 · 3 min read

A getter method retrieves the value of an instance variable from an object. It is common practice to have the getter method’s name match the instance variable’s name.

We can create them ourselves:

class Person
def initialize(name)
@name = name
end
def name # creates getter method for name
@name
end
end
mike = Person.new('Mike')
mike.name # calling getter method, returns "Mike"

The attr_reader method automatically creates a getter method for each desired state we supply as comma separated symbols:

class Person
attr_reader :name # creates getter method for name
def initialize(name)
@name = name
end
end
mike = Person.new('Mike')
mike.name # calling getter method, returns "Mike"

A setter method establishes or reestablishes the value for an instance variable. It is common practice to have the setter method’s name match the instance variable’s name:

class Person
attr_reader :name, :age #creates getter method's age & name

def initialize(name)
@name = name
end
def age=(a) # creates setter method for age
@age = a
end
end
mike = Person.new('Mike')
mike.age = 20 # calling setter method
mike.age # calling getter method, returns 20

The attr_writer method automatically creates a setter method for each desired state we supply as comma separated symbols:

class Person
attr_reader :name, :age
attr_writer :name, :age # creates the setter methods

def initialize(name)
@name = name
end
end
mike = Person.new('Mike')
mike.age = 20 # calling setter method
mike.age # calling getter method, returns 20

Instance variables in general are not created until the method in which they are initialized has been called. The initialize method is called instantly when a new object is created. In absence of an initialize method, or one without the instance variables, the setter method will initialize instance variable(s) if they haven’t been initialized elsewhere. Unlike the initialize method, the setter method is not called atomically. So, the states inside the setter method will not be created until the setter method is called:

class Person
attr_writer :name # creates setter method
end
mike = Person.newp mike #prints: <Person:0x007fcc190c03e0>
mike.name = "Rob"
p mike #prints: #<Person:0x007fcc190c03e0 @name="Rob">

The attr_accessor method creates both the getter and setter method for each desired state we provide as comma separated symbols:

class Person
attr_accessor :name, :age # creates getter and setter methods

def initialize(name)
@name = name
end
end
mike = Person.new('Mike')
mike.age = 20 # calling setter method
mike.age # calling getter method, returns 20

If you need your getter and setter methods to be custom, you must write them yourself:

class Person
def initialize(name)
@name = name
end
def name # getter method
"My name is #{@name}!"
end
end
mike = Person.new('Mike')
mike.name # returns "My name is Mike!"

If no custom work is required, I choose to save time and just use the attr_* methods.

When using the setter methods inside of the class, self is required. When using the getter methods inside of the class, self is optional.

class Person
attr_accessor :name
def initialize(name)
@name = name
end
def change_name_to_nil
self.name = nil # setter method inside class
end
def say_hello
"#{name} says HELLO!" # getter method inside class
end
end
mike = Person.new('Mike')
mike.say_hello # returns "Mike says HELLO!"
mike.change_name_to_nil
mike.name # returns nil