Ich möchte ein Proc, das Lambda-Verhalten zeigt (Argumentüberprüfung), in eines konvertieren, das nicht funktioniert. Im Folgenden ist ein sehr konstruiertes Beispiel, aber es sollte den Punkt zu vermitteln:Ignoriere Lambda-Argumentprüfung
Das Ziel ist die Schaffung eines DSL, die etwa wie folgt aussieht:
NumberSeries.perform do
add first_series: -> { natural_numbers.take(10) },
second_series: -> { fibonacci_numbers.take(10) }
end
Beachten Sie, dass natural_numbers
und fibonacci_numbers
nicht als Argumente übergeben im DSL. Die Implementierung von add
etwa wie folgt aussieht:
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
Nun, wenn ich ->
mit proc
im DSL ersetzen, wird es funktionieren. Um jedoch die Lambda-Ausdrücke zu halten, würde ich
ArgumentError: wrong number of arguments (1 for 0)
bekommen als BasicObject#instance_eval
selbst auf das Lambda liefert, aber das Lambda erwartet keine Argumente.
Ich will nicht Fiddle
aus offensichtlichen Gründen verwenden.
Does 'instance_exec' Arbeit statt - die Sie Argumente zu übergeben können (oder in diesem Fall nicht)? – matt
Ich bin verwirrt. Warum definierst du nicht einfach dein DSL mit Procs? 'add first_series: proc {natural_numbers.take (10)}' ist genauso elegant. –
@matt, yep, 'instance_exec' hat den Trick gemacht. Keine Ahnung, wie ich daran nicht gedacht habe. Auch wenn es die Frage nicht beantwortet, löst es das ursprüngliche Problem, also füge das als Antwort hinzu und wenn keiner weiß, wie es geht, werde ich es akzeptieren. – ndn