Skip to content

Add setting to Style/CaseEquality to allow x.===(y) (explicit parentheses) #14684

@jez

Description

@jez

Is your feature request related to a problem? Please describe.

/some_pattern/ === x

This code is rejected by the Style/CaseEquality cop. The recommended style here requires doing

case x when /some_pattern/ then true else false end

which is more verbose.

One of the main motivations for banning === is to ensure that people who frequently work with JavaScript doesn't use === out of habit, mistakenly assuming that it is the "normal" equality operator of ==.

However, there are valid use cases for ===. For example, if you tried to rewrite /some_pattern/ === x without, you either end up with the verbose solution above, or the more brittle solution of

x =~ /some_pattern/

which will raise an exception if x doesn't have the =~ method, or

/some_pattern/ =~ x

which will raise an exception if x cannot be implicitly converted into a String.

In this case, /some_pattern/ === x is the least brittle and most concise solution to the problem.

Describe the solution you'd like

It would be nice to have an option for the Style/CaseEquality cop that permits the call if it uses the explicit x.===(y) syntax, i.e., an explicit . and parentheses.

  • It's unlikely that people switching between a JavaScript and Ruby codebase would habitually write this form—it would be far more likely that they intend to call Ruby's case equality operator, not generic equality.
  • It's still more terse than the alternative of fully expanding a case/when expression.

This would be guarded with an option (like the two existing options for the Style/CaseEquality cop: AllowOnConstant and AllowOnSelfClass).

As a suggestion: AllowOnExplicitCall, but I'm open to alternative names.

Describe alternatives you've considered

There are some alternatives considered above, like

  • just use case/when
  • just disable the cop when this is needed
  • codebases could define a separate helper method, like Utils.case_equality(x, y) to make things more explicit

Additional context

The concrete problem we're encountering is when upgrading legacy Ruby codebases that relied on the existence of Object#=~, which was made deprecated and eventually removed. As we find instances where the code was relying on this, we would like to be able to use === to replace the call to =~ but we run against this cop.


If adding such an option is a welcome change, I'd be happy to contribute this change.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions