在Ruby中,使用“def initialize(value ='')”初始化类实例的好处是什么?

时间:2014-11-14 17:31:07

标签: ruby class oop

我的任务是为编码挑战创建一个无与伦比的tic tac toe对手,我想创建一个Ruby gem来做到这一点,它具有适当的测试覆盖率和体面的面向对象设计(OOD)。

之前从未制作过我自己的宝石,并成为正确的OOD原则的新生,我找到了一篇很好的博客文章,其中详细介绍了我的需求:http://codequizzes.wordpress.com/2013/10/25/creating-a-tic-tac-toe-game-with-ruby/

在定义Cell类时,以下代码为例:

module TicTacToe
  class Cell
    attr_accessor :value

    def initialize (value = "")
      @value = value
    end 

  end
end

在我看来,考虑到这种初始化的简单性,我们可以轻松地做到这一点:

module TicTacToe
  class Cell
    attr_accessor :value

    def initialize
      @value = ""
    end 

  end
end

那么在第二种方式上做第一种方式的理由是什么呢?

修改

好的,我觉得现在有点傻了;阅读博客文章更近一点,它清楚地说明了

  

Cell类包含在TicTacToe模块中,以遵循Ruby gem约定,并在其他项目中包含gem时防止>类名冲突。 如果Cell已初始化>没有任何参数,则单元格的值将为空字符串,但Cell也可以使用参数进行初始化。在实例化单元格后,其值无法更新。

但是,我仍然对最后一句话感到困惑,“在实例化单元格后,其值无法更新。”

我认为在这个例子中这是不正确的,至于我的理解, attr_accessor 方法使值既可读又可写 - 因为它是可写的,我不能通过说<更新它/ p>

move = Cell.new
move.value = X 

2 个答案:

答案 0 :(得分:3)

第一种情况:

def initialize (value = "")
  @value = value
end
如果没有传递参数进行初始化,

会将@value设置为空字符串。如果将参数传递给initialize,则value将设置为该参数。

第二种情况:

def initialize
  @value = ""
end 

将始终将@value设置为空字符串,并且不接受参数。

示例:

如果我们有

module TicTacToe
  class Cell
    attr_accessor :value
    def initialize (value = "")
      @value = value
    end 
  end
end

c = TicTacToe::Cell.new("hello")
puts c.value

代码会打印你好。

使用上面相同的代码,但将最后两行更改为

c = TicTacToe::Cell.new
puts c.value    

代码什么都不打印(除了空字符串外)。

现在,如果我们将代码更改为第二种方式:

module TicTacToe
  class Cell
    attr_accessor :value
    def initialize
      @value = ""
    end 
  end
end

c = TicTacToe::Cell.new
puts c.value

这将再次输出空字符串。但是,这次我们尝试将最后两行更改为:

c = TicTacToe::Cell.new("hello")
puts c.value

我们得到一个错误,因为初始化程序不期望参数。因此,除了空字符串之外,我们无法使用任何@value实例化它。

关于您的修改:

是的,您仍然可以更改@value。如果您想阻止这种情况,请通过更改

使其可读
attr_accessor :value

attr_reader :value

答案 1 :(得分:0)

这个网站实际上很好地解释了上述两种方式的优缺点:http://www.rubyist.net/~slagell/ruby/objinitialization.html

对于您的第一个示例,将'value'作为参数传递给参数允许您覆盖此默认值,而您的第二个示例强制'@value'变量始终为“”,而不管条件是否发生变化。

如果这有帮助,请告诉我。