9

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.

1

2 Answers 2

6

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().

Sign up to request clarification or add additional context in comments.

Comments

0
a=Proc.new do |b|
    puts "start"
    b.call
    puts "end"
end
def do_something(a,&b)
  AnotherClass.instance_eval { a.call(b) }
end

1 Comment

That wont work. instance_eval doesn't capture variables in the same way as normal blocks do.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.