Why are setter methods not used in initialization?

Recently I've been reading "Practical Object Oriented Design in Ruby", and I noticed one of the best practices was to use accessor methods instead of directly grabbing the @instance_variable . For example:

class Foo
  attr_accessor :bar

  def initialize(my_argument)
    @bar = my_argument
  end

  # bad
  # def lorem_ipsum
  #     @bar * 999
  # end

  # good
  def lorem_ipsum
    bar * 999
  end

end

It makes sense to keep things DRY, and, in case I need to process @bar somehow before actually grabbing its value. However, I noticed that the initialize method sets the value of the @bar instance variable directly:

class Foo
  attr_accessor :bar

  def initialize(my_argument)
    @bar = my_argument #<-- why isn't self.bar = my_argument used here?
  end

Is there a reason for this? Shouldn't the setter method be used instead of directly using the = operator to set the value of the instance variable?


You're right, it would make much more sense to do

class Foo
  attr_accessor :bar

  def initialize(my_argument)
    self.bar = my_argument
  end
end

Arguments differ as to whether you should respect encapsulation within the object itself or not, but if you believe in that, then, yes, you should do this.


The initializer SETS the value upon initialization. The accessor lets you access (read/write) via the symbol after the object is already instantiated.

This post might help you understand: What is attr_accessor in Ruby?


Actually, the setter can be used in initialize the same as in other methods, but setter cannot be used without a receiver.

I think you can use a_foo.bar= or self.bar= , but cannot use bar= without a receiver, because, in the later case, bar will be treated as a local variable rather than a setter method:

class Song
  attr_accessor :name
  def initialize(name)
    self.name = name
  end
  def test_setter1(value)
    @name = value
  end
  def test_setter2(value)
    name = value #name is local variable
  end
end

s = Song.new("Mike")
p s
s.test_setter1("John")
p s
s.test_setter2("Rosy")
p s

This results in:

#<Song:0x23a50b8 @name="Mike">
#<Song:0x23a50b8 @name="John">
#<Song:0x23a50b8 @name="John">
链接地址: http://www.djcxy.com/p/25784.html

上一篇: 与attr相比,ActiveRecord如何定义方法

下一篇: 为什么在初始化时不使用setter方法?