Rubocop: FormatStringToken false positive in arbitrary string literal

Created on 25 May 2017  路  5Comments  路  Source: rubocop-hq/rubocop

Expected behavior

Rubocop should not fail on %{} in arbitrary strings when not using format.

Actual behavior

test.rb:1:32: C: Style/FormatStringToken: Prefer annotated tokens (like %<foo>s) over template tokens (like %{foo}).
IMAGEMAGICK_OPTIONS = '-extent %{width}x%{height}'

Steps to reproduce the problem

Create a file called test.rb with the following contents:

IMAGEMAGICK_OPTIONS = '-extent %{width}x%{height}'

Then run rubocop test.rb.

RuboCop version

Include the output of rubocop -V. Here's an example:

$ rubocop -V
0.49.0 (using Parser 2.4.0.0, running on ruby 2.3.3 x86_64-linux)

Most helpful comment

Another false positive case is inside Rails routes.rb file:

  get '/guides/:id', to: redirect('/blog/%{id}')

All 5 comments

I think this would be much less useful if this was the only behavior or the default behavior. How about a configuration option like OnlyCheckInsideFormat that would reduce the checks to strings inside Kernel#format, String#%, and Kernel#sprintf?

Another false positive case is inside Rails routes.rb file:

  get '/guides/:id', to: redirect('/blog/%{id}')

Another false positive case in Rails validation :message.

validates :age, numericality: { message: "%{value} seems wrong" }

ref: http://guides.rubyonrails.org/active_record_validations.html#message

Yet another false positive with Grok patterns like %{FUBAR}.

https://github.com/logstash-plugins/logstash-patterns-core/tree/master/patterns

We can't fix this easily, because of a combination of factors:

  • Unfortunately the %{} syntax is also valid in Ruby format strings.
  • There is no way for us to know whether a string will be passed to Kernel#format during runtime.
  • We have plenty of tools for dealing with false positives, but false negatives will forever remain unknown if we allow them.

So the solution to this is to use one of the existing means of removing false positives. (In order of decreasing granularity):

  1. Inline disable directives: # rubocop#disable Style/FormatStringtToken. Effective for singular instances.
  2. Disable it for certain files by using Exclude in .rubocop.yml. Effective for DSL files like Rails routes.
  3. Disable the cop altogether. Last resort, or for projects that don't use Ruby format strings.
Was this page helpful?
0 / 5 - 0 ratings

Related issues

benoittgt picture benoittgt  路  3Comments

NobodysNightmare picture NobodysNightmare  路  3Comments

bquorning picture bquorning  路  3Comments

david942j picture david942j  路  3Comments

herwinw picture herwinw  路  3Comments