# 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