Parent

Class Index [+]

Quicksearch

ActiveSupport::OrderedHash

The order of iteration over hashes in Ruby 1.8 is undefined. For example, you do not know the order in which keys will return keys, or each yield pairs. ActiveSupport::OrderedHash implements a hash that preserves insertion order, as in Ruby 1.9:

  oh = ActiveSupport::OrderedHash.new
  oh[:a] = 1
  oh[:b] = 2
  oh.keys # => [:a, :b], this order is guaranteed

ActiveSupport::OrderedHash is namespaced to prevent conflicts with other implementations.

Public Class Methods

[](*args) click to toggle source
    # File lib/active_support/ordered_hash.rb, line 73
73:       def self.[](*args)
74:         ordered_hash = new
75: 
76:         if (args.length == 1 && args.first.is_a?(Array))
77:           args.first.each do |key_value_pair|
78:             next unless (key_value_pair.is_a?(Array))
79:             ordered_hash[key_value_pair[0]] = key_value_pair[1]
80:           end
81: 
82:           return ordered_hash
83:         end
84: 
85:         unless (args.size % 2 == 0)
86:           raise ArgumentError.new("odd number of arguments for Hash")
87:         end
88: 
89:         args.each_with_index do |val, ind|
90:           next if (ind % 2 != 0)
91:           ordered_hash[val] = args[ind + 1]
92:         end
93: 
94:         ordered_hash
95:       end
new(*args, &block) click to toggle source

In MRI the Hash class is core and written in C. In particular, methods are programmed with explicit C function calls and polymorphism is not honored.

For example, []= is crucial in this implementation to maintain the @keys array but hash.c invokes rb_hash_aset() originally. This prevents method reuse through inheritance and forces us to reimplement stuff.

For instance, we cannot use the inherited # because albeit the algorithm itself would work, our []= is not being called at all by the C code.

    # File lib/active_support/ordered_hash.rb, line 68
68:       def initialize(*args, &block)
69:         super
70:         @keys = []
71:       end

Public Instance Methods

[]=(key, value) click to toggle source
     # File lib/active_support/ordered_hash.rb, line 103
103:       def []=(key, value)
104:         @keys << key unless has_key?(key)
105:         super
106:       end
clear() click to toggle source
     # File lib/active_support/ordered_hash.rb, line 174
174:       def clear
175:         super
176:         @keys.clear
177:         self
178:       end
delete(key) click to toggle source
     # File lib/active_support/ordered_hash.rb, line 108
108:       def delete(key)
109:         if has_key? key
110:           index = @keys.index(key)
111:           @keys.delete_at index
112:         end
113:         super
114:       end
delete_if() click to toggle source
     # File lib/active_support/ordered_hash.rb, line 116
116:       def delete_if
117:         super
118:         sync_keys!
119:         self
120:       end
each() click to toggle source
     # File lib/active_support/ordered_hash.rb, line 160
160:       def each
161:         return to_enum(:each) unless block_given?
162:         @keys.each {|key| yield [key, self[key]]}
163:         self
164:       end
each_key() click to toggle source
     # File lib/active_support/ordered_hash.rb, line 148
148:       def each_key
149:         return to_enum(:each_key) unless block_given?
150:         @keys.each { |key| yield key }
151:         self
152:       end
each_pair() click to toggle source
     # File lib/active_support/ordered_hash.rb, line 166
166:       def each_pair
167:         return to_enum(:each_pair) unless block_given?
168:         @keys.each {|key| yield key, self[key]}
169:         self
170:       end
each_value() click to toggle source
     # File lib/active_support/ordered_hash.rb, line 154
154:       def each_value
155:         return to_enum(:each_value) unless block_given?
156:         @keys.each { |key| yield self[key]}
157:         self
158:       end
encode_with(coder) click to toggle source
    # File lib/active_support/ordered_hash.rb, line 28
28:     def encode_with(coder)
29:       coder.represent_seq '!omap', map { |k,v| { k => v } }
30:     end
extractable_options?() click to toggle source

Returns true to make sure that this hash is extractable via Array#extract_options!

    # File lib/active_support/ordered_hash.rb, line 51
51:     def extractable_options?
52:       true
53:     end
initialize_copy(other) click to toggle source
     # File lib/active_support/ordered_hash.rb, line 97
 97:       def initialize_copy(other)
 98:         super
 99:         # make a deep copy of keys
100:         @keys = other.keys
101:       end
inspect() click to toggle source
     # File lib/active_support/ordered_hash.rb, line 212
212:       def inspect
213:         "#<OrderedHash #{super}>"
214:       end
invert() click to toggle source
     # File lib/active_support/ordered_hash.rb, line 208
208:       def invert
209:         OrderedHash[self.to_a.map!{|key_value_pair| key_value_pair.reverse}]
210:       end
keys() click to toggle source
     # File lib/active_support/ordered_hash.rb, line 132
132:       def keys
133:         @keys.dup
134:       end
merge(other_hash, &block) click to toggle source
     # File lib/active_support/ordered_hash.rb, line 197
197:       def merge(other_hash, &block)
198:         dup.merge!(other_hash, &block)
199:       end
merge!(other_hash) click to toggle source
     # File lib/active_support/ordered_hash.rb, line 186
186:       def merge!(other_hash)
187:         if block_given?
188:           other_hash.each { |k, v| self[k] = key?(k) ? yield(k, self[k], v) : v }
189:         else
190:           other_hash.each { |k, v| self[k] = v }
191:         end
192:         self
193:       end
nested_under_indifferent_access() click to toggle source
    # File lib/active_support/ordered_hash.rb, line 46
46:     def nested_under_indifferent_access
47:       self
48:     end
reject(&block) click to toggle source
     # File lib/active_support/ordered_hash.rb, line 128
128:       def reject(&block)
129:         dup.reject!(&block)
130:       end
reject!() click to toggle source
     # File lib/active_support/ordered_hash.rb, line 122
122:       def reject!
123:         super
124:         sync_keys!
125:         self
126:       end
replace(other) click to toggle source

When replacing with another hash, the initial order of our keys must come from the other hash -ordered or not.

     # File lib/active_support/ordered_hash.rb, line 202
202:       def replace(other)
203:         super
204:         @keys = other.keys
205:         self
206:       end
shift() click to toggle source
     # File lib/active_support/ordered_hash.rb, line 180
180:       def shift
181:         k = @keys.first
182:         v = delete(k)
183:         [k, v]
184:       end
sync_keys!() click to toggle source
     # File lib/active_support/ordered_hash.rb, line 217
217:         def sync_keys!
218:           @keys.delete_if {|k| !has_key?(k)}
219:         end
to_a() click to toggle source
     # File lib/active_support/ordered_hash.rb, line 144
144:       def to_a
145:         @keys.map { |key| [ key, self[key] ] }
146:       end
to_hash() click to toggle source
     # File lib/active_support/ordered_hash.rb, line 140
140:       def to_hash
141:         self
142:       end
to_yaml(opts = {}) click to toggle source
    # File lib/active_support/ordered_hash.rb, line 32
32:     def to_yaml(opts = {})
33:       if YAML.const_defined?(:ENGINE) && !YAML::ENGINE.syck?
34:         return super
35:       end
36: 
37:       YAML.quick_emit(self, opts) do |out|
38:         out.seq(taguri) do |seq|
39:           each do |k, v|
40:             seq.add(k => v)
41:           end
42:         end
43:       end
44:     end
to_yaml_type() click to toggle source
    # File lib/active_support/ordered_hash.rb, line 24
24:     def to_yaml_type
25:       "!tag:yaml.org,2002:omap"
26:     end
values() click to toggle source
     # File lib/active_support/ordered_hash.rb, line 136
136:       def values
137:         @keys.collect { |key| self[key] }
138:       end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.