2

我正在尝试了解块和过程,我觉得这应该是可行的,但到目前为止我还没有成功。

我想要什么:

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,我不挑剔)发送到函数?另外,如果你有时间,上面发生了什么?为什么那行不通?

4

2 回答 2

5

You seem to be confusing blocks and procs. A block is not a ruby object. You cannot pass it like

foo(args, block)

The only way to pass it is foo(args){...} or foo(args) do ... end. However, in method definition, you can receive a block, convert it into a proc, and accept it as one of its arguments like this:

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

On the other hand, You can pass a proc object as an argument like

foo(args, proc)

There are several ways to create a proc object, and a literal that is close to the block literal is the lambda: ->{...}, but it is different from the block syntax {...}. Using this, you can do

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

but not

foo(args, {...})

unless {...} is a hash.

于 2013-06-15T08:40:32.463 回答
2

根据sawa的回答,我能够Monkey.tell使用块和proc重新创建问题()中的函数。它们在这里,以防其他人发现它们有用!

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 + "!" }
于 2013-06-15T09:17:44.577 回答