lemon
lemon

Reputation: 9205

attr_accessor vs attr_reader & instance variables

could anyone please tell me the difference (if there are any) between

class Car
  attr_accessor :engine
  def initialize(engine)
    self.engine = engine
  end
end

and

class Car
  attr_reader :engine
  def initialize(engine)
    @engine = engine
  end
end

Or are they practically the same?

Upvotes: 11

Views: 8868

Answers (4)

KC S
KC S

Reputation: 4935

They are NOT the same.

To explain it in code

car = Car.new('cool engine')

For attr reader, you can only read

car.engine 
# cool engine

but you can't do

car.engine = 'even cool engine'

For attr_accessor, you can do both read and write

car.engine
# cool engine
car.engine = 'even cool engine'
car.engine
# even cool engine

For instance variables

Use only instance variables if you don't want to expose them to the outside world

class Car
  # You don't need to use attr_reader and attr_accessor here if you don't want to expose them to outside world
  def initialize(engine)
    @engine = engine
  end
end

Upvotes: 2

Jörg W Mittag
Jörg W Mittag

Reputation: 369556

No, they are not the same.

In the first example, you defined a method engine= and you call that method inside initialize. This would, for example, allow a subclass of Car to override the engine= to do something specific, and when you then call initialize, the method call would be dispatched to that overridden method. This allows subclasses to extend the behavior of Car without having to know about its internal representation.

Upvotes: 0

Arup Rakshit
Arup Rakshit

Reputation: 118289

attr_accessor defines getter and setter.attr_reader defines only getter.

class Car
  attr_reader :engine
  def initialize(engine)
    @engine = engine
  end
end

Car.instance_methods(false) # => [:engine]

With the above code you defined only def engine; @engine ;end.

class Car
  attr_accessor :engine
  def initialize(engine)
    self.engine = engine
  end
end

Car.instance_methods(false) # => [:engine, :engine=]

With the above code you defined only def engine; @engine ;end and def engine=(engine) ;@engine = engine ;end.

Upvotes: 20

ghstcode
ghstcode

Reputation: 2912

attr_accessor :engine allows you to read AND write to the variable @engine.

attr_reader :engine only allows you to read the value of @engine

self.engine = engine and @engine = engine pretty much do the same thing.

Upvotes: 7

Related Questions