忽略 lambda 参数检查
Ignore lambda argument checking
我想将表现出 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)
as BasicObject#instance_eval
将 self 交给 lambda,但 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
我想将表现出 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)
as BasicObject#instance_eval
将 self 交给 lambda,但 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