2016-04-14 17 views
4

ラムダ動作(引数チェック)を示すprocを、そうでないものに変換したい。以下は、非常に不自然な例ですが、全体には、ポイントを取得する必要があります:natural_numbersfibonacci_numbersが引数として渡されていないことをラムダ引数チェックを無視する

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

注:目的は次のようになりますDSLを作成することです

DSLではaddの実装は、このようなものになります。私はDSLでproc->を置き換える場合は、今すぐ

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 

を、それが動作します。しかし、ラムダを保ち、私はBasicObject#instance_evalとして

ArgumentError: wrong number of arguments (1 for 0)

になるだろうラムダに自己をもたらしますが、ラムダは引数を期待していません。


明白な理由からFiddleを使用したくありません。

+2

代わりに 'instance_exec'が働いていますか?引数を渡すことができますか? – matt

+0

私は混乱しています。なぜあなたはprocsであなたのDSLを定義するだけではありませんか? 'add first_series:proc {natural_numbers.take(10)}'も同様にエレガントです。 –

+0

@matt、うん、 'instance_exec'がトリックをしました。どのように私はそれを考えていない考えていない。それは質問に答えることはできませんが、それは元の問題を解決するので、答えとしてそれを追加し、誰もそれを行う方法を知らないなら、私はそれを受け入れます。 – ndn

答えて

1

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 
関連する問題