简体   繁体   中英

Ruby lambda's proc's and 'instance_eval'

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM