-
Notifications
You must be signed in to change notification settings - Fork 2.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
IndifferentHash improvements #1427
Conversation
Hrrm, it doesn't like ActiveSupport's hash extensions, which get pulled in by RABL during testing. I'll look into it. |
@mwpastore Broken test was fixed in #1425. Please rebase these commits. |
@namusyaka Hmm, not quite. |
This is due to the method defined by We can avoid the failure by patching temporary workaround: diff --git a/lib/sinatra/indifferent_hash.rb b/lib/sinatra/indifferent_hash.rb
index bf94f4e1..38427f05 100644
--- a/lib/sinatra/indifferent_hash.rb
+++ b/lib/sinatra/indifferent_hash.rb
@@ -164,7 +164,7 @@ module Sinatra
def transform_keys!
super
- super(&method(:convert_key))
+ IndifferentHash[super(&method(:convert_key))]
end
end
diff --git a/test/indifferent_hash_test.rb b/test/indifferent_hash_test.rb
index a22d33ee..0a7ed94b 100644
--- a/test/indifferent_hash_test.rb
+++ b/test/indifferent_hash_test.rb
@@ -4,6 +4,7 @@
#
require 'minitest/autorun' unless defined?(Minitest)
+require 'active_support/core_ext/hash/conversions'
require_relative '../lib/sinatra/indifferent_hash'
class TestIndifferentHashBasics < Minitest::Test However, I don't like the temporary patch. If you have any better solution, please write up or send pull request. I'm going to re-visit this issue next week. |
Disregard my last comment. Whether we remove ActiveSupport or not, we still need to make IndifferentHash work when active_support/core_ext/hash is loaded. Let me make another run at it. |
I don't think that's correct. Sinatra::IndifferentHash#transform_keys(!) never calls Hash#transform_keys; it only ever calls Hash#transform_keys!. By design. irb(main):003:0> require 'active_support/core_ext/hash/conversions'
=> true
irb(main):004:0> foo = Sinatra::IndifferentHash.new
=> {}
irb(main):005:0> foo['bar'] = 'qux'
=> "qux"
irb(main):009:0> foo.transform_keys!(&:upcase).class
=> Sinatra::IndifferentHash
irb(main):008:0> foo.transform_keys(&:upcase).class
=> Sinatra::IndifferentHash This is without your patch above. |
The problem is that Sinatra::IndifferentHash is being loaded before active_support/core_ext/hash when the full test suite is run under Ruby <2.5. It doesn't think Hash#transform_keys! is defined, so it doesn't attempt to redefine its behavior. At runtime, however, the method is there (on Sinatra::IndifferentHash's ancestor(s)), so it uses that without the indifferent access tweaks. Fixing it "correctly" for both the test suite and production use would require some foreknowledge of whether or not active_support/core_ext/hash either has been or will be loaded in the current Ruby process. This issue extends to other Hash methods that active_support/core_ext/hash backports to older Rubies (so it's not restricted to just e.g. active_support/core_ext/hash/keys or active_support/core_ext/hash/conversions). Here's a list of solutions and workarounds and why they're bad:
Hopefully there's an option I'm overlooking. If not, I think the best approach is a hybrid of 4 and 3 above: we preemptively load active_support/core_ext/hash in the test suite, and print a warning on boot if ActiveSupport is present in
Let me know your thoughts. |
The 3 + 4 hybrid plan seems to be good. |
Specifically, between ActiveSupport's core extensions to Hash and our own IndifferentHash class.
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.
Looks good to me.
## 2.0.4 / 2018-09-15 * Don't blow up when passing frozen string to `send_file` disposition [#1137](sinatra/sinatra#1137) by Andrew Selder * Fix ubygems LoadError [#1436](sinatra/sinatra#1436) by Pavel Rosick�«ò * Unescape regex captures [#1446](sinatra/sinatra#1446) by Jordan Owens * Slight performance improvements for IndifferentHash [#1427](sinatra/sinatra#1427) by Mike Pastore * Improve development support and documentation and source code by Will Yang, Jake Craige, Grey Baker and Guilherme Goettems Schneider ## 2.0.3 / 2018-06-09 * Fix the backports gem regression [#1442](sinatra/sinatra#1442) by Marc-Andr�«± Lafortune ## 2.0.2 / 2018-06-05 * Escape invalid query parameters [#1432](sinatra/sinatra#1432) by Kunpei Sakai * The patch fixes [CVE-2018-11627](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-11627). * Fix undefined method error for `Sinatra::RequiredParams` with hash key [#1431](sinatra/sinatra#1431) by Arpit Chauhan * Add xml content-types to valid html_types for Rack::Protection [#1413](sinatra/sinatra#1413) by Reenan Arbitrario * Encode route parameters using :default_encoding setting [#1412](sinatra/sinatra#1412) by Brian m. Carlson * Fix unpredictable behaviour from Sinatra::ConfigFile [#1244](sinatra/sinatra#1244) by John Hope * Add Sinatra::IndifferentHash#slice [#1405](sinatra/sinatra#1405) by Shota Iguchi * Remove status code 205 from drop body response [#1398](sinatra/sinatra#1398) by Shota Iguchi * Ignore empty captures from params [#1390](sinatra/sinatra#1390) by Shota Iguchi * Improve development support and documentation and source code by Zp Yuan, Andreas Finger, Olle Jonsson, Shota Iguchi, Nikita Bulai and Joshua O'Brien
No description provided.