【问题标题】:when calling instance_eval(&lambda) to pass current context got error 'wrong number of arguments'调用 instance_eval(&lambda) 传递当前上下文时出现错误“参数数量错误”
【发布时间】:2013-05-14 18:57:44
【问题描述】:

要明确 - 这段代码运行完美 - code with proc

但如果我将 Proc.new 更改为 lambda,则会出现错误

ArgumentError: wrong number of arguments (1 for 0)

可能是因为 instance_eval 想将 self 作为参数传递,而 lambda 将其视为方法,不接受未知参数?

有两个例子——第一个是有效的:

class Rule
  def get_rule
    Proc.new { puts name }
  end
end

class Person
  attr_accessor :name

  def init_rule 
    @name = "ruby"
    instance_eval(&Rule.new.get_rule)
  end
end

第二个不是:

class Rule
  def get_rule
    lambda { puts name }
  end
end

class Person
   attr_accessor :name

   def init_rule 
     @name = "ruby"
     instance_eval(&Rule.new.get_rule)
   end
end

谢谢

【问题讨论】:

    标签: ruby lambda metaprogramming


    【解决方案1】:

    您的假设实际上是正确的。 Self 被传递给 Proc 和 lambda,因为它正在被 instance_eval'ed。 Procs 和 lambdas 之间的一个主要区别是 lambdas 检查传递给它们的块的数量。

    所以:

     class Rule
       def get_rule
         lambda { |s| puts s.inspect; puts name; }
       end
     end
    
    
    class Person
       attr_accessor :name
    
       def init_rule 
         @name = "ruby"
         instance_eval(&Rule.new.get_rule)
       end
    end
    
     p = Person.new
     p.init_rule
    
     #<Person:0x007fd1099f53d0 @name="ruby">
     ruby 
    

    在这里,我告诉 lambda 期待一个具有 arity 1 的块,正如您在参数检查中看到的那样,参数确实是 Person 类的 self 实例。

    【讨论】:

    • 不是p.get_rule而不是p.init_rule吗?
    • 不,不是。最初发布的代码在调用Person#init_rule 时调用instance_eval,这是我调用并得到该输入的内容,也是问题的主题。将我的答案编辑回原来的样子。
    猜你喜欢
    • 2019-10-26
    • 1970-01-01
    • 2020-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-05
    • 1970-01-01
    • 2017-11-15
    相关资源
    最近更新 更多