RubyでBooleanSymbolエラーが出た場合の解消方法

#概要
RuboCopでBooleanSymbolエラーが出た場合の解消方法を3つ記載しています。
・（推奨）シンボルをBoolean以外の名前にする
・（非推奨）シンボルではなく文字列にする
・（応急処置）RuboCop警告を無視する


#Rubocopでのシンボルエラー
Rubocopを使ってコミット時にコーデング規約に沿っているかを強制的にチェックしています。
今回は、コミット時に下記のエラーが出ました。
（Gitコマンドは、oh-my-zshのエイリアスを使用しています）

```
melpserver git:(d845f23b) ga .
➜  melpserver git:(d845f23b) ✗ gc -m "create clinic section function"
Starting db ... done
Inspecting 1 file
Offenses:

app/models/clinic.rb:434:10: W: Lint/BooleanSymbol: Symbol with a boolean name - you probably meant to use true.
    when :true
         ^^^^^
app/models/clinic.rb:436:10: W: Lint/BooleanSymbol: Symbol with a boolean name - you probably meant to use false.
    when :false
         ^^^^^^

1 file inspected, 2 offenses detected
```



該当コードはこちら。患者さんの診察券番号のあり・なし・不明に応じて、患者入力フォームの出し分けを行なっています。

```ruby:clinic.rb
  def active_patient_form_setting(has_medical_examination_number)
    case has_medical_examination_number.try(:to_sym)
    when :true
      patient_form_settings.find { |s| s.examination_type_cd == 'return_visit' }
    when :false
      patient_form_settings.find { |s| s.examination_type_cd == 'first_visit' }
    when :unknown
      patient_form_settings.find { |s| s.examination_type_cd == 'forgot_number' }
    else
      patient_form_settings.find { |s| s.examination_type_cd == 'not_use' }
    end
  end

```

エラーを調べると、[こちら](https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Lint/BooleanSymbol) に
>**Booleanシンボル（:true, :false）は、使っちゃダメだよ。RuboCopで警告出るよ**

と記載ありました。ご丁寧にも、「true, falseのタイプミスなんじゃないの？」という助言までw
今回はタイプミスではないので、RuboCopの警告通りに、:trueをtrueにするのではなく、エラー解消する必要があります。

#解消方法3つ
**1つ目（非推奨）：シンボルではなく、文字列にする**

```ruby:clinic.rb
  def active_patient_form_setting(has_medical_examination_number)
    case has_medical_examination_number
    when 'true'
      patient_form_settings.find { |s| s.examination_type_cd == 'return_visit' }
    when 'false'
      patient_form_settings.find { |s| s.examination_type_cd == 'first_visit' }
    when 'unknown'
      patient_form_settings.find { |s| s.examination_type_cd == 'forgot_number' }
    else
      patient_form_settings.find { |s| s.examination_type_cd == 'not_use' }
    end
  end
```

上記のように、has_medical_medical_number引数のシンボル化を削除し、文字列として（:trueではなく'true'）処理するという方法です。

ただし、文字列よりもシンボルの方が処理速度が速いため、基本的にはシンボル処理した方が良いので非推奨です。詳しくは、[Rubyの文字列とシンボルの違いをキッチリ説明できる人になりたい](https://qiita.com/Kta-M/items/53a13ef60e14fcb41193)を参照して下さい。

**２つ目：シンボル名をboolean以外に変更する**

```ruby:clinic.rb
  def active_patient_form_setting(has_medical_examination_number)
    case has_medical_examination_number.try(:to_sym)
    when :have
      patient_form_settings.find { |s| s.examination_type_cd == 'return_visit' }
    when :not_have
      patient_form_settings.find { |s| s.examination_type_cd == 'first_visit' }
    when :unknown
      patient_form_settings.find { |s| s.examination_type_cd == 'forgot_number' }
    else
      patient_form_settings.find { |s| s.examination_type_cd == 'not_use' }
    end
  end
```

上記のように、:true, :falseではなくて、:have, :not_haveなどboolean以外のシンボルを使う方法です。影響範囲が少なく、ここだけの変更で済む場合は、これがベストでしょう。



**３つ目（応急処置）：RuboCop警告をコメントで無効化する**
booleanシンボル名の変更の影響範囲が広い場合の応急処置として、RuboCop警告を無効化するという手段もあります。

例えば、今回の場合はメソッドの引数であるhas_medical_examination_numberには、true, false, unknownが格納されていて、他のファイルでも呼び出しを行なっているので、:true→：haveなどとシンボル名を変更する場合、他のhas_medical_examination_numberを使っている部分も全て変更する必要が出てきます。


RuboCop警告文無効化の方法ですが、[こちら](https://github.com/rubocop-hq/rubocop/blob/master/manual/configuration.md#disabling-cops-within-source-code) に記載がありました。
>Disabling Cops within Source Code
 One or more individual cops can be disabled locally in a section of a file by adding a comment such as
>>rubocop:disable Metrics/LineLength, Style/StringLiterals
  [...]
  rubocop:enable Metrics/LineLength, Style/StringLiterals

今回の場合は、RuboCopの警告内容は、Lint/BooleanSymbolですので、下記のように、該当部分の前後をコメントします


```ruby:clinic.rb
  # rubocop:disable Lint/BooleanSymbol
  def active_patient_form_setting(has_medical_examination_number)
    case has_medical_examination_number.try(:to_sym)
    when :true
      patient_form_settings.find { |s| s.examination_type_cd == 'return_visit' }
    when :false
      patient_form_settings.find { |s| s.examination_type_cd == 'first_visit' }
    when :unknown
      patient_form_settings.find { |s| s.examination_type_cd == 'forgot_number' }
    else
      patient_form_settings.find { |s| s.examination_type_cd == 'not_use' }
    end
  end
  # rubocop:enable Lint/BooleanSymbol
```

これで、git add, commitすると

    melpserver git:(26d5f9a7) ✗ ga .
    melpserver git:(26d5f9a7) ✗ gc -m "avoid RuboCop warning"
    Starting db ... done
    Inspecting 1 file
    .
    1 file inspected, no offenses detected
    1 file changed, 2 insertions(+), 3 deletions(-)


RuboCop警告が無視され、git pushできるようになりました。


ただし、これは応急処置ですので、今後このエラーは修正する必要あります。
もっとも、事前にBooleanシンボルは警告出ることを知っていて、使わないようにするのがベストですが、もし事後ではまった場合の情報共有としてでした。


#参考にしたサイト
* [Class: RuboCop::Cop::Lint::BooleanSymbol](https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Lint/BooleanSymbol)
* [Rubyの文字列とシンボルの違いをキッチリ説明できる人になりたい](https://qiita.com/Kta-M/items/53a13ef60e14fcb41193)
* [RuboCopの警告をコメントで無効化する方法](https://qiita.com/tbpgr/items/a9000c5c6fa92a46c206)