LoginSignup
3
1

More than 3 years have passed since last update.

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

Last updated at Posted at 2019-06-03

概要

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

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

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

エラーを調べると、こちら

Booleanシンボル(:true, :false)は、使っちゃダメだよ。RuboCopで警告出るよ

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

解消方法3つ

1つ目(非推奨):シンボルではなく、文字列にする

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の文字列とシンボルの違いをキッチリ説明できる人になりたいを参照して下さい。

2つ目:シンボル名をboolean以外に変更する

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以外のシンボルを使う方法です。影響範囲が少なく、ここだけの変更で済む場合は、これがベストでしょう。

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

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

RuboCop警告文無効化の方法ですが、こちら に記載がありました。

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ですので、下記のように、該当部分の前後をコメントします

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シンボルは警告出ることを知っていて、使わないようにするのがベストですが、もし事後ではまった場合の情報共有としてでした。

参考にしたサイト

3
1
0

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
3
1