What is `attr_accessor` in Ruby, and how does it work?

What is attr_accessor in Ruby, and how does it work?

I’m having a hard time understanding attr_accessor Ruby, Can someone explain its purpose and how it differs from attr_reader and attr_writer?

attr_accessor in Ruby is a shortcut for creating getter and setter methods for instance variables. Instead of writing separate methods manually, you can define them in a single line.

For example, without attr_accessor:
class Person
  def initialize(name)
    @name = name
  end

  def name
    @name # Getter method
  end

  def name=(new_name)
    @name = new_name # Setter method
  end
end

person = Person.new("Alice")
puts person.name      # "Alice"
person.name = "Bob"
puts person.name      # "Bob"

With attr_accessor, you can simplify it:

class Person
  attr_accessor :name 

  def initialize(name)
    @name = name
  end
end

person = Person.new("Alice")
puts person.name      # "Alice"
person.name = "Bob"
puts person.name      # "Bob"

This does the same thing but in a cleaner way.

Comparison with attr_reader and attr_writer : That’s a great example! But sometimes, you don’t need both reading and writing access.

attr_reader → Only creates a getter (read-only property).
attr_writer → Only creates a setter (write-only property).

Example:

class Person
  attr_reader :name   # Read-only
  attr_writer :age    # Write-only

  def initialize(name, age)
    @name = name
    @age = age
  end
end

person = Person.new("Alice", 25)
puts person.name  # ✅ Works: "Alice"
# person.name = "Bob"  ❌ Error! (No setter method)

person.age = 30    # ✅ Works (Setter is available)
# puts person.age  ❌ Error! (No getter method)

Use attr_reader when you only need to access a value and attr_writer when you only need to modify it.

Best Practices and Considerations :

Both explanations are spot on! Just a couple of things to consider:

  • Encapsulation: If an attribute shouldn’t be modified directly, prefer attr_reader over attr_accessor.

  • Custom Logic: If you need extra logic when getting or setting a value, manually define methods instead of using attr_accessor.

For example:

class Person
  def initialize(name, age)
    @name = name
    @age = age
  end

  def age
    @age > 18 ? @age : "Underage"
  end
end

Here, age applies logic before returning the value, which attr_accessor wouldn’t allow.