How to use ‘attr_reader’, ‘attr_writer’, and ‘attr_accessor’ in Ruby?
In Ruby, `attr_reader`, `attr_writer`, and `attr_accessor` are convenient shortcuts for defining getter and setter methods for class attributes. These methods help simplify the creation of instance variables and provide controlled access to them.
- attr_reader: This method is used to define getter methods for one or more instance variables. It generates methods that allow you to read the values of those variables but not modify them. Here’s an example:
```ruby
class Person
attr_reader :name, :age
def initialize(name, age)
@name = name
@age = age
end
end
person = Person.new("Alice", 30)
puts person.name # Output: Alice
``` In this example, `attr_reader` is used to generate getter methods for `name` and `age`, allowing you to read their values using `person.name` and `person.age`.
- attr_writer: This method is used to define setter methods for one or more instance variables. It generates methods that allow you to modify the values of those variables but not read them. Here’s an example:
```ruby
class Person
attr_writer :name, :age
def initialize(name, age)
@name = name
@age = age
end
end
person = Person.new("Alice", 30)
person.name = "Bob"
``` In this example, `attr_writer` is used to generate setter methods for `name` and `age`, allowing you to set their values using `person.name = “Bob”` and `person.age = 25`.
- attr_accessor: This method combines the functionality of `attr_reader` and `attr_writer`. It generates both getter and setter methods for one or more instance variables, allowing you to read and modify their values. Here’s an example:
```ruby
class Person
attr_accessor :name, :age
def initialize(name, age)
@name = name
@age = age
end
end
person = Person.new("Alice", 30)
puts person.name # Output: Alice
person.age = 25
``` In this example, `attr_accessor` is used to generate both getter and setter methods for `name` and `age`, allowing you to read and modify their values conveniently.
These methods help improve code readability and maintainability by providing a concise way to define attribute accessors. They are commonly used in Ruby classes to create simple, clean, and controlled interfaces for working with instance variables.

