activesupport 5.0.7.2

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.
Files changed (236) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +1018 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +39 -0
  5. data/lib/active_support.rb +99 -0
  6. data/lib/active_support/all.rb +3 -0
  7. data/lib/active_support/array_inquirer.rb +44 -0
  8. data/lib/active_support/backtrace_cleaner.rb +103 -0
  9. data/lib/active_support/benchmarkable.rb +49 -0
  10. data/lib/active_support/builder.rb +6 -0
  11. data/lib/active_support/cache.rb +701 -0
  12. data/lib/active_support/cache/file_store.rb +204 -0
  13. data/lib/active_support/cache/mem_cache_store.rb +207 -0
  14. data/lib/active_support/cache/memory_store.rb +167 -0
  15. data/lib/active_support/cache/null_store.rb +41 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +172 -0
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +44 -0
  18. data/lib/active_support/callbacks.rb +791 -0
  19. data/lib/active_support/concern.rb +142 -0
  20. data/lib/active_support/concurrency/latch.rb +26 -0
  21. data/lib/active_support/concurrency/share_lock.rb +226 -0
  22. data/lib/active_support/configurable.rb +148 -0
  23. data/lib/active_support/core_ext.rb +4 -0
  24. data/lib/active_support/core_ext/array.rb +7 -0
  25. data/lib/active_support/core_ext/array/access.rb +90 -0
  26. data/lib/active_support/core_ext/array/conversions.rb +211 -0
  27. data/lib/active_support/core_ext/array/extract_options.rb +29 -0
  28. data/lib/active_support/core_ext/array/grouping.rb +107 -0
  29. data/lib/active_support/core_ext/array/inquiry.rb +17 -0
  30. data/lib/active_support/core_ext/array/prepend_and_append.rb +7 -0
  31. data/lib/active_support/core_ext/array/wrap.rb +46 -0
  32. data/lib/active_support/core_ext/benchmark.rb +14 -0
  33. data/lib/active_support/core_ext/big_decimal.rb +1 -0
  34. data/lib/active_support/core_ext/big_decimal/conversions.rb +14 -0
  35. data/lib/active_support/core_ext/class.rb +2 -0
  36. data/lib/active_support/core_ext/class/attribute.rb +128 -0
  37. data/lib/active_support/core_ext/class/attribute_accessors.rb +4 -0
  38. data/lib/active_support/core_ext/class/subclasses.rb +41 -0
  39. data/lib/active_support/core_ext/date.rb +5 -0
  40. data/lib/active_support/core_ext/date/acts_like.rb +8 -0
  41. data/lib/active_support/core_ext/date/blank.rb +12 -0
  42. data/lib/active_support/core_ext/date/calculations.rb +143 -0
  43. data/lib/active_support/core_ext/date/conversions.rb +95 -0
  44. data/lib/active_support/core_ext/date/zones.rb +6 -0
  45. data/lib/active_support/core_ext/date_and_time/calculations.rb +335 -0
  46. data/lib/active_support/core_ext/date_and_time/compatibility.rb +14 -0
  47. data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
  48. data/lib/active_support/core_ext/date_time.rb +5 -0
  49. data/lib/active_support/core_ext/date_time/acts_like.rb +14 -0
  50. data/lib/active_support/core_ext/date_time/blank.rb +12 -0
  51. data/lib/active_support/core_ext/date_time/calculations.rb +199 -0
  52. data/lib/active_support/core_ext/date_time/compatibility.rb +16 -0
  53. data/lib/active_support/core_ext/date_time/conversions.rb +105 -0
  54. data/lib/active_support/core_ext/digest/uuid.rb +51 -0
  55. data/lib/active_support/core_ext/enumerable.rb +146 -0
  56. data/lib/active_support/core_ext/file.rb +1 -0
  57. data/lib/active_support/core_ext/file/atomic.rb +68 -0
  58. data/lib/active_support/core_ext/hash.rb +9 -0
  59. data/lib/active_support/core_ext/hash/compact.rb +24 -0
  60. data/lib/active_support/core_ext/hash/conversions.rb +262 -0
  61. data/lib/active_support/core_ext/hash/deep_merge.rb +38 -0
  62. data/lib/active_support/core_ext/hash/except.rb +22 -0
  63. data/lib/active_support/core_ext/hash/indifferent_access.rb +23 -0
  64. data/lib/active_support/core_ext/hash/keys.rb +170 -0
  65. data/lib/active_support/core_ext/hash/reverse_merge.rb +22 -0
  66. data/lib/active_support/core_ext/hash/slice.rb +48 -0
  67. data/lib/active_support/core_ext/hash/transform_values.rb +29 -0
  68. data/lib/active_support/core_ext/integer.rb +3 -0
  69. data/lib/active_support/core_ext/integer/inflections.rb +29 -0
  70. data/lib/active_support/core_ext/integer/multiple.rb +10 -0
  71. data/lib/active_support/core_ext/integer/time.rb +29 -0
  72. data/lib/active_support/core_ext/kernel.rb +4 -0
  73. data/lib/active_support/core_ext/kernel/agnostics.rb +11 -0
  74. data/lib/active_support/core_ext/kernel/concern.rb +12 -0
  75. data/lib/active_support/core_ext/kernel/debugger.rb +3 -0
  76. data/lib/active_support/core_ext/kernel/reporting.rb +43 -0
  77. data/lib/active_support/core_ext/kernel/singleton_class.rb +6 -0
  78. data/lib/active_support/core_ext/load_error.rb +31 -0
  79. data/lib/active_support/core_ext/marshal.rb +22 -0
  80. data/lib/active_support/core_ext/module.rb +12 -0
  81. data/lib/active_support/core_ext/module/aliasing.rb +74 -0
  82. data/lib/active_support/core_ext/module/anonymous.rb +28 -0
  83. data/lib/active_support/core_ext/module/attr_internal.rb +36 -0
  84. data/lib/active_support/core_ext/module/attribute_accessors.rb +212 -0
  85. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +141 -0
  86. data/lib/active_support/core_ext/module/concerning.rb +135 -0
  87. data/lib/active_support/core_ext/module/delegation.rb +216 -0
  88. data/lib/active_support/core_ext/module/deprecation.rb +23 -0
  89. data/lib/active_support/core_ext/module/introspection.rb +68 -0
  90. data/lib/active_support/core_ext/module/method_transplanting.rb +3 -0
  91. data/lib/active_support/core_ext/module/qualified_const.rb +70 -0
  92. data/lib/active_support/core_ext/module/reachable.rb +8 -0
  93. data/lib/active_support/core_ext/module/remove_method.rb +35 -0
  94. data/lib/active_support/core_ext/name_error.rb +31 -0
  95. data/lib/active_support/core_ext/numeric.rb +4 -0
  96. data/lib/active_support/core_ext/numeric/bytes.rb +64 -0
  97. data/lib/active_support/core_ext/numeric/conversions.rb +144 -0
  98. data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
  99. data/lib/active_support/core_ext/numeric/time.rb +74 -0
  100. data/lib/active_support/core_ext/object.rb +14 -0
  101. data/lib/active_support/core_ext/object/acts_like.rb +10 -0
  102. data/lib/active_support/core_ext/object/blank.rb +143 -0
  103. data/lib/active_support/core_ext/object/conversions.rb +4 -0
  104. data/lib/active_support/core_ext/object/deep_dup.rb +53 -0
  105. data/lib/active_support/core_ext/object/duplicable.rb +124 -0
  106. data/lib/active_support/core_ext/object/inclusion.rb +27 -0
  107. data/lib/active_support/core_ext/object/instance_variables.rb +28 -0
  108. data/lib/active_support/core_ext/object/json.rb +205 -0
  109. data/lib/active_support/core_ext/object/to_param.rb +1 -0
  110. data/lib/active_support/core_ext/object/to_query.rb +84 -0
  111. data/lib/active_support/core_ext/object/try.rb +146 -0
  112. data/lib/active_support/core_ext/object/with_options.rb +69 -0
  113. data/lib/active_support/core_ext/range.rb +4 -0
  114. data/lib/active_support/core_ext/range/conversions.rb +31 -0
  115. data/lib/active_support/core_ext/range/each.rb +21 -0
  116. data/lib/active_support/core_ext/range/include_range.rb +23 -0
  117. data/lib/active_support/core_ext/range/overlaps.rb +8 -0
  118. data/lib/active_support/core_ext/regexp.rb +5 -0
  119. data/lib/active_support/core_ext/securerandom.rb +23 -0
  120. data/lib/active_support/core_ext/string.rb +13 -0
  121. data/lib/active_support/core_ext/string/access.rb +104 -0
  122. data/lib/active_support/core_ext/string/behavior.rb +6 -0
  123. data/lib/active_support/core_ext/string/conversions.rb +57 -0
  124. data/lib/active_support/core_ext/string/exclude.rb +11 -0
  125. data/lib/active_support/core_ext/string/filters.rb +102 -0
  126. data/lib/active_support/core_ext/string/indent.rb +43 -0
  127. data/lib/active_support/core_ext/string/inflections.rb +244 -0
  128. data/lib/active_support/core_ext/string/inquiry.rb +13 -0
  129. data/lib/active_support/core_ext/string/multibyte.rb +53 -0
  130. data/lib/active_support/core_ext/string/output_safety.rb +260 -0
  131. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -0
  132. data/lib/active_support/core_ext/string/strip.rb +23 -0
  133. data/lib/active_support/core_ext/string/zones.rb +14 -0
  134. data/lib/active_support/core_ext/struct.rb +3 -0
  135. data/lib/active_support/core_ext/time.rb +5 -0
  136. data/lib/active_support/core_ext/time/acts_like.rb +8 -0
  137. data/lib/active_support/core_ext/time/calculations.rb +290 -0
  138. data/lib/active_support/core_ext/time/compatibility.rb +14 -0
  139. data/lib/active_support/core_ext/time/conversions.rb +67 -0
  140. data/lib/active_support/core_ext/time/marshal.rb +3 -0
  141. data/lib/active_support/core_ext/time/zones.rb +111 -0
  142. data/lib/active_support/core_ext/uri.rb +24 -0
  143. data/lib/active_support/dependencies.rb +755 -0
  144. data/lib/active_support/dependencies/autoload.rb +77 -0
  145. data/lib/active_support/dependencies/interlock.rb +55 -0
  146. data/lib/active_support/deprecation.rb +43 -0
  147. data/lib/active_support/deprecation/behaviors.rb +90 -0
  148. data/lib/active_support/deprecation/instance_delegator.rb +37 -0
  149. data/lib/active_support/deprecation/method_wrappers.rb +70 -0
  150. data/lib/active_support/deprecation/proxy_wrappers.rb +149 -0
  151. data/lib/active_support/deprecation/reporting.rb +112 -0
  152. data/lib/active_support/descendants_tracker.rb +60 -0
  153. data/lib/active_support/duration.rb +235 -0
  154. data/lib/active_support/duration/iso8601_parser.rb +122 -0
  155. data/lib/active_support/duration/iso8601_serializer.rb +51 -0
  156. data/lib/active_support/evented_file_update_checker.rb +199 -0
  157. data/lib/active_support/execution_wrapper.rb +126 -0
  158. data/lib/active_support/executor.rb +6 -0
  159. data/lib/active_support/file_update_checker.rb +157 -0
  160. data/lib/active_support/gem_version.rb +15 -0
  161. data/lib/active_support/gzip.rb +36 -0
  162. data/lib/active_support/hash_with_indifferent_access.rb +329 -0
  163. data/lib/active_support/i18n.rb +13 -0
  164. data/lib/active_support/i18n_railtie.rb +115 -0
  165. data/lib/active_support/inflections.rb +70 -0
  166. data/lib/active_support/inflector.rb +7 -0
  167. data/lib/active_support/inflector/inflections.rb +242 -0
  168. data/lib/active_support/inflector/methods.rb +390 -0
  169. data/lib/active_support/inflector/transliterate.rb +112 -0
  170. data/lib/active_support/json.rb +2 -0
  171. data/lib/active_support/json/decoding.rb +74 -0
  172. data/lib/active_support/json/encoding.rb +127 -0
  173. data/lib/active_support/key_generator.rb +71 -0
  174. data/lib/active_support/lazy_load_hooks.rb +76 -0
  175. data/lib/active_support/locale/en.yml +135 -0
  176. data/lib/active_support/log_subscriber.rb +109 -0
  177. data/lib/active_support/log_subscriber/test_helper.rb +104 -0
  178. data/lib/active_support/logger.rb +106 -0
  179. data/lib/active_support/logger_silence.rb +28 -0
  180. data/lib/active_support/logger_thread_safe_level.rb +31 -0
  181. data/lib/active_support/message_encryptor.rb +114 -0
  182. data/lib/active_support/message_verifier.rb +134 -0
  183. data/lib/active_support/multibyte.rb +21 -0
  184. data/lib/active_support/multibyte/chars.rb +231 -0
  185. data/lib/active_support/multibyte/unicode.rb +413 -0
  186. data/lib/active_support/notifications.rb +212 -0
  187. data/lib/active_support/notifications/fanout.rb +157 -0
  188. data/lib/active_support/notifications/instrumenter.rb +91 -0
  189. data/lib/active_support/number_helper.rb +368 -0
  190. data/lib/active_support/number_helper/number_converter.rb +182 -0
  191. data/lib/active_support/number_helper/number_to_currency_converter.rb +44 -0
  192. data/lib/active_support/number_helper/number_to_delimited_converter.rb +28 -0
  193. data/lib/active_support/number_helper/number_to_human_converter.rb +68 -0
  194. data/lib/active_support/number_helper/number_to_human_size_converter.rb +62 -0
  195. data/lib/active_support/number_helper/number_to_percentage_converter.rb +12 -0
  196. data/lib/active_support/number_helper/number_to_phone_converter.rb +58 -0
  197. data/lib/active_support/number_helper/number_to_rounded_converter.rb +92 -0
  198. data/lib/active_support/option_merger.rb +25 -0
  199. data/lib/active_support/ordered_hash.rb +48 -0
  200. data/lib/active_support/ordered_options.rb +81 -0
  201. data/lib/active_support/per_thread_registry.rb +58 -0
  202. data/lib/active_support/proxy_object.rb +13 -0
  203. data/lib/active_support/rails.rb +27 -0
  204. data/lib/active_support/railtie.rb +51 -0
  205. data/lib/active_support/reloader.rb +129 -0
  206. data/lib/active_support/rescuable.rb +173 -0
  207. data/lib/active_support/security_utils.rb +27 -0
  208. data/lib/active_support/string_inquirer.rb +26 -0
  209. data/lib/active_support/subscriber.rb +120 -0
  210. data/lib/active_support/tagged_logging.rb +77 -0
  211. data/lib/active_support/test_case.rb +88 -0
  212. data/lib/active_support/testing/assertions.rb +99 -0
  213. data/lib/active_support/testing/autorun.rb +5 -0
  214. data/lib/active_support/testing/constant_lookup.rb +50 -0
  215. data/lib/active_support/testing/declarative.rb +26 -0
  216. data/lib/active_support/testing/deprecation.rb +36 -0
  217. data/lib/active_support/testing/file_fixtures.rb +34 -0
  218. data/lib/active_support/testing/isolation.rb +115 -0
  219. data/lib/active_support/testing/method_call_assertions.rb +41 -0
  220. data/lib/active_support/testing/setup_and_teardown.rb +50 -0
  221. data/lib/active_support/testing/stream.rb +42 -0
  222. data/lib/active_support/testing/tagged_logging.rb +25 -0
  223. data/lib/active_support/testing/time_helpers.rb +136 -0
  224. data/lib/active_support/time.rb +18 -0
  225. data/lib/active_support/time_with_zone.rb +511 -0
  226. data/lib/active_support/values/time_zone.rb +484 -0
  227. data/lib/active_support/values/unicode_tables.dat +0 -0
  228. data/lib/active_support/version.rb +8 -0
  229. data/lib/active_support/xml_mini.rb +209 -0
  230. data/lib/active_support/xml_mini/jdom.rb +181 -0
  231. data/lib/active_support/xml_mini/libxml.rb +77 -0
  232. data/lib/active_support/xml_mini/libxmlsax.rb +82 -0
  233. data/lib/active_support/xml_mini/nokogiri.rb +81 -0
  234. data/lib/active_support/xml_mini/nokogirisax.rb +85 -0
  235. data/lib/active_support/xml_mini/rexml.rb +128 -0
  236. metadata +349 -0
@@ -0,0 +1,38 @@
1
+ class Hash
2
+ # Returns a new hash with +self+ and +other_hash+ merged recursively.
3
+ #
4
+ # h1 = { a: true, b: { c: [1, 2, 3] } }
5
+ # h2 = { a: false, b: { x: [3, 4, 5] } }
6
+ #
7
+ # h1.deep_merge(h2) # => { a: false, b: { c: [1, 2, 3], x: [3, 4, 5] } }
8
+ #
9
+ # Like with Hash#merge in the standard library, a block can be provided
10
+ # to merge values:
11
+ #
12
+ # h1 = { a: 100, b: 200, c: { c1: 100 } }
13
+ # h2 = { b: 250, c: { c1: 200 } }
14
+ # h1.deep_merge(h2) { |key, this_val, other_val| this_val + other_val }
15
+ # # => { a: 100, b: 450, c: { c1: 300 } }
16
+ def deep_merge(other_hash, &block)
17
+ dup.deep_merge!(other_hash, &block)
18
+ end
19
+
20
+ # Same as +deep_merge+, but modifies +self+.
21
+ def deep_merge!(other_hash, &block)
22
+ other_hash.each_pair do |current_key, other_value|
23
+ this_value = self[current_key]
24
+
25
+ self[current_key] = if this_value.is_a?(Hash) && other_value.is_a?(Hash)
26
+ this_value.deep_merge(other_value, &block)
27
+ else
28
+ if block_given? && key?(current_key)
29
+ block.call(current_key, this_value, other_value)
30
+ else
31
+ other_value
32
+ end
33
+ end
34
+ end
35
+
36
+ self
37
+ end
38
+ end
@@ -0,0 +1,22 @@
1
+ class Hash
2
+ # Returns a hash that includes everything except given keys.
3
+ # hash = { a: true, b: false, c: nil }
4
+ # hash.except(:c) # => { a: true, b: false }
5
+ # hash.except(:a, :b) # => { c: nil }
6
+ # hash # => { a: true, b: false, c: nil }
7
+ #
8
+ # This is useful for limiting a set of parameters to everything but a few known toggles:
9
+ # @person.update(params[:person].except(:admin))
10
+ def except(*keys)
11
+ dup.except!(*keys)
12
+ end
13
+
14
+ # Removes the given keys from hash and returns it.
15
+ # hash = { a: true, b: false, c: nil }
16
+ # hash.except!(:c) # => { a: true, b: false }
17
+ # hash # => { a: true, b: false }
18
+ def except!(*keys)
19
+ keys.each { |key| delete(key) }
20
+ self
21
+ end
22
+ end
@@ -0,0 +1,23 @@
1
+ require 'active_support/hash_with_indifferent_access'
2
+
3
+ class Hash
4
+
5
+ # Returns an <tt>ActiveSupport::HashWithIndifferentAccess</tt> out of its receiver:
6
+ #
7
+ # { a: 1 }.with_indifferent_access['a'] # => 1
8
+ def with_indifferent_access
9
+ ActiveSupport::HashWithIndifferentAccess.new(self)
10
+ end
11
+
12
+ # Called when object is nested under an object that receives
13
+ # #with_indifferent_access. This method will be called on the current object
14
+ # by the enclosing object and is aliased to #with_indifferent_access by
15
+ # default. Subclasses of Hash may overwrite this method to return +self+ if
16
+ # converting to an <tt>ActiveSupport::HashWithIndifferentAccess</tt> would not be
17
+ # desirable.
18
+ #
19
+ # b = { b: 1 }
20
+ # { a: b }.with_indifferent_access['a'] # calls b.nested_under_indifferent_access
21
+ # # => {"b"=>1}
22
+ alias nested_under_indifferent_access with_indifferent_access
23
+ end
@@ -0,0 +1,170 @@
1
+ class Hash
2
+ # Returns 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 } # => {"NAME"=>"Rob", "AGE"=>"28"}
7
+ #
8
+ # If you do not provide a +block+, it will return an Enumerator
9
+ # for chaining with other methods:
10
+ #
11
+ # hash.transform_keys.with_index { |k, i| [k, i].join } # => {"name0"=>"Rob", "age1"=>"28"}
12
+ def transform_keys
13
+ return enum_for(:transform_keys) { size } unless block_given?
14
+ result = {}
15
+ each_key do |key|
16
+ result[yield(key)] = self[key]
17
+ end
18
+ result
19
+ end unless method_defined? :transform_keys
20
+
21
+ # Destructively converts all keys using the +block+ operations.
22
+ # Same as +transform_keys+ but modifies +self+.
23
+ def transform_keys!
24
+ return enum_for(:transform_keys!) { size } unless block_given?
25
+ keys.each do |key|
26
+ self[yield(key)] = delete(key)
27
+ end
28
+ self
29
+ end unless method_defined? :transform_keys!
30
+
31
+ # Returns a new hash with all keys converted to strings.
32
+ #
33
+ # hash = { name: 'Rob', age: '28' }
34
+ #
35
+ # hash.stringify_keys
36
+ # # => {"name"=>"Rob", "age"=>"28"}
37
+ def stringify_keys
38
+ transform_keys(&:to_s)
39
+ end
40
+
41
+ # Destructively converts all keys to strings. Same as
42
+ # +stringify_keys+, but modifies +self+.
43
+ def stringify_keys!
44
+ transform_keys!(&:to_s)
45
+ end
46
+
47
+ # Returns a new hash with all keys converted to symbols, as long as
48
+ # they respond to +to_sym+.
49
+ #
50
+ # hash = { 'name' => 'Rob', 'age' => '28' }
51
+ #
52
+ # hash.symbolize_keys
53
+ # # => {:name=>"Rob", :age=>"28"}
54
+ def symbolize_keys
55
+ transform_keys{ |key| key.to_sym rescue key }
56
+ end
57
+ alias_method :to_options, :symbolize_keys
58
+
59
+ # Destructively converts all keys to symbols, as long as they respond
60
+ # to +to_sym+. Same as +symbolize_keys+, but modifies +self+.
61
+ def symbolize_keys!
62
+ transform_keys!{ |key| key.to_sym rescue key }
63
+ end
64
+ alias_method :to_options!, :symbolize_keys!
65
+
66
+ # Validates all keys in a hash match <tt>*valid_keys</tt>, raising
67
+ # +ArgumentError+ on a mismatch.
68
+ #
69
+ # Note that keys are treated differently than HashWithIndifferentAccess,
70
+ # meaning that string and symbol keys will not match.
71
+ #
72
+ # { name: 'Rob', years: '28' }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key: :years. Valid keys are: :name, :age"
73
+ # { name: 'Rob', age: '28' }.assert_valid_keys('name', 'age') # => raises "ArgumentError: Unknown key: :name. Valid keys are: 'name', 'age'"
74
+ # { name: 'Rob', age: '28' }.assert_valid_keys(:name, :age) # => passes, raises nothing
75
+ def assert_valid_keys(*valid_keys)
76
+ valid_keys.flatten!
77
+ each_key do |k|
78
+ unless valid_keys.include?(k)
79
+ raise ArgumentError.new("Unknown key: #{k.inspect}. Valid keys are: #{valid_keys.map(&:inspect).join(', ')}")
80
+ end
81
+ end
82
+ end
83
+
84
+ # Returns a new hash with all keys converted by the block operation.
85
+ # This includes the keys from the root hash and from all
86
+ # nested hashes and arrays.
87
+ #
88
+ # hash = { person: { name: 'Rob', age: '28' } }
89
+ #
90
+ # hash.deep_transform_keys{ |key| key.to_s.upcase }
91
+ # # => {"PERSON"=>{"NAME"=>"Rob", "AGE"=>"28"}}
92
+ def deep_transform_keys(&block)
93
+ _deep_transform_keys_in_object(self, &block)
94
+ end
95
+
96
+ # Destructively converts all keys by using the block operation.
97
+ # This includes the keys from the root hash and from all
98
+ # nested hashes and arrays.
99
+ def deep_transform_keys!(&block)
100
+ _deep_transform_keys_in_object!(self, &block)
101
+ end
102
+
103
+ # Returns a new hash with all keys converted to strings.
104
+ # This includes the keys from the root hash and from all
105
+ # nested hashes and arrays.
106
+ #
107
+ # hash = { person: { name: 'Rob', age: '28' } }
108
+ #
109
+ # hash.deep_stringify_keys
110
+ # # => {"person"=>{"name"=>"Rob", "age"=>"28"}}
111
+ def deep_stringify_keys
112
+ deep_transform_keys(&:to_s)
113
+ end
114
+
115
+ # Destructively converts all keys to strings.
116
+ # This includes the keys from the root hash and from all
117
+ # nested hashes and arrays.
118
+ def deep_stringify_keys!
119
+ deep_transform_keys!(&:to_s)
120
+ end
121
+
122
+ # Returns a new hash with all keys converted to symbols, as long as
123
+ # they respond to +to_sym+. This includes the keys from the root hash
124
+ # and from all nested hashes and arrays.
125
+ #
126
+ # hash = { 'person' => { 'name' => 'Rob', 'age' => '28' } }
127
+ #
128
+ # hash.deep_symbolize_keys
129
+ # # => {:person=>{:name=>"Rob", :age=>"28"}}
130
+ def deep_symbolize_keys
131
+ deep_transform_keys{ |key| key.to_sym rescue key }
132
+ end
133
+
134
+ # Destructively converts all keys to symbols, as long as they respond
135
+ # to +to_sym+. This includes the keys from the root hash and from all
136
+ # nested hashes and arrays.
137
+ def deep_symbolize_keys!
138
+ deep_transform_keys!{ |key| key.to_sym rescue key }
139
+ end
140
+
141
+ private
142
+ # support methods for deep transforming nested hashes and arrays
143
+ def _deep_transform_keys_in_object(object, &block)
144
+ case object
145
+ when Hash
146
+ object.each_with_object({}) do |(key, value), result|
147
+ result[yield(key)] = _deep_transform_keys_in_object(value, &block)
148
+ end
149
+ when Array
150
+ object.map {|e| _deep_transform_keys_in_object(e, &block) }
151
+ else
152
+ object
153
+ end
154
+ end
155
+
156
+ def _deep_transform_keys_in_object!(object, &block)
157
+ case object
158
+ when Hash
159
+ object.keys.each do |key|
160
+ value = object.delete(key)
161
+ object[yield(key)] = _deep_transform_keys_in_object!(value, &block)
162
+ end
163
+ object
164
+ when Array
165
+ object.map! {|e| _deep_transform_keys_in_object!(e, &block)}
166
+ else
167
+ object
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,22 @@
1
+ class Hash
2
+ # Merges the caller into +other_hash+. For example,
3
+ #
4
+ # options = options.reverse_merge(size: 25, velocity: 10)
5
+ #
6
+ # is equivalent to
7
+ #
8
+ # options = { size: 25, velocity: 10 }.merge(options)
9
+ #
10
+ # This is particularly useful for initializing an options hash
11
+ # with default values.
12
+ def reverse_merge(other_hash)
13
+ other_hash.merge(self)
14
+ end
15
+
16
+ # Destructive +reverse_merge+.
17
+ def reverse_merge!(other_hash)
18
+ # right wins if there is no left
19
+ merge!( other_hash ){|key,left,right| left }
20
+ end
21
+ alias_method :reverse_update, :reverse_merge!
22
+ end
@@ -0,0 +1,48 @@
1
+ class Hash
2
+ # Slices a hash to include only the given keys. Returns a hash containing
3
+ # the given keys.
4
+ #
5
+ # { a: 1, b: 2, c: 3, d: 4 }.slice(:a, :b)
6
+ # # => {:a=>1, :b=>2}
7
+ #
8
+ # This is useful for limiting an options hash to valid keys before
9
+ # passing to a method:
10
+ #
11
+ # def search(criteria = {})
12
+ # criteria.assert_valid_keys(:mass, :velocity, :time)
13
+ # end
14
+ #
15
+ # search(options.slice(:mass, :velocity, :time))
16
+ #
17
+ # If you have an array of keys you want to limit to, you should splat them:
18
+ #
19
+ # valid_keys = [:mass, :velocity, :time]
20
+ # search(options.slice(*valid_keys))
21
+ def slice(*keys)
22
+ keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
23
+ keys.each_with_object(self.class.new) { |k, hash| hash[k] = self[k] if has_key?(k) }
24
+ end
25
+
26
+ # Replaces the hash with only the given keys.
27
+ # Returns a hash containing the removed key/value pairs.
28
+ #
29
+ # { a: 1, b: 2, c: 3, d: 4 }.slice!(:a, :b)
30
+ # # => {:c=>3, :d=>4}
31
+ def slice!(*keys)
32
+ keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
33
+ omit = slice(*self.keys - keys)
34
+ hash = slice(*keys)
35
+ hash.default = default
36
+ hash.default_proc = default_proc if default_proc
37
+ replace(hash)
38
+ omit
39
+ end
40
+
41
+ # Removes and returns the key/value pairs matching the given keys.
42
+ #
43
+ # { a: 1, b: 2, c: 3, d: 4 }.extract!(:a, :b) # => {:a=>1, :b=>2}
44
+ # { a: 1, b: 2 }.extract!(:a, :x) # => {:a=>1}
45
+ def extract!(*keys)
46
+ keys.each_with_object(self.class.new) { |key, result| result[key] = delete(key) if has_key?(key) }
47
+ end
48
+ end
@@ -0,0 +1,29 @@
1
+ class Hash
2
+ # Returns a new hash with the results of running +block+ once for every value.
3
+ # The keys are unchanged.
4
+ #
5
+ # { a: 1, b: 2, c: 3 }.transform_values { |x| x * 2 } # => { a: 2, b: 4, c: 6 }
6
+ #
7
+ # If you do not provide a +block+, it will return an Enumerator
8
+ # for chaining with other methods:
9
+ #
10
+ # { a: 1, b: 2 }.transform_values.with_index { |v, i| [v, i].join.to_i } # => { a: 10, b: 21 }
11
+ def transform_values
12
+ return enum_for(:transform_values) { size } unless block_given?
13
+ return {} if empty?
14
+ result = self.class.new
15
+ each do |key, value|
16
+ result[key] = yield(value)
17
+ end
18
+ result
19
+ end unless method_defined? :transform_values
20
+
21
+ # Destructively converts all values using the +block+ operations.
22
+ # Same as +transform_values+ but modifies +self+.
23
+ def transform_values!
24
+ return enum_for(:transform_values!) { size } unless block_given?
25
+ each do |key, value|
26
+ self[key] = yield(value)
27
+ end
28
+ end unless method_defined? :transform_values!
29
+ end
@@ -0,0 +1,3 @@
1
+ require 'active_support/core_ext/integer/multiple'
2
+ require 'active_support/core_ext/integer/inflections'
3
+ require 'active_support/core_ext/integer/time'
@@ -0,0 +1,29 @@
1
+ require 'active_support/inflector'
2
+
3
+ class Integer
4
+ # Ordinalize turns a number into an ordinal string used to denote the
5
+ # position in an ordered sequence such as 1st, 2nd, 3rd, 4th.
6
+ #
7
+ # 1.ordinalize # => "1st"
8
+ # 2.ordinalize # => "2nd"
9
+ # 1002.ordinalize # => "1002nd"
10
+ # 1003.ordinalize # => "1003rd"
11
+ # -11.ordinalize # => "-11th"
12
+ # -1001.ordinalize # => "-1001st"
13
+ def ordinalize
14
+ ActiveSupport::Inflector.ordinalize(self)
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
29
+ end
@@ -0,0 +1,10 @@
1
+ class Integer
2
+ # Check whether the integer is evenly divisible by the argument.
3
+ #
4
+ # 0.multiple_of?(0) # => true
5
+ # 6.multiple_of?(5) # => false
6
+ # 10.multiple_of?(2) # => true
7
+ def multiple_of?(number)
8
+ number != 0 ? self % number == 0 : zero?
9
+ end
10
+ end
@@ -0,0 +1,29 @@
1
+ require 'active_support/duration'
2
+ require 'active_support/core_ext/numeric/time'
3
+
4
+ class Integer
5
+ # Enables the use of time calculations and declarations, like <tt>45.minutes +
6
+ # 2.hours + 4.years</tt>.
7
+ #
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.
11
+ #
12
+ # # equivalent to Time.now.advance(months: 1)
13
+ # 1.month.from_now
14
+ #
15
+ # # equivalent to Time.now.advance(years: 2)
16
+ # 2.years.from_now
17
+ #
18
+ # # equivalent to Time.now.advance(months: 4, years: 5)
19
+ # (4.months + 5.years).from_now
20
+ def months
21
+ ActiveSupport::Duration.months(self)
22
+ end
23
+ alias :month :months
24
+
25
+ def years
26
+ ActiveSupport::Duration.years(self)
27
+ end
28
+ alias :year :years
29
+ end
@@ -0,0 +1,4 @@
1
+ require 'active_support/core_ext/kernel/agnostics'
2
+ require 'active_support/core_ext/kernel/concern'
3
+ require 'active_support/core_ext/kernel/reporting'
4
+ require 'active_support/core_ext/kernel/singleton_class'
@@ -0,0 +1,11 @@
1
+ class Object
2
+ # Makes backticks behave (somewhat more) similarly on all platforms.
3
+ # On win32 `nonexistent_command` raises Errno::ENOENT; on Unix, the
4
+ # spawned shell prints a message to stderr and sets $?. We emulate
5
+ # Unix on the former but not the latter.
6
+ def `(command) #:nodoc:
7
+ super
8
+ rescue Errno::ENOENT => e
9
+ STDERR.puts "#$0: #{e}"
10
+ end
11
+ end