Home > Net >  ruby: rubocop complains on converting if else to case statement
ruby: rubocop complains on converting if else to case statement

Time:04-14

I have following if else statement that rubocop complained about Style/CaseLikeIf: Convert if-elsif to case-when

if obj.is_a? Rest::Headers
  obj
elsif obj.is_a? Hash
  Rest::Headers.new(**obj)
elsif obj.is_a? Array
  Rest::Headers.new(**obj.to_h)
else
  raise 'Invalid object type for Headers!'
end

I converted it into case statement

case
when (obj.is_a? Rest::Headers)
  obj
when (obj.is_a? Hash)
  Rest::Headers.new(**obj)
when (obj.is_a? Array)
  Rest::Headers.new(**obj.to_h)
else
  raise 'Invalid object type for Headers!'
end

But now rubocop complained Do not use empty case condition, instead use an if expression. Does anyone know what is wrong with my case statement?

CodePudding user response:

Ruby wants you to convert to a case that matches on the types themselves. case in Ruby doesn't just match on equality. A statement of the form

case a
when b
  ...
end

The case will call b === a (note the triple equals here, which does not mean equality) and trigger the when block if it's true.

=== is defined on Object to be equivalent to ==, but many classes override it.

  • Regular expressions use it to pattern match against the right-hand side
  • Ranges check whether the right-hand side is included in the range
  • Classes check whether the right-hand side is_a? instance of the class.

And it's that third bullet point that Rubocop suggests you use.

case obj
when Rest::Headers
  obj
when Hash
  Rest::Headers.new(**obj)
when Array
  Rest::Headers.new(**obj.to_h)
else
  raise 'Invalid object type for Headers!'
end

Note that I never explicitly call is_a? here; the case block automagically knows to do that.

CodePudding user response:

I assume Rubocop expects case obj.

Refer to the rubydoc.info page for more information:

Consider disabling the cop.

  •  Tags:  
  • ruby
  • Related