我的任务是为编码挑战创建一个无与伦比的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
答案 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'变量始终为“”,而不管条件是否发生变化。
如果这有帮助,请告诉我。