Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby - Possible to pass a block as a param as an actual block to another function?

This is what I'm trying to do:

def call_block(in_class = "String", &block)
    instance = eval("#{in_class}.new")
    puts "instance class: #{instance.class}"
    instance.instance_eval{ block.call }
end


# --- TEST EXAMPLE ---
# This outputs "class: String" every time
"sdlkfj".instance_eval {  puts "class: #{self.class}" }

# This will only output "class: Object" every time
# I'm trying to get this to output "class: String" though
call_block("String") { puts "class: #{self.class}" }

On the line where it says "instance.instance_eval{ block.call }", I'm trying to find another way to make the new instance variable run instance eval on the block. The only way I can think of to get it to do that is to pass instance_eval the original block, not as a variable or anything, but as a real block like in the test example.

Any tips?

like image 365
Markus O'Reilly Avatar asked Mar 18 '10 08:03

Markus O'Reilly


1 Answers

Yes. You can pass the block to the other method by prepending the block variable with an ampersand like so:

def foo &blk
  # now, blk is a variable bound to a block object
  bar &blk
end

The reason your are getting "class: Object" is that Ruby uses lexical scoping. This means that self in puts "class: #{self.class}" refers to main, the default context.

like image 144
allyourcode Avatar answered Nov 10 '22 15:11

allyourcode