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

时间:2022-09-01 21:20:58

I'm trying to learn about blocks and procs and I feel like this should be doable, but so far I haven't been successful.

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

What I'd like:

我想:

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 })

Or something similar.

或类似的东西。

The closest I found was http://mudge.name/2011/01/26/passing-blocks-in-ruby-without-block.html which seemed to require creating a passing method to send the blocks around:

我找到的最接近的是http://mudge.name/2011/01/26/passing-block- in- in- out-block.html,它似乎需要创建一个通过的方法来发送block:

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

If I use the same passing method set up in my code I can get it to work, but it seems like unnecessary code. I tried calling Monkey.tell("ape", { "ook!" }) directly, but got syntax error, unexpected '}', expecting tASSOC

如果我使用在代码中设置的相同传递方法,我可以让它工作,但这似乎是不必要的代码。我试着打电话给猴子。告诉(“猿”,{”的书!”})直接,但得到语法错误,意外的'},期望tASSOC

Is it possible to send a variable and a block (or proc, I'm not picky) to a function in one call? Also, if you have time, what's going on above? Why doesn't that work?

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

2 个解决方案

#1


5  

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

你似乎把积木和procs搞混了。块不是ruby对象。你不能像那样传过去

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:

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

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

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

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

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

有几种方法可以创建proc对象,而接近块文本的文字是lambda: ->{…},但是它与块语法{…}不同。使用这个,你可以做到

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

but not

但不是

foo(args, {...})

unless {...} is a hash.

除非{…}是一个散列。

#2


2  

Based on sawa's answer I was able to recreate the function in the question (Monkey.tell) using a block and proc. Here they are in case anyone else finds them useful!

基于sawa的回答,我可以用block和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 + "!" }

#1


5  

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

你似乎把积木和procs搞混了。块不是ruby对象。你不能像那样传过去

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:

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

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

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

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

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

有几种方法可以创建proc对象,而接近块文本的文字是lambda: ->{…},但是它与块语法{…}不同。使用这个,你可以做到

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

but not

但不是

foo(args, {...})

unless {...} is a hash.

除非{…}是一个散列。

#2


2  

Based on sawa's answer I was able to recreate the function in the question (Monkey.tell) using a block and proc. Here they are in case anyone else finds them useful!

基于sawa的回答,我可以用block和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 + "!" }