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

Lint/SafeNavigationChain and try #3915

Closed
MOZGIII opened this issue Jan 16, 2017 · 16 comments
Closed

Lint/SafeNavigationChain and try #3915

MOZGIII opened this issue Jan 16, 2017 · 16 comments

Comments

@MOZGIII
Copy link

MOZGIII commented Jan 16, 2017

Cop Lint/SafeNavigationChain does not allow try and try!.


Expected behavior

try and try! should be allowed after &. in Rails.

Actual behavior

Cop does not allow try and try! after &. in Rails.

Steps to reproduce the problem

$ echo 'a&.b.try(:c)' | rubocop -s demo
Inspecting 1 file
W

Offenses:

demo:1:5: W: Do not chain ordinary method call after safe navigation operator.
a&.b.try(:c)
    ^

1 file inspected, 1 offense detected

RuboCop version

$ rubocop -V
0.47.0 (using Parser 2.3.3.1, running on ruby 2.3.1 x86_64-linux)
@bbatsov
Copy link
Collaborator

bbatsov commented Jan 16, 2017

I see no reason why someone should write code like this. Some rationale would be useful...

@MOZGIII
Copy link
Author

MOZGIII commented Jan 16, 2017

Here: property&.params.try(:purpose)&.code

params is a polymorphic model here, thus can either have or not have purpose method.
This is the most compact way to write the code for a particular situation.

@MOZGIII
Copy link
Author

MOZGIII commented Jan 16, 2017

This cop detected a lot of problems in our code, however some of them are false-positives due to this issue.
It's very useful, but would be much better with the fix.

@MOZGIII
Copy link
Author

MOZGIII commented Jan 16, 2017

Also, it's just perfectly fine to write something like nil.try(...) or nil.try!(...) in Rails, so if it needs to be checked it should probably be done in a separate cop.
Idea for a cop btw: use &. instead of .try!(...) where possible.

@mikegee
Copy link
Contributor

mikegee commented Jan 17, 2017

It would be nice if more folks contributed their thoughts on this. I'm not convinced the change requested improves the code.

In the particular case presented: property&.params.try(:purpose)&.code. I think defining the purpose method on all the objects params might return is a better approach.

@pocke
Copy link
Collaborator

pocke commented Jan 17, 2017

it is reasonable.

Idea for a cop btw: use &. instead of .try!(...) where possible.

We can use Rails/SafeNavigation cop for the purpose.
https://github.com/bbatsov/rubocop/blob/master/lib/rubocop/cop/rails/safe_navigation.rb

In the particular case presented: property&.params.try(:purpose)&.code. I think defining the purpose method on all the objects params might return is a better approach.

Yeah, however, I think it is out of scope for this cop.
The refactoring should be suggested by other cop or other analyser.

@bbatsov
Copy link
Collaborator

bbatsov commented Jan 17, 2017 via email

pocke added a commit to pocke/rubocop that referenced this issue Jan 17, 2017
bbatsov pushed a commit that referenced this issue Jan 17, 2017
@igas
Copy link

igas commented Jan 19, 2017

Does it make sense to add more exceptions? for example:

foo&.bar.presence
foo&.bar.present?
foo&.bar.nil?

@MOZGIII
Copy link
Author

MOZGIII commented Jan 19, 2017

I guess so. Any method that can be used in nil? is technically legal, so all of them should be allowed.

@pocke
Copy link
Collaborator

pocke commented Jan 19, 2017

Does it make sense to add more exceptions? for example:

.present? and .nil? have been added to exceptions already. However, .presence hasn't been added yet.

The following methods are added by RoR into NilClass.

acts_like?
as_json
__binding__
blank?
bullet_key
byebug
class_eval
debugger
deep_dup
duplicable?
gem
html_safe?
in?
instance_values
instance_variable_names
load_dependency
presence
presence_in
present?
pretty_inspect
pretty_print
pretty_print_cycle
pretty_print_inspect
pretty_print_instance_variables
primary_key_value
pry
psych_to_yaml
require_dependency
require_or_load
suppress_warnings
to_json
to_param
to_query
to_yaml
to_yaml_properties
try
try!
unloadable
with_options

However, the cop supports only blank?, present? and try.

Should the cop support the above all methods?

@bbatsov
Copy link
Collaborator

bbatsov commented Jan 19, 2017

Maybe we should just make this configurable and let people add there whatever they want. I myself hate a style of programming that assumes nils can pop up everywhere...

@bbatsov
Copy link
Collaborator

bbatsov commented Jan 19, 2017

At any rate - I wouldn't go overboard with this...

@MOZGIII
Copy link
Author

MOZGIII commented Jan 19, 2017

I agree. It's currently almost impossible to deduce a set of methods that are allowed to be called after &. or .try(...).
It will also vary from project to project.
But sane defaults are great anyway.

@MOZGIII
Copy link
Author

MOZGIII commented Jan 20, 2017

Could you please push release to rubygems?

@bbatsov
Copy link
Collaborator

bbatsov commented Jan 20, 2017 via email

@bbatsov
Copy link
Collaborator

bbatsov commented Jan 20, 2017

P.S. My decision might change if more bugs get fixed in the next couple of days.

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

No branches or pull requests

5 participants