对于具有定义方法的类,我有require
。我甚至将它放在attr_accessor
中,我非常确定是否完全过剩。但无论我在何处或如何表达,我都无法摆脱这个错误NoMethodError: undefined method "next_node" for nil:NilClass
。我正在运行minitest
来使用TDD,并且在这一点上超级挂了。
编辑我在测试nil
list.head.next_node
值
require './lib/node'
class LinkedList
attr_accessor :head,
:next_node
def initialize(head = nil)
@head = head
@next_node = next_node
end
def append(sound)
#@next_node = nil
@head = Node.new(sound)
sound
end
end
这是我的测试方法
def test_does_head_move_value_to_next_node
list = LinkedList.new
list.head.next_node
# assert_nil list.head.next_node
end
答案 0 :(得分:1)
LinkedList.new
会调用您的initialize
;未传输head
参数,因此将分配默认值nil
。 @head = head
会将nil
存储在@head
属性中。
稍后,您的list.head
使用(根本不是必需的)访问者,并返回之前存储的nil
。然后.next_node
被发送到nil
,但NilClass
没有定义这样的方法。为了让list.head.next_node
调用您的next_node
方法,@head
需要是LinkedList
个对象,而不是nil
。
如果您希望保护自己不受此影响,可以使用:
list.head.next_node if list.head
或使用Ruby 2.3引入的安全导航操作符&.
,它将检查左侧是nil
并返回nil
(如果是)(如果没有则调用方法) :
list.head&.next_node
编辑:还有一个微妙的错误,在您的代码中是无害的,但在某些其他情况下可能会完全出乎意料。
@next_node = next_node
由于您尚未在next_node
方法中定义initialize
变量,因此Ruby会断定您希望调用访问者。此访问者将返回@next_node
,因此您最终会执行@next_node = @next_node
。幸运的是,@next_node
已经以nil
开头,所以尽管完全没必要,但这项任务至少不会失败。
但是,如果你自己定义了访问者,请这样说:
def next_node
@next_node ||= LinkedList.new
end
(返回@next_node
;如果是nil
,则首先创建一个新的空LinkedList
,将其设置为@next_node
然后返回),然后你就进入真的很麻烦,因为如果你现在说LinkedList.new
,你会尝试分配给@next_node
一个LinkedList.new
,它会尝试分配给@next_node
LinkedList.new
,它会尝试分配给@next_node
一个LinkedList.new
,这将... Ctrl-C