提交 b2c42ec3 编写于 作者: C Charlie Somerville

Merge pull request #20 from github/dont-use-ordered-hash

Replace use of OrderedHash with regular hashes
......@@ -261,7 +261,7 @@ def execute_grouped_calculation(operation, column_name, column, options) #:nodoc
key_records = key_records.inject({}) { |hsh, r| hsh.merge(r.id => r) }
end
calculated_data.inject(ActiveSupport::OrderedHash.new) do |all, row|
calculated_data.inject({}) do |all, row|
key = group_aliases.map{|group_alias| type_cast_calculated_value(row[group_alias], group_columns[group_alias])}
key = key.first if key.size == 1
key = key_records[key] if associated
......
......@@ -295,7 +295,7 @@ def empty?
# Removes all errors that have been added.
def clear
@errors = ActiveSupport::OrderedHash.new
@errors = {}
end
# Returns the total number of errors added. Two errors added to the same attribute will be counted as such.
......
......@@ -552,7 +552,7 @@ def test_should_ignore_new_associated_records_if_a_reject_if_proc_returns_false
end
def test_should_sort_the_hash_by_the_keys_before_building_new_associated_models
attributes = ActiveSupport::OrderedHash.new
attributes = {}
attributes['123726353'] = { :name => 'Grace OMalley' }
attributes['2'] = { :name => 'Privateers Greed' } # 2 is lower then 123726353
@pirate.send(association_setter, attributes)
......@@ -562,7 +562,6 @@ def test_should_sort_the_hash_by_the_keys_before_building_new_associated_models
def test_should_raise_an_argument_error_if_something_else_than_a_hash_is_passed
assert_nothing_raised(ArgumentError) { @pirate.send(association_setter, {}) }
assert_nothing_raised(ArgumentError) { @pirate.send(association_setter, ActiveSupport::OrderedHash.new) }
assert_raise_with_message ArgumentError, 'Hash or Array expected, got String ("foo")' do
@pirate.send(association_setter, "foo")
......
require 'active_support/ordered_hash'
module Enumerable
# Ruby 1.8.7 introduces group_by, but the result isn't ordered. Override it.
remove_method(:group_by) if [].respond_to?(:group_by) && RUBY_VERSION < '1.9'
# Collect an enumerable into sets, grouped by the result of a block. Useful,
# for example, for grouping records by date.
#
# Example:
#
# latest_transcripts.group_by(&:day).each do |day, transcripts|
# p "#{day} -> #{transcripts.map(&:class).join(', ')}"
# end
# "2006-03-01 -> Transcript"
# "2006-02-28 -> Transcript"
# "2006-02-27 -> Transcript, Transcript"
# "2006-02-26 -> Transcript, Transcript"
# "2006-02-25 -> Transcript"
# "2006-02-24 -> Transcript, Transcript"
# "2006-02-23 -> Transcript"
def group_by
assoc = ActiveSupport::OrderedHash.new
each do |element|
key = yield(element)
if assoc.has_key?(key)
assoc[key] << element
else
assoc[key] = [element]
end
end
assoc
end unless [].respond_to?(:group_by)
# Calculates a sum from the elements. Examples:
#
# payments.sum { |p| p.price * p.tax_rate }
......@@ -62,26 +28,6 @@ def sum(identity = 0, &block)
end
end
# Iterates over a collection, passing the current element *and* the
# +memo+ to the block. Handy for building up hashes or
# reducing collections down to one object. Examples:
#
# %w(foo bar).each_with_object({}) { |str, hsh| hsh[str] = str.upcase } #=> {'foo' => 'FOO', 'bar' => 'BAR'}
#
# *Note* that you can't use immutable objects like numbers, true or false as
# the memo. You would think the following returns 120, but since the memo is
# never changed, it does not.
#
# (1..5).each_with_object(1) { |value, memo| memo *= value } # => 1
#
def each_with_object(memo, &block)
memo.tap do |m|
each do |element|
block.call(element, m)
end
end
end unless [].respond_to?(:each_with_object)
# Convert an enumerable to a hash. Examples:
#
# people.index_by(&:login)
......@@ -103,15 +49,6 @@ def many?(&block)
size > 1
end
# Returns true if none of the elements match the given block.
#
# success = responses.none? {|r| r.status / 100 == 5 }
#
# This is a builtin method in Ruby 1.8.7 and later.
def none?(&block)
!any?(&block)
end unless [].respond_to?(:none?)
# The negative of the Enumerable#include?. Returns true if the collection does not include the object.
def exclude?(object)
......
require 'yaml'
YAML.add_builtin_type("omap") do |type, val|
ActiveSupport::OrderedHash[val.map(&:to_a).map(&:first)]
end
# OrderedHash is namespaced to prevent conflicts with other implementations
module ActiveSupport
class OrderedHash < ::Hash #:nodoc:
def to_yaml_type
"!tag:yaml.org,2002:omap"
end
def to_yaml(opts = {})
YAML.quick_emit(self, opts) do |out|
out.seq(taguri, to_yaml_style) do |seq|
each do |k, v|
seq.add(k => v)
end
end
end
end
# Hash is ordered in Ruby 1.9!
if RUBY_VERSION < '1.9'
def initialize(*args, &block)
super
@keys = []
end
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 % 2 == 0)
raise ArgumentError.new("odd number of arguments for Hash")
end
args.each_with_index do |val, ind|
next if (ind % 2 != 0)
ordered_hash[val] = args[ind + 1]
end
ordered_hash
end
def initialize_copy(other)
super
# make a deep copy of keys
@keys = other.keys
end
def []=(key, value)
@keys << key if !has_key?(key)
super
end
def delete(key)
if has_key? key
index = @keys.index(key)
@keys.delete_at index
end
super
end
def delete_if
super
sync_keys!
self
end
def reject!
super
sync_keys!
self
end
def reject(&block)
dup.reject!(&block)
end
def keys
@keys.dup
end
def values
@keys.collect { |key| self[key] }
end
def to_hash
self
end
def to_a
@keys.map { |key| [ key, self[key] ] }
end
def each_key
@keys.each { |key| yield key }
end
def each_value
@keys.each { |key| yield self[key]}
end
def each
@keys.each {|key| yield [key, self[key]]}
end
alias_method :each_pair, :each
def clear
super
@keys.clear
self
end
def shift
k = @keys.first
v = delete(k)
[k, v]
end
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
alias_method :update, :merge!
def merge(other_hash, &block)
dup.merge!(other_hash, &block)
end
# When replacing with another hash, the initial order of our keys must come from the other hash -ordered or not.
def replace(other)
super
@keys = other.keys
self
end
def invert
OrderedHash[self.to_a.map!{|key_value_pair| key_value_pair.reverse}]
end
def inspect
"#<OrderedHash #{super}>"
end
private
def sync_keys!
@keys.delete_if {|k| !has_key?(k)}
end
end
end
end
ActiveSupport::OrderedHash = Hash
module ActiveSupport #:nodoc:
class OrderedOptions < OrderedHash #:nodoc:
class OrderedOptions < Hash #:nodoc:
def []=(key, value)
super(key.to_sym, value)
end
......
......@@ -20,7 +20,7 @@ def index
def process(string, current_level=3, counters=[1])
s = StringScanner.new(string)
level_hash = ActiveSupport::OrderedHash.new
level_hash = {}
while !s.eos?
re = %r{^h(\d)(?:\((#.*?)\))?\s*\.\s*(.*)$}
......
......@@ -34,7 +34,7 @@ def self.metals
def initialize(app)
@app = app
@metals = ActiveSupport::OrderedHash.new
@metals = {}
self.class.metals.each { |app| @metals[app] = true }
freeze
end
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册