Are blocks passed as arguments?

I can pass arguments to such functions:

func 1, 2, 3 

or I can use brackets like:

 func(1, 2, 3) 

Later, I learned about functions such as list.each , which I pass (not sure if this is true) to the unit for working with each element:

 list.each {|x| puts x} 

I assumed that this simply passed the block as an argument to each , but this does not seem to be because:

 list.each( {|x| puts x} ) 

does not work.

I realized this when shown:

 5.upto(9) {|x| puts x} 

Which makes no sense at all if the block is just an argument.

What's going on here? Any resource you can point me to help explain this, and perhaps other structural things that are not immediately obvious?

+4
source share
2 answers

The blocks are really a bit special, but can also be used as arguments. Consider this function:

 def greet yield "Hello" end greet{ |greeting| puts "#{greeting} to you" } 

You can also write the same:

 def greet(&block) block.call("Hello") end greet{ |greeting| puts "#{greeting} to you" } # which is equivalent to: my_proc = proc{ |greeting| puts "#{greeting}, nice to see you." } greet(&my_proc) 

In the end, blocks are a special form of procs with special syntax that makes them more useful. But you can still access the procs and transfer them.

+6
source

methods can take exactly one block, sort of like a special argument.

 def foo yield 123 end foo { |x| puts x } #=> 123 

Notice how this method accepts null arguments, but still accepts a block. This is because this block suspension syntax using a method is a special case. Any block passed to a method can be started with the yield keyword. And you can even ask if the block with the block_given? keyword block_given? .

If you want to write it in a local variable, you can do this using special syntax.

 def foo(a, &block) block.call a end foo(123) { |x| puts x } #=> 123 

In this case, you commit the block argument explicitly, with the & prefix in the argument list. Now you have a variable for this block, which you can send a call message to execute. Just be aware that this should appear at the end of the argument list.

Also pay attention to parens. foo(123) { |x| puts x } foo(123) { |x| puts x } . The argument list is stopped, the parsers are closed, and the attached block appears after. Again, because this is a special case in the syntax.

+4
source

Source: https://habr.com/ru/post/1483420/


All Articles