You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Style/CaseLikeIf is unsafe in edge cases. It gives false positives if both:
if or elsif includes a regular expression, and
the code that's executed when the condition is true depends on something in the match other than the existence or numerical position of a match.
Expected behavior
I expect RuboCop to not generate a Style/CaseLikeIf offense.
Actual behavior
RuboCop generates a Style/CaseLikeIf offense.
Steps to reproduce the problem
Create an if-elsif where the if or elsif includes =~ or .match and the conditionally executed code depends on something in the match other than true/false or the position of the match.
Each if or elsif has a named capture group that's used in the following conditionally executed code.
But if you re-write the above as a case statement, , e.g.:
casevalwhen/^(?<yr>\d{4})$/yyyymmdd([yr,1,1],[yr,12,31])
...
end
then the named capture group (yr)is not available to the conditionally executed code.
This is due to the fact that when uses ===, which is not equivalent to the =~ used in if and elsif. Compare
$ /(?<yr>\d{4})/ === "20190815";yrtruenil
with
$ /(?<yr>\d{4})/ =~ "20190815";yr0"2019"
Comment:
Some options:
Mark Style/CaseLikeIf as unsafe.
Make Style/CaseLikeIf safe by catching all the edge cases. Strikes me as very difficult or impossible to accomplish.
Make Style/CaseLikeIf safe by ignoring conditionals where an if or elsif includes =~ or .match. (I don't like this. Style/CaseLikeIf does work for the most common regex use case, and I wouldn't like to throw that away.)
Yeah, I already prepared a PR to fix this: #8504. Hopefully it will be merged soon. There I am going to prevent this cop from throwing an offense if there is a regexp with named captures inside and =~ or match is used. It isn't ideal though, it won't throw an offense if there is a regexp with named captures which are not used later. But probably this would be a very edgy case.
Style/CaseLikeIf is unsafe in edge cases. It gives false positives if both:
if
orelsif
includes a regular expression, andExpected behavior
I expect RuboCop to not generate a Style/CaseLikeIf offense.
Actual behavior
RuboCop generates a Style/CaseLikeIf offense.
Steps to reproduce the problem
Create an
if-elsif
where theif
orelsif
includes=~
or.match
and the conditionally executed code depends on something in the match other than true/false or the position of the match.In my case the problematic code was
Each
if
orelsif
has a named capture group that's used in the following conditionally executed code.But if you re-write the above as a
case
statement, , e.g.:then the named capture group (
yr
)is not available to the conditionally executed code.This is due to the fact that
when
uses===
, which is not equivalent to the=~
used inif
andelsif
. Comparewith
Comment:
Some options:
Style/CaseLikeIf
as unsafe.Style/CaseLikeIf
safe by catching all the edge cases. Strikes me as very difficult or impossible to accomplish.Style/CaseLikeIf
safe by ignoring conditionals where anif
orelsif
includes=~
or.match
. (I don't like this.Style/CaseLikeIf
does work for the most common regex use case, and I wouldn't like to throw that away.)RuboCop version
0.88.0 (using Parser 2.7.1.4, rubocop-ast 0.3.0, running on ruby 2.6.6 x86_64-linux)
The text was updated successfully, but these errors were encountered: