monetra-ruby 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +35 -0
- data/lib/monetra.rb +239 -0
- data/lib/monetra/active_support.rb +42 -0
- data/lib/monetra/active_support/binding_of_caller.rb +84 -0
- data/lib/monetra/active_support/breakpoint.rb +523 -0
- data/lib/monetra/active_support/caching_tools.rb +62 -0
- data/lib/monetra/active_support/clean_logger.rb +38 -0
- data/lib/monetra/active_support/core_ext.rb +1 -0
- data/lib/monetra/active_support/core_ext/array.rb +7 -0
- data/lib/monetra/active_support/core_ext/array/conversions.rb +72 -0
- data/lib/monetra/active_support/core_ext/array/grouping.rb +46 -0
- data/lib/monetra/active_support/core_ext/bigdecimal.rb +3 -0
- data/lib/monetra/active_support/core_ext/bigdecimal/formatting.rb +7 -0
- data/lib/monetra/active_support/core_ext/blank.rb +50 -0
- data/lib/monetra/active_support/core_ext/cgi.rb +5 -0
- data/lib/monetra/active_support/core_ext/cgi/escape_skipping_slashes.rb +14 -0
- data/lib/monetra/active_support/core_ext/class.rb +3 -0
- data/lib/monetra/active_support/core_ext/class/attribute_accessors.rb +44 -0
- data/lib/monetra/active_support/core_ext/class/inheritable_attributes.rb +115 -0
- data/lib/monetra/active_support/core_ext/class/removal.rb +24 -0
- data/lib/monetra/active_support/core_ext/date.rb +6 -0
- data/lib/monetra/active_support/core_ext/date/conversions.rb +39 -0
- data/lib/monetra/active_support/core_ext/enumerable.rb +62 -0
- data/lib/monetra/active_support/core_ext/exception.rb +33 -0
- data/lib/monetra/active_support/core_ext/hash.rb +13 -0
- data/lib/monetra/active_support/core_ext/hash/conversions.rb +148 -0
- data/lib/monetra/active_support/core_ext/hash/diff.rb +11 -0
- data/lib/monetra/active_support/core_ext/hash/indifferent_access.rb +88 -0
- data/lib/monetra/active_support/core_ext/hash/keys.rb +53 -0
- data/lib/monetra/active_support/core_ext/hash/reverse_merge.rb +25 -0
- data/lib/monetra/active_support/core_ext/integer.rb +7 -0
- data/lib/monetra/active_support/core_ext/integer/even_odd.rb +24 -0
- data/lib/monetra/active_support/core_ext/integer/inflections.rb +15 -0
- data/lib/monetra/active_support/core_ext/kernel.rb +4 -0
- data/lib/monetra/active_support/core_ext/kernel/agnostics.rb +11 -0
- data/lib/monetra/active_support/core_ext/kernel/daemonizing.rb +15 -0
- data/lib/monetra/active_support/core_ext/kernel/reporting.rb +51 -0
- data/lib/monetra/active_support/core_ext/kernel/requires.rb +24 -0
- data/lib/monetra/active_support/core_ext/load_error.rb +38 -0
- data/lib/monetra/active_support/core_ext/logger.rb +16 -0
- data/lib/monetra/active_support/core_ext/module.rb +7 -0
- data/lib/monetra/active_support/core_ext/module/aliasing.rb +57 -0
- data/lib/monetra/active_support/core_ext/module/attr_internal.rb +31 -0
- data/lib/monetra/active_support/core_ext/module/attribute_accessors.rb +44 -0
- data/lib/monetra/active_support/core_ext/module/delegation.rb +41 -0
- data/lib/monetra/active_support/core_ext/module/inclusion.rb +11 -0
- data/lib/monetra/active_support/core_ext/module/introspection.rb +21 -0
- data/lib/monetra/active_support/core_ext/module/loading.rb +13 -0
- data/lib/monetra/active_support/core_ext/name_error.rb +20 -0
- data/lib/monetra/active_support/core_ext/numeric.rb +7 -0
- data/lib/monetra/active_support/core_ext/numeric/bytes.rb +44 -0
- data/lib/monetra/active_support/core_ext/numeric/time.rb +72 -0
- data/lib/monetra/active_support/core_ext/object.rb +2 -0
- data/lib/monetra/active_support/core_ext/object/extending.rb +47 -0
- data/lib/monetra/active_support/core_ext/object/misc.rb +34 -0
- data/lib/monetra/active_support/core_ext/pathname.rb +7 -0
- data/lib/monetra/active_support/core_ext/pathname/clean_within.rb +14 -0
- data/lib/monetra/active_support/core_ext/proc.rb +12 -0
- data/lib/monetra/active_support/core_ext/range.rb +5 -0
- data/lib/monetra/active_support/core_ext/range/conversions.rb +21 -0
- data/lib/monetra/active_support/core_ext/string.rb +13 -0
- data/lib/monetra/active_support/core_ext/string/access.rb +58 -0
- data/lib/monetra/active_support/core_ext/string/conversions.rb +19 -0
- data/lib/monetra/active_support/core_ext/string/inflections.rb +153 -0
- data/lib/monetra/active_support/core_ext/string/iterators.rb +17 -0
- data/lib/monetra/active_support/core_ext/string/starts_ends_with.rb +20 -0
- data/lib/monetra/active_support/core_ext/symbol.rb +12 -0
- data/lib/monetra/active_support/core_ext/time.rb +7 -0
- data/lib/monetra/active_support/core_ext/time/calculations.rb +188 -0
- data/lib/monetra/active_support/core_ext/time/conversions.rb +36 -0
- data/lib/monetra/active_support/dependencies.rb +187 -0
- data/lib/monetra/active_support/deprecation.rb +106 -0
- data/lib/monetra/active_support/inflections.rb +53 -0
- data/lib/monetra/active_support/inflector.rb +179 -0
- data/lib/monetra/active_support/json.rb +37 -0
- data/lib/monetra/active_support/json/encoders.rb +25 -0
- data/lib/monetra/active_support/json/encoders/core.rb +65 -0
- data/lib/monetra/active_support/option_merger.rb +25 -0
- data/lib/monetra/active_support/ordered_options.rb +50 -0
- data/lib/monetra/active_support/reloadable.rb +30 -0
- data/lib/monetra/active_support/values/time_zone.rb +180 -0
- data/lib/monetra/active_support/vendor/builder.rb +13 -0
- data/lib/monetra/active_support/vendor/builder/blankslate.rb +63 -0
- data/lib/monetra/active_support/vendor/builder/xchar.rb +112 -0
- data/lib/monetra/active_support/vendor/builder/xmlbase.rb +145 -0
- data/lib/monetra/active_support/vendor/builder/xmlevents.rb +63 -0
- data/lib/monetra/active_support/vendor/builder/xmlmarkup.rb +328 -0
- data/lib/monetra/active_support/vendor/flexmock.rb +84 -0
- data/lib/monetra/active_support/vendor/xml_simple.rb +1019 -0
- data/lib/monetra/active_support/version.rb +9 -0
- data/lib/monetra/active_support/whiny_nil.rb +38 -0
- data/test/test.rb +21 -0
- metadata +167 -0
@@ -0,0 +1,24 @@
|
|
1
|
+
class Class #:nodoc:
|
2
|
+
def remove_subclasses
|
3
|
+
Object.remove_subclasses_of(self)
|
4
|
+
end
|
5
|
+
|
6
|
+
def subclasses
|
7
|
+
Object.subclasses_of(self).map { |o| o.to_s }
|
8
|
+
end
|
9
|
+
|
10
|
+
def remove_class(*klasses)
|
11
|
+
klasses.flatten.each do |klass|
|
12
|
+
# Skip this class if there is nothing bound to this name
|
13
|
+
next unless defined?(klass.name)
|
14
|
+
|
15
|
+
basename = klass.to_s.split("::").last
|
16
|
+
parent = klass.parent
|
17
|
+
|
18
|
+
# Skip this class if it does not match the current one bound to this name
|
19
|
+
next unless parent.const_defined?(basename) && klass = parent.const_get(basename)
|
20
|
+
|
21
|
+
parent.send :remove_const, basename unless parent == klass
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module ActiveSupport #:nodoc:
|
2
|
+
module CoreExtensions #:nodoc:
|
3
|
+
module Date #:nodoc:
|
4
|
+
# Getting dates in different convenient string representations and other objects
|
5
|
+
module Conversions
|
6
|
+
DATE_FORMATS = {
|
7
|
+
:short => "%e %b",
|
8
|
+
:long => "%B %e, %Y"
|
9
|
+
}
|
10
|
+
|
11
|
+
def self.included(klass) #:nodoc:
|
12
|
+
klass.send(:alias_method, :to_default_s, :to_s)
|
13
|
+
klass.send(:alias_method, :to_s, :to_formatted_s)
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_formatted_s(format = :default)
|
17
|
+
DATE_FORMATS[format] ? strftime(DATE_FORMATS[format]).strip : to_default_s
|
18
|
+
end
|
19
|
+
|
20
|
+
# To be able to keep Dates and Times interchangeable on conversions
|
21
|
+
def to_date
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_time(form = :local)
|
26
|
+
if respond_to?(:hour)
|
27
|
+
::Time.send(form, year, month, day, hour, min, sec)
|
28
|
+
else
|
29
|
+
::Time.send(form, year, month, day)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def xmlschema
|
34
|
+
to_time.xmlschema
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Enumerable #:nodoc:
|
2
|
+
# Collect an enumerable into sets, grouped by the result of a block. Useful,
|
3
|
+
# for example, for grouping records by date.
|
4
|
+
#
|
5
|
+
# e.g.
|
6
|
+
#
|
7
|
+
# latest_transcripts.group_by(&:day).each do |day, transcripts|
|
8
|
+
# p "#{day} -> #{transcripts.map(&:class) * ', '}"
|
9
|
+
# end
|
10
|
+
# "2006-03-01 -> Transcript"
|
11
|
+
# "2006-02-28 -> Transcript"
|
12
|
+
# "2006-02-27 -> Transcript, Transcript"
|
13
|
+
# "2006-02-26 -> Transcript, Transcript"
|
14
|
+
# "2006-02-25 -> Transcript"
|
15
|
+
# "2006-02-24 -> Transcript, Transcript"
|
16
|
+
# "2006-02-23 -> Transcript"
|
17
|
+
def group_by
|
18
|
+
inject({}) do |groups, element|
|
19
|
+
(groups[yield(element)] ||= []) << element
|
20
|
+
groups
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Calculates a sum from the elements. Examples:
|
25
|
+
#
|
26
|
+
# payments.sum { |p| p.price * p.tax_rate }
|
27
|
+
# payments.sum(&:price)
|
28
|
+
#
|
29
|
+
# This is instead of payments.inject { |sum, p| sum + p.price }
|
30
|
+
#
|
31
|
+
# Also calculates sums without the use of a block:
|
32
|
+
# [5, 15, 10].sum # => 30
|
33
|
+
#
|
34
|
+
# The default identity (sum of an empty list) is zero.
|
35
|
+
# However, you can override this default:
|
36
|
+
#
|
37
|
+
# [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)
|
38
|
+
#
|
39
|
+
def sum(identity = 0, &block)
|
40
|
+
return identity unless size > 0
|
41
|
+
if block_given?
|
42
|
+
map(&block).sum
|
43
|
+
else
|
44
|
+
inject { |sum, element| sum + element }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Convert an enumerable to a hash. Examples:
|
49
|
+
#
|
50
|
+
# people.index_by(&:login)
|
51
|
+
# => { "nextangle" => <Person ...>, "chade-" => <Person ...>, ...}
|
52
|
+
# people.index_by { |person| "#{person.first_name} #{person.last_name}" }
|
53
|
+
# => { "Chade- Fowlersburg-e" => <Person ...>, "David Heinemeier Hansson" => <Person ...>, ...}
|
54
|
+
#
|
55
|
+
def index_by
|
56
|
+
inject({}) do |accum, elem|
|
57
|
+
accum[yield(elem)] = elem
|
58
|
+
accum
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class Exception # :nodoc:
|
2
|
+
def clean_message
|
3
|
+
Pathname.clean_within message
|
4
|
+
end
|
5
|
+
|
6
|
+
TraceSubstitutions = []
|
7
|
+
FrameworkRegexp = /generated|vendor|dispatch|ruby|script\/\w+/
|
8
|
+
|
9
|
+
def clean_backtrace
|
10
|
+
backtrace.collect do |line|
|
11
|
+
Pathname.clean_within(TraceSubstitutions.inject(line) do |line, (regexp, sub)|
|
12
|
+
line.gsub regexp, sub
|
13
|
+
end)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def application_backtrace
|
18
|
+
before_application_frame = true
|
19
|
+
|
20
|
+
trace = clean_backtrace.reject do |line|
|
21
|
+
non_app_frame = (line =~ FrameworkRegexp)
|
22
|
+
before_application_frame = false unless non_app_frame
|
23
|
+
non_app_frame && ! before_application_frame
|
24
|
+
end
|
25
|
+
|
26
|
+
# If we didn't find any application frames, return an empty app trace.
|
27
|
+
before_application_frame ? [] : trace
|
28
|
+
end
|
29
|
+
|
30
|
+
def framework_backtrace
|
31
|
+
clean_backtrace.select {|line| line =~ FrameworkRegexp}
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/hash/keys'
|
2
|
+
require File.dirname(__FILE__) + '/hash/indifferent_access'
|
3
|
+
require File.dirname(__FILE__) + '/hash/reverse_merge'
|
4
|
+
require File.dirname(__FILE__) + '/hash/conversions'
|
5
|
+
require File.dirname(__FILE__) + '/hash/diff'
|
6
|
+
|
7
|
+
class Hash #:nodoc:
|
8
|
+
include ActiveSupport::CoreExtensions::Hash::Keys
|
9
|
+
include ActiveSupport::CoreExtensions::Hash::IndifferentAccess
|
10
|
+
include ActiveSupport::CoreExtensions::Hash::ReverseMerge
|
11
|
+
include ActiveSupport::CoreExtensions::Hash::Conversions
|
12
|
+
include ActiveSupport::CoreExtensions::Hash::Diff
|
13
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'xml_simple'
|
3
|
+
|
4
|
+
module ActiveSupport #:nodoc:
|
5
|
+
module CoreExtensions #:nodoc:
|
6
|
+
module Hash #:nodoc:
|
7
|
+
module Conversions
|
8
|
+
XML_TYPE_NAMES = {
|
9
|
+
::Fixnum => "integer",
|
10
|
+
::Float => "float",
|
11
|
+
::Date => "date",
|
12
|
+
::DateTime => "datetime",
|
13
|
+
::Time => "datetime",
|
14
|
+
::TrueClass => "boolean",
|
15
|
+
::FalseClass => "boolean"
|
16
|
+
} unless defined? XML_TYPE_NAMES
|
17
|
+
|
18
|
+
XML_FORMATTING = {
|
19
|
+
"date" => Proc.new { |date| date.to_s(:db) },
|
20
|
+
"datetime" => Proc.new { |time| time.xmlschema },
|
21
|
+
"binary" => Proc.new { |binary| Base64.encode64(binary) }
|
22
|
+
} unless defined? XML_FORMATTING
|
23
|
+
|
24
|
+
def self.included(klass)
|
25
|
+
klass.extend(ClassMethods)
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_xml(options = {})
|
29
|
+
options[:indent] ||= 2
|
30
|
+
options.reverse_merge!({ :builder => Builder::XmlMarkup.new(:indent => options[:indent]),
|
31
|
+
:root => "hash" })
|
32
|
+
options[:builder].instruct! unless options.delete(:skip_instruct)
|
33
|
+
dasherize = !options.has_key?(:dasherize) || options[:dasherize]
|
34
|
+
root = dasherize ? options[:root].to_s.dasherize : options[:root].to_s
|
35
|
+
|
36
|
+
options[:builder].__send__(root) do
|
37
|
+
each do |key, value|
|
38
|
+
case value
|
39
|
+
when ::Hash
|
40
|
+
value.to_xml(options.merge({ :root => key, :skip_instruct => true }))
|
41
|
+
when ::Array
|
42
|
+
value.to_xml(options.merge({ :root => key, :children => key.to_s.singularize, :skip_instruct => true}))
|
43
|
+
when ::Method, ::Proc
|
44
|
+
# If the Method or Proc takes two arguments, then
|
45
|
+
# pass the suggested child element name. This is
|
46
|
+
# used if the Method or Proc will be operating over
|
47
|
+
# multiple records and needs to create an containing
|
48
|
+
# element that will contain the objects being
|
49
|
+
# serialized.
|
50
|
+
if 1 == value.arity
|
51
|
+
value.call(options.merge({ :root => key, :skip_instruct => true }))
|
52
|
+
else
|
53
|
+
value.call(options.merge({ :root => key, :skip_instruct => true }), key.to_s.singularize)
|
54
|
+
end
|
55
|
+
else
|
56
|
+
if value.respond_to?(:to_xml)
|
57
|
+
value.to_xml(options.merge({ :root => key, :skip_instruct => true }))
|
58
|
+
else
|
59
|
+
type_name = XML_TYPE_NAMES[value.class]
|
60
|
+
|
61
|
+
key = dasherize ? key.to_s.dasherize : key.to_s
|
62
|
+
|
63
|
+
attributes = options[:skip_types] || value.nil? || type_name.nil? ? { } : { :type => type_name }
|
64
|
+
if value.nil?
|
65
|
+
attributes[:nil] = true
|
66
|
+
end
|
67
|
+
|
68
|
+
options[:builder].tag!(key,
|
69
|
+
XML_FORMATTING[type_name] ? XML_FORMATTING[type_name].call(value) : value,
|
70
|
+
attributes
|
71
|
+
)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
module ClassMethods
|
80
|
+
def create_from_xml(xml)
|
81
|
+
# TODO: Refactor this into something much cleaner that doesn't rely on XmlSimple
|
82
|
+
undasherize_keys(typecast_xml_value(XmlSimple.xml_in(xml,
|
83
|
+
'forcearray' => false,
|
84
|
+
'forcecontent' => true,
|
85
|
+
'keeproot' => true,
|
86
|
+
'contentkey' => '__content__')
|
87
|
+
))
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
def typecast_xml_value(value)
|
92
|
+
case value.class.to_s
|
93
|
+
when "Hash"
|
94
|
+
if value.has_key?("__content__")
|
95
|
+
content = translate_xml_entities(value["__content__"])
|
96
|
+
case value["type"]
|
97
|
+
when "integer" then content.to_i
|
98
|
+
when "boolean" then content.strip == "true"
|
99
|
+
when "datetime" then ::Time.parse(content).utc
|
100
|
+
when "date" then ::Date.parse(content)
|
101
|
+
else content
|
102
|
+
end
|
103
|
+
else
|
104
|
+
value.empty? || value['nil'] == 'true' ? nil : value.inject({}) do |h,(k,v)|
|
105
|
+
h[k] = typecast_xml_value(v)
|
106
|
+
h
|
107
|
+
end
|
108
|
+
end
|
109
|
+
when "Array"
|
110
|
+
value.map! { |i| typecast_xml_value(i) }
|
111
|
+
case value.length
|
112
|
+
when 0 then nil
|
113
|
+
when 1 then value.first
|
114
|
+
else value
|
115
|
+
end
|
116
|
+
when "String"
|
117
|
+
value
|
118
|
+
else
|
119
|
+
raise "can't typecast #{value.inspect}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def translate_xml_entities(value)
|
124
|
+
value.gsub(/</, "<").
|
125
|
+
gsub(/>/, ">").
|
126
|
+
gsub(/"/, '"').
|
127
|
+
gsub(/'/, "'").
|
128
|
+
gsub(/&/, "&")
|
129
|
+
end
|
130
|
+
|
131
|
+
def undasherize_keys(params)
|
132
|
+
case params.class.to_s
|
133
|
+
when "Hash"
|
134
|
+
params.inject({}) do |h,(k,v)|
|
135
|
+
h[k.to_s.tr("-", "_")] = undasherize_keys(v)
|
136
|
+
h
|
137
|
+
end
|
138
|
+
when "Array"
|
139
|
+
params.map { |v| undasherize_keys(v) }
|
140
|
+
else
|
141
|
+
params
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# this class has dubious semantics and we only have it so that
|
2
|
+
# people can write params[:key] instead of params['key']
|
3
|
+
|
4
|
+
class HashWithIndifferentAccess < Hash
|
5
|
+
def initialize(constructor = {})
|
6
|
+
if constructor.is_a?(Hash)
|
7
|
+
super()
|
8
|
+
update(constructor)
|
9
|
+
else
|
10
|
+
super(constructor)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def default(key = nil)
|
15
|
+
if key.is_a?(Symbol) && include?(key = key.to_s)
|
16
|
+
self[key]
|
17
|
+
else
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
|
23
|
+
alias_method :regular_update, :update unless method_defined?(:regular_update)
|
24
|
+
|
25
|
+
def []=(key, value)
|
26
|
+
regular_writer(convert_key(key), convert_value(value))
|
27
|
+
end
|
28
|
+
|
29
|
+
def update(other_hash)
|
30
|
+
other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
alias_method :merge!, :update
|
35
|
+
|
36
|
+
def key?(key)
|
37
|
+
super(convert_key(key))
|
38
|
+
end
|
39
|
+
|
40
|
+
alias_method :include?, :key?
|
41
|
+
alias_method :has_key?, :key?
|
42
|
+
alias_method :member?, :key?
|
43
|
+
|
44
|
+
def fetch(key, *extras)
|
45
|
+
super(convert_key(key), *extras)
|
46
|
+
end
|
47
|
+
|
48
|
+
def values_at(*indices)
|
49
|
+
indices.collect {|key| self[convert_key(key)]}
|
50
|
+
end
|
51
|
+
|
52
|
+
def dup
|
53
|
+
HashWithIndifferentAccess.new(self)
|
54
|
+
end
|
55
|
+
|
56
|
+
def merge(hash)
|
57
|
+
self.dup.update(hash)
|
58
|
+
end
|
59
|
+
|
60
|
+
def delete(key)
|
61
|
+
super(convert_key(key))
|
62
|
+
end
|
63
|
+
|
64
|
+
def stringify_keys!; self end
|
65
|
+
def symbolize_keys!; self end
|
66
|
+
|
67
|
+
protected
|
68
|
+
def convert_key(key)
|
69
|
+
key.kind_of?(Symbol) ? key.to_s : key
|
70
|
+
end
|
71
|
+
def convert_value(value)
|
72
|
+
value.is_a?(Hash) ? value.with_indifferent_access : value
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
module ActiveSupport #:nodoc:
|
77
|
+
module CoreExtensions #:nodoc:
|
78
|
+
module Hash #:nodoc:
|
79
|
+
module IndifferentAccess #:nodoc:
|
80
|
+
def with_indifferent_access
|
81
|
+
hash = HashWithIndifferentAccess.new(self)
|
82
|
+
hash.default = self.default
|
83
|
+
hash
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module ActiveSupport #:nodoc:
|
2
|
+
module CoreExtensions #:nodoc:
|
3
|
+
module Hash #:nodoc:
|
4
|
+
module Keys
|
5
|
+
# Return a new hash with all keys converted to strings.
|
6
|
+
def stringify_keys
|
7
|
+
inject({}) do |options, (key, value)|
|
8
|
+
options[key.to_s] = value
|
9
|
+
options
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Destructively convert all keys to strings.
|
14
|
+
def stringify_keys!
|
15
|
+
keys.each do |key|
|
16
|
+
unless key.class.to_s == "String" # weird hack to make the tests run when string_ext_test.rb is also running
|
17
|
+
self[key.to_s] = self[key]
|
18
|
+
delete(key)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
# Return a new hash with all keys converted to symbols.
|
25
|
+
def symbolize_keys
|
26
|
+
inject({}) do |options, (key, value)|
|
27
|
+
options[key.to_sym] = value
|
28
|
+
options
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Destructively convert all keys to symbols.
|
33
|
+
def symbolize_keys!
|
34
|
+
keys.each do |key|
|
35
|
+
unless key.is_a?(Symbol)
|
36
|
+
self[key.to_sym] = self[key]
|
37
|
+
delete(key)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
alias_method :to_options, :symbolize_keys
|
44
|
+
alias_method :to_options!, :symbolize_keys!
|
45
|
+
|
46
|
+
def assert_valid_keys(*valid_keys)
|
47
|
+
unknown_keys = keys - [valid_keys].flatten
|
48
|
+
raise(ArgumentError, "Unknown key(s): #{unknown_keys.join(", ")}") unless unknown_keys.empty?
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|