Ruby: フラグ引数は「コードの臭い」(翻訳)

概要

原著者の許諾を得て翻訳・公開いたします。

Ruby: フラグ引数は「コードの臭い」(翻訳)

フラグ引数は、メソッドの振る舞いを変更するbooleanです。フラグ引数があるということは、このコードが外的要素に応じていくつものシナリオを演じていることを示しています。高度なレベルのコード片が、低レベルメソッドひとつで右往左往しているのです。

次の簡単なコード例で考えてみましょう。

def create_task(description, priority, preview: true, email: true)
  task = Task.new
  task.status = "open"
  task.description = description
  task.priority = priority

  unless preview
    task.save!
    index_in_search_engine(task)
    send_task_created_email_notification(task) if email
  end

  task
end

previewemailがこのメソッドのフラグ引数です。このメソッドは、必要に応じてさまざまな形で呼び出されることになります。このフラグ引数は、メソッド呼び出しに何らかの混乱をもたらします。

# タスクを1件作成してメール通知を1件送付
create_task("Read the newspaper", "low", preview: false)

# タスクを1件作成するがメール通知は送信しない
create_task("Read the newspaper", "low", preview: false, email: false)

# プレビュー用のタスクを作成する
create_task("Read the newspaper", "low", preview: true)

さまざまなシナリオで使われるロジックがcreate_taskに相乗りしているため、メソッドが少々読みづらくなっています。あるシナリオを理解するためには他のシナリオを除外して考えなければならなくなるので、余分な集中力を求められます。フラグ引数の数が増えれば、あっという間に複雑化して手に負えなくなるでしょう。

普通のメソッドはこのようにして生まれたりしません。ロジックで小さな変更を求められたときに、フラグ引数で済ませてしまうと、すぐにでもそうなります。

コードの臭いを消すには、メソッドをもっと小さい複数のメソッドに分割します。

def create_task_and_send_notification(description, priority)
  create_task(description, priority).tap do |task|
    send_task_created_email_notification(task)
  end
end

def create_task(description, priority)
  build_task(description, priority).tap do |task|
    task.save!
    index_in_search_engine(task)
  end
end

def build_task(description, priority)
  Task.new.tap do |task|
    task.status = "open"
    task.description = description
    task.priority = priority
  end
end

これなら、それぞれのメソッドは異なるシナリオで実行されますし、ほぼ何の苦労もなく読めます。フラグ引数でメソッドの振る舞いを変えるのではなく、シナリオに応じて呼ぶメソッドを変えれば済みます。

# タスクを1件作成してメール通知を1件送付
create_task_and_send_notification("Read the newspaper", "low")

# タスクを1件作成するがメール通知は送信しない
create_task("Read the newspaper", "low")

# プレビュー用のタスクを作成する
build_task("Read the newspaper", "low")

関連記事

Ruby:「プリマドンナメソッド」の臭いの警告を私が受け入れるまで(翻訳)

Ruby/Railsのプロ開発者としての5年間を振り返る(翻訳)

デザインも頼めるシステム開発会社をお探しならBPS株式会社までどうぞ 開発エンジニア積極採用中です! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

hachi8833

Twitter: @hachi8833、GitHub: @hachi8833 コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。 これまでにRuby on Rails チュートリアル第2版の半分ほど、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れてそれぞれ一部を翻訳。 かと思うと、正規表現の粋を尽くした日本語エラーチェックサービス enno.jpを運営。 実は最近Go言語が好き。 仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。

hachi8833の書いた記事

週刊Railsウォッチ

インフラ

ActiveSupport探訪シリーズ