この記事は何
この記事は、宣言的なプログラムを書くために使える、ちょっとしたテクニックを紹介していきたいと思います。
宣言的なプログラミングが何かは以下の記事が参考になると思います。
テクニック集
テクニック1: 変数は使い回さない
Rubyの場合、定数が少しピーキーな挙動になっているので、基本的に全ての変数は可変になってしまうと思います。
変数を使いまわしたり、値を変更するのはできるだけ避けることで、コードが追いやすくなり、冪等性の担保されたコードがかけるようになります。
a = 1
a += 1
a = 1
b = a + 1
テクニック2: 破壊的メソッドは用いない
破壊的メソッドは、自身の状態を変更させるメソッドです。これらのメソッドを用いると、テクニック1で述べた内容と同じく、コードが追いづらくなります。
値の変更はできるだけ非破壊的なメソッドと変数代入を用いるようにしましょう。
a = [1, 1]
a.uniq!
a = [1, 1]
b = a.uniq
テクニック3: each
の代わりにmap
やeach_with_object
、sum
などのArrayの組み込みメソッドを用いる
基本的にループ処理はeach
が使えれば実装が行えます。しかし、each
を用いると基本的に変数の使い回しが発生してしまいます。
Arrayクラスには組み込みのmap/reduce系のメソッドが多く用意されているので、できるだけそれらのメソッドを使うようにしましょう。
sum = 0
numbers.each |number|
sum += number
end
scores = []
data.each |datum|
score << datum[:score]
end
sum = numbers.sum
scores = data.map |datum|
datum[:score]
end
テクニック4: 値による分岐はHashとStrategyパターンを用いる
受け取った値によって返す値や処理を変えたい時は、case文やif文を用いると思います。
これらを用いる代わりに、HashとStrategyパターンを用いることで、より宣言的なコードにすることが可能です。
def return_value1(type)
case type
when :a then 1000
when :b then 2000
end
end
def return_value2(type)
case type
when :a then 1
when :b then 2
end
end
class A
def value1
1000
end
def value2
1
end
end
class B
def value1
2000
end
def value2
2
end
end
VALUE_CLASS_MAP = {
a: A,
b: B
}
def return_value1(type)
VALUE_CLASS_MAP[type].new.value1
end
def return_value2(type)
VALUE_CLASS_MAP[type].new.value2
end