为什么在初始化时不使用setter方法?

最近我一直在阅读“面向实践的面向对象的Ruby设计”,并且我注意到其中一个最佳实践是使用访问器方法,而不是直接抓取@instance_variable 。 例如:

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

保持DRY是有意义的,并且在需要在实际获取其值的情况下以某种方式处理@bar情况下。 但是,我注意到initialize方法直接设置了@bar实例变量的值:

class Foo
  attr_accessor :bar

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

是否有一个原因? 不应该使用setter方法而不是直接使用=运算符来设置实例变量的值?


你说得对,这样做会更有意义

class Foo
  attr_accessor :bar

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

关于你是否应该尊重对象本身中的封装,争论不同,但是如果你相信那个,那么,是的,你应该这样做。


初始化器在初始化时设置该值。 访问器允许您在对象已经实例化之后通过符号访问(读取/写入)。

这篇文章可能会帮助你理解:什么是Ruby中的attr_accessor?


实际上,setter可以像其他方法一样initialize ,但setter不能在没有接收器的情况下使用。

我认为你可以使用a_foo.bar=self.bar= ,但不能使用bar=没有接收器,因为在后面的例子中, bar将被视为局部变量而不是setter方法:

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

这导致:

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

上一篇: Why are setter methods not used in initialization?

下一篇: rails 3.1, why devise can't build the resource?