Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new Lint/BooleanSymbol cop #4515

Merged
merged 1 commit into from
Jun 18, 2017
Merged

Conversation

droptheplot
Copy link
Contributor

@droptheplot droptheplot commented Jun 14, 2017

A few days ago I had this bug when someone accidentally used :true instead of true. This leads to some problems since both :true and :false are "truthy" values and it's hard to notice this because they are quite normal symbols.

I think in most cases you want to use just standard booleans so I suggest to mark it as an issue.


Before submitting the PR make sure the following are checked:

  • Wrote good commit messages.
  • Commit message starts with [Fix #issue-number] (if the related issue exists).
  • Used the same coding conventions as the rest of the project.
  • Feature branch is up-to-date with master (if not - rebase it).
  • Squashed related commits together.
  • Added tests.
  • Added an entry to the Changelog if the new code introduces user-observable changes. See changelog entry format.
  • All tests(rake spec) are passing.
  • The new code doesn't generate RuboCop offenses that are checked by rake internal_investigation.
  • The PR relates to only one subject with a clear title
    and description in grammatically correct, complete sentences.
  • Updated cop documentation with rake generate_cops_documentation (required only when you've added a new cop or changed the configuration/documentation of an existing cop).

# true
#
class BooleanSymbol < Cop
MSG = 'Use `%<name>s` instead of `:%<name>s`.'.freeze
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the cop description and the message should allude to the fact that this might be accidental, since there are actual cases where you'd want :true or :false, and just saying "use true instead" is actually wrong. WDYT? 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you're right. I made message similar to Lint/AssignmentInCondition.

@Drenmi
Copy link
Collaborator

Drenmi commented Jun 15, 2017

Interesting case! 🙂 I think this can be enabled by default, but could actually be turned off in RuboCop's own .rubocop.yml, since the codebase deals heavily with describing code, and legitimate uses of :true and :false will be more common than accidents. WDYT?

@droptheplot
Copy link
Contributor Author

@Drenmi That's right, I disabled it for internal_investigation.

# @example
#
# # bad
#
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This empty line seems redundant to me.

# @example
#
# # good
#
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

# true
#
class BooleanSymbol < Cop
MSG = 'Boolean symbol - you probably meant to use `%s`.'.freeze
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Symbol with a boolean value name (or something like this). "Boolean symbol" sounds a bit strange to me.

MSG = 'Boolean symbol - you probably meant to use `%s`.'.freeze

def on_sym(node)
match = node.source.match(/\A:(true|false)\z/)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That seems like an overkill - you can just check if the symbol is :true or :false.

module RuboCop
module Cop
module Lint
# This cop checks for boolean symbols.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd expand this text a bit.

@droptheplot droptheplot force-pushed the boolean-symbol branch 3 times, most recently from 92e6f51 to b62c96b Compare June 15, 2017 11:16
@droptheplot
Copy link
Contributor Author

@bbatsov, fixed.

@rrosenblum
Copy link
Contributor

My first thought when reading through the description was cool, should this also look for 'true' and 'false'. Then I started thinking about the use cases for that which wouldn't always be safe to convert the string versions because of cases like environment variables. Then I started questioning the usage for symbols.

Is this going to be prone to a high volume of false positive?

# @example
#
# # bad
# :true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While we are at it, we might as well add in the bad and good example for false. 2 extra lines of documentation that would then cover 100% of the cases.

def on_sym(node)
name = node.source[1..-1]

return unless %w[true false].include?(name)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any thoughts on using a node matcher?

def_node_matcher :boolean_symbol?, '(sym {:true :false})'

def on_sym(node)
  return unless boolean_symbol?(node)
  add_offense(node, :expression, format(MSG, node.source[1..-1]))
end

RUBY
end

it 'do not registers an offense when using regular symbol' do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it provide value to add a test for the boolean versions of true and false?

@droptheplot
Copy link
Contributor Author

@rrosenblum Thanks, I've made changes according to your comments.

Is this going to be prone to a high volume of false positive?

For example I checked rails:

> ack -hc "true"
6398
> ack -hc "'true'"
39
> ack -hc " :true"
4

And rubocop:

> ack -hc "true"
2573
> ack -hc "'true'"
11
> ack -hc " :true"
3

I think it should be treated like Lint/AssignmentInCondition.

@bbatsov bbatsov merged commit a52d49a into rubocop:master Jun 18, 2017
@droptheplot
Copy link
Contributor Author

@bbatsov, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants