このページは原文を AI が翻訳したものです。

Rubyでは、関数にブロック引数を渡すとき、先頭に&を付けます。例を見てみましょう。

Symbol

to_procを実装するオブジェクトの使用例として、Symbolがよく挙げられます。

["a", "b", "c"].map { |s| s.upcase } # => ["A", "B", "C"]
["a", "b", "c"].map(&:upcase)        # => ["A", "B", "C"]

この2行のコードは同じ動作をします。

これが機能する理由は、Symbolto_procメソッドを実装しているからです。そのメソッドは、*このprocの引数を受け取り、そのシンボルに対応する名前のメソッドを呼び出す*だけです。

この構文は、mapsort_byのような単純なブロックを取るメソッドのショートカットとしてよく見かけます。

もっとシンプルに

通常のdoブロックを関数に渡すこともできますが、もっとシンプルにできる場合もあります。例を見てみましょう。

numbers = 1..5

operator = gets

number = Integer(gets)

if operator.start_with?("t")
  puts numbers.collect { |n| n * number }.join(", ")
else
  puts numbers.collect { |n| n + number }.join(", ")
end

このコードは動きますが、見た目が良くありません。以下のようにリファクタリングできます。

numbers = 1..5

operator = gets

number = Integer(gets)

if operator.start_with?("t")
  calc = ->(n) { n * number }
else
  calc = ->(n) { n + number }
end

puts numbers.map(&calc).join(", ")

このバージョンでは、正しいブロックをcalcという変数に代入し、そのcalcをmapメソッドに&を付けて渡しています。

しかし、このコードを書くもっと短い方法があります。Rubyのオブジェクトには`method`というメソッドがあり、シンボルを受け取って、同じ名前のオブジェクトのメソッドを返します。

operators = get

number = Integer(gets)

method = number.method(operator.start_with?("t") ? :* : :+)

puts (1..5).map(&method).join(", ")

この場合、methodを使って入力に基づいて:+または:*という名前のメソッドを取得し、アンパサンドのto_procの力を使って、そのメソッドを呼び出すprocを作成しています。

Epona
執筆Epona

There's nothing wrong with having a little fun

x.com/simura_epona

コメントを読み込み中…