Instance_eval with a block

Hello,

Can someone please explain why the following code doesn’t work?

P.S. If I move the methods out of class ‘TestEval’, things work as
expected. I’m guessing it has to do with Binding or some such trickery,
but I’m stumped.

Thanks,
-Brad

···

class TestEval
def install_attrs(attrs)
attrs.each { |k, v|
type.send(:attr_accessor, k)
send("#{k}=", v)
}
end

def output(params, block)
install_attrs(params)
instance_eval { block.call }
end
end # class TestEval

block = proc { @name }

test = TestEval.new

params = {
‘name’ => ‘Joe’,
}

puts test.output(params, block)

params[‘name’] = 'Marty’
puts test.output(params, block)


See embedded comments:

Brad Hilton wrote:

Hello,

Can someone please explain why the following code doesn’t work?

P.S. If I move the methods out of class ‘TestEval’, things work as
expected. I’m guessing it has to do with Binding or some such trickery,
but I’m stumped.

Thanks,
-Brad


class TestEval
def install_attrs(attrs)
attrs.each { |k, v|
type.send(:attr_accessor, k)
send("#{k}=", v)
}
end

def output(params, block)
install_attrs(params)
instance_eval { block.call }

   instance_eval &block  # Fixes it. This changes the "self"
                         # binding for block.

end
end # class TestEval

@name = “FOO” # This is what the @name below was getting bound
# to, and “block.call” preserved that binding.

···

block = proc { @name }

test = TestEval.new

params = {
‘name’ => ‘Joe’,
}

puts test.output(params, block)

params[‘name’] = 'Marty’
puts test.output(params, block)



Joel VanderWerf California PATH, UC Berkeley
mailto:vjoel@path.berkeley.edu Ph. (510) 231-9446
http://www.path.berkeley.edu FAX (510) 231-9512