Question

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?

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top