When I pass a lambda to instance_eval as the block, it seems to pass an extra argument:
lamb = -> { puts 'hi' }
proc = Proc.new { puts 'hi' }
instance_eval(&lamb)
# >> ArgumentError: wrong number of arguments (given 1, expected 0)
#    from (irb):5:in `block in irb_binding'
#    from (irb):7:in `instance_eval'
instance_eval(&proc)
# => hi
instance_exec(&lamb)
# => hi
Why is this the case? Note that this question is NOT about why lambda throws an error. That is well understood. The question is about WHY instance_eval sends self of the receiver as a parameter. It is not needed, and confusing. And AFAIK not documented.
This helps, but doesn't explain WHY ruby would do it this way. The whole point of instance_eval is to set self to the receiver; why confuse things by also passing self to the proc?