-
Notifications
You must be signed in to change notification settings - Fork 21.8k
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
Eagerload active_support/json/encoding in active_support/core_ext/object/to_json #12203
Conversation
By the way, I can squash the commits if preferred, but since they are not really related I think it's better to keep the isolated. |
/cc @steveklabnik in case you have any objections |
@@ -1,8 +1,8 @@ | |||
# The core extentions for JSON encoding are definied here. |
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.
typo: defined
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.
Oops, fixed, thanks!
Any way to test this? |
I was thinking really hard about this and I couldn't come up with any good ideas, any hints? :P I have some ideas that might work when the test file is run in isolation, but I'm not sure if there are any good ways to test this as part of the suite without relying the order the tests are run/loaded. |
TL;DR The primary driver is to remove autoload surprise. This is related to rails#12106. (The root cause for that ticket is that json/add defines Regexp#to_json among others, but here I'll reproduce the problem without json/add.) Before: >> require 'active_support/core_ext/to_json' => true >> //.as_json NoMethodError: undefined method `as_json' for //:Regexp from (irb):3 from /Users/godfrey/.rvm/rubies/ruby-2.0.0-p195/bin/irb:16:in `<main>' >> //.to_json => "\"(?-mix:)\"" >> //.as_json => "(?-mix:)" After: >> require 'active_support/core_ext/to_json' => true >> //.as_json => "(?-mix:)" This is because ActiveSupport::JSON is autoloaded the first time Object#to_json is called, which causes additional core extentions (previously defined in active_support/json/encoding.rb) to be loaded. When someone require 'active_support/core_ext', the expectation is that it would add certain methods to the core classes NOW. The previous behaviour causes additional methods to be loaded the first time you call `to_json`, which could cause nasty surprises and other unplesant side-effects. This change moves all core extensions in to core_ext/json. AS::JSON is still autoloaded on first #to_json call, but since it nolonger include the core extensions, it should address the aforementioned bug. *Requiring core_ext/object/to_json now causes a deprecation warnning*
Sorry @jeremy, I changed my mind again – the final solution I proposed in the inline notes seems like the safest and cleanest solution to fix this, and on second thought the distinction between With this change, chance of regressing on this same issue seems pretty slim, so I removed the test. If we want to backport this (I think the bug might be worth fixing in other branches), we can probably just do the same thing minus the deprecation warning. I just didn't feel too good about silencing the circular require warning as I'm unsure of the impact. This should be ready for merge barring any extra feedback 👍 |
Eagerload active_support/json/encoding in active_support/core_ext/object/to_json
In rails#12203, the JSON core extensions were moved into the `core_ext` folder. Unfortunately, there are some corresponding requires that were left behind. The problem is partially addressed in rails#12710, this commit fixes the rest.
`Time#as_json`, `Date#as_json` and `DateTime#as_json` incorrectly depends on a delegation that is set up in `active_support/json/encoding`. We cannot simply require that file in `core_ext/object/json` because it would cause a circular dependency problem (see #12203 for background). We should instead rely on AS's autoload to load that file for us on-demand. To trigger autoload correctly, we need to reference the `AS::JSON::Encoding` constant instead of using the delegated version. Fixes #16131.
`Time#as_json`, `Date#as_json` and `DateTime#as_json` incorrectly depends on a delegation that is set up in `active_support/json/encoding`. We cannot simply require that file in `core_ext/object/json` because it would cause a circular dependency problem (see #12203 for background). We should instead rely on AS's autoload to load that file for us on-demand. To trigger autoload correctly, we need to reference the `AS::JSON::Encoding` constant instead of using the delegated version. Fixes #16131.
`Time#as_json`, `Date#as_json` and `DateTime#as_json` incorrectly depends on a delegation that is set up in `active_support/json/encoding`. We cannot simply require that file in `core_ext/object/json` because it would cause a circular dependency problem (see #12203 for background). We should instead rely on AS's autoload to load that file for us on-demand. To trigger autoload correctly, we need to reference the `AS::JSON::Encoding` constant instead of using the delegated version. Fixes #16131.
`Time#as_json`, `Date#as_json` and `DateTime#as_json` incorrectly depends on a delegation that is set up in `active_support/json/encoding`. We cannot simply require that file in `core_ext/object/json` because it would cause a circular dependency problem (see #12203 for background). We should instead rely on AS's autoload to load that file for us on-demand. To trigger autoload correctly, we need to reference the `AS::JSON::Encoding` constant instead of using the delegated version. Fixes #16131.
This is related to #12106. (The root cause for that ticket is that json/add defines Regexp#to_json among others, but here I'll reproduce the problem without json/add.)
Before:
After:
When someone require 'active_support/core_ext', the expectation is that it would add certain methods to the core classes NOW. The previous behaviour causes additional methods to be loaded the first time you call
to_json
, which could cause nasty surprises.