Je souhaite convertir un proc qui présente un comportement lambda (contrôle d'argument) en un qui ne l'est pas. Ce qui suit est un exemple très artificiel, mais il devrait obtenir le point sur:Ignorer la vérification des arguments lambda
L'objectif est de créer une connexion DSL qui ressemble à ceci:
NumberSeries.perform do
add first_series: -> { natural_numbers.take(10) },
second_series: -> { fibonacci_numbers.take(10) }
end
Notez que natural_numbers
et fibonacci_numbers
ne sont pas passés comme arguments dans la DSL. La mise en œuvre de add
ressemble à ceci:
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
Maintenant, si je remplace ->
avec proc
dans le DSL, cela fonctionnera. Cependant, en gardant les lambdas, je recevrais
ArgumentError: wrong number of arguments (1 for 0)
comme BasicObject#instance_eval
cède auto au lambda, mais le lambda attend aucun argument.
Je ne veux pas utiliser Fiddle
pour des raisons évidentes.
Est-ce que le travail 'instance_exec' place - qui vous permet de passer des arguments (ou non dans ce cas)? – matt
Je suis confus. Pourquoi ne pas simplement définir votre DSL avec procs? 'add first_series: proc {natural_numbers.take (10)}' est tout aussi élégant. –
@matt, oui, 'instance_exec' a fait l'affaire. Aucune idée de comment je n'ai pas pensé à ça. Même s'il ne répond pas à la question, il résout le problème original, donc ajoutez-le comme réponse et si personne ne sait comment le faire, je l'accepterai. – ndn