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

Wrong Lint/UnneededSplatExpansion #3512

Closed
YukiJikumaru opened this issue Sep 19, 2016 · 12 comments
Closed

Wrong Lint/UnneededSplatExpansion #3512

YukiJikumaru opened this issue Sep 19, 2016 · 12 comments
Labels

Comments

@YukiJikumaru
Copy link
Contributor

Expected behavior

$ cat hoge.rb
# frozen_string_literal: true
# nodoc
class Hello < ApplicationRecord
  OTHER_COLUMNS = %i(
    column_B
    column_C
  ).freeze

  validates(
    *[:column_A, *OTHER_COLUMNS],
    allow_nil: true,
    numericality: {
      only_integer: true,
      greater_than_or_equal_to: 0,
      less_than_or_equal_to: 10
    }
  )
end

$ rubocop hoge.rb

This should not generate Lint/UnneededSplatExpansion offenses.

Actual behavior

$ rubocop hoge.rb
Inspecting 1 file
W

Offenses:

hoge.rb:10:5: W: Unnecessary splat expansion.
    *[:column_A, *OTHER_COLUMNS],
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

1 file inspected, 1 offense detected

$ rubocop --rails hoge.rb
Inspecting 1 file
W

Offenses:

hoge.rb:10:5: W: Unnecessary splat expansion.
    *[:column_A, *OTHER_COLUMNS],
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

1 file inspected, 1 offense detected

If modify like below, offense stops.

  validates(
+    *[:column_A, *OTHER_COLUMNS],
-    *[:column_A, *OTHER_COLUMNS],
    allow_nil: true,

However this code produces NoMethodError.

NoMethodError: undefined method `to_sym' for #<Array:0x007efe849b0828>

Steps to reproduce the problem

$ mkdir work
$ cd work
$ rubocop -V
0.43.0 (using Parser 2.3.1.3, running on ruby 2.3.1 x86_64-linux)
$ wget https://raw.githubusercontent.com/bbatsov/rubocop/v0.43.0/config/default.yml
$ wget https://raw.githubusercontent.com/bbatsov/rubocop/v0.43.0/config/enabled.yml
$ wget https://raw.githubusercontent.com/bbatsov/rubocop/v0.43.0/config/disabled.yml
$ cat <<EOF > hoge.rb && rubocop --config default.yml hoge.rb
# frozen_string_literal: true
# nodoc
class Hello < ApplicationRecord
  OTHER_COLUMNS = %i(
    column_B
    column_C
  ).freeze

  validates(
    *[:column_A, *OTHER_COLUMNS],
    allow_nil: true,
    numericality: {
      only_integer: true,
      greater_than_or_equal_to: 0,
      less_than_or_equal_to: 10
    }
  )
end
EOF

RuboCop version

$ rubocop -V
0.43.0 (using Parser 2.3.1.3, running on ruby 2.3.1 x86_64-linux)
@rikas
Copy link

rikas commented Sep 19, 2016

Same here!

In Rails

{'one' => 1, 'two' => 2, 'three' => 3}.slice(*%w(one three))
=> {"one"=>1, "three"=>3}

Rubocop tells me

W: Unnecessary splat expansion.
        {'one' => 1, 'two' => 2, 'three' => 3}.slice(*%w(one three))

Which is wrong, because the result is not the same.

{'one' => 1, 'two' => 2, 'three' => 3}.slice(%w(one three))
=> {}
$ rubocop -V
0.43.0 (using Parser 2.3.1.3, running on ruby 2.3.0 x86_64-darwin15)

@bbatsov bbatsov added the bug label Sep 19, 2016
@tejasbubane
Copy link
Contributor

Rubocop is detecting and correcting the offense. This does not seem to be a bug:

⇒  cat rubocop_bug_test.rb
{ 'one' => 1, 'two' => 2, 'three' => 3 }.slice(*%w(one three))
⇒  rubocop -a rubocop_bug_test.rb
Inspecting 1 file
W

Offenses:

rubocop_bug_test.rb:1:48: W: [Corrected] Unnecessary splat expansion.
{ 'one' => 1, 'two' => 2, 'three' => 3 }.slice(*%w(one three))
                                               ^^^^^^^^^^^^^^

1 file inspected, 1 offense detected, 1 offense corrected
⇒  cat rubocop_bug_test.rb
{ 'one' => 1, 'two' => 2, 'three' => 3 }.slice('one', 'three')

@NobodysNightmare
Copy link
Contributor

Also false positive for Pathname#join:

Rails.root.join(*['a', 'b', 'c'])

Please tell me if you would rather like a separate issue.

@backus
Copy link
Contributor

backus commented Sep 21, 2016

@NobodysNightmare I'm not sure what is wrong with your example. It correctly autocorrects to Rails.root.join('a', 'b', 'c'). What is the problem?

@NobodysNightmare
Copy link
Contributor

NobodysNightmare commented Sep 21, 2016

Okay I see... Apparently the error message was simply confusing to me.

"Unneccessary splat expansion" implies to me, that I do not need to expand the array (i.e. leave the splat operator out). However, what the cop wants to tell me is that I could just have written the parameter list out manually... Right?

So it was me misunderstanding the cop, sorry...

@rikas
Copy link

rikas commented Sep 21, 2016

@tejasbubane you're right. I didn't get the obvious change. 😞

@backus
Copy link
Contributor

backus commented Sep 21, 2016

👍 no problem @NobodysNightmare

@rikas
Copy link

rikas commented Sep 21, 2016

I agree that the message can be misinterpreted. That was also my interpretation, hence my example above wihtout the splat operator but keeping the array.

Maybe changing the error copy would be a good thing to do.

tejasbubane added a commit to tejasbubane/rubocop that referenced this issue Sep 22, 2016
…on` for array

In case of array splat for method parameter, the default message was
ambiguous. `Unnecessary splat expansion.` made people just remove the
splat expansion and pass the array as parameter which is obviously not
the same as passing splat arguments. Change the message to
`Pass array contents as separate arguments.` to
the message in such cases to make the intension more clear.
@tejasbubane
Copy link
Contributor

Regarding the original issue by @YukiJikumaru (with splat inside splat). Rubocop works as expected.

original code:

validates(
    *[:column_A, *OTHER_COLUMNS]
)

gets autocorrected to:

validates(
  :column_A, *OTHER_COLUMNS
)

Hence this is not a bug.

Maybe changing the error copy would be a good thing to do.

@rikas Sent a PR.

@YukiJikumaru
Copy link
Contributor Author

@tejasbubane Thank you for your answer!

bbatsov pushed a commit that referenced this issue Sep 23, 2016
… array (#3526)

In case of array splat for method parameter, the default message was
ambiguous. `Unnecessary splat expansion.` made people just remove the
splat expansion and pass the array as parameter which is obviously not
the same as passing splat arguments. Change the message to
`Pass array contents as separate arguments.` to
the message in such cases to make the intension more clear.
mikezter added a commit to mikezter/rubocop that referenced this issue Sep 28, 2016
* bbatsov/master: (80 commits)
  [Fix rubocop#3540] Make `Style/GuardClause` register offense for instance & singleton methods
  [Fix rubocop#3436] issue related to Rails/SaveBang when returning non-bang call from the parent method
  Allow `#to_yml` to produce single-quoted strings
  Add support for StyleGuideBaseURL and update rules
  Add spec for the existing style guide URL implementation
  Fix the changelog
  Edited regular expression for normal case to fix issues rubocop#3514 and rubocop#3516 (rubocop#3524)
  Add a rake task for generation a new cop (rubocop#3533)
  [Fix rubocop#3510] Various bug fixes for SafeNavigation (rubocop#3517)
  [Fix rubocop#3512] Change error message of `Lint/UnneededSplatExpansion` for array (rubocop#3526)
  Fix false positive in `Lint/AssignmentInCondition` (rubocop#3520) (rubocop#3529)
  Rename a mismatched filename (rubocop#3523)
  Fix a broken changelog entry
  [Fix rubocop#3511] Style/TernaryParentheses false positive (rubocop#3513)
  Fix the release notes for 0.43
  Cut 0.43.0
  [Fix rubocop#3462] Don't flag single-line methods
  Fix false negatives in `Rails/NotNullColumn` cop (rubocop#3508)
  Remove unused doubled methods (rubocop#3509)
  [Fix rubocop#3485] Make OneLineConditional cop ignore empty else (rubocop#3487)
  ...
Neodelf pushed a commit to Neodelf/rubocop that referenced this issue Oct 15, 2016
…on` for array (rubocop#3526)

In case of array splat for method parameter, the default message was
ambiguous. `Unnecessary splat expansion.` made people just remove the
splat expansion and pass the array as parameter which is obviously not
the same as passing splat arguments. Change the message to
`Pass array contents as separate arguments.` to
the message in such cases to make the intension more clear.
@samnang
Copy link

samnang commented Jan 10, 2017

It seems false positive here:

Rails.root.join(*%w(db seeders users.rb))

Rubocop complaints on this:

Lint/UnneededSplatExpansion: Pass array contents as separate arguments.

I know I could get rid of this warning with:

Rails.root.join('db', 'seeders', 'users.rb')

%i, %w, and %W seem doesn't recognise here. If it's a bug, please let me know if you want a separate issue.

@tejasbubane
Copy link
Contributor

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

No branches or pull requests

7 participants