ruby – 忽略lambda参数检查

我想将展示lambda行为(参数检查)的proc转换为不具备lambda行为的proc.以下是一个非常人为的例子,但它应该指出:

目的是创建一个看起来像这样的DSL:

NumberSeries.perform do
  add first_series:  -> { natural_numbers.take(10) },
      second_series: -> { fibonacci_numbers.take(10) }
end

请注意,natural_numbers和fibonacci_numbers不会作为DSL中的参数传递. add的实现看起来像这样:

NaturalNumbersFibonacciNumbers = Struct.new(:natural_numbers, :fibonacci_numbers)
FAMOUS_NUMBER_SERIES = NaturalNumbersFibonacciNumbers.
                         new(natural_numbers, fibonacci_numbers)

def add(first_series:, second_series:)
  first_numbers  = FAMOUS_NUMBER_SERIES.instance_eval(&first_series)
  second_numbers = FAMOUS_NUMBER_SERIES.instance_eval(&second_series)
  first_numbers.zip(second_numbers).map { |x, y| x + y }
end

现在,如果我替换 – >在DSL中使用proc,它会起作用.但是,保持lambdas,我会得到

ArgumentError: wrong number of arguments (1 for 0)

因为BasicObject#instance_eval向lambda产生self,但是lambda没有参数.

出于显而易见的原因,我不想使用Fiddle.

最佳答案
instance_exec是instance_eval的替代方法,它允许您控制传递给块的参数,而不像instance_eval那样传递接收器.您可以将它用作问题的解决方法,因为它允许您传递零参数:

irb:108:0>  Object.new.instance_eval &-> { puts "Hello" }
ArgumentError: wrong number of arguments (given 1, expected 0)
    from (irb):108:in `block in irb_binding'
    from (irb):108:in `instance_eval'
    from (irb):108
    from /Users/matt/.rubies/ruby-2.3.0/bin/irb:11:in `<main>'
irb:109:0>  Object.new.instance_exec &-> { puts "Hello" }
Hello
=> nil
点赞