activesupport 3.2.22.5 → 4.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +325 -136
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -2
- data/lib/active_support.rb +8 -21
- data/lib/active_support/backtrace_cleaner.rb +33 -25
- data/lib/active_support/basic_object.rb +7 -17
- data/lib/active_support/benchmarkable.rb +19 -15
- data/lib/active_support/buffered_logger.rb +9 -113
- data/lib/active_support/cache.rb +203 -171
- data/lib/active_support/cache/file_store.rb +12 -12
- data/lib/active_support/cache/mem_cache_store.rb +24 -30
- data/lib/active_support/cache/memory_store.rb +2 -0
- data/lib/active_support/callbacks.rb +195 -247
- data/lib/active_support/concern.rb +16 -23
- data/lib/active_support/concurrency/latch.rb +27 -0
- data/lib/active_support/configurable.rb +69 -12
- data/lib/active_support/core_ext.rb +1 -0
- data/lib/active_support/core_ext/array.rb +0 -1
- data/lib/active_support/core_ext/array/access.rb +17 -9
- data/lib/active_support/core_ext/array/conversions.rb +113 -55
- data/lib/active_support/core_ext/array/extract_options.rb +2 -2
- data/lib/active_support/core_ext/array/grouping.rb +21 -22
- data/lib/active_support/core_ext/array/uniq_by.rb +12 -9
- data/lib/active_support/core_ext/array/wrap.rb +11 -14
- data/lib/active_support/core_ext/big_decimal/conversions.rb +7 -24
- data/lib/active_support/core_ext/class/attribute.rb +12 -8
- data/lib/active_support/core_ext/class/attribute_accessors.rb +14 -12
- data/lib/active_support/core_ext/class/delegating_attributes.rb +15 -19
- data/lib/active_support/core_ext/class/subclasses.rb +11 -5
- data/lib/active_support/core_ext/date.rb +6 -0
- data/lib/active_support/core_ext/date/calculations.rb +34 -188
- data/lib/active_support/core_ext/date/conversions.rb +16 -38
- data/lib/active_support/core_ext/date/infinite_comparable.rb +5 -0
- data/lib/active_support/core_ext/date/zones.rb +25 -2
- data/lib/active_support/core_ext/date_and_time/calculations.rb +232 -0
- data/lib/active_support/core_ext/date_time.rb +5 -0
- data/lib/active_support/core_ext/date_time/acts_like.rb +0 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +73 -65
- data/lib/active_support/core_ext/date_time/conversions.rb +21 -33
- data/lib/active_support/core_ext/date_time/infinite_comparable.rb +5 -0
- data/lib/active_support/core_ext/date_time/zones.rb +11 -8
- data/lib/active_support/core_ext/enumerable.rb +26 -73
- data/lib/active_support/core_ext/file.rb +0 -1
- data/lib/active_support/core_ext/file/atomic.rb +27 -11
- data/lib/active_support/core_ext/hash.rb +0 -1
- data/lib/active_support/core_ext/hash/conversions.rb +145 -79
- data/lib/active_support/core_ext/hash/deep_merge.rb +14 -8
- data/lib/active_support/core_ext/hash/diff.rb +5 -4
- data/lib/active_support/core_ext/hash/except.rb +1 -9
- data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -5
- data/lib/active_support/core_ext/hash/keys.rb +108 -24
- data/lib/active_support/core_ext/hash/reverse_merge.rb +2 -3
- data/lib/active_support/core_ext/hash/slice.rb +12 -12
- data/lib/active_support/core_ext/infinite_comparable.rb +35 -0
- data/lib/active_support/core_ext/integer/inflections.rb +13 -1
- data/lib/active_support/core_ext/integer/time.rb +17 -12
- data/lib/active_support/core_ext/kernel/debugger.rb +2 -2
- data/lib/active_support/core_ext/kernel/reporting.rb +36 -22
- data/lib/active_support/core_ext/kernel/singleton_class.rb +0 -7
- data/lib/active_support/core_ext/load_error.rb +7 -5
- data/lib/active_support/core_ext/logger.rb +7 -23
- data/lib/active_support/core_ext/marshal.rb +19 -0
- data/lib/active_support/core_ext/module.rb +1 -3
- data/lib/active_support/core_ext/module/aliasing.rb +8 -9
- data/lib/active_support/core_ext/module/anonymous.rb +2 -7
- data/lib/active_support/core_ext/module/attr_internal.rb +0 -1
- data/lib/active_support/core_ext/module/attribute_accessors.rb +12 -10
- data/lib/active_support/core_ext/module/delegation.rb +57 -40
- data/lib/active_support/core_ext/module/deprecation.rb +19 -3
- data/lib/active_support/core_ext/module/introspection.rb +17 -27
- data/lib/active_support/core_ext/module/qualified_const.rb +8 -20
- data/lib/active_support/core_ext/module/remove_method.rb +1 -5
- data/lib/active_support/core_ext/numeric.rb +2 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +135 -0
- data/lib/active_support/core_ext/numeric/infinite_comparable.rb +9 -0
- data/lib/active_support/core_ext/numeric/time.rb +6 -6
- data/lib/active_support/core_ext/object.rb +1 -0
- data/lib/active_support/core_ext/object/acts_like.rb +4 -4
- data/lib/active_support/core_ext/object/blank.rb +7 -23
- data/lib/active_support/core_ext/object/deep_dup.rb +46 -0
- data/lib/active_support/core_ext/object/duplicable.rb +1 -30
- data/lib/active_support/core_ext/object/inclusion.rb +6 -6
- data/lib/active_support/core_ext/object/instance_variables.rb +7 -12
- data/lib/active_support/core_ext/object/to_json.rb +8 -0
- data/lib/active_support/core_ext/object/to_param.rb +5 -2
- data/lib/active_support/core_ext/object/try.rb +46 -25
- data/lib/active_support/core_ext/object/with_options.rb +7 -8
- data/lib/active_support/core_ext/proc.rb +3 -0
- data/lib/active_support/core_ext/range.rb +0 -2
- data/lib/active_support/core_ext/range/conversions.rb +0 -2
- data/lib/active_support/core_ext/range/include_range.rb +1 -1
- data/lib/active_support/core_ext/range/overlaps.rb +1 -1
- data/lib/active_support/core_ext/string.rb +2 -2
- data/lib/active_support/core_ext/string/access.rb +95 -90
- data/lib/active_support/core_ext/string/conversions.rb +29 -38
- data/lib/active_support/core_ext/string/encoding.rb +6 -9
- data/lib/active_support/core_ext/string/filters.rb +24 -18
- data/lib/active_support/core_ext/string/indent.rb +43 -0
- data/lib/active_support/core_ext/string/inflections.rb +70 -60
- data/lib/active_support/core_ext/string/inquiry.rb +2 -2
- data/lib/active_support/core_ext/string/multibyte.rb +41 -64
- data/lib/active_support/core_ext/string/output_safety.rb +59 -51
- data/lib/active_support/core_ext/string/zones.rb +13 -0
- data/lib/active_support/core_ext/struct.rb +6 -0
- data/lib/active_support/core_ext/thread.rb +74 -0
- data/lib/active_support/core_ext/time.rb +6 -0
- data/lib/active_support/core_ext/time/calculations.rb +105 -193
- data/lib/active_support/core_ext/time/conversions.rb +27 -51
- data/lib/active_support/core_ext/time/infinite_comparable.rb +5 -0
- data/lib/active_support/core_ext/time/marshal.rb +0 -27
- data/lib/active_support/core_ext/time/zones.rb +27 -17
- data/lib/active_support/core_ext/uri.rb +13 -17
- data/lib/active_support/dependencies.rb +160 -141
- data/lib/active_support/dependencies/autoload.rb +47 -20
- data/lib/active_support/deprecation.rb +39 -14
- data/lib/active_support/deprecation/behaviors.rb +44 -30
- data/lib/active_support/deprecation/instance_delegator.rb +24 -0
- data/lib/active_support/deprecation/method_wrappers.rb +33 -18
- data/lib/active_support/deprecation/proxy_wrappers.rb +58 -13
- data/lib/active_support/deprecation/reporting.rb +40 -11
- data/lib/active_support/descendants_tracker.rb +34 -19
- data/lib/active_support/duration.rb +6 -8
- data/lib/active_support/file_update_checker.rb +63 -47
- data/lib/active_support/gzip.rb +11 -5
- data/lib/active_support/hash_with_indifferent_access.rb +112 -37
- data/lib/active_support/i18n.rb +4 -0
- data/lib/active_support/i18n_railtie.rb +5 -22
- data/lib/active_support/inflections.rb +14 -12
- data/lib/active_support/inflector/inflections.rb +108 -71
- data/lib/active_support/inflector/methods.rb +181 -160
- data/lib/active_support/inflector/transliterate.rb +16 -17
- data/lib/active_support/json/decoding.rb +18 -17
- data/lib/active_support/json/encoding.rb +93 -39
- data/lib/active_support/json/variable.rb +10 -1
- data/lib/active_support/key_generator.rb +75 -0
- data/lib/active_support/lazy_load_hooks.rb +21 -19
- data/lib/active_support/locale/en.yml +100 -3
- data/lib/active_support/log_subscriber.rb +56 -36
- data/lib/active_support/log_subscriber/test_helper.rb +18 -15
- data/lib/active_support/logger.rb +57 -0
- data/lib/active_support/logger_silence.rb +24 -0
- data/lib/active_support/message_encryptor.rb +32 -29
- data/lib/active_support/message_verifier.rb +8 -14
- data/lib/active_support/multibyte.rb +5 -28
- data/lib/active_support/multibyte/chars.rb +80 -333
- data/lib/active_support/multibyte/unicode.rb +74 -64
- data/lib/active_support/notifications.rb +57 -25
- data/lib/active_support/notifications/fanout.rb +105 -18
- data/lib/active_support/notifications/instrumenter.rb +32 -13
- data/lib/active_support/number_helper.rb +636 -0
- data/lib/active_support/ordered_hash.rb +8 -190
- data/lib/active_support/ordered_options.rb +21 -23
- data/lib/active_support/proxy_object.rb +13 -0
- data/lib/active_support/rails.rb +27 -0
- data/lib/active_support/railtie.rb +12 -32
- data/lib/active_support/rescuable.rb +9 -4
- data/lib/active_support/string_inquirer.rb +13 -8
- data/lib/active_support/tagged_logging.rb +51 -73
- data/lib/active_support/test_case.rb +46 -17
- data/lib/active_support/testing/assertions.rb +56 -26
- data/lib/active_support/testing/autorun.rb +5 -0
- data/lib/active_support/testing/constant_lookup.rb +52 -0
- data/lib/active_support/testing/declarative.rb +1 -1
- data/lib/active_support/testing/deprecation.rb +0 -19
- data/lib/active_support/testing/isolation.rb +25 -58
- data/lib/active_support/testing/pending.rb +5 -43
- data/lib/active_support/testing/setup_and_teardown.rb +6 -92
- data/lib/active_support/testing/tagged_logging.rb +25 -0
- data/lib/active_support/time.rb +6 -21
- data/lib/active_support/time_with_zone.rb +78 -43
- data/lib/active_support/values/time_zone.rb +77 -58
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +4 -4
- data/lib/active_support/xml_mini.rb +35 -17
- data/lib/active_support/xml_mini/jdom.rb +9 -17
- data/lib/active_support/xml_mini/libxml.rb +1 -2
- data/lib/active_support/xml_mini/libxmlsax.rb +1 -2
- data/lib/active_support/xml_mini/nokogiri.rb +1 -2
- data/lib/active_support/xml_mini/nokogirisax.rb +1 -2
- data/lib/active_support/xml_mini/rexml.rb +6 -8
- metadata +107 -77
- data/lib/active_support/base64.rb +0 -54
- data/lib/active_support/core_ext/array/random_access.rb +0 -30
- data/lib/active_support/core_ext/date/freeze.rb +0 -33
- data/lib/active_support/core_ext/exception.rb +0 -3
- data/lib/active_support/core_ext/file/path.rb +0 -5
- data/lib/active_support/core_ext/float.rb +0 -1
- data/lib/active_support/core_ext/float/rounding.rb +0 -19
- data/lib/active_support/core_ext/hash/deep_dup.rb +0 -18
- data/lib/active_support/core_ext/io.rb +0 -15
- data/lib/active_support/core_ext/module/method_names.rb +0 -14
- data/lib/active_support/core_ext/module/synchronization.rb +0 -45
- data/lib/active_support/core_ext/process.rb +0 -1
- data/lib/active_support/core_ext/process/daemon.rb +0 -23
- data/lib/active_support/core_ext/range/blockless_step.rb +0 -29
- data/lib/active_support/core_ext/range/cover.rb +0 -3
- data/lib/active_support/core_ext/rexml.rb +0 -46
- data/lib/active_support/core_ext/string/interpolation.rb +0 -2
- data/lib/active_support/core_ext/time/publicize_conversion_methods.rb +0 -10
- data/lib/active_support/memoizable.rb +0 -116
- data/lib/active_support/multibyte/exceptions.rb +0 -8
- data/lib/active_support/multibyte/utils.rb +0 -60
- data/lib/active_support/ruby/shim.rb +0 -22
- data/lib/active_support/security_utils.rb +0 -27
- data/lib/active_support/testing/mochaing.rb +0 -7
- data/lib/active_support/testing/performance.rb +0 -317
- data/lib/active_support/testing/performance/jruby.rb +0 -115
- data/lib/active_support/testing/performance/rubinius.rb +0 -113
- data/lib/active_support/testing/performance/ruby.rb +0 -152
- data/lib/active_support/testing/performance/ruby/mri.rb +0 -57
- data/lib/active_support/testing/performance/ruby/yarv.rb +0 -57
- data/lib/active_support/time/autoload.rb +0 -5
- data/lib/active_support/whiny_nil.rb +0 -24
@@ -1,20 +1,26 @@
|
|
1
1
|
class Hash
|
2
2
|
# Returns a new hash with +self+ and +other_hash+ merged recursively.
|
3
3
|
#
|
4
|
-
# h1 = {:
|
5
|
-
# h2 = {:
|
4
|
+
# h1 = { x: { y: [4,5,6] }, z: [7,8,9] }
|
5
|
+
# h2 = { x: { y: [7,8,9] }, z: 'xyz' }
|
6
6
|
#
|
7
|
-
# h1.deep_merge(h2) #=> {
|
8
|
-
# h2.deep_merge(h1) #=> {
|
9
|
-
|
10
|
-
|
7
|
+
# h1.deep_merge(h2) #=> {x: {y: [7, 8, 9]}, z: "xyz"}
|
8
|
+
# h2.deep_merge(h1) #=> {x: {y: [4, 5, 6]}, z: [7, 8, 9]}
|
9
|
+
# h1.deep_merge(h2) { |key, old, new| Array.wrap(old) + Array.wrap(new) }
|
10
|
+
# #=> {:x=>{:y=>[4, 5, 6, 7, 8, 9]}, :z=>[7, 8, 9, "xyz"]}
|
11
|
+
def deep_merge(other_hash, &block)
|
12
|
+
dup.deep_merge!(other_hash, &block)
|
11
13
|
end
|
12
14
|
|
13
15
|
# Same as +deep_merge+, but modifies +self+.
|
14
|
-
def deep_merge!(other_hash)
|
16
|
+
def deep_merge!(other_hash, &block)
|
15
17
|
other_hash.each_pair do |k,v|
|
16
18
|
tv = self[k]
|
17
|
-
|
19
|
+
if tv.is_a?(Hash) && v.is_a?(Hash)
|
20
|
+
self[k] = tv.deep_merge(v, &block)
|
21
|
+
else
|
22
|
+
self[k] = block && tv ? block.call(k, tv, v) : v
|
23
|
+
end
|
18
24
|
end
|
19
25
|
self
|
20
26
|
end
|
@@ -1,13 +1,14 @@
|
|
1
1
|
class Hash
|
2
2
|
# Returns a hash that represents the difference between two hashes.
|
3
3
|
#
|
4
|
-
# Examples:
|
5
|
-
#
|
6
4
|
# {1 => 2}.diff(1 => 2) # => {}
|
7
5
|
# {1 => 2}.diff(1 => 3) # => {1 => 2}
|
8
6
|
# {}.diff(1 => 2) # => {1 => 2}
|
9
7
|
# {1 => 2, 3 => 4}.diff(1 => 2) # => {3 => 4}
|
10
|
-
def diff(
|
11
|
-
|
8
|
+
def diff(other)
|
9
|
+
ActiveSupport::Deprecation.warn "Hash#diff is no longer used inside of Rails, and is being deprecated with no replacement. If you're using it to compare hashes for the purpose of testing, please use MiniTest's assert_equal instead."
|
10
|
+
dup.
|
11
|
+
delete_if { |k, v| other[k] == v }.
|
12
|
+
merge!(other.dup.delete_if { |k, v| has_key?(k) })
|
12
13
|
end
|
13
14
|
end
|
@@ -2,15 +2,7 @@ class Hash
|
|
2
2
|
# Return a hash that includes everything but the given keys. This is useful for
|
3
3
|
# limiting a set of parameters to everything but a few known toggles:
|
4
4
|
#
|
5
|
-
# @person.
|
6
|
-
#
|
7
|
-
# If the receiver responds to +convert_key+, the method is called on each of the
|
8
|
-
# arguments. This allows +except+ to play nice with hashes with indifferent access
|
9
|
-
# for instance:
|
10
|
-
#
|
11
|
-
# {:a => 1}.with_indifferent_access.except(:a) # => {}
|
12
|
-
# {:a => 1}.with_indifferent_access.except("a") # => {}
|
13
|
-
#
|
5
|
+
# @person.update(params[:person].except(:admin))
|
14
6
|
def except(*keys)
|
15
7
|
dup.except!(*keys)
|
16
8
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'active_support/hash_with_indifferent_access'
|
2
2
|
|
3
3
|
class Hash
|
4
|
+
|
4
5
|
# Returns an <tt>ActiveSupport::HashWithIndifferentAccess</tt> out of its receiver:
|
5
6
|
#
|
6
|
-
# {:
|
7
|
-
#
|
7
|
+
# { a: 1 }.with_indifferent_access['a'] # => 1
|
8
8
|
def with_indifferent_access
|
9
9
|
ActiveSupport::HashWithIndifferentAccess.new_from_hash_copying_default(self)
|
10
10
|
end
|
@@ -16,8 +16,7 @@ class Hash
|
|
16
16
|
# converting to an <tt>ActiveSupport::HashWithIndifferentAccess</tt> would not be
|
17
17
|
# desirable.
|
18
18
|
#
|
19
|
-
# b = {:
|
20
|
-
# {:
|
21
|
-
#
|
19
|
+
# b = { b: 1 }
|
20
|
+
# { a: b }.with_indifferent_access['a'] # calls b.nested_under_indifferent_access
|
22
21
|
alias nested_under_indifferent_access with_indifferent_access
|
23
22
|
end
|
@@ -1,54 +1,138 @@
|
|
1
1
|
class Hash
|
2
|
+
# Return a new hash with all keys converted using the block operation.
|
3
|
+
#
|
4
|
+
# hash = { name: 'Rob', age: '28' }
|
5
|
+
#
|
6
|
+
# hash.transform_keys{ |key| key.to_s.upcase }
|
7
|
+
# # => { "NAME" => "Rob", "AGE" => "28" }
|
8
|
+
def transform_keys
|
9
|
+
result = {}
|
10
|
+
each_key do |key|
|
11
|
+
result[yield(key)] = self[key]
|
12
|
+
end
|
13
|
+
result
|
14
|
+
end
|
15
|
+
|
16
|
+
# Destructively convert all keys using the block operations.
|
17
|
+
# Same as transform_keys but modifies +self+.
|
18
|
+
def transform_keys!
|
19
|
+
keys.each do |key|
|
20
|
+
self[yield(key)] = delete(key)
|
21
|
+
end
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
2
25
|
# Return a new hash with all keys converted to strings.
|
3
26
|
#
|
4
|
-
# { :
|
5
|
-
#
|
27
|
+
# hash = { name: 'Rob', age: '28' }
|
28
|
+
#
|
29
|
+
# hash.stringify_keys
|
30
|
+
# #=> { "name" => "Rob", "age" => "28" }
|
6
31
|
def stringify_keys
|
7
|
-
|
32
|
+
transform_keys{ |key| key.to_s }
|
8
33
|
end
|
9
34
|
|
10
35
|
# Destructively convert all keys to strings. Same as
|
11
36
|
# +stringify_keys+, but modifies +self+.
|
12
37
|
def stringify_keys!
|
13
|
-
|
14
|
-
self[key.to_s] = delete(key)
|
15
|
-
end
|
16
|
-
self
|
38
|
+
transform_keys!{ |key| key.to_s }
|
17
39
|
end
|
18
40
|
|
19
41
|
# Return a new hash with all keys converted to symbols, as long as
|
20
42
|
# they respond to +to_sym+.
|
21
43
|
#
|
22
|
-
# { 'name' => 'Rob', '
|
23
|
-
#
|
44
|
+
# hash = { 'name' => 'Rob', 'age' => '28' }
|
45
|
+
#
|
46
|
+
# hash.symbolize_keys
|
47
|
+
# #=> { name: "Rob", age: "28" }
|
24
48
|
def symbolize_keys
|
25
|
-
|
49
|
+
transform_keys{ |key| key.to_sym rescue key }
|
26
50
|
end
|
51
|
+
alias_method :to_options, :symbolize_keys
|
27
52
|
|
28
53
|
# Destructively convert all keys to symbols, as long as they respond
|
29
54
|
# to +to_sym+. Same as +symbolize_keys+, but modifies +self+.
|
30
55
|
def symbolize_keys!
|
31
|
-
|
32
|
-
self[(key.to_sym rescue key) || key] = delete(key)
|
33
|
-
end
|
34
|
-
self
|
56
|
+
transform_keys!{ |key| key.to_sym rescue key }
|
35
57
|
end
|
36
|
-
|
37
|
-
alias_method :to_options, :symbolize_keys
|
38
58
|
alias_method :to_options!, :symbolize_keys!
|
39
59
|
|
40
|
-
# Validate all keys in a hash match
|
41
|
-
# Note that keys are NOT treated indifferently, meaning if you
|
42
|
-
# as keys, this will fail.
|
60
|
+
# Validate all keys in a hash match <tt>*valid_keys</tt>, raising ArgumentError
|
61
|
+
# on a mismatch. Note that keys are NOT treated indifferently, meaning if you
|
62
|
+
# use strings for keys but assert symbols as keys, this will fail.
|
43
63
|
#
|
44
|
-
#
|
45
|
-
# { :
|
46
|
-
# { :
|
47
|
-
# { :name => "Rob", :age => "28" }.assert_valid_keys(:name, :age) # => passes, raises nothing
|
64
|
+
# { name: 'Rob', years: '28' }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key: years"
|
65
|
+
# { name: 'Rob', age: '28' }.assert_valid_keys('name', 'age') # => raises "ArgumentError: Unknown key: name"
|
66
|
+
# { name: 'Rob', age: '28' }.assert_valid_keys(:name, :age) # => passes, raises nothing
|
48
67
|
def assert_valid_keys(*valid_keys)
|
49
68
|
valid_keys.flatten!
|
50
69
|
each_key do |k|
|
51
|
-
raise(
|
70
|
+
raise ArgumentError.new("Unknown key: #{k}") unless valid_keys.include?(k)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Return a new hash with all keys converted by the block operation.
|
75
|
+
# This includes the keys from the root hash and from all
|
76
|
+
# nested hashes.
|
77
|
+
#
|
78
|
+
# hash = { person: { name: 'Rob', age: '28' } }
|
79
|
+
#
|
80
|
+
# hash.deep_transform_keys{ |key| key.to_s.upcase }
|
81
|
+
# # => { "PERSON" => { "NAME" => "Rob", "AGE" => "28" } }
|
82
|
+
def deep_transform_keys(&block)
|
83
|
+
result = {}
|
84
|
+
each do |key, value|
|
85
|
+
result[yield(key)] = value.is_a?(Hash) ? value.deep_transform_keys(&block) : value
|
86
|
+
end
|
87
|
+
result
|
88
|
+
end
|
89
|
+
|
90
|
+
# Destructively convert all keys by using the block operation.
|
91
|
+
# This includes the keys from the root hash and from all
|
92
|
+
# nested hashes.
|
93
|
+
def deep_transform_keys!(&block)
|
94
|
+
keys.each do |key|
|
95
|
+
value = delete(key)
|
96
|
+
self[yield(key)] = value.is_a?(Hash) ? value.deep_transform_keys!(&block) : value
|
52
97
|
end
|
98
|
+
self
|
99
|
+
end
|
100
|
+
|
101
|
+
# Return a new hash with all keys converted to strings.
|
102
|
+
# This includes the keys from the root hash and from all
|
103
|
+
# nested hashes.
|
104
|
+
#
|
105
|
+
# hash = { person: { name: 'Rob', age: '28' } }
|
106
|
+
#
|
107
|
+
# hash.deep_stringify_keys
|
108
|
+
# # => { "person" => { "name" => "Rob", "age" => "28" } }
|
109
|
+
def deep_stringify_keys
|
110
|
+
deep_transform_keys{ |key| key.to_s }
|
111
|
+
end
|
112
|
+
|
113
|
+
# Destructively convert all keys to strings.
|
114
|
+
# This includes the keys from the root hash and from all
|
115
|
+
# nested hashes.
|
116
|
+
def deep_stringify_keys!
|
117
|
+
deep_transform_keys!{ |key| key.to_s }
|
118
|
+
end
|
119
|
+
|
120
|
+
# Return a new hash with all keys converted to symbols, as long as
|
121
|
+
# they respond to +to_sym+. This includes the keys from the root hash
|
122
|
+
# and from all nested hashes.
|
123
|
+
#
|
124
|
+
# hash = { 'person' => { 'name' => 'Rob', 'age' => '28' } }
|
125
|
+
#
|
126
|
+
# hash.deep_symbolize_keys
|
127
|
+
# # => { person: { name: "Rob", age: "28" } }
|
128
|
+
def deep_symbolize_keys
|
129
|
+
deep_transform_keys{ |key| key.to_sym rescue key }
|
130
|
+
end
|
131
|
+
|
132
|
+
# Destructively convert all keys to symbols, as long as they respond
|
133
|
+
# to +to_sym+. This includes the keys from the root hash and from all
|
134
|
+
# nested hashes.
|
135
|
+
def deep_symbolize_keys!
|
136
|
+
deep_transform_keys!{ |key| key.to_sym rescue key }
|
53
137
|
end
|
54
138
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
class Hash
|
2
2
|
# Merges the caller into +other_hash+. For example,
|
3
3
|
#
|
4
|
-
# options = options.reverse_merge(:
|
4
|
+
# options = options.reverse_merge(size: 25, velocity: 10)
|
5
5
|
#
|
6
6
|
# is equivalent to
|
7
7
|
#
|
8
|
-
# options = {:
|
8
|
+
# options = { size: 25, velocity: 10 }.merge(options)
|
9
9
|
#
|
10
10
|
# This is particularly useful for initializing an options hash
|
11
11
|
# with default values.
|
@@ -18,6 +18,5 @@ class Hash
|
|
18
18
|
# right wins if there is no left
|
19
19
|
merge!( other_hash ){|key,left,right| left }
|
20
20
|
end
|
21
|
-
|
22
21
|
alias_method :reverse_update, :reverse_merge!
|
23
22
|
end
|
@@ -3,7 +3,7 @@ class Hash
|
|
3
3
|
# limiting an options hash to valid keys before passing to a method:
|
4
4
|
#
|
5
5
|
# def search(criteria = {})
|
6
|
-
# assert_valid_keys(:mass, :velocity, :time)
|
6
|
+
# criteria.assert_valid_keys(:mass, :velocity, :time)
|
7
7
|
# end
|
8
8
|
#
|
9
9
|
# search(options.slice(:mass, :velocity, :time))
|
@@ -13,17 +13,17 @@ class Hash
|
|
13
13
|
# valid_keys = [:mass, :velocity, :time]
|
14
14
|
# search(options.slice(*valid_keys))
|
15
15
|
def slice(*keys)
|
16
|
-
keys
|
17
|
-
hash = self
|
18
|
-
keys.each { |k| hash[k] = self[k] if has_key?(k) }
|
19
|
-
hash
|
16
|
+
keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
|
17
|
+
keys.each_with_object(self.class.new) { |k, hash| hash[k] = self[k] if has_key?(k) }
|
20
18
|
end
|
21
19
|
|
22
20
|
# Replaces the hash with only the given keys.
|
23
|
-
# Returns a hash
|
24
|
-
#
|
21
|
+
# Returns a hash containing the removed key/value pairs.
|
22
|
+
#
|
23
|
+
# { a: 1, b: 2, c: 3, d: 4 }.slice!(:a, :b)
|
24
|
+
# # => {:c=>3, :d=>4}
|
25
25
|
def slice!(*keys)
|
26
|
-
keys
|
26
|
+
keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
|
27
27
|
omit = slice(*self.keys - keys)
|
28
28
|
hash = slice(*keys)
|
29
29
|
replace(hash)
|
@@ -31,10 +31,10 @@ class Hash
|
|
31
31
|
end
|
32
32
|
|
33
33
|
# Removes and returns the key/value pairs matching the given keys.
|
34
|
-
#
|
34
|
+
#
|
35
|
+
# { a: 1, b: 2, c: 3, d: 4 }.extract!(:a, :b) # => {:a=>1, :b=>2}
|
36
|
+
# { a: 1, b: 2 }.extract!(:a, :x) # => {:a=>1}
|
35
37
|
def extract!(*keys)
|
36
|
-
result =
|
37
|
-
keys.each {|key| result[key] = delete(key) }
|
38
|
-
result
|
38
|
+
keys.each_with_object(self.class.new) { |key, result| result[key] = delete(key) if has_key?(key) }
|
39
39
|
end
|
40
40
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
require 'active_support/core_ext/module/aliasing'
|
3
|
+
require 'active_support/core_ext/object/try'
|
4
|
+
|
5
|
+
module InfiniteComparable
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
alias_method_chain :<=>, :infinity
|
10
|
+
end
|
11
|
+
|
12
|
+
define_method :'<=>_with_infinity' do |other|
|
13
|
+
if other.class == self.class
|
14
|
+
public_send :'<=>_without_infinity', other
|
15
|
+
else
|
16
|
+
infinite = try(:infinite?)
|
17
|
+
other_infinite = other.try(:infinite?)
|
18
|
+
|
19
|
+
# inf <=> inf
|
20
|
+
if infinite && other_infinite
|
21
|
+
infinite <=> other_infinite
|
22
|
+
# not_inf <=> inf
|
23
|
+
elsif other_infinite
|
24
|
+
-other_infinite
|
25
|
+
# inf <=> not_inf
|
26
|
+
elsif infinite
|
27
|
+
infinite
|
28
|
+
else
|
29
|
+
conversion = "to_#{self.class.name.downcase}"
|
30
|
+
other = other.public_send(conversion) if other.respond_to?(conversion)
|
31
|
+
public_send :'<=>_without_infinity', other
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -10,8 +10,20 @@ class Integer
|
|
10
10
|
# 1003.ordinalize # => "1003rd"
|
11
11
|
# -11.ordinalize # => "-11th"
|
12
12
|
# -1001.ordinalize # => "-1001st"
|
13
|
-
#
|
14
13
|
def ordinalize
|
15
14
|
ActiveSupport::Inflector.ordinalize(self)
|
16
15
|
end
|
16
|
+
|
17
|
+
# Ordinal returns the suffix used to denote the position
|
18
|
+
# in an ordered sequence such as 1st, 2nd, 3rd, 4th.
|
19
|
+
#
|
20
|
+
# 1.ordinal # => "st"
|
21
|
+
# 2.ordinal # => "nd"
|
22
|
+
# 1002.ordinal # => "nd"
|
23
|
+
# 1003.ordinal # => "rd"
|
24
|
+
# -11.ordinal # => "th"
|
25
|
+
# -1001.ordinal # => "st"
|
26
|
+
def ordinal
|
27
|
+
ActiveSupport::Inflector.ordinal(self)
|
28
|
+
end
|
17
29
|
end
|
@@ -1,21 +1,26 @@
|
|
1
|
+
require 'active_support/duration'
|
2
|
+
require 'active_support/core_ext/numeric/time'
|
3
|
+
|
1
4
|
class Integer
|
2
|
-
# Enables the use of time calculations and declarations, like 45.minutes +
|
5
|
+
# Enables the use of time calculations and declarations, like <tt>45.minutes +
|
6
|
+
# 2.hours + 4.years</tt>.
|
3
7
|
#
|
4
|
-
# These methods use Time#advance for precise date calculations when using
|
5
|
-
# as well as adding or subtracting their
|
8
|
+
# These methods use Time#advance for precise date calculations when using
|
9
|
+
# <tt>from_now</tt>, +ago+, etc. as well as adding or subtracting their
|
10
|
+
# results from a Time object.
|
6
11
|
#
|
7
|
-
# # equivalent to Time.now.advance(:
|
12
|
+
# # equivalent to Time.now.advance(months: 1)
|
8
13
|
# 1.month.from_now
|
9
14
|
#
|
10
|
-
# # equivalent to Time.now.advance(:
|
15
|
+
# # equivalent to Time.now.advance(years: 2)
|
11
16
|
# 2.years.from_now
|
12
17
|
#
|
13
|
-
# # equivalent to Time.now.advance(:
|
18
|
+
# # equivalent to Time.now.advance(months: 4, years: 5)
|
14
19
|
# (4.months + 5.years).from_now
|
15
20
|
#
|
16
|
-
# While these methods provide precise calculation when used as in the examples
|
17
|
-
# should be taken to note that this is not true if the result of
|
18
|
-
# converted before use:
|
21
|
+
# While these methods provide precise calculation when used as in the examples
|
22
|
+
# above, care should be taken to note that this is not true if the result of
|
23
|
+
# +months+, +years+, etc is converted before use:
|
19
24
|
#
|
20
25
|
# # equivalent to 30.days.to_i.from_now
|
21
26
|
# 1.month.to_i.from_now
|
@@ -24,9 +29,9 @@ class Integer
|
|
24
29
|
# 1.year.to_f.from_now
|
25
30
|
#
|
26
31
|
# In such cases, Ruby's core
|
27
|
-
# Date[http://
|
28
|
-
# Time[http://
|
29
|
-
# date and time arithmetic
|
32
|
+
# Date[http://ruby-doc.org/stdlib/libdoc/date/rdoc/Date.html] and
|
33
|
+
# Time[http://ruby-doc.org/stdlib/libdoc/time/rdoc/Time.html] should be used for precision
|
34
|
+
# date and time arithmetic.
|
30
35
|
def months
|
31
36
|
ActiveSupport::Duration.new(self * 30.days, [[:months, self]])
|
32
37
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module Kernel
|
2
2
|
unless respond_to?(:debugger)
|
3
|
-
# Starts a debugging session if
|
3
|
+
# Starts a debugging session if the +debugger+ gem has been loaded (call rails server --debugger to do load it).
|
4
4
|
def debugger
|
5
|
-
message = "\n***** Debugger requested, but was not available (ensure
|
5
|
+
message = "\n***** Debugger requested, but was not available (ensure the debugger gem is listed in Gemfile/installed as gem): Start server with --debugger to enable *****\n"
|
6
6
|
defined?(Rails) ? Rails.logger.info(message) : $stderr.puts(message)
|
7
7
|
end
|
8
8
|
alias breakpoint debugger unless respond_to?(:breakpoint)
|