brad brad - 15 days ago 5
Ruby Question

Ruby block, procs and instance_eval

I recently tried to do something akin to this:

a = "some string"
b = Proc.new{ upcase }
a.instance_eval b


Which gives the error:


TypeError: can't convert Proc into String


but this works:

def b(&block)
"some string".instance_eval &block
end

b{ upcase }


A further look with this method:

def b(&block)
"some string".instance_eval block
end


Yields the same
Proc to String
error.

So... my understanding of blocks is that they are just procs. But there's obviously something special about having this
&
ampersand...

Can someone explain this to me? Is it possible to convert a normal proc to be whatever it is that is special about this
&block
object?

edit



Just figured out my second question, prepend an
&
to the proc... that was easy, but WHAT is this really doing?

Answer

All you have to do for your first example to work is this:

>> a.instance_eval &b #=> "SOME STRING"

The reason is that instance_eval needs either a string or a block and the ampersand provides the latter.

For understanding the differences between blocks and procs, maybe the following blog post helps:

Understanding Ruby Blocks, Procs and Lambdas