如何将块/ proc和变量直接传递给函数?

时间:2013-06-15 07:57:09

标签: ruby variables block proc

我正在尝试学习块和触发器,我觉得这应该是可行的,但到目前为止我还没有成功。

我想要的是什么:

def main_action(generic_variable, block)
 generic_variable += 1 # I do more interesting stuff than this in my version
 yield(generic_variable)
end

main_action(3, {|num| num + 5 })

或类似的东西。

我发现最接近的是http://mudge.name/2011/01/26/passing-blocks-in-ruby-without-block.html,这似乎需要创建一个传递方法来发送块:

class Monkey

  # Monkey.tell_ape { "ook!" }
  # ape: ook!
  #  => nil
  def self.tell_ape(&block)
    tell("ape", &block)
  end

  def self.tell(name, &block)
    puts "#{name}: #{block.call}"
  end
end

如果我使用在我的代码中设置的相同传递方法,我可以使它工作,但它似乎是不必要的代码。我尝试直接致电Monkey.tell("ape", { "ook!" }),但获得syntax error, unexpected '}', expecting tASSOC

是否可以在一次调用中向一个函数发送一个变量和一个块(或proc,我不挑剔)?另外,如果你有时间,上面发生了什么?为什么不起作用?

2 个答案:

答案 0 :(得分:5)

你似乎混淆了块和触发器。块不是ruby对象。你不能像

那样传递它
foo(args, block)

传递它的唯一方法是foo(args){...}foo(args) do ... end。但是,在方法定义中,您可以接收一个块,将其转换为proc,并将其作为其参数之一接受,如下所示:

def foo(args, &block)
  ...
end

另一方面,您可以将proc对象作为参数传递,如

foo(args, proc)

有几种方法可以创建proc对象,并且靠近块文字的文字是lambda:->{...},但它与块语法{...}不同。使用它,你可以做到

foo(args, ->{...})

但不是

foo(args, {...})

除非{...}是哈希值。

答案 1 :(得分:2)

基于sawa's answer我能够使用块和proc在问题(Monkey.tell)中重新创建函数。在这里,以防其他人发现它们有用!

def tell_proc(name, proc)
  puts "#{name}: #{proc.call('ook')}"
end
tell_proc('ape', ->(sound) { sound + "!" })

def tell_block(name, &block)
  puts "#{name}: #{block.call('ook')}"
end
tell_block('ape') {|sound| sound + "!" }