vint
vint copied to clipboard
New Rule Suggestion: Prohibit equality comparisons with get() calls with no defaults
I have a suggestion for a new rule, which I might try and submit a pull request myself for, at some point. I think it would be a good idea to complain about the following code:
if get(l:some_dictionary, 'foo') ==# 'bar'
The problem with the code above is that if the key is not defined, then the comparison returns 1, as the default value is 0, and 0 ==# 'bar' returns 1 because the String on the right hand side is first converted to a Number, and the result of that conversion is 0. Using a default value fixes the problem.
if get(l:some_dictionary, 'foo', '') ==# 'bar'
It might even be an idea, and easier to implement, to just always ask for a default value to be used when calling get.
Comparisons using match/ignore case equality operators sound like a great idea to prevent that bug. I'd also suggest catching empty(get()) or len(get()) since you have the same string conversion problem.
But would non string comparisons result in no warning:
if get(l:some_dictionary, 'foo') == g:threshold
if get(l:some_dictionary, 'foo') > 0
if get(l:some_dictionary, 'foo')
Maybe it always asks for a default value, unless it's using an numerical/ignorecase comparison where it's more likely the 0 default was expected.