我一直在寻找类似的问题,但无法找到解决此案的方法:
我有这堂课:
class BinarySearchTree
....
find_work_node = Proc.new do |value, node, method|
return if node.nil?
if value == node.value
node = self.send(method node)
elsif value < node.value
node.left = find_work_node.call(value, node.left, method)
elsif
node.right = find_work_node.call(value, node.right, method)
end
node
end
# Delete a specific value from the tree
def delete(value, node = @root, block = find_work_node)
block.call(value, node, :delete_node)
end
....
end
当我尝试调用delete
方法时,会出现此错误:
undefined local variable or method `find_work_node' for #<BinarySearchTree:0x00000001018708> (NameError)
如何在find_work_node
方法中将proc delete
设置为默认参数?
答案 0 :(得分:4)
delete方法是一个实例方法,因此默认值应该是可以从实例方法的范围访问的变量。使用类变量@@var
或实例变量@var
示例:
class A
@@class_var = Proc.new{|v| puts v}
def initialize
@instance_var = Proc.new{|v| puts v}
end
def m1 a=@@class_var
a.call "foo"
end
def m2 a=@instance_var
a.call "bar"
end
end
a = A.new
a.m1
# foo
a.m2
# bar
答案 1 :(得分:1)
问题在于范围。您将find_work_node
定义为类体中的局部变量,这样它的范围限定在类体中,只能在其中访问,但不能在您定义的任何方法中访问。
请注意,只是将其更改为实例变量@find_work_node
将不起作用,因为它仍然是类级别的实例变量,虽然您不会再出现此错误,但{{1}方法参数中的变量将为nil。您需要在类的@find_work_node
方法中初始化它:
initialize
答案 2 :(得分:1)
您可以通过在所有大写字母中定义find_work_node
类使其成为常量,然后在实例方法中可以访问它。请注意,在irb会话中,在实例方法中无法访问output_bar,但OUTPUT_FOO是:
2.3.0 :001 > output_bar = -> { puts "I am bar." }; def bar; output_bar.(); end; bar
NameError: undefined local variable or method `output_bar' for main:Object
from (irb):1:in `bar'
from (irb):1
from /Users/kbennett/.rvm/rubies/ruby-2.3.0/bin/irb:11:in `<main>'
2.3.0 :002 > OUTPUT_FOO = -> { puts "I am foo." }; def foo; OUTPUT_FOO.(); end; foo
I am foo.
=> nil
另请注意,尽管该示例使用lambdas,但变量包含的数据类型无关紧要。
定义返回Proc。
的方法也很有用