14
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Rubyで宣言的なプログラムを書くためのテクニックTips

Last updated at Posted at 2022-07-05

この記事は何

この記事は、宣言的なプログラムを書くために使える、ちょっとしたテクニックを紹介していきたいと思います。

宣言的なプログラミングが何かは以下の記事が参考になると思います。

テクニック集

テクニック1: 変数は使い回さない

Rubyの場合、定数が少しピーキーな挙動になっているので、基本的に全ての変数は可変になってしまうと思います。
変数を使いまわしたり、値を変更するのはできるだけ避けることで、コードが追いやすくなり、冪等性の担保されたコードがかけるようになります。

bad
a = 1
a += 1
good
a = 1
b = a + 1

テクニック2: 破壊的メソッドは用いない

破壊的メソッドは、自身の状態を変更させるメソッドです。これらのメソッドを用いると、テクニック1で述べた内容と同じく、コードが追いづらくなります。

値の変更はできるだけ非破壊的なメソッドと変数代入を用いるようにしましょう。

bad
a = [1, 1]
a.uniq!
good
a = [1, 1]
b = a.uniq

テクニック3: eachの代わりにmapeach_with_objectsumなどのArrayの組み込みメソッドを用いる

基本的にループ処理はeachが使えれば実装が行えます。しかし、eachを用いると基本的に変数の使い回しが発生してしまいます。
Arrayクラスには組み込みのmap/reduce系のメソッドが多く用意されているので、できるだけそれらのメソッドを使うようにしましょう。

bad

sum = 0
numbers.each |number|
  sum += number
end

scores = []
data.each |datum|
  score <<  datum[:score]
end

good
sum = numbers.sum

scores = data.map |datum|
  datum[:score] 
end

テクニック4: 値による分岐はHashとStrategyパターンを用いる

受け取った値によって返す値や処理を変えたい時は、case文やif文を用いると思います。
これらを用いる代わりに、HashとStrategyパターンを用いることで、より宣言的なコードにすることが可能です。 

bad
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

good
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
14
6
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?