クラン・コラ・ブログ(アイルランド音楽の森):ソウル・フラワー・ユニオン、NHKテレビに登場
ラミ犬さんへ。
TVを持っていないのが悔やまれます。
関数を返す関数っていつ使うの
Route 477(2008-01-10)
釈迦に説法のような気もしますが、力尽きていらっしゃるようなので。
まず普通にstring_ltを実装してみます。で、これの文字列の比較部分だけを変更して、その他の部分を共有する方法について考えてみます。
def string_lt(*strs) (1 ... strs.size).each do |i| return false unless strs[i - 1] < strs[i] end true end p string_lt('a', 'b', 'c') # => true
Rubyではブロックを使ってそのメソッドに特化の部分をメソッド外部から与えることができます。個人的にはこれが一番Rubyらしいアプローチだと思います。
def string_comparer(*strs, &test) (1 ... strs.size).each do |i| return false unless test[strs[i - 1], strs[i]] end true end def string_lt(*strs) string_comparer(*strs) {|s1, s2| s1 < s2 } end p string_lt('a', 'b', 'c') # => true
関数を生成する関数じゃないといやだ!という人は、lambdaを使って似たようなことができます。
def make_string_comparer(&test) lambda do |*strs| (1 ... strs.size).each do |i| return false unless test[strs[i - 1], strs[i]] end true end end string_lt = make_string_comparer {|s1, s2| s1 < s2 } p string_lt['a', 'b', 'c'] # => true
関数型言語を使うようになってから、こんな感じの高階関数が好きになりました。ぜひ関数型言語を学ぼう! 普段あんまり使わなくても得られるものはあります。