2016-05-01 9 views
0

RubyでProcsを理解しようとしていますが、これに対して私はいくつかのエクササイズを試みています。Ruby Procs - 構文エラーで終了する

まず私は、この行に

[1, 4, 5, 3].map(&:anything) 

を入力し、その結果として、私はエラーを得た:

NoMethodError: undefined method anything' for 1:Fixnum .

は、その後、私はこれを試してみてください:

[1, 4, 5, 3].map(&:to_s) 

そして新しい配列文字列に変換された数値が返されました:

=> ["1", "4", "5", "3"]`.

これらの2つの例では、[1, 4, 5, 3].map(&:anything)のようなものを呼び出すと、配列内の各要素に対してanythingメソッドが呼び出されると結論づけられます。 Fixnumはanythingメソッドを実装していないため、最初の例はエラーで終了し、2番目の例は成功しました。

Fixnumに+メソッドがある場合は、[1, 4, 5, 3].map(&:+2)と呼ぶことができます。しかし、これは構文エラーで終了します。

syntax error, unexpected tINTEGER, expecting ')' [1, 4, 5, 3].map(&:+2)

をFixumが+メソッドを持っている場合、この最後は私にこの構文エラーを与えているのはなぜ?私が間違っていることは何ですか?

答えて

2

&は、to_procメソッドを呼び出すためのショートカットです。 シンボル(:anything)があるため、to_procメソッドがシンボルに対して呼び出されます。これは、引数として渡されるオブジェクト上の対応する名前(anything)でメソッドを呼び出すprocを返します。

mapのような列挙子でこれを行う場合、実際にはコレクション内の各オブジェクトに対してメソッドを呼び出します。

このショートカットでは、メソッドに引数を渡すことはできません。

+は、引数として別の方法を取る数にメソッドを呼び出すためだけの構文糖である)しかし、あなたは、このようなユースケースのためにカリー化を使用することができます

add = -> (a, b) { a + b } 
add_two = add.curry.call(2) 

p [1,2,3,4].map(&add_two) # => [3, 4, 5, 6] 
1

&:method_nameは、{|x| x.anything}の代わりに使用できるショートカットです。これは、ブロックを受け取るどのメソッドでも使用できます。

# So this line... 
[1,2,3].map(&:anything) 

# ... is equivalent to this line 
[1,2,3].map {|x| x.anything } 

# Same can go here: 
[job1, job2, job2].each(&:process) 

引数を受け取らないメソッドに対してのみ使用できることに注意してください。引数2を送信しようとしていたため、構文エラーが発生しました。

関連する問題