链表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 = headnil 存储在 @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