Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are blocks passed as arguments?

Tags:

syntax

ruby

I can pass arguments to functions like this:

func 1, 2, 3

or I can use brackets like:

func(1, 2, 3)

Later on I learned about functions like list.each which I pass (not sure if this is what's really happening) a block to operate on each element:

list.each {|x| puts x}

I assumed this just passed the block as an argument to the each function, but this doesn't seem to be the case because:

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

does not work.

I realized this when shown:

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

Which doesn't make sense at all if the block is simply an argument.

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

like image 927
Matthew Sainsbury Avatar asked Dec 26 '22 03:12

Matthew Sainsbury


1 Answers

Blocks are indeed 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 could also write the exact same thing like this:

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 a special syntax which makes them more usable. But you can still access the procs and pass them around.

like image 109
Holger Just Avatar answered Dec 30 '22 09:12

Holger Just