我和我的朋友们正在做一些基本的Ruby练习来了解Ruby语言,我们遇到了一个有趣的行为,但我们还不能理解。基本上,我们正在创造一个
tree
node
,它只包含一个值和一个零或多个值的数组
nodes
. 我们正在使用
rspec
的autospec测试运行程序。有一次我们开始编写测试来禁止无限递归(一种循环树结构)。
下面是我们的测试:
it "breaks on a circular reference, which we will fix later" do
tree1 = Node.new 1
tree2 = Node.new 1
tree2.add_child tree1
tree1.add_child tree2
(tree1 == tree2).should be_false
end
下面是节点类:
class Node
attr_accessor :value
attr_reader :nodes
def initialize initial_value = nil
@value = initial_value
@nodes = []
end
def add_child child
@nodes.push child
@nodes.sort! { |node1, node2| node1.value <=> node2.value }
end
def == node
return (@value == node.value) && (@nodes == node.nodes)
end
end
我们期望测试的最后一行会导致无限递归,直到堆栈溢出,因为它应该不断地将子节点相互比较,并且永远找不到叶节点。(我们的印象是
==
数组上的运算符将遍历数组并调用
在每个孩子身上,基于
the array page of RubyDoc
puts
进入
==
方法来查看它被调用的频率,我们发现它正好被调用了三次,然后测试就通过了。
我们错过了什么?
编辑
be_false
在测试中
be_true
然后测试失败。所以它肯定认为数组是不相等的,只是没有在它们上面递归(除了对
==