将proc设置为默认方法参数

时间:2016-04-27 01:52:16

标签: ruby

我一直在寻找类似的问题,但无法找到解决此案的方法:

我有这堂课:

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设置为默认参数?

3 个答案:

答案 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。

的方法也很有用