忽略lambda参数检查
问题描述:
我想将展现lambda行为(参数检查)的proc转换为不具有lambda行为的参数。下面是一个很做作的例子,但它应该得到跨越点:忽略lambda参数检查
的目的是创造一个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
取代->
,它会工作。然而,保持lambda表达式,我会得到
ArgumentError: wrong number of arguments (1 for 0)
为BasicObject#instance_eval
产生自我拉姆达,但拉姆达预计没有参数。
我不想使用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
是否'instance_exec'工作,而不是 - 它允许你传递参数(或不在这种情况下)? – matt
我很困惑。为什么不直接用procs定义DSL? 'add first_series:proc {natural_numbers.take(10)}'同样优雅。 –
@matt,yep,'instance_exec'完成了这个诀窍。不知道我怎么没有想到这一点。尽管它没有回答这个问题,但它解决了原来的问题,所以补充说,作为答案,如果没有人知道如何去做,我会接受它。 – ndn