链表class初始化错误
Linked list class initialization error
我有 require
用于已定义方法的 class。我什至把它放在 attr_accessor
中,我很确定它是否完全多余。但是无论我把它放在哪里或者怎么放,我都无法摆脱这个错误NoMethodError: undefined method "next_node" for nil:NilClass
。我 运行 minitest
使用 TDD 并且在这一点上超级挂断电话。
EDIT 我在测试 list.head.next_node
时尝试 return 一个 nil
值
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
LinkedList.new
将调用您的 initialize
;未传输 head
参数,因此将分配默认值 nil
。 @head = head
将 nil
存储在 @head
属性中。
稍后,您的 list.head
使用(完全不是不必要的)访问器,并且 return 是之前存储在那里的 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
和return nil
如果是(如果不是则调用该方法):
list.head&.next_node
编辑:还有一个微妙的错误,它在您的代码中是无害的,但在其他情况下可能会做一些完全出乎意料的事情。
@next_node = next_node
由于您没有在 initialize
方法中定义 next_node
变量,Ruby 将断定您希望调用访问器。此访问器将 return @next_node
,所以你最终会做 @next_node = @next_node
。幸运的是,@next_node
已经以 nil
开始,所以赋值虽然完全没有必要,但至少不会失败。
但是,如果您自己定义了访问器,请这样说:
def next_node
@next_node ||= LinkedList.new
end
(return @next_node
;如果是nil
,那么先新建一个空的LinkedList
,设置为@next_node
和return that), 那么你真的有麻烦了,因为如果你现在说 LinkedList.new
,你将尝试分配给 @next_node
一个 LinkedList.new
,它会尝试分配给它的 @next_node
a LinkedList.new
,它将尝试分配给它的 @next_node
a LinkedList.new
,这将...Ctrl-C
我有 require
用于已定义方法的 class。我什至把它放在 attr_accessor
中,我很确定它是否完全多余。但是无论我把它放在哪里或者怎么放,我都无法摆脱这个错误NoMethodError: undefined method "next_node" for nil:NilClass
。我 运行 minitest
使用 TDD 并且在这一点上超级挂断电话。
EDIT 我在测试 list.head.next_node
nil
值
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
LinkedList.new
将调用您的 initialize
;未传输 head
参数,因此将分配默认值 nil
。 @head = head
将 nil
存储在 @head
属性中。
稍后,您的 list.head
使用(完全不是不必要的)访问器,并且 return 是之前存储在那里的 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
和return nil
如果是(如果不是则调用该方法):
list.head&.next_node
编辑:还有一个微妙的错误,它在您的代码中是无害的,但在其他情况下可能会做一些完全出乎意料的事情。
@next_node = next_node
由于您没有在 initialize
方法中定义 next_node
变量,Ruby 将断定您希望调用访问器。此访问器将 return @next_node
,所以你最终会做 @next_node = @next_node
。幸运的是,@next_node
已经以 nil
开始,所以赋值虽然完全没有必要,但至少不会失败。
但是,如果您自己定义了访问器,请这样说:
def next_node
@next_node ||= LinkedList.new
end
(return @next_node
;如果是nil
,那么先新建一个空的LinkedList
,设置为@next_node
和return that), 那么你真的有麻烦了,因为如果你现在说 LinkedList.new
,你将尝试分配给 @next_node
一个 LinkedList.new
,它会尝试分配给它的 @next_node
a LinkedList.new
,它将尝试分配给它的 @next_node
a LinkedList.new
,这将...Ctrl-C