Reek - Long Parameter List Smell

Ruby の静的解析ツール一式をまとめて実行できる [RubyCritic](http://tbpgr.hatenablog.com/entry/2016/09/02/022606) を使って静的解析をしていたところ、
[Reek](http://tbpgr.hatenablog.com/entry/2016/08/25/230610) の Long Parameter List の警告がでてきて怒られました。

## <i class='fa fa-warning'></i> Long Parameter List Smell
Reekのドキュメントにおける Long Parameter List の臭いの説明は以下です。

>A Long Parameter List occurs when a method has a lot of parameters.

[Long Parameter List - docs - troessner/reek](https://github.com/troessner/reek/blob/master/docs/Long-Parameter-List.md)

## <i class='fa fa-check-circle'></i> 問題点
引数が多ければ多いほど、関数（メソッド）内部の構造は複雑になる。

## <i class='fa fa-list'></i> 原因
### <i class='fa fa-cube'></i> ケース1
呼び出し先のメソッド内で計算可能なパラメーターを引き渡している

#### <i class='fa fa-frown-o'></i> Before

```ruby
class Person
  attr_reader :first_name, :last_name, :age

  def initialize(first_name, last_name, age)
    @first_name, @last_name, @age = first_name, last_name, age
  end

  def display_name
    "#{first_name} #{last_name}"
  end

  def display_age
    "(#{age})"
  end

  def show_name_age
    name = display_name
    age = display_age
    puts display_name_age(name, age)
  end

  def display_name_age(name, age)
    "#{name} #{age}"
  end
end

tanaka = Person.new('kazuya', 'tanaka', 34)
tanaka.show_name_age # => kazuya tanaka (34)
```

#### <i class='fa fa-smile-o'></i> After

```ruby
class Person
  attr_reader :first_name, :last_name, :age

  def initialize(first_name, last_name, age)
    @first_name, @last_name, @age = first_name, last_name, age
  end

  def display_name
    "#{first_name} #{last_name}"
  end

  def display_age
    "(#{age})"
  end

  def show_name_age
    puts display_name_age
  end

  def display_name_age
    "#{display_name} #{display_age}"
  end
end

tanaka = Person.new('kazuya', 'tanaka', 34)
tanaka.show_name_age # => kazuya tanaka (34)
```

### <i class='fa fa-cube'></i> ケース2
オブジェクトを渡せばいいところを、バラバラに渡している

#### <i class='fa fa-frown-o'></i> Before

```ruby
class Person
  attr_reader :name, :age

  def initialize(name, age)
    @name,@age = name, age
  end
end

def show_name_age(name, age)
  puts "#{name} (#{age})"
end

tanaka = Person.new('tanaka', 34)
show_name_age(tanaka.name, tanaka.age) # => tanaka (34)
```

#### <i class='fa fa-smile-o'></i> After

個別のパラメータの代わりにオブジェクトを渡します

```ruby
class Person
  attr_reader :name, :age

  def initialize(name, age)
    @name,@age = name, age
  end
end

def show_name_age(person)
  puts "#{person.name} (#{person.age})"
end

tanaka = Person.new('tanaka', 34)
show_name_age(tanaka) # => tanaka (34)
```


### <i class='fa fa-cube'></i> ケース3
まとめたほうがいいパラメータをバラバラに扱っている

#### <i class='fa fa-frown-o'></i> Before

```ruby
def show_name_age(name, age)
  puts "#{name} (#{age})"
end

show_name_age("tanaka", 34) # => tanaka (34)
```

#### <i class='fa fa-smile-o'></i> After

```ruby
class Person
  attr_reader :name, :age

  def initialize(name, age)
    @name,@age = name, age
  end
end

def show_name_age(person)
  puts "#{person.name} (#{person.age})"
end

tanaka = Person.new('tanaka', 34)
show_name_age(tanaka) # => tanaka (34)
```

## <i class="fa fa-book" style="font-size:1em;"></i> 外部資料
* [Long Parameter List - Refactoring / Code Smells / Bloaters - sourcemaking.com](https://sourcemaking.com/refactoring/smells/long-parameter-list)
* [多すぎる引数 - Strategic Choice](http://d.hatena.ne.jp/asakichy/20121023/1350943892)