-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
New cop checks for braces in function calls with hash arguments. #551
Conversation
This cop would be very useful for me! One question: should the default be
|
@@ -184,3 +184,6 @@ TrivialAccessors: | |||
VariableName: | |||
# Valid values are: snake_case, camelCase | |||
EnforcedStyle: snake_case | |||
|
|||
BracesInHashParameters: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'd prefer BracesAroundHashParameters
. And keep the cops in alphabetical order in this file.
@dblock This cop seems like a good idea. I've added some source code comments. I agree with @fancyremarker that the default should be to not have braces. Oh, and you also need to make sure that the source code passes |
Updated with all the suggested changes/fixes. Enforcing the default style of |
end | ||
|
||
it 'accepts multiple hash parameters' do | ||
inspect_source(cop, ['where(x: "y", foo: "bar")']) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is actually just one hash with multiple keys, so the heading "accepts multiple hash parameters" is wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed and updated all names.
Added a few more comments. Sorry I didn't write them all at once. I noticed you chose to stick with |
Renamed |
Updated, squashed. Please re-review. Happy to make more changes as you see fit. |
Updated again, squashed. Not using a regexp anymore, thanks for insisting, this is a lot better. |
@dblock :-) Code looks good now. You'll have to rebase on top of the current |
…s with hash parameters.
Here're you go. |
New cop checks for braces in function calls with hash arguments.
Thanks! |
end | ||
|
||
it 'one non-hash parameter followed by a hash parameter with braces' do | ||
inspect_source(cop, ['where(1, { y: 2 })']) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the same as a "bad" example from the style guide, so I think it's wrong to accept it when EnforcedStyle
is no_braces
.
class Person < ActiveRecord::Base
# bad
validates(:name, { presence: true, length: { within: 1..10 } })
# good
validates :name, presence: true, length: { within: 1..10 }
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I noticed yesterday that the code currently checks only methods with 1 argument, which is problematic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we should also make the check when there are multiple arguments, and check the last argument. Do you want to look at that, @dblock?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is quite right. First, the violation of parenthesis is a different beast, and not something that relates to braces. I support a cop for that of course, as it's bad :)
For the braces, you can't just check the last argument. Here's am ambiguous function where we may need to disambiguate the arguments:
def sort_of_validates(name, options, parameters = {})
puts "NAME: #{name}"
puts "OPTIONS: #{options}"
puts "PARAMETERS: #{parameters}"
end
sort_of_validates :name, presence: true, length: { within: 1..10 }
# NAME: name
# OPTIONS: {:presence=>true, :length=>{:within=>1..10}}
# PARAMETERS: {}
sort_of_validates :name, { presence: true }, { length: { within: 1..10 } }
# NAME: name
# OPTIONS: {:presence=>true}
# PARAMETERS: {:length=>{:within=>1..10}}
I am not sure what to do. Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's how I see it. Only the last hash parameter can omit the braces. That's Ruby syntax. If you want the presence
and length
values to go in two different parameters, you have to put braces around presence: true
. Then you can put braces around length: { within: 1..10 }
, or leave them out. It won't change the meaning. It's just a style issue and that's what we're checking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jonas054 is totally right.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. Thinking out loud ...
where({ x: 1 }, { y: 2 })
Should be treated as a special case and not register an offence, because it would seem weird that multiple hashes in the same expression are written with or without braces?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Opened #567, lets move the discussion there if there's more.
It's quite common to make function calls such as
where({ x: 1 })
, in which case the curly braces are not required and you can writewhere(x: 1)
. TheBracesInHashParameters
supports both arequired
(default) and anone
style, keeping things consistent either way.