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?
From the docs
For procs created using lambda or ->() an error is generated if the wrong number of parameters are passed to a Proc with multiple parameters. For procs created using Proc.new or Kernel.proc, extra parameters are silently discarded.
In your case both lamb
and proc
called with one parameter
From the docs of instance_eval
When instance_eval is given a block, obj is also passed in as the block's only argument
instance_eval
is method of BasicObject
class and can be called within instance. So given block will have access for private methods for example.
class Test
def call
secret_number + 100
end
private
def secret_number
42
end
end
test = Test.new
show_secret = -> (obj) { puts secret_number }
test.instance_eval(&show_secret) # print 42
Without instance self
of current context will be passed as an argument. I think instance_eval
was designed more for calling it within objects.
From the docs of instance_eval
In order to set the context, the variable self is set to obj while the code is executing, giving the code access to obj's instance variables and private methods.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.