method_name= 是如何工作的?
How does method_name= work under the hood?
我在 Ruby 中破解了链表的一个简单实现,我遇到了一些非常奇怪的事情。
我创建了一个 List
class 和 attr_accessor
到 first_node
。像这样:
class List
attr_accessor :first_node
# Some code here ...
end
然后,在执行方法 delete_at
时出现以下错误
linearly.rb:39:in `delete_at': undefined method `next' for nil:NilClass (NoMethodError)
from linearly.rb:81:in `<main>'
这是方法的一部分:
def delete_at(position)
if position == 0
deleted_node = first_node
first_node = first_node.next # This is line 39.
return deleted_node
else
# More code here ...
我忘记使用 class 变量 @first_node
,而是使用了 reader 方法 first_node
。然后,我开始想知道为什么在同一行中使用 first_node=
时 first_node
returns nil
。
是否在设置新值之前将 @first_node
设置为 nil
?
请注意,这段代码工作正常:
def delete_at(position)
if position == 0
deleted_node = first_node
first_node = deleted_node.next
return deleted_node
else
# Some code here ...
编辑:
这就是我调用实现的方式:
list = List.new
list.first_node = Node.new(1)
list.first_node.next = Node.new(2)
list.first_node.next.next = Node.new(3)
puts "Delete at 0"
puts list.delete_at(0)
你确定@first_node已经设置了吗?取消设置时实例变量将 return 为 nil。
class Test
attr_accessor :foo
def print_foo
puts "@foo=[#{@foo}]"
puts "foo=[#{foo}]"
puts @foo.nil?
end
end
t1 = Test.new
t1.foo # => nil
t1.print_foo # prints "@foo=[]" and "foo=[]" and returns true
这个:
first_node = first_node.next
创建一个名为 first_node
的局部变量。变量声明被提升到 Ruby 范围的顶部,因此您的方法等效于:
def delete_at(position)
deleted_node = nil # Declare deleted_node and first_node
first_node = nil # as local variables.
if position == 0
deleted_node = first_node
first_node = deleted_node.next
return deleted_node
else
# Some code here ...
这意味着您方法中的所有 first_node
引用都将是本地 first_node
变量,而不是 attr_accessor
为您创建的 getter 和设置方法。
要么不要使用与方法名称匹配的变量,要么通过为方法调用提供 self
接收器来明确说明您的意思:
def delete_at(position)
if position == 0
deleted_node = self.first_node
self.first_node = deleted_node.next
#...
我在 Ruby 中破解了链表的一个简单实现,我遇到了一些非常奇怪的事情。
我创建了一个 List
class 和 attr_accessor
到 first_node
。像这样:
class List
attr_accessor :first_node
# Some code here ...
end
然后,在执行方法 delete_at
时出现以下错误
linearly.rb:39:in `delete_at': undefined method `next' for nil:NilClass (NoMethodError)
from linearly.rb:81:in `<main>'
这是方法的一部分:
def delete_at(position)
if position == 0
deleted_node = first_node
first_node = first_node.next # This is line 39.
return deleted_node
else
# More code here ...
我忘记使用 class 变量 @first_node
,而是使用了 reader 方法 first_node
。然后,我开始想知道为什么在同一行中使用 first_node=
时 first_node
returns nil
。
是否在设置新值之前将 @first_node
设置为 nil
?
请注意,这段代码工作正常:
def delete_at(position)
if position == 0
deleted_node = first_node
first_node = deleted_node.next
return deleted_node
else
# Some code here ...
编辑:
这就是我调用实现的方式:
list = List.new
list.first_node = Node.new(1)
list.first_node.next = Node.new(2)
list.first_node.next.next = Node.new(3)
puts "Delete at 0"
puts list.delete_at(0)
你确定@first_node已经设置了吗?取消设置时实例变量将 return 为 nil。
class Test
attr_accessor :foo
def print_foo
puts "@foo=[#{@foo}]"
puts "foo=[#{foo}]"
puts @foo.nil?
end
end
t1 = Test.new
t1.foo # => nil
t1.print_foo # prints "@foo=[]" and "foo=[]" and returns true
这个:
first_node = first_node.next
创建一个名为 first_node
的局部变量。变量声明被提升到 Ruby 范围的顶部,因此您的方法等效于:
def delete_at(position)
deleted_node = nil # Declare deleted_node and first_node
first_node = nil # as local variables.
if position == 0
deleted_node = first_node
first_node = deleted_node.next
return deleted_node
else
# Some code here ...
这意味着您方法中的所有 first_node
引用都将是本地 first_node
变量,而不是 attr_accessor
为您创建的 getter 和设置方法。
要么不要使用与方法名称匹配的变量,要么通过为方法调用提供 self
接收器来明确说明您的意思:
def delete_at(position)
if position == 0
deleted_node = self.first_node
self.first_node = deleted_node.next
#...