Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

OrderedHash#invert returns an unordered hash

#4875

ActiveSupport::OrderedHash#invert will return an hash of indeterminate order, which is inconsistent with Ruby 1.9.

>> a = {"foo" => "FOO", "bar" => "BAR", "baz" => "BAZ"}
=> {"baz"=>"BAZ", "foo"=>"FOO", "bar"=>"BAR"}
>> b = ActiveSupport::OrderedHash[[["foo", "FOO"], ["bar", "BAR"], ["baz", "BAZ"]]]
=> #<OrderedHash {"baz"=>"BAZ", "foo"=>"FOO", "bar"=>"BAR"}>
>> a.keys
=> ["baz", "foo", "bar"]
>> b.keys
=> ["foo", "bar", "baz"]
>> a.invert
=> {"BAZ"=>"baz", "FOO"=>"foo", "BAR"=>"bar"}
>> b.invert
=> {"BAZ"=>"baz", "FOO"=>"foo", "BAR"=>"bar"}
>> a.invert.invert
=> {"baz"=>"BAZ", "foo"=>"FOO", "bar"=>"BAR"}
>> b.invert.invert
=> {"baz"=>"BAZ", "foo"=>"FOO", "bar"=>"BAR"}

Reported by Chris Griego · June 16th, 2010 @ 08:36 PM

State: resolved
Milestone: 3.0.2
Assigned to: José Valim José Valim
Importance: Low

Activity

  1. chaitanyav
    chaitanyav

    It's working correctly

    neo@myhost awesome]$ irb
    irb(main):001:0> require 'active_support'
    => true
    irb(main):002:0> a = ActiveSupport::OrderedHash.new
    => {}
    irb(main):003:0> a["1"] = 2
    => 2
    irb(main):004:0> a["3"] = 4
    => 4
    irb(main):005:0> a["5"] = 6
    => 6
    irb(main):006:0> a
    => {"1"=>2, "3"=>4, "5"=>6}
    irb(main):007:0> a.class
    => ActiveSupport::OrderedHash
    irb(main):008:0> a.invert
    => {2=>"1", 4=>"3", 6=>"5"}
    irb(main):009:0> a.invert.invert
    => {"1"=>2, "3"=>4, "5"=>6}
    
    rb(main):010:0> b = Hash.new
    => {}
    irb(main):011:0> b["1"] = 2
    => 2
    irb(main):012:0> b["3"] = 4
    => 4
    irb(main):013:0> b["5"] = 6
    => 6
    irb(main):014:0> b
    => {"1"=>2, "3"=>4, "5"=>6}
    irb(main):015:0> b.invert.invert
    => {"1"=>2, "3"=>4, "5"=>6}
    

    BTW, I am using Ruby 1.9.2 and Rails 3 Beta 4

    Edited by Rohit Arondekar for formating.

    June 26th, 2010 @ 06:22 AM

  2. chaitanyav
    chaitanyav
    • No changes were found…

    June 26th, 2010 @ 06:23 AM

  3. chaitanyav
    chaitanyav

    Also checked it your example.

    irb(main):022:0> b = ActiveSupport::OrderedHash[[["foo", "FOO"], ["bar", "BAR"], ["baz", "BAZ"]]]
    => {"foo"=>"FOO", "bar"=>"BAR", "baz"=>"BAZ"}
    irb(main):023:0> a = {"foo" => "FOO", "bar" => "BAR", "baz" => "BAZ"}
    => {"foo"=>"FOO", "bar"=>"BAR", "baz"=>"BAZ"}
    irb(main):024:0> a.invert.invert
    => {"foo"=>"FOO", "bar"=>"BAR", "baz"=>"BAZ"}
    irb(main):025:0> b.invert.invert
    => {"foo"=>"FOO", "bar"=>"BAR", "baz"=>"BAZ"}
    irb(main):026:0>
    

    It works as intended.

    June 26th, 2010 @ 06:29 AM

  4. Chris Griego
    Chris Griego

    Hashes in Ruby 1.9 are ordered by default and ActiveSupport::OrderedHash simply inherits its ordered behavior from Hash when the Ruby version is >= 1.9. ActiveSupport::OrderedHash exists to support ordered behavior in Ruby 1.8.

    June 26th, 2010 @ 06:40 AM

  5. chaitanyav
    chaitanyav

    Chris the instance method invert returns a new Hash,

    In Ruby 1.9 since the ordering is preserved in Hash, it wont matter. But the 'invert' method needs to be overridden in OrderedHash for Ruby 1.8

    irb(main):003:0> a = ActiveSupport::OrderedHash.new
    => {}
    irb(main):004:0> a["1"] = 2
    => 2
    irb(main):005:0> a["3"] = 4
    => 4
    irb(main):006:0> a
    => {"1"=>2, "3"=>4}
    irb(main):007:0> a.class
    => ActiveSupport::OrderedHash
    irb(main):008:0> a.invert.class
    => Hash
    

    June 26th, 2010 @ 07:53 AM

  6. Rohit Arondekar
    Rohit Arondekar
    • Importance changed from to Low

    chaitanyav, I've edited your posts for formating. Please wrap code/console output like things in @@@. See http://help.lighthouseapp.com/faqs/getting-started/how-do-i-format-... for more information.

    June 26th, 2010 @ 07:59 AM

  7. Rohit Arondekar
    Rohit Arondekar
    • State changed from new to incomplete
    • Milestone cleared.

    Can one of you start working on a patch with tests?

    June 26th, 2010 @ 08:04 AM

  8. chaitanyav
  9. Rohit Arondekar
    Rohit Arondekar
    • Tag changed from activesupport, orderedhash to activesupport, orderedhash, patch
    • State changed from incomplete to verified
    • Assigned user set to José Valim

    +1 Applies cleanly & tests pass.

    June 26th, 2010 @ 11:03 AM

  10. Repository
  11. Repository
    Repository
    • State changed from verified to resolved

    (from [aa48ab05f40788bd9f54124f91b0ad86869a7b06]) Tidy up tests in previous commit since they did not assure an OrderedHash is returned (the test would pass for an array and would pass by chance for hashes).

    [#4875 OrderedHash#invert returns an unordered hash state:resolved] http://github.com/rails/rails/commit/aa48ab05f40788bd9f54124f91b0ad...

    June 26th, 2010 @ 11:11 AM

  12. Chris Griego
    Chris Griego

    Thanks chaitanyav for the patch!

    José Valim, the three commits also apply cleanly to the 2-3-stable branch with passing tests. Would you backport them?

    June 26th, 2010 @ 04:00 PM

  13. José Valim
    José Valim

    Chris, how are you applying the commits? Using git cherry-pick? For some reason, it's creating conflicts here.

    June 26th, 2010 @ 04:46 PM

  14. Chris Griego
    Chris Griego

    I was using cherry-pick. I just tried chaitanyav's patch file and that applied cleanly as well for me.

    June 26th, 2010 @ 04:57 PM

  15. Repository
    Repository

    (from [0e9190c902d075c70e2f54096ae55476ed47b6a3]) Tidy up tests in previous commit since they did not assure an OrderedHash is returned (the test would pass for an array and would pass by chance for hashes).

    [#4875 OrderedHash#invert returns an unordered hash state:resolved] http://github.com/rails/rails/commit/0e9190c902d075c70e2f54096ae554...

    June 26th, 2010 @ 05:17 PM

  16. Jeremy Kemper