Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass a block to another in Ruby?

Tags:

ruby

block

Assuming I have the following proc:

a = Proc.new do
    puts "start"
    yield
    puts "end"
end

Also assuming I pass a to another method which subsequently calls instance_eval on another class with that block, how can I now pass a block onto the end of that method which gets yielded in a.

For example:

def do_something(a,&b)
    AnotherClass.instance_eval(&a) # how can I pass b to a here?
end

a = Proc.new do
    puts "start"
    yield
    puts "end"
end

do_something(a) do
    puts "this block is b!"
end

Output should of course should be:

start
this block is b!
end

How can I pass the secondary block to a in the instance_eval?

I need something like this for the basis of a Ruby templating system I'm working on.

like image 657
Alex Coplan Avatar asked Jul 03 '12 15:07

Alex Coplan


People also ask

Can you pass functions in Ruby?

The symbol terminology is Ruby's built-in way to allow you to reference a function without calling it. By placing the symbol in the argument for receives_function, we are able to pass all the info along and actually get into the receives_function code block before executing anything.

What is &Block in Ruby?

The &block is a way of sending a piece of Ruby code in to a method and then evaluating that code in the scope of that method. In your example code above it means a partial named cart will be rendered in a div.

What are procs in Ruby?

A Proc object is an encapsulation of a block of code, which can be stored in a local variable, passed to a method or another Proc, and can be called. Proc is an essential concept in Ruby and a core of its functional programming features.

What is * args in Ruby?

In the code you posted, *args simply indicates that the method accepts a variable number of arguments in an array called args . It could have been called anything you want (following the Ruby naming rules, of course).


1 Answers

You can't use yield in a. Rather, you have to pass a Proc object. This would be the new code:

def do_something(a,&b)
    AnotherClass.instance_exec(b, &a)
end

a = Proc.new do |b|
    puts "start"
    b.call
    puts "end"
end

do_something(a) do
    puts "this block is b!"
end

yield is only for methods. In this new code, I used instance_exec (new in Ruby 1.9) which allows you to pass parameters to the block. Because of that, we can pass the Proc object b as a parameter to a, which can call it with Proc#call().

like image 185
Linuxios Avatar answered Oct 15 '22 17:10

Linuxios