Class: RuboCop::Cop::DevDoc::Style::StringSymbolComparison
- Inherits:
-
Base
- Object
- Base
- RuboCop::Cop::DevDoc::Style::StringSymbolComparison
- Defined in:
- lib/rubocop/cop/dev_doc/style/string_symbol_comparison.rb
Overview
Flag direct ‘==` / `!=` comparisons between a known-string source and a symbol literal. Such comparisons are silently always false (`’draft’ == :draft` is ‘false` in Ruby), so they signal that the caller forgot to convert at the boundary.
## Rationale Strings and symbols are not equal in Ruby, and string-typed values arrive from boundaries the developer doesn’t control: HTTP params, request headers, ENV. Comparing one of these directly against a symbol literal is a guaranteed bug. Convert at the boundary instead — see ‘best_practices/backend/en/01a_defensive_programming.md` item 7.
❌
if params[:status] == :draft # always false
✔ Convert at the boundary, then compare
@filter_status = params[:status]&.to_sym
if @filter_status == :draft
## Sources detected
## Limitations The cop only catches the direct comparison form. Once the value flows into a local or instance variable, type information is lost and Rubocop cannot trace it back to the original string source. Those cases are caught by review.
Constant Summary collapse
- MSG =
'Comparing string-typed `%<source>s` to a symbol literal is always false. ' \ 'Convert at the boundary with `&.to_sym` or compare against a string instead ' \ '(see backend/01a_defensive_programming.md item 7).'.freeze
- RESTRICT_ON_SEND =
%i[== !=].freeze
Instance Method Summary collapse
Instance Method Details
#on_send(node) ⇒ Object
63 64 65 66 67 68 69 70 71 72 |
# File 'lib/rubocop/cop/dev_doc/style/string_symbol_comparison.rb', line 63 def on_send(node) lhs = node.receiver rhs = node.first_argument return unless lhs && rhs source_node = pick_string_source(lhs, rhs) return unless source_node add_offense(node, message: format(MSG, source: source_node.source)) end |