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

Blacklist ruby keywords for scopes #14582

Merged
merged 1 commit into from
Apr 3, 2014

Conversation

arthurnn
Copy link
Member

@arthurnn arthurnn commented Apr 3, 2014

@@ -29,6 +29,8 @@ def self.set_name_cache(name, value)
end
}

BLACKLISTED_CLASS_METHODS = %w(private public protected alias and BEGIN begin break case class def defined? do else elsif END end ensure false for if in module next nil not or redo rescue retry return self super then true undef unless until when while yield).freeze
Copy link
Member Author

Choose a reason for hiding this comment

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

Not just if I should break this in multiple lines or not. Let me know

Copy link
Member

Choose a reason for hiding this comment

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

Better to break the lines. Also we don't need to freeze

Copy link
Member Author

Choose a reason for hiding this comment

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

Done!

@arthurnn
Copy link
Member Author

arthurnn commented Apr 3, 2014

cc @tenderlove

@fw42
Copy link
Contributor

fw42 commented Apr 3, 2014

Do we have to hardcode that list? Can't we get that dynamically from somewhere? Like Class.methods or something like that.

@rafaelfranca
Copy link
Member

@fw42 this list is not only about method on Class, it is also about some ruby keywords. I think it is fine to use a hardcoded list.

@fw42
Copy link
Contributor

fw42 commented Apr 3, 2014

public/protected/private are not keywords in Ruby as far as I know

@chancancode
Copy link
Member

Can we add the test cases to the enum tests as well? 😄

@rafaelfranca
Copy link
Member

@fw42 this is why I said "not only about"

@chancancode
Copy link
Member

Seems good, some comments:

  1. We should (eventually) add this to attribute methods too perhaps? The list would be slightly different, but it seems like the bulk of it can be shared
  2. The list seems slightly on the aggressive side – I don't see most of the keywords actually causing problems. For example, Mission.rescue seems reasonable:
>> class A
>>   def rescue
>>     puts 'lol'
>>   end
>> 
?>   begin
?>     raise
>>   rescue
>>     puts 'omg'
>>   end
>> end
omg
=> nil
>> A.rescue
lol
=> nil

When you call it on the class as an explicit receiver it resolves correctly (the common usage for a scope), and when you use it without the receiver the keyword takes precedence (the common usage for the rescue keyword).

Not that I would recommend defining a scope with those names, but since this is supposed to be a "helpful" feature to help you discover problems early on, perhaps we can start with the most dangerous scenario so we don't stop people from upgrading over the unlikely problems.

Not a huge deal though as I don't think anyone will actually define a scope called if... so I'll leave it to you and @rafaelfranca to decide where to draw the line.

@rafaelfranca rafaelfranca added this to the 4.1.0 milestone Apr 3, 2014
@arthurnn
Copy link
Member Author

arthurnn commented Apr 3, 2014

@chancancode Enum tests added .

About what it should be on the list, I am on the fence about it.
I guess having a bigger list is better, but I am no strong about it too.

Let me know, I can change the list content.

@chancancode
Copy link
Member

@​rafaelfranca thoughts? If you don't feel strongly about this either we can probably just keep it as is and merge 

Sent from Mailbox for iPhone

On Thu, Apr 3, 2014 at 12:13 PM, Arthur Nogueira Neves
notifications@github.com wrote:

@chancancode Enum tests added .
About what it should be on the list, I am on the fence about it.
I guess having a bigger list is better, but I am no strong about it too.

Let me know, I can change the list content.

Reply to this email directly or view it on GitHub:
#14582 (comment)

@rafaelfranca
Copy link
Member

@arthurnn I think is better to trim down this list a little. You can check which method would be problematic using the same code @chancancode used in the above comment. WDYT?

@rafaelfranca
Copy link
Member

I'm more concerned to release a patch release only to remove methods from this list.

@arthurnn
Copy link
Member Author

arthurnn commented Apr 3, 2014

@rafaelfranca make sense. TBH, keywords doesnt need to be in that list, as @chancancode showed in his code... I will have only private protected public on the list for now. Specially because this is going to 4.1 ..

@rafaelfranca
Copy link
Member

Seems good.

Add tests to make sure scopes cannot be create with names such as:
private, protected, public.
Make sure enum values don't collide with those methods too.
@arthurnn
Copy link
Member Author

arthurnn commented Apr 3, 2014

Done.

rafaelfranca added a commit that referenced this pull request Apr 3, 2014
@rafaelfranca rafaelfranca merged commit 362203e into rails:master Apr 3, 2014
rafaelfranca added a commit that referenced this pull request Apr 3, 2014
rafaelfranca added a commit that referenced this pull request Apr 3, 2014
Blacklist ruby keywords for scopes
Conflicts:
	activerecord/CHANGELOG.md
@wincent
Copy link
Contributor

wincent commented Apr 11, 2014

This broke my app, which has a couple of public scopes (which have been working fine for years).

I've fixed it, but I was disappointed to see a non-essential change like this slip in after RC and days before final release. (And more so because there is no rationale expressed here or in the commit message for why this change is a good idea; public, private, protected aren't keywords as far as I know.)

@arthurnn arthurnn deleted the blacklist_ruby_methods branch April 11, 2014 01:05
@arthurnn
Copy link
Member Author

@wincent you can read it in here #14583 about, why defining a self.public method is a bad idea.
tl;dr: alias_method_chain will not work in models that define a scope :public

@wincent
Copy link
Contributor

wincent commented Apr 11, 2014

Thanks for the link!

On Thursday, April 10, 2014, Arthur Nogueira Neves notifications@github.com
wrote:

@wincent https://github.com/wincent you can read it in here #14583https://github.com/rails/rails/pull/14583about, why defining a
self.public method is a bad idea.
tl;dr: alias_method_chain will not work in models that define a scope
:public


Reply to this email directly or view it on GitHubhttps://github.com//pull/14582#issuecomment-40161848
.

@chancancode
Copy link
Member

Good call @wincent, for the future, it would be nice to include the rationale in the commit message for these kind of changes, so that when someone git blame and found the commit they'll know what's going on, I'll keep that in mind when writing commit messages (and reviewing commits) in the future!

In this case, this is dangerous because things would appear to work on the surface but could be strangely broken inside, and it could be very non-obvious and tricky to debug. For example:

class Posts < AR::Base
  enum visibility: [:public, :private]

  private
    def dont_call_me
      ...
    end
end

Post.new.dont_call_me # <- it works, huh.

myabc added a commit to myabc/openproject that referenced this pull request Jun 29, 2015
Avoid collision with `public` class method. As of Rails 4.1, `public`
is explicitly black-listed as a scope name:
rails/rails#14582
myabc added a commit to myabc/openproject that referenced this pull request Jun 29, 2015
Avoid collision with `public` class method. As of Rails 4.1, `public`
is explicitly black-listed as a scope name:
rails/rails#14582
myabc added a commit to myabc/openproject that referenced this pull request Jun 30, 2015
Avoid collision with `public` class method. As of Rails 4.1, `public`
is explicitly black-listed as a scope name:
rails/rails#14582
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.

None yet

5 participants