Ruby でもメソッドをブロックの代わりに渡したい
C# でコードを書いていると以下のようなコードを R# がよく薦めてきます。(久しぶりに C# 書いたけど、これで合ってるかな。。)
// 前提 var list = new[] {1, 2, 3, 4}; private int Method(int) { // なんか処理して int を返す } // before list.Select(x => Method(x)); // after list.Select(Method);
ここで使ってる Select
は IEnumerable
のメソッドですが、引数は System.Func<TSource, TResult>
の delegate となっています。
after のようにできるのは、その delegate とシグネチャが一致しているメソッドであれば同じように扱えるという仕様を利用しています。
Ruby の Symbol#to_proc
Ruby は Symbol#to_proc
があるので配列の各要素のメソッドを以下のように呼び出せます。
list = [1, 2, 3, 4] list.map(&:to_s) # 単に数値を文字に変えるだけですが、int の to_s メソッドを呼び出している。 => ["1", "2", "3", "4"]
これは Ruby を使い出してすごい便利と思った機能だったのですが、一方で C# のようにメソッドを渡せないのかなぁと思ってました。
def double(num) num * 2 end list.map {|num| double(num) } # これを list.map(double) ぐらいで書きたい
Method は to_proc できるらしい
Object#method
で Method のオブジェクトにできるので
double_method = method(:double) => #<Method: Object#double> double_method.to_proc => #<Proc:0x007fb79abcf0d0 (lambda)> list.map(&double_method) # or list.map(&method(:double))
ちょっと冗長に見えるけど、少しだけ C# の書き方に近い感じになって嬉しい。でも method を呼び出すのは、ちょっと微妙っちゃ微妙ですよね。。