F# の例があります。
let a n = Convert.ToString(n:int32)
そして、私は言うことができます:
3 |> a
に評価され"3"
ます。Rubyにも同様の構造がありますか?
これは F# (および他の FP 言語) のメソッド連鎖であり、関数合成でも、Ruby のメソッド連鎖でもありませんa.b.c.d
。
これを Ruby で実装するのは非常に簡単です。F# リファレンス ドキュメントから直接引用:
let function1 x = x + 1
let function2 x = x * 2
let result = 100 |> function1 |> function2
//> val result : int = 202
これは Ruby で次のように記述できます。
function1 = -> x { x + 1 }
function2 = -> x { x * 2 }
result = 100.pipe(function1).pipe(function2)
# => 202
の次の実装ではObject#pipe
:
class Object
def pipe(callable)
callable.(self)
end
end
またはあなたの例で:
a = -> n { String(n) }
3.pipe(a)
# => '3'
と
let f x y = x * y
3 |> f(2)
// > 6
になる
f = -> (x, y) { x * y }
3.pipe(f.curry.(2))
# => 6
Ruby は、この F#/Ocaml/Haskel 表記をサポートしていません。私はあなたがそれについて何かできると信じていますが。しかし、要点は、そうすべきではないということです。
機能的なスタイルで実装したい場合 (これは素晴らしいことです)、Enumerable
ruby が提供する機能を使用できます - inject
、map
、select
など。
これにより、ハッキングのないクリーンで読みやすい Ruby コードが得られます。
PS:質問に+1。ルビーを始めた頃、私も自問自答しました。
そのような表記はありませんが、特定のメソッドObject
に渡すメソッドを追加できますself
。何かのようなもの:
class Object
def pass_to(m)
m.call(self)
end
end
これにより、次のような呼び出しが可能になります。
def convert_to_string(n)
n.to_s
end
def reverse_string(s)
s.reverse
end
123
.pass_to(method(:convert_to_string))
.pass_to(method(:reverse_string))
#=> "321"
またはラムダを使用して:
convert_to_string = -> n { n.to_s }
reverse_string = -> s { s.reverse }
123
.pass_to(convert_to_string)
.pass_to(reverse_string)
#=> "321"
これは、 にto_s
メッセージを送信して123
( を返し"123"
)、次に にreverse
メッセージを送信することと同じ"123"
です。
123
.to_s
.reverse
#=> "321"