class OrderedHash

This class was copied from an old version of ActiveSupport.

Public Class Methods

[](*args) click to toggle source
# File lib/sass/util/ordered_hash.rb, line 39
def self.[](*args)
  ordered_hash = new

  if args.length == 1 && args.first.is_a?(Array)
    args.first.each do |key_value_pair|
      next unless key_value_pair.is_a?(Array)
      ordered_hash[key_value_pair[0]] = key_value_pair[1]
    end

    return ordered_hash
  end

  unless args.size.even?
    raise ArgumentError.new("odd number of arguments for Hash")
  end

  args.each_with_index do |val, ind|
    next if ind.odd?
    ordered_hash[val] = args[ind + 1]
  end

  ordered_hash
end
new(*args) 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 merge! because albeit the algorithm itself would work, our []= is not being called at all by the C code.

Calls superclass method
# File lib/sass/util/ordered_hash.rb, line 34
def initialize(*args)
  super
  @keys = []
end

Public Instance Methods

[]=(key, value) click to toggle source
Calls superclass method
# File lib/sass/util/ordered_hash.rb, line 69
def []=(key, value)
  @keys << key unless has_key?(key)
  super
end
clear() click to toggle source
Calls superclass method
# File lib/sass/util/ordered_hash.rb, line 140
def clear
  super
  @keys.clear
  self
end
delete(key) click to toggle source
Calls superclass method
# File lib/sass/util/ordered_hash.rb, line 74
def delete(key)
  if has_key? key
    index = @keys.index(key)
    @keys.delete_at index
  end
  super
end
delete_if() click to toggle source
Calls superclass method
# File lib/sass/util/ordered_hash.rb, line 82
def delete_if
  super
  sync_keys!
  self
end
each() { |key, self| ... } click to toggle source
# File lib/sass/util/ordered_hash.rb, line 126
def each
  return to_enum(:each) unless block_given?
  @keys.each {|key| yield [key, self[key]]}
  self
end
each_key() { |key| ... } click to toggle source
# File lib/sass/util/ordered_hash.rb, line 114
def each_key
  return to_enum(:each_key) unless block_given?
  @keys.each {|key| yield key}
  self
end
each_pair() { |key, self| ... } click to toggle source
# File lib/sass/util/ordered_hash.rb, line 132
def each_pair
  return to_enum(:each_pair) unless block_given?
  @keys.each {|key| yield key, self[key]}
  self
end
each_value() { |self| ... } click to toggle source
# File lib/sass/util/ordered_hash.rb, line 120
def each_value
  return to_enum(:each_value) unless block_given?
  @keys.each {|key| yield self[key]}
  self
end
initialize_copy(other) click to toggle source
Calls superclass method
# File lib/sass/util/ordered_hash.rb, line 63
def initialize_copy(other)
  super
  # make a deep copy of keys
  @keys = other.keys
end
inspect() click to toggle source
# File lib/sass/util/ordered_hash.rb, line 183
def inspect
  "#<OrderedHash #{super}>"
end
invert() click to toggle source
# File lib/sass/util/ordered_hash.rb, line 179
def invert
  OrderedHash[to_a.map! {|key_value_pair| key_value_pair.reverse}]
end
keys() click to toggle source
# File lib/sass/util/ordered_hash.rb, line 98
def keys
  @keys.dup
end
merge(other_hash) { |k, v1, v2| ... } click to toggle source
# File lib/sass/util/ordered_hash.rb, line 163
def merge(other_hash)
  if block_given?
    dup.merge!(other_hash) {|k, v1, v2| yield k, v1, v2}
  else
    dup.merge!(other_hash)
  end
end
merge!(other_hash) { |k, self, v| ... } click to toggle source
# File lib/sass/util/ordered_hash.rb, line 152
def merge!(other_hash)
  if block_given?
    other_hash.each {|k, v| self[k] = key?(k) ? yield(k, self[k], v) : v}
  else
    other_hash.each {|k, v| self[k] = v}
  end
  self
end
Also aliased as: update
reject() { |h, k| ... } click to toggle source
# File lib/sass/util/ordered_hash.rb, line 94
def reject
  dup.reject! {|h, k| yield h, k}
end
reject!() click to toggle source
Calls superclass method
# File lib/sass/util/ordered_hash.rb, line 88
def reject!
  super
  sync_keys!
  self
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.

Calls superclass method
# File lib/sass/util/ordered_hash.rb, line 173
def replace(other)
  super
  @keys = other.keys
  self
end
shift() click to toggle source
# File lib/sass/util/ordered_hash.rb, line 146
def shift
  k = @keys.first
  v = delete(k)
  [k, v]
end
to_a() click to toggle source
# File lib/sass/util/ordered_hash.rb, line 110
def to_a
  @keys.map {|key| [key, self[key]]}
end
to_hash() click to toggle source
# File lib/sass/util/ordered_hash.rb, line 106
def to_hash
  self
end
update(other_hash)
Alias for: merge!
values() click to toggle source
# File lib/sass/util/ordered_hash.rb, line 102
def values
  @keys.map {|key| self[key]}
end

Private Instance Methods

sync_keys!() click to toggle source
# File lib/sass/util/ordered_hash.rb, line 189
def sync_keys!
  @keys.delete_if {|k| !has_key?(k)}
end