activesupport 5.0.0 → 6.1.0

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.

Files changed (268) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +343 -590
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +5 -4
  5. data/lib/active_support/actionable_error.rb +48 -0
  6. data/lib/active_support/all.rb +5 -3
  7. data/lib/active_support/array_inquirer.rb +11 -5
  8. data/lib/active_support/backtrace_cleaner.rb +33 -5
  9. data/lib/active_support/benchmarkable.rb +5 -3
  10. data/lib/active_support/builder.rb +3 -1
  11. data/lib/active_support/cache/file_store.rb +45 -53
  12. data/lib/active_support/cache/mem_cache_store.rb +81 -79
  13. data/lib/active_support/cache/memory_store.rb +69 -41
  14. data/lib/active_support/cache/null_store.rb +11 -4
  15. data/lib/active_support/cache/redis_cache_store.rb +493 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +74 -37
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
  18. data/lib/active_support/cache.rb +332 -161
  19. data/lib/active_support/callbacks.rb +657 -586
  20. data/lib/active_support/concern.rb +79 -6
  21. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +35 -0
  22. data/lib/active_support/concurrency/share_lock.rb +59 -19
  23. data/lib/active_support/configurable.rb +15 -17
  24. data/lib/active_support/configuration_file.rb +46 -0
  25. data/lib/active_support/core_ext/array/access.rb +21 -7
  26. data/lib/active_support/core_ext/array/conversions.rb +20 -18
  27. data/lib/active_support/core_ext/array/extract.rb +21 -0
  28. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  29. data/lib/active_support/core_ext/array/grouping.rb +3 -1
  30. data/lib/active_support/core_ext/array/inquiry.rb +3 -1
  31. data/lib/active_support/core_ext/array/wrap.rb +2 -0
  32. data/lib/active_support/core_ext/array.rb +9 -7
  33. data/lib/active_support/core_ext/benchmark.rb +5 -3
  34. data/lib/active_support/core_ext/big_decimal/conversions.rb +6 -6
  35. data/lib/active_support/core_ext/big_decimal.rb +3 -1
  36. data/lib/active_support/core_ext/class/attribute.rb +52 -49
  37. data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
  38. data/lib/active_support/core_ext/class/subclasses.rb +18 -26
  39. data/lib/active_support/core_ext/class.rb +4 -2
  40. data/lib/active_support/core_ext/date/acts_like.rb +3 -1
  41. data/lib/active_support/core_ext/date/blank.rb +3 -1
  42. data/lib/active_support/core_ext/date/calculations.rb +16 -13
  43. data/lib/active_support/core_ext/date/conversions.rb +23 -21
  44. data/lib/active_support/core_ext/date/zones.rb +4 -2
  45. data/lib/active_support/core_ext/date.rb +7 -5
  46. data/lib/active_support/core_ext/date_and_time/calculations.rb +82 -53
  47. data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -5
  48. data/lib/active_support/core_ext/date_and_time/zones.rb +9 -9
  49. data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
  50. data/lib/active_support/core_ext/date_time/blank.rb +3 -1
  51. data/lib/active_support/core_ext/date_time/calculations.rb +23 -11
  52. data/lib/active_support/core_ext/date_time/compatibility.rb +15 -2
  53. data/lib/active_support/core_ext/date_time/conversions.rb +14 -13
  54. data/lib/active_support/core_ext/date_time.rb +7 -5
  55. data/lib/active_support/core_ext/digest/uuid.rb +7 -5
  56. data/lib/active_support/core_ext/digest.rb +3 -0
  57. data/lib/active_support/core_ext/enumerable.rb +165 -29
  58. data/lib/active_support/core_ext/file/atomic.rb +7 -5
  59. data/lib/active_support/core_ext/file.rb +3 -1
  60. data/lib/active_support/core_ext/hash/conversions.rb +40 -39
  61. data/lib/active_support/core_ext/hash/deep_merge.rb +8 -12
  62. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  63. data/lib/active_support/core_ext/hash/except.rb +4 -2
  64. data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -2
  65. data/lib/active_support/core_ext/hash/keys.rb +9 -36
  66. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  67. data/lib/active_support/core_ext/hash/slice.rb +8 -29
  68. data/lib/active_support/core_ext/hash.rb +10 -9
  69. data/lib/active_support/core_ext/integer/inflections.rb +3 -1
  70. data/lib/active_support/core_ext/integer/multiple.rb +3 -1
  71. data/lib/active_support/core_ext/integer/time.rb +11 -18
  72. data/lib/active_support/core_ext/integer.rb +5 -3
  73. data/lib/active_support/core_ext/kernel/concern.rb +3 -1
  74. data/lib/active_support/core_ext/kernel/reporting.rb +3 -1
  75. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  76. data/lib/active_support/core_ext/kernel.rb +5 -4
  77. data/lib/active_support/core_ext/load_error.rb +2 -23
  78. data/lib/active_support/core_ext/marshal.rb +6 -2
  79. data/lib/active_support/core_ext/module/aliasing.rb +5 -48
  80. data/lib/active_support/core_ext/module/anonymous.rb +2 -0
  81. data/lib/active_support/core_ext/module/attr_internal.rb +7 -5
  82. data/lib/active_support/core_ext/module/attribute_accessors.rb +53 -59
  83. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +31 -24
  84. data/lib/active_support/core_ext/module/concerning.rb +16 -11
  85. data/lib/active_support/core_ext/module/delegation.rb +159 -44
  86. data/lib/active_support/core_ext/module/deprecation.rb +2 -0
  87. data/lib/active_support/core_ext/module/introspection.rb +23 -26
  88. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  89. data/lib/active_support/core_ext/module/remove_method.rb +5 -23
  90. data/lib/active_support/core_ext/module.rb +13 -12
  91. data/lib/active_support/core_ext/name_error.rb +36 -2
  92. data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
  93. data/lib/active_support/core_ext/numeric/conversions.rb +129 -134
  94. data/lib/active_support/core_ext/numeric/time.rb +18 -26
  95. data/lib/active_support/core_ext/numeric.rb +5 -4
  96. data/lib/active_support/core_ext/object/acts_like.rb +12 -1
  97. data/lib/active_support/core_ext/object/blank.rb +14 -2
  98. data/lib/active_support/core_ext/object/conversions.rb +6 -4
  99. data/lib/active_support/core_ext/object/deep_dup.rb +4 -2
  100. data/lib/active_support/core_ext/object/duplicable.rb +13 -62
  101. data/lib/active_support/core_ext/object/inclusion.rb +3 -1
  102. data/lib/active_support/core_ext/object/instance_variables.rb +2 -0
  103. data/lib/active_support/core_ext/object/json.rb +42 -15
  104. data/lib/active_support/core_ext/object/to_param.rb +3 -1
  105. data/lib/active_support/core_ext/object/to_query.rb +10 -5
  106. data/lib/active_support/core_ext/object/try.rb +20 -8
  107. data/lib/active_support/core_ext/object/with_options.rb +15 -2
  108. data/lib/active_support/core_ext/object.rb +14 -12
  109. data/lib/active_support/core_ext/range/compare_range.rb +82 -0
  110. data/lib/active_support/core_ext/range/conversions.rb +35 -25
  111. data/lib/active_support/core_ext/range/each.rb +5 -2
  112. data/lib/active_support/core_ext/range/include_time_with_zone.rb +28 -0
  113. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  114. data/lib/active_support/core_ext/range.rb +7 -4
  115. data/lib/active_support/core_ext/regexp.rb +10 -1
  116. data/lib/active_support/core_ext/securerandom.rb +28 -6
  117. data/lib/active_support/core_ext/string/access.rb +9 -18
  118. data/lib/active_support/core_ext/string/behavior.rb +2 -0
  119. data/lib/active_support/core_ext/string/conversions.rb +5 -2
  120. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  121. data/lib/active_support/core_ext/string/filters.rb +47 -4
  122. data/lib/active_support/core_ext/string/indent.rb +6 -4
  123. data/lib/active_support/core_ext/string/inflections.rb +78 -29
  124. data/lib/active_support/core_ext/string/inquiry.rb +4 -1
  125. data/lib/active_support/core_ext/string/multibyte.rb +10 -5
  126. data/lib/active_support/core_ext/string/output_safety.rb +86 -31
  127. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
  128. data/lib/active_support/core_ext/string/strip.rb +5 -1
  129. data/lib/active_support/core_ext/string/zones.rb +4 -2
  130. data/lib/active_support/core_ext/string.rb +15 -13
  131. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +14 -0
  132. data/lib/active_support/core_ext/symbol.rb +3 -0
  133. data/lib/active_support/core_ext/time/acts_like.rb +3 -1
  134. data/lib/active_support/core_ext/time/calculations.rb +117 -45
  135. data/lib/active_support/core_ext/time/compatibility.rb +13 -2
  136. data/lib/active_support/core_ext/time/conversions.rb +18 -12
  137. data/lib/active_support/core_ext/time/zones.rb +9 -7
  138. data/lib/active_support/core_ext/time.rb +7 -5
  139. data/lib/active_support/core_ext/uri.rb +12 -7
  140. data/lib/active_support/core_ext.rb +3 -2
  141. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  142. data/lib/active_support/current_attributes.rb +208 -0
  143. data/lib/active_support/dependencies/autoload.rb +2 -0
  144. data/lib/active_support/dependencies/interlock.rb +7 -1
  145. data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
  146. data/lib/active_support/dependencies.rb +172 -98
  147. data/lib/active_support/deprecation/behaviors.rb +45 -13
  148. data/lib/active_support/deprecation/constant_accessor.rb +52 -0
  149. data/lib/active_support/deprecation/disallowed.rb +56 -0
  150. data/lib/active_support/deprecation/instance_delegator.rb +16 -2
  151. data/lib/active_support/deprecation/method_wrappers.rb +32 -17
  152. data/lib/active_support/deprecation/proxy_wrappers.rb +35 -7
  153. data/lib/active_support/deprecation/reporting.rb +61 -16
  154. data/lib/active_support/deprecation.rb +17 -9
  155. data/lib/active_support/descendants_tracker.rb +61 -9
  156. data/lib/active_support/digest.rb +20 -0
  157. data/lib/active_support/duration/iso8601_parser.rb +67 -66
  158. data/lib/active_support/duration/iso8601_serializer.rb +25 -17
  159. data/lib/active_support/duration.rb +349 -46
  160. data/lib/active_support/encrypted_configuration.rb +45 -0
  161. data/lib/active_support/encrypted_file.rb +117 -0
  162. data/lib/active_support/environment_inquirer.rb +20 -0
  163. data/lib/active_support/evented_file_update_checker.rb +88 -112
  164. data/lib/active_support/execution_wrapper.rb +25 -13
  165. data/lib/active_support/executor.rb +3 -1
  166. data/lib/active_support/file_update_checker.rb +56 -51
  167. data/lib/active_support/fork_tracker.rb +62 -0
  168. data/lib/active_support/gem_version.rb +4 -2
  169. data/lib/active_support/gzip.rb +7 -5
  170. data/lib/active_support/hash_with_indifferent_access.rb +153 -49
  171. data/lib/active_support/i18n.rb +9 -6
  172. data/lib/active_support/i18n_railtie.rb +30 -20
  173. data/lib/active_support/inflections.rb +13 -11
  174. data/lib/active_support/inflector/inflections.rb +28 -15
  175. data/lib/active_support/inflector/methods.rb +120 -109
  176. data/lib/active_support/inflector/transliterate.rb +60 -25
  177. data/lib/active_support/inflector.rb +7 -5
  178. data/lib/active_support/json/decoding.rb +30 -29
  179. data/lib/active_support/json/encoding.rb +22 -11
  180. data/lib/active_support/json.rb +4 -2
  181. data/lib/active_support/key_generator.rb +6 -36
  182. data/lib/active_support/lazy_load_hooks.rb +53 -20
  183. data/lib/active_support/locale/en.rb +33 -0
  184. data/lib/active_support/locale/en.yml +7 -3
  185. data/lib/active_support/log_subscriber/test_helper.rb +11 -9
  186. data/lib/active_support/log_subscriber.rb +51 -18
  187. data/lib/active_support/logger.rb +9 -22
  188. data/lib/active_support/logger_silence.rb +14 -21
  189. data/lib/active_support/logger_thread_safe_level.rb +55 -8
  190. data/lib/active_support/message_encryptor.rb +170 -53
  191. data/lib/active_support/message_verifier.rb +91 -20
  192. data/lib/active_support/messages/metadata.rb +80 -0
  193. data/lib/active_support/messages/rotation_configuration.rb +23 -0
  194. data/lib/active_support/messages/rotator.rb +57 -0
  195. data/lib/active_support/multibyte/chars.rb +24 -78
  196. data/lib/active_support/multibyte/unicode.rb +21 -352
  197. data/lib/active_support/multibyte.rb +4 -2
  198. data/lib/active_support/notifications/fanout.rb +121 -19
  199. data/lib/active_support/notifications/instrumenter.rb +78 -14
  200. data/lib/active_support/notifications.rb +80 -12
  201. data/lib/active_support/number_helper/number_converter.rb +17 -16
  202. data/lib/active_support/number_helper/number_to_currency_converter.rb +6 -9
  203. data/lib/active_support/number_helper/number_to_delimited_converter.rb +5 -3
  204. data/lib/active_support/number_helper/number_to_human_converter.rb +13 -12
  205. data/lib/active_support/number_helper/number_to_human_size_converter.rb +11 -13
  206. data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
  207. data/lib/active_support/number_helper/number_to_phone_converter.rb +5 -4
  208. data/lib/active_support/number_helper/number_to_rounded_converter.rb +18 -55
  209. data/lib/active_support/number_helper/rounding_helper.rb +50 -0
  210. data/lib/active_support/number_helper.rb +45 -16
  211. data/lib/active_support/option_merger.rb +25 -4
  212. data/lib/active_support/ordered_hash.rb +6 -4
  213. data/lib/active_support/ordered_options.rb +23 -9
  214. data/lib/active_support/parameter_filter.rb +133 -0
  215. data/lib/active_support/per_thread_registry.rb +7 -5
  216. data/lib/active_support/proxy_object.rb +2 -0
  217. data/lib/active_support/rails.rb +8 -9
  218. data/lib/active_support/railtie.rb +62 -11
  219. data/lib/active_support/reloader.rb +12 -11
  220. data/lib/active_support/rescuable.rb +20 -11
  221. data/lib/active_support/secure_compare_rotator.rb +51 -0
  222. data/lib/active_support/security_utils.rb +26 -15
  223. data/lib/active_support/string_inquirer.rb +12 -3
  224. data/lib/active_support/subscriber.rb +77 -23
  225. data/lib/active_support/tagged_logging.rb +52 -17
  226. data/lib/active_support/test_case.rb +106 -29
  227. data/lib/active_support/testing/assertions.rb +144 -8
  228. data/lib/active_support/testing/autorun.rb +5 -10
  229. data/lib/active_support/testing/constant_lookup.rb +2 -1
  230. data/lib/active_support/testing/declarative.rb +3 -1
  231. data/lib/active_support/testing/deprecation.rb +4 -2
  232. data/lib/active_support/testing/file_fixtures.rb +4 -0
  233. data/lib/active_support/testing/isolation.rb +19 -24
  234. data/lib/active_support/testing/method_call_assertions.rb +31 -2
  235. data/lib/active_support/testing/parallelization/server.rb +78 -0
  236. data/lib/active_support/testing/parallelization/worker.rb +100 -0
  237. data/lib/active_support/testing/parallelization.rb +51 -0
  238. data/lib/active_support/testing/setup_and_teardown.rb +13 -8
  239. data/lib/active_support/testing/stream.rb +30 -29
  240. data/lib/active_support/testing/tagged_logging.rb +3 -1
  241. data/lib/active_support/testing/time_helpers.rb +125 -24
  242. data/lib/active_support/time.rb +14 -12
  243. data/lib/active_support/time_with_zone.rb +142 -55
  244. data/lib/active_support/values/time_zone.rb +160 -53
  245. data/lib/active_support/version.rb +3 -1
  246. data/lib/active_support/xml_mini/jdom.rb +115 -114
  247. data/lib/active_support/xml_mini/libxml.rb +15 -14
  248. data/lib/active_support/xml_mini/libxmlsax.rb +16 -18
  249. data/lib/active_support/xml_mini/nokogiri.rb +13 -13
  250. data/lib/active_support/xml_mini/nokogirisax.rb +15 -16
  251. data/lib/active_support/xml_mini/rexml.rb +18 -9
  252. data/lib/active_support/xml_mini.rb +44 -42
  253. data/lib/active_support.rb +19 -10
  254. metadata +79 -37
  255. data/lib/active_support/concurrency/latch.rb +0 -19
  256. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
  257. data/lib/active_support/core_ext/hash/compact.rb +0 -20
  258. data/lib/active_support/core_ext/hash/transform_values.rb +0 -29
  259. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
  260. data/lib/active_support/core_ext/kernel/debugger.rb +0 -3
  261. data/lib/active_support/core_ext/module/method_transplanting.rb +0 -3
  262. data/lib/active_support/core_ext/module/qualified_const.rb +0 -70
  263. data/lib/active_support/core_ext/module/reachable.rb +0 -8
  264. data/lib/active_support/core_ext/numeric/inquiry.rb +0 -26
  265. data/lib/active_support/core_ext/range/include_range.rb +0 -23
  266. data/lib/active_support/core_ext/struct.rb +0 -3
  267. data/lib/active_support/core_ext/time/marshal.rb +0 -3
  268. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,5 +1,8 @@
1
- require 'active_support/core_ext/hash/keys'
2
- require 'active_support/core_ext/hash/reverse_merge'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/hash/keys"
4
+ require "active_support/core_ext/hash/reverse_merge"
5
+ require "active_support/core_ext/hash/except"
3
6
 
4
7
  module ActiveSupport
5
8
  # Implements a hash where keys <tt>:foo</tt> and <tt>"foo"</tt> are considered
@@ -40,6 +43,12 @@ module ActiveSupport
40
43
  # rgb = { black: '#000000', white: '#FFFFFF' }.with_indifferent_access
41
44
  #
42
45
  # which may be handy.
46
+ #
47
+ # To access this class outside of Rails, require the core extension with:
48
+ #
49
+ # require "active_support/core_ext/hash/indifferent_access"
50
+ #
51
+ # which will, in turn, require this file.
43
52
  class HashWithIndifferentAccess < Hash
44
53
  # Returns +true+ so that <tt>Array#extract_options!</tt> finds members of
45
54
  # this class.
@@ -60,7 +69,7 @@ module ActiveSupport
60
69
  super()
61
70
  update(constructor)
62
71
 
63
- hash = constructor.to_hash
72
+ hash = constructor.is_a?(Hash) ? constructor : constructor.to_hash
64
73
  self.default = hash.default if hash.default
65
74
  self.default_proc = hash.default_proc if hash.default_proc
66
75
  else
@@ -68,25 +77,6 @@ module ActiveSupport
68
77
  end
69
78
  end
70
79
 
71
- def default(*args)
72
- arg_key = args.first
73
-
74
- if include?(key = convert_key(arg_key))
75
- self[key]
76
- else
77
- super
78
- end
79
- end
80
-
81
- def self.new_from_hash_copying_default(hash)
82
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
83
- `ActiveSupport::HashWithIndifferentAccess.new_from_hash_copying_default`
84
- has been deprecated, and will be removed in Rails 5.1. The behavior of
85
- this method is now identical to the behavior of `.new`.
86
- MSG
87
- new(hash)
88
- end
89
-
90
80
  def self.[](*args)
91
81
  new.merge!(Hash[*args])
92
82
  end
@@ -101,12 +91,12 @@ module ActiveSupport
101
91
  #
102
92
  # This value can be later fetched using either +:key+ or <tt>'key'</tt>.
103
93
  def []=(key, value)
104
- regular_writer(convert_key(key), convert_value(value, for: :assignment))
94
+ regular_writer(convert_key(key), convert_value(value, conversion: :assignment))
105
95
  end
106
96
 
107
97
  alias_method :store, :[]=
108
98
 
109
- # Updates the receiver in-place, merging in the hash passed as argument:
99
+ # Updates the receiver in-place, merging in the hashes passed as arguments:
110
100
  #
111
101
  # hash_1 = ActiveSupport::HashWithIndifferentAccess.new
112
102
  # hash_1[:key] = 'value'
@@ -116,7 +106,10 @@ module ActiveSupport
116
106
  #
117
107
  # hash_1.update(hash_2) # => {"key"=>"New Value!"}
118
108
  #
119
- # The argument can be either an
109
+ # hash = ActiveSupport::HashWithIndifferentAccess.new
110
+ # hash.update({ "a" => 1 }, { "b" => 2 }) # => { "a" => 1, "b" => 2 }
111
+ #
112
+ # The arguments can be either an
120
113
  # <tt>ActiveSupport::HashWithIndifferentAccess</tt> or a regular +Hash+.
121
114
  # In either case the merge respects the semantics of indifferent access.
122
115
  #
@@ -131,18 +124,15 @@ module ActiveSupport
131
124
  # hash_1[:key] = 10
132
125
  # hash_2['key'] = 12
133
126
  # hash_1.update(hash_2) { |key, old, new| old + new } # => {"key"=>22}
134
- def update(other_hash)
135
- if other_hash.is_a? HashWithIndifferentAccess
136
- super(other_hash)
127
+ def update(*other_hashes, &block)
128
+ if other_hashes.size == 1
129
+ update_with_single_argument(other_hashes.first, block)
137
130
  else
138
- other_hash.to_hash.each_pair do |key, value|
139
- if block_given? && key?(key)
140
- value = yield(convert_key(key), self[key], value)
141
- end
142
- regular_writer(convert_key(key), convert_value(value))
131
+ other_hashes.each do |other_hash|
132
+ update_with_single_argument(other_hash, block)
143
133
  end
144
- self
145
134
  end
135
+ self
146
136
  end
147
137
 
148
138
  alias_method :merge!, :update
@@ -161,7 +151,6 @@ module ActiveSupport
161
151
  alias_method :has_key?, :key?
162
152
  alias_method :member?, :key?
163
153
 
164
-
165
154
  # Same as <tt>Hash#[]</tt> where the key passed as argument can be
166
155
  # either a string or a symbol:
167
156
  #
@@ -175,6 +164,19 @@ module ActiveSupport
175
164
  super(convert_key(key))
176
165
  end
177
166
 
167
+ # Same as <tt>Hash#assoc</tt> where the key passed as argument can be
168
+ # either a string or a symbol:
169
+ #
170
+ # counters = ActiveSupport::HashWithIndifferentAccess.new
171
+ # counters[:foo] = 1
172
+ #
173
+ # counters.assoc('foo') # => ["foo", 1]
174
+ # counters.assoc(:foo) # => ["foo", 1]
175
+ # counters.assoc(:zoo) # => nil
176
+ def assoc(key)
177
+ super(convert_key(key))
178
+ end
179
+
178
180
  # Same as <tt>Hash#fetch</tt> where the key passed as argument can be
179
181
  # either a string or a symbol:
180
182
  #
@@ -189,14 +191,55 @@ module ActiveSupport
189
191
  super(convert_key(key), *extras)
190
192
  end
191
193
 
194
+ # Same as <tt>Hash#dig</tt> where the key passed as argument can be
195
+ # either a string or a symbol:
196
+ #
197
+ # counters = ActiveSupport::HashWithIndifferentAccess.new
198
+ # counters[:foo] = { bar: 1 }
199
+ #
200
+ # counters.dig('foo', 'bar') # => 1
201
+ # counters.dig(:foo, :bar) # => 1
202
+ # counters.dig(:zoo) # => nil
203
+ def dig(*args)
204
+ args[0] = convert_key(args[0]) if args.size > 0
205
+ super(*args)
206
+ end
207
+
208
+ # Same as <tt>Hash#default</tt> where the key passed as argument can be
209
+ # either a string or a symbol:
210
+ #
211
+ # hash = ActiveSupport::HashWithIndifferentAccess.new(1)
212
+ # hash.default # => 1
213
+ #
214
+ # hash = ActiveSupport::HashWithIndifferentAccess.new { |hash, key| key }
215
+ # hash.default # => nil
216
+ # hash.default('foo') # => 'foo'
217
+ # hash.default(:foo) # => 'foo'
218
+ def default(*args)
219
+ super(*args.map { |arg| convert_key(arg) })
220
+ end
221
+
192
222
  # Returns an array of the values at the specified indices:
193
223
  #
194
224
  # hash = ActiveSupport::HashWithIndifferentAccess.new
195
225
  # hash[:a] = 'x'
196
226
  # hash[:b] = 'y'
197
227
  # hash.values_at('a', 'b') # => ["x", "y"]
198
- def values_at(*indices)
199
- indices.collect { |key| self[convert_key(key)] }
228
+ def values_at(*keys)
229
+ super(*keys.map { |key| convert_key(key) })
230
+ end
231
+
232
+ # Returns an array of the values at the specified indices, but also
233
+ # raises an exception when one of the keys can't be found.
234
+ #
235
+ # hash = ActiveSupport::HashWithIndifferentAccess.new
236
+ # hash[:a] = 'x'
237
+ # hash[:b] = 'y'
238
+ # hash.fetch_values('a', 'b') # => ["x", "y"]
239
+ # hash.fetch_values('a', 'c') { |key| 'z' } # => ["x", "z"]
240
+ # hash.fetch_values('a', 'c') # => KeyError: key not found: "c"
241
+ def fetch_values(*indices, &block)
242
+ super(*indices.map { |key| convert_key(key) }, &block)
200
243
  end
201
244
 
202
245
  # Returns a shallow copy of the hash.
@@ -205,7 +248,7 @@ module ActiveSupport
205
248
  # dup = hash.dup
206
249
  # dup[:a][:c] = 'c'
207
250
  #
208
- # hash[:a][:c] # => nil
251
+ # hash[:a][:c] # => "c"
209
252
  # dup[:a][:c] # => "c"
210
253
  def dup
211
254
  self.class.new(self).tap do |new_hash|
@@ -216,8 +259,8 @@ module ActiveSupport
216
259
  # This method has the same semantics of +update+, except it does not
217
260
  # modify the receiver but rather returns a new hash with indifferent
218
261
  # access with the result of the merge.
219
- def merge(hash, &block)
220
- self.dup.update(hash, &block)
262
+ def merge(*hashes, &block)
263
+ dup.update(*hashes, &block)
221
264
  end
222
265
 
223
266
  # Like +merge+ but the other way around: Merges the receiver into the
@@ -229,11 +272,13 @@ module ActiveSupport
229
272
  def reverse_merge(other_hash)
230
273
  super(self.class.new(other_hash))
231
274
  end
275
+ alias_method :with_defaults, :reverse_merge
232
276
 
233
277
  # Same semantics as +reverse_merge+ but modifies the receiver in-place.
234
278
  def reverse_merge!(other_hash)
235
- replace(reverse_merge( other_hash ))
279
+ super(self.class.new(other_hash))
236
280
  end
281
+ alias_method :with_defaults!, :reverse_merge!
237
282
 
238
283
  # Replaces the contents of this hash with other_hash.
239
284
  #
@@ -248,6 +293,11 @@ module ActiveSupport
248
293
  super(convert_key(key))
249
294
  end
250
295
 
296
+ def except(*keys)
297
+ slice(*self.keys - keys.map { |key| convert_key(key) })
298
+ end
299
+ alias_method :without, :except
300
+
251
301
  def stringify_keys!; self end
252
302
  def deep_stringify_keys!; self end
253
303
  def stringify_keys; dup end
@@ -255,6 +305,7 @@ module ActiveSupport
255
305
  undef :symbolize_keys!
256
306
  undef :deep_symbolize_keys!
257
307
  def symbolize_keys; to_hash.symbolize_keys! end
308
+ alias_method :to_options, :symbolize_keys
258
309
  def deep_symbolize_keys; to_hash.deep_symbolize_keys! end
259
310
  def to_options!; self end
260
311
 
@@ -268,34 +319,72 @@ module ActiveSupport
268
319
  dup.tap { |hash| hash.reject!(*args, &block) }
269
320
  end
270
321
 
322
+ def transform_values(*args, &block)
323
+ return to_enum(:transform_values) unless block_given?
324
+ dup.tap { |hash| hash.transform_values!(*args, &block) }
325
+ end
326
+
327
+ def transform_keys(*args, &block)
328
+ return to_enum(:transform_keys) unless block_given?
329
+ dup.tap { |hash| hash.transform_keys!(*args, &block) }
330
+ end
331
+
332
+ def transform_keys!
333
+ return enum_for(:transform_keys!) { size } unless block_given?
334
+ keys.each do |key|
335
+ self[yield(key)] = delete(key)
336
+ end
337
+ self
338
+ end
339
+
340
+ def slice(*keys)
341
+ keys.map! { |key| convert_key(key) }
342
+ self.class.new(super)
343
+ end
344
+
345
+ def slice!(*keys)
346
+ keys.map! { |key| convert_key(key) }
347
+ super
348
+ end
349
+
350
+ def compact
351
+ dup.tap(&:compact!)
352
+ end
353
+
271
354
  # Convert to a regular hash with string keys.
272
355
  def to_hash
273
356
  _new_hash = Hash.new
274
357
  set_defaults(_new_hash)
275
358
 
276
359
  each do |key, value|
277
- _new_hash[key] = convert_value(value, for: :to_hash)
360
+ _new_hash[key] = convert_value(value, conversion: :to_hash)
278
361
  end
279
362
  _new_hash
280
363
  end
281
364
 
282
- protected
283
- def convert_key(key)
284
- key.kind_of?(Symbol) ? key.to_s : key
365
+ private
366
+ if Symbol.method_defined?(:name)
367
+ def convert_key(key)
368
+ key.kind_of?(Symbol) ? key.name : key
369
+ end
370
+ else
371
+ def convert_key(key)
372
+ key.kind_of?(Symbol) ? key.to_s : key
373
+ end
285
374
  end
286
375
 
287
- def convert_value(value, options = {})
376
+ def convert_value(value, conversion: nil)
288
377
  if value.is_a? Hash
289
- if options[:for] == :to_hash
378
+ if conversion == :to_hash
290
379
  value.to_hash
291
380
  else
292
381
  value.nested_under_indifferent_access
293
382
  end
294
383
  elsif value.is_a?(Array)
295
- if options[:for] != :assignment || value.frozen?
384
+ if conversion != :assignment || value.frozen?
296
385
  value = value.dup
297
386
  end
298
- value.map! { |e| convert_value(e, options) }
387
+ value.map! { |e| convert_value(e, conversion: conversion) }
299
388
  else
300
389
  value
301
390
  end
@@ -308,7 +397,22 @@ module ActiveSupport
308
397
  target.default = default
309
398
  end
310
399
  end
400
+
401
+ def update_with_single_argument(other_hash, block)
402
+ if other_hash.is_a? HashWithIndifferentAccess
403
+ regular_update(other_hash, &block)
404
+ else
405
+ other_hash.to_hash.each_pair do |key, value|
406
+ if block && key?(key)
407
+ value = block.call(convert_key(key), self[key], value)
408
+ end
409
+ regular_writer(convert_key(key), convert_value(value))
410
+ end
411
+ end
412
+ end
311
413
  end
312
414
  end
313
415
 
416
+ # :stopdoc:
417
+
314
418
  HashWithIndifferentAccess = ActiveSupport::HashWithIndifferentAccess
@@ -1,13 +1,16 @@
1
- require 'active_support/core_ext/hash/deep_merge'
2
- require 'active_support/core_ext/hash/except'
3
- require 'active_support/core_ext/hash/slice'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/hash/deep_merge"
4
+ require "active_support/core_ext/hash/except"
5
+ require "active_support/core_ext/hash/slice"
4
6
  begin
5
- require 'i18n'
7
+ require "i18n"
6
8
  rescue LoadError => e
7
9
  $stderr.puts "The i18n gem is not available. Please add it to your Gemfile and run bundle install"
8
10
  raise e
9
11
  end
10
- require 'active_support/lazy_load_hooks'
12
+ require "active_support/lazy_load_hooks"
11
13
 
12
14
  ActiveSupport.run_load_hooks(:i18n)
13
- I18n.load_path << "#{File.dirname(__FILE__)}/locale/en.yml"
15
+ I18n.load_path << File.expand_path("locale/en.yml", __dir__)
16
+ I18n.load_path << File.expand_path("locale/en.rb", __dir__)
@@ -1,7 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support"
2
- require "active_support/file_update_checker"
3
4
  require "active_support/core_ext/array/wrap"
4
5
 
6
+ # :enddoc:
7
+
5
8
  module I18n
6
9
  class Railtie < Rails::Railtie
7
10
  config.i18n = ActiveSupport::OrderedOptions.new
@@ -9,6 +12,8 @@ module I18n
9
12
  config.i18n.load_path = []
10
13
  config.i18n.fallbacks = ActiveSupport::OrderedOptions.new
11
14
 
15
+ config.eager_load_namespaces << I18n
16
+
12
17
  # Set the i18n configuration after initialization since a lot of
13
18
  # configuration is still usually done in application initializers.
14
19
  config.after_initialize do |app|
@@ -21,8 +26,6 @@ module I18n
21
26
  I18n::Railtie.initialize_i18n(app)
22
27
  end
23
28
 
24
- protected
25
-
26
29
  @i18n_inited = false
27
30
 
28
31
  # Setup i18n configuration.
@@ -42,11 +45,13 @@ module I18n
42
45
  case setting
43
46
  when :railties_load_path
44
47
  reloadable_paths = value
45
- app.config.i18n.load_path.unshift(*value.map(&:existent).flatten)
48
+ app.config.i18n.load_path.unshift(*value.flat_map(&:existent))
46
49
  when :load_path
47
50
  I18n.load_path += value
51
+ when :raise_on_missing_translations
52
+ forward_raise_on_missing_translations_config(app)
48
53
  else
49
- I18n.send("#{setting}=", value)
54
+ I18n.public_send("#{setting}=", value)
50
55
  end
51
56
  end
52
57
 
@@ -58,24 +63,28 @@ module I18n
58
63
  directories = watched_dirs_with_extensions(reloadable_paths)
59
64
  reloader = app.config.file_watcher.new(I18n.load_path.dup, directories) do
60
65
  I18n.load_path.keep_if { |p| File.exist?(p) }
61
- I18n.load_path |= reloadable_paths.map(&:existent).flatten
62
-
63
- I18n.reload!
66
+ I18n.load_path |= reloadable_paths.flat_map(&:existent)
64
67
  end
65
68
 
66
69
  app.reloaders << reloader
67
70
  app.reloader.to_run do
68
71
  reloader.execute_if_updated { require_unload_lock! }
69
- # TODO: remove the following line as soon as the return value of
70
- # callbacks is ignored, that is, returning `false` does not
71
- # display a deprecation warning or halts the callback chain.
72
- true
73
72
  end
74
73
  reloader.execute
75
74
 
76
75
  @i18n_inited = true
77
76
  end
78
77
 
78
+ def self.forward_raise_on_missing_translations_config(app)
79
+ ActiveSupport.on_load(:action_view) do
80
+ self.raise_on_missing_translations = app.config.i18n.raise_on_missing_translations
81
+ end
82
+
83
+ ActiveSupport.on_load(:action_controller) do
84
+ AbstractController::Translation.raise_on_missing_translations = app.config.i18n.raise_on_missing_translations
85
+ end
86
+ end
87
+
79
88
  def self.include_fallbacks_module
80
89
  I18n.backend.class.include(I18n::Backend::Fallbacks)
81
90
  end
@@ -83,14 +92,15 @@ module I18n
83
92
  def self.init_fallbacks(fallbacks)
84
93
  include_fallbacks_module
85
94
 
86
- args = case fallbacks
87
- when ActiveSupport::OrderedOptions
88
- [*(fallbacks[:defaults] || []) << fallbacks[:map]].compact
89
- when Hash, Array
90
- Array.wrap(fallbacks)
91
- else # TrueClass
92
- []
93
- end
95
+ args = \
96
+ case fallbacks
97
+ when ActiveSupport::OrderedOptions
98
+ [*(fallbacks[:defaults] || []) << fallbacks[:map]].compact
99
+ when Hash, Array
100
+ Array.wrap(fallbacks)
101
+ else # TrueClass
102
+ [I18n.default_locale]
103
+ end
94
104
 
95
105
  I18n.fallbacks = I18n::Locale::Fallbacks.new(*args)
96
106
  end
@@ -1,4 +1,6 @@
1
- require 'active_support/inflector/inflections'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/inflector/inflections"
2
4
 
3
5
  #--
4
6
  # Defines the standard inflection rules. These are the starting point for
@@ -8,8 +10,8 @@ require 'active_support/inflector/inflections'
8
10
  #++
9
11
  module ActiveSupport
10
12
  Inflector.inflections(:en) do |inflect|
11
- inflect.plural(/$/, 's')
12
- inflect.plural(/s$/i, 's')
13
+ inflect.plural(/$/, "s")
14
+ inflect.plural(/s$/i, "s")
13
15
  inflect.plural(/^(ax|test)is$/i, '\1es')
14
16
  inflect.plural(/(octop|vir)us$/i, '\1i')
15
17
  inflect.plural(/(octop|vir)i$/i, '\1i')
@@ -18,7 +20,7 @@ module ActiveSupport
18
20
  inflect.plural(/(buffal|tomat)o$/i, '\1oes')
19
21
  inflect.plural(/([ti])um$/i, '\1a')
20
22
  inflect.plural(/([ti])a$/i, '\1a')
21
- inflect.plural(/sis$/i, 'ses')
23
+ inflect.plural(/sis$/i, "ses")
22
24
  inflect.plural(/(?:([^f])fe|([lr])f)$/i, '\1\2ves')
23
25
  inflect.plural(/(hive)$/i, '\1s')
24
26
  inflect.plural(/([^aeiouy]|qu)y$/i, '\1ies')
@@ -30,7 +32,7 @@ module ActiveSupport
30
32
  inflect.plural(/^(oxen)$/i, '\1')
31
33
  inflect.plural(/(quiz)$/i, '\1zes')
32
34
 
33
- inflect.singular(/s$/i, '')
35
+ inflect.singular(/s$/i, "")
34
36
  inflect.singular(/(ss)$/i, '\1')
35
37
  inflect.singular(/(n)ews$/i, '\1ews')
36
38
  inflect.singular(/([ti])a$/i, '\1um')
@@ -58,12 +60,12 @@ module ActiveSupport
58
60
  inflect.singular(/(quiz)zes$/i, '\1')
59
61
  inflect.singular(/(database)s$/i, '\1')
60
62
 
61
- inflect.irregular('person', 'people')
62
- inflect.irregular('man', 'men')
63
- inflect.irregular('child', 'children')
64
- inflect.irregular('sex', 'sexes')
65
- inflect.irregular('move', 'moves')
66
- inflect.irregular('zombie', 'zombies')
63
+ inflect.irregular("person", "people")
64
+ inflect.irregular("man", "men")
65
+ inflect.irregular("child", "children")
66
+ inflect.irregular("sex", "sexes")
67
+ inflect.irregular("move", "moves")
68
+ inflect.irregular("zombie", "zombies")
67
69
 
68
70
  inflect.uncountable(%w(equipment information rice money species series fish sheep jeans police))
69
71
  end
@@ -1,6 +1,7 @@
1
- require 'concurrent/map'
2
- require 'active_support/core_ext/array/prepend_and_append'
3
- require 'active_support/i18n'
1
+ # frozen_string_literal: true
2
+
3
+ require "concurrent/map"
4
+ require "active_support/i18n"
4
5
 
5
6
  module ActiveSupport
6
7
  module Inflector
@@ -43,13 +44,14 @@ module ActiveSupport
43
44
  end
44
45
 
45
46
  def add(words)
46
- self.concat(words.flatten.map(&:downcase))
47
- @regex_array += self.map {|word| to_regex(word) }
47
+ words = words.flatten.map(&:downcase)
48
+ concat(words)
49
+ @regex_array += words.map { |word| to_regex(word) }
48
50
  self
49
51
  end
50
52
 
51
53
  def uncountable?(str)
52
- @regex_array.any? { |regex| regex === str }
54
+ @regex_array.any? { |regex| regex.match? str }
53
55
  end
54
56
 
55
57
  private
@@ -62,17 +64,21 @@ module ActiveSupport
62
64
  @__instance__[locale] ||= new
63
65
  end
64
66
 
65
- attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms, :acronym_regex
67
+ attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms
68
+
69
+ attr_reader :acronyms_camelize_regex, :acronyms_underscore_regex # :nodoc:
66
70
 
67
71
  def initialize
68
- @plurals, @singulars, @uncountables, @humans, @acronyms, @acronym_regex = [], [], Uncountables.new, [], {}, /(?=a)b/
72
+ @plurals, @singulars, @uncountables, @humans, @acronyms = [], [], Uncountables.new, [], {}
73
+ define_acronym_regex_patterns
69
74
  end
70
75
 
71
76
  # Private, for the test suite.
72
77
  def initialize_dup(orig) # :nodoc:
73
- %w(plurals singulars uncountables humans acronyms acronym_regex).each do |scope|
74
- instance_variable_set("@#{scope}", orig.send(scope).dup)
78
+ %w(plurals singulars uncountables humans acronyms).each do |scope|
79
+ instance_variable_set("@#{scope}", orig.public_send(scope).dup)
75
80
  end
81
+ define_acronym_regex_patterns
76
82
  end
77
83
 
78
84
  # Specifies a new acronym. An acronym must be specified as it will appear
@@ -126,7 +132,7 @@ module ActiveSupport
126
132
  # camelize 'mcdonald' # => 'McDonald'
127
133
  def acronym(word)
128
134
  @acronyms[word.downcase] = word
129
- @acronym_regex = /#{@acronyms.values.join("|")}/
135
+ define_acronym_regex_patterns
130
136
  end
131
137
 
132
138
  # Specifies a new pluralization rule and its replacement. The rule can
@@ -215,12 +221,19 @@ module ActiveSupport
215
221
  # clear :plurals
216
222
  def clear(scope = :all)
217
223
  case scope
218
- when :all
219
- @plurals, @singulars, @uncountables, @humans = [], [], Uncountables.new, []
220
- else
221
- instance_variable_set "@#{scope}", []
224
+ when :all
225
+ @plurals, @singulars, @uncountables, @humans = [], [], Uncountables.new, []
226
+ else
227
+ instance_variable_set "@#{scope}", []
222
228
  end
223
229
  end
230
+
231
+ private
232
+ def define_acronym_regex_patterns
233
+ @acronym_regex = @acronyms.empty? ? /(?=a)b/ : /#{@acronyms.values.join("|")}/
234
+ @acronyms_camelize_regex = /^(?:#{@acronym_regex}(?=\b|[A-Z_])|\w)/
235
+ @acronyms_underscore_regex = /(?:(?<=([A-Za-z\d]))|\b)(#{@acronym_regex})(?=\b|[^a-z])/
236
+ end
224
237
  end
225
238
 
226
239
  # Yields a singleton instance of Inflector::Inflections so you can specify