activesupport 5.1.7 → 6.1.7

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 (262) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +434 -490
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +6 -5
  5. data/lib/active_support/actionable_error.rb +48 -0
  6. data/lib/active_support/all.rb +2 -0
  7. data/lib/active_support/array_inquirer.rb +6 -2
  8. data/lib/active_support/backtrace_cleaner.rb +31 -3
  9. data/lib/active_support/benchmarkable.rb +3 -1
  10. data/lib/active_support/builder.rb +2 -0
  11. data/lib/active_support/cache/file_store.rb +37 -36
  12. data/lib/active_support/cache/mem_cache_store.rb +72 -56
  13. data/lib/active_support/cache/memory_store.rb +61 -33
  14. data/lib/active_support/cache/null_store.rb +10 -3
  15. data/lib/active_support/cache/redis_cache_store.rb +493 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +67 -21
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +2 -0
  18. data/lib/active_support/cache.rb +310 -126
  19. data/lib/active_support/callbacks.rb +106 -100
  20. data/lib/active_support/concern.rb +79 -6
  21. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +18 -0
  22. data/lib/active_support/concurrency/share_lock.rb +2 -1
  23. data/lib/active_support/configurable.rb +12 -14
  24. data/lib/active_support/configuration_file.rb +51 -0
  25. data/lib/active_support/core_ext/array/access.rb +21 -7
  26. data/lib/active_support/core_ext/array/conversions.rb +7 -5
  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 +2 -0
  30. data/lib/active_support/core_ext/array/inquiry.rb +2 -0
  31. data/lib/active_support/core_ext/array/wrap.rb +2 -0
  32. data/lib/active_support/core_ext/array.rb +3 -1
  33. data/lib/active_support/core_ext/benchmark.rb +4 -2
  34. data/lib/active_support/core_ext/big_decimal/conversions.rb +2 -0
  35. data/lib/active_support/core_ext/big_decimal.rb +2 -0
  36. data/lib/active_support/core_ext/class/attribute.rb +50 -47
  37. data/lib/active_support/core_ext/class/attribute_accessors.rb +2 -0
  38. data/lib/active_support/core_ext/class/subclasses.rb +18 -40
  39. data/lib/active_support/core_ext/class.rb +2 -0
  40. data/lib/active_support/core_ext/date/acts_like.rb +2 -0
  41. data/lib/active_support/core_ext/date/blank.rb +2 -0
  42. data/lib/active_support/core_ext/date/calculations.rb +8 -5
  43. data/lib/active_support/core_ext/date/conversions.rb +12 -10
  44. data/lib/active_support/core_ext/date/zones.rb +2 -0
  45. data/lib/active_support/core_ext/date.rb +2 -0
  46. data/lib/active_support/core_ext/date_and_time/calculations.rb +61 -37
  47. data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -1
  48. data/lib/active_support/core_ext/date_and_time/zones.rb +2 -1
  49. data/lib/active_support/core_ext/date_time/acts_like.rb +2 -0
  50. data/lib/active_support/core_ext/date_time/blank.rb +2 -0
  51. data/lib/active_support/core_ext/date_time/calculations.rb +3 -1
  52. data/lib/active_support/core_ext/date_time/compatibility.rb +7 -5
  53. data/lib/active_support/core_ext/date_time/conversions.rb +2 -1
  54. data/lib/active_support/core_ext/date_time.rb +2 -0
  55. data/lib/active_support/core_ext/digest/uuid.rb +4 -1
  56. data/lib/active_support/core_ext/digest.rb +3 -0
  57. data/lib/active_support/core_ext/enumerable.rb +174 -71
  58. data/lib/active_support/core_ext/file/atomic.rb +3 -1
  59. data/lib/active_support/core_ext/file.rb +2 -0
  60. data/lib/active_support/core_ext/hash/conversions.rb +7 -5
  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 +2 -0
  65. data/lib/active_support/core_ext/hash/keys.rb +3 -30
  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 +3 -2
  69. data/lib/active_support/core_ext/integer/inflections.rb +2 -0
  70. data/lib/active_support/core_ext/integer/multiple.rb +3 -1
  71. data/lib/active_support/core_ext/integer/time.rb +7 -14
  72. data/lib/active_support/core_ext/integer.rb +2 -0
  73. data/lib/active_support/core_ext/kernel/concern.rb +2 -0
  74. data/lib/active_support/core_ext/kernel/reporting.rb +2 -0
  75. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  76. data/lib/active_support/core_ext/kernel.rb +2 -1
  77. data/lib/active_support/core_ext/load_error.rb +3 -8
  78. data/lib/active_support/core_ext/marshal.rb +4 -0
  79. data/lib/active_support/core_ext/module/aliasing.rb +2 -0
  80. data/lib/active_support/core_ext/module/anonymous.rb +2 -0
  81. data/lib/active_support/core_ext/module/attr_internal.rb +4 -2
  82. data/lib/active_support/core_ext/module/attribute_accessors.rb +44 -56
  83. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +18 -18
  84. data/lib/active_support/core_ext/module/concerning.rb +15 -10
  85. data/lib/active_support/core_ext/module/delegation.rb +103 -58
  86. data/lib/active_support/core_ext/module/deprecation.rb +2 -0
  87. data/lib/active_support/core_ext/module/introspection.rb +18 -15
  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 +3 -1
  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 +131 -129
  94. data/lib/active_support/core_ext/numeric/time.rb +7 -15
  95. data/lib/active_support/core_ext/numeric.rb +2 -1
  96. data/lib/active_support/core_ext/object/acts_like.rb +12 -1
  97. data/lib/active_support/core_ext/object/blank.rb +13 -3
  98. data/lib/active_support/core_ext/object/conversions.rb +2 -0
  99. data/lib/active_support/core_ext/object/deep_dup.rb +3 -1
  100. data/lib/active_support/core_ext/object/duplicable.rb +9 -114
  101. data/lib/active_support/core_ext/object/inclusion.rb +2 -0
  102. data/lib/active_support/core_ext/object/instance_variables.rb +2 -0
  103. data/lib/active_support/core_ext/object/json.rb +22 -2
  104. data/lib/active_support/core_ext/object/to_param.rb +2 -0
  105. data/lib/active_support/core_ext/object/to_query.rb +2 -0
  106. data/lib/active_support/core_ext/object/try.rb +19 -7
  107. data/lib/active_support/core_ext/object/with_options.rb +4 -2
  108. data/lib/active_support/core_ext/object.rb +2 -0
  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 +4 -1
  115. data/lib/active_support/core_ext/regexp.rb +10 -5
  116. data/lib/active_support/core_ext/securerandom.rb +25 -3
  117. data/lib/active_support/core_ext/string/access.rb +7 -16
  118. data/lib/active_support/core_ext/string/behavior.rb +2 -0
  119. data/lib/active_support/core_ext/string/conversions.rb +3 -0
  120. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  121. data/lib/active_support/core_ext/string/filters.rb +44 -1
  122. data/lib/active_support/core_ext/string/indent.rb +2 -0
  123. data/lib/active_support/core_ext/string/inflections.rb +69 -16
  124. data/lib/active_support/core_ext/string/inquiry.rb +3 -0
  125. data/lib/active_support/core_ext/string/multibyte.rb +9 -4
  126. data/lib/active_support/core_ext/string/output_safety.rb +104 -20
  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 +2 -0
  130. data/lib/active_support/core_ext/string.rb +2 -0
  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 +2 -0
  134. data/lib/active_support/core_ext/time/calculations.rb +76 -18
  135. data/lib/active_support/core_ext/time/compatibility.rb +4 -2
  136. data/lib/active_support/core_ext/time/conversions.rb +4 -0
  137. data/lib/active_support/core_ext/time/zones.rb +6 -4
  138. data/lib/active_support/core_ext/time.rb +2 -0
  139. data/lib/active_support/core_ext/uri.rb +11 -6
  140. data/lib/active_support/core_ext.rb +3 -1
  141. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  142. data/lib/active_support/current_attributes.rb +210 -0
  143. data/lib/active_support/dependencies/autoload.rb +2 -0
  144. data/lib/active_support/dependencies/interlock.rb +2 -0
  145. data/lib/active_support/dependencies/zeitwerk_integration.rb +120 -0
  146. data/lib/active_support/dependencies.rb +134 -60
  147. data/lib/active_support/deprecation/behaviors.rb +43 -11
  148. data/lib/active_support/deprecation/constant_accessor.rb +4 -2
  149. data/lib/active_support/deprecation/disallowed.rb +56 -0
  150. data/lib/active_support/deprecation/instance_delegator.rb +2 -1
  151. data/lib/active_support/deprecation/method_wrappers.rb +29 -21
  152. data/lib/active_support/deprecation/proxy_wrappers.rb +32 -6
  153. data/lib/active_support/deprecation/reporting.rb +54 -9
  154. data/lib/active_support/deprecation.rb +9 -2
  155. data/lib/active_support/descendants_tracker.rb +61 -9
  156. data/lib/active_support/digest.rb +22 -0
  157. data/lib/active_support/duration/iso8601_parser.rb +6 -6
  158. data/lib/active_support/duration/iso8601_serializer.rb +20 -14
  159. data/lib/active_support/duration.rb +102 -45
  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 +84 -117
  164. data/lib/active_support/execution_wrapper.rb +19 -13
  165. data/lib/active_support/executor.rb +2 -0
  166. data/lib/active_support/file_update_checker.rb +2 -1
  167. data/lib/active_support/fork_tracker.rb +64 -0
  168. data/lib/active_support/gem_version.rb +3 -1
  169. data/lib/active_support/gzip.rb +2 -0
  170. data/lib/active_support/hash_with_indifferent_access.rb +123 -41
  171. data/lib/active_support/i18n.rb +4 -1
  172. data/lib/active_support/i18n_railtie.rb +19 -14
  173. data/lib/active_support/inflections.rb +2 -0
  174. data/lib/active_support/inflector/inflections.rb +19 -8
  175. data/lib/active_support/inflector/methods.rb +87 -77
  176. data/lib/active_support/inflector/transliterate.rb +56 -18
  177. data/lib/active_support/inflector.rb +2 -0
  178. data/lib/active_support/json/decoding.rb +27 -26
  179. data/lib/active_support/json/encoding.rb +13 -3
  180. data/lib/active_support/json.rb +2 -0
  181. data/lib/active_support/key_generator.rb +3 -33
  182. data/lib/active_support/lazy_load_hooks.rb +7 -2
  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 +2 -0
  186. data/lib/active_support/log_subscriber.rb +42 -11
  187. data/lib/active_support/logger.rb +4 -17
  188. data/lib/active_support/logger_silence.rb +13 -20
  189. data/lib/active_support/logger_thread_safe_level.rb +54 -7
  190. data/lib/active_support/message_encryptor.rb +100 -32
  191. data/lib/active_support/message_verifier.rb +85 -14
  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 +12 -68
  196. data/lib/active_support/multibyte/unicode.rb +17 -327
  197. data/lib/active_support/multibyte.rb +2 -0
  198. data/lib/active_support/notifications/fanout.rb +118 -16
  199. data/lib/active_support/notifications/instrumenter.rb +73 -9
  200. data/lib/active_support/notifications.rb +74 -8
  201. data/lib/active_support/number_helper/number_converter.rb +7 -6
  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 -2
  204. data/lib/active_support/number_helper/number_to_human_converter.rb +6 -3
  205. data/lib/active_support/number_helper/number_to_human_size_converter.rb +6 -3
  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 -2
  208. data/lib/active_support/number_helper/number_to_rounded_converter.rb +14 -27
  209. data/lib/active_support/number_helper/rounding_helper.rb +16 -30
  210. data/lib/active_support/number_helper.rb +40 -12
  211. data/lib/active_support/option_merger.rb +24 -3
  212. data/lib/active_support/ordered_hash.rb +3 -1
  213. data/lib/active_support/ordered_options.rb +17 -5
  214. data/lib/active_support/parameter_filter.rb +133 -0
  215. data/lib/active_support/per_thread_registry.rb +4 -1
  216. data/lib/active_support/proxy_object.rb +2 -0
  217. data/lib/active_support/rails.rb +3 -10
  218. data/lib/active_support/railtie.rb +60 -9
  219. data/lib/active_support/reloader.rb +12 -11
  220. data/lib/active_support/rescuable.rb +7 -6
  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 +6 -3
  224. data/lib/active_support/subscriber.rb +74 -24
  225. data/lib/active_support/tagged_logging.rb +44 -8
  226. data/lib/active_support/test_case.rb +94 -2
  227. data/lib/active_support/testing/assertions.rb +58 -20
  228. data/lib/active_support/testing/autorun.rb +2 -0
  229. data/lib/active_support/testing/constant_lookup.rb +2 -0
  230. data/lib/active_support/testing/declarative.rb +2 -0
  231. data/lib/active_support/testing/deprecation.rb +2 -1
  232. data/lib/active_support/testing/file_fixtures.rb +4 -0
  233. data/lib/active_support/testing/isolation.rb +4 -2
  234. data/lib/active_support/testing/method_call_assertions.rb +30 -1
  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 +12 -7
  239. data/lib/active_support/testing/stream.rb +3 -2
  240. data/lib/active_support/testing/tagged_logging.rb +2 -0
  241. data/lib/active_support/testing/time_helpers.rb +78 -13
  242. data/lib/active_support/time.rb +2 -0
  243. data/lib/active_support/time_with_zone.rb +113 -41
  244. data/lib/active_support/values/time_zone.rb +54 -25
  245. data/lib/active_support/version.rb +2 -0
  246. data/lib/active_support/xml_mini/jdom.rb +5 -4
  247. data/lib/active_support/xml_mini/libxml.rb +4 -2
  248. data/lib/active_support/xml_mini/libxmlsax.rb +6 -4
  249. data/lib/active_support/xml_mini/nokogiri.rb +4 -2
  250. data/lib/active_support/xml_mini/nokogirisax.rb +5 -3
  251. data/lib/active_support/xml_mini/rexml.rb +12 -3
  252. data/lib/active_support/xml_mini.rb +5 -11
  253. data/lib/active_support.rb +18 -13
  254. metadata +71 -32
  255. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
  256. data/lib/active_support/core_ext/hash/compact.rb +0 -27
  257. data/lib/active_support/core_ext/hash/transform_values.rb +0 -30
  258. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
  259. data/lib/active_support/core_ext/module/reachable.rb +0 -8
  260. data/lib/active_support/core_ext/numeric/inquiry.rb +0 -26
  261. data/lib/active_support/core_ext/range/include_range.rb +0 -23
  262. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,5 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/hash/keys"
2
4
  require "active_support/core_ext/hash/reverse_merge"
5
+ require "active_support/core_ext/hash/except"
6
+ require "active_support/core_ext/hash/slice"
3
7
 
4
8
  module ActiveSupport
5
9
  # Implements a hash where keys <tt>:foo</tt> and <tt>"foo"</tt> are considered
@@ -66,7 +70,7 @@ module ActiveSupport
66
70
  super()
67
71
  update(constructor)
68
72
 
69
- hash = constructor.to_hash
73
+ hash = constructor.is_a?(Hash) ? constructor : constructor.to_hash
70
74
  self.default = hash.default if hash.default
71
75
  self.default_proc = hash.default_proc if hash.default_proc
72
76
  else
@@ -88,12 +92,12 @@ module ActiveSupport
88
92
  #
89
93
  # This value can be later fetched using either +:key+ or <tt>'key'</tt>.
90
94
  def []=(key, value)
91
- regular_writer(convert_key(key), convert_value(value, for: :assignment))
95
+ regular_writer(convert_key(key), convert_value(value, conversion: :assignment))
92
96
  end
93
97
 
94
98
  alias_method :store, :[]=
95
99
 
96
- # Updates the receiver in-place, merging in the hash passed as argument:
100
+ # Updates the receiver in-place, merging in the hashes passed as arguments:
97
101
  #
98
102
  # hash_1 = ActiveSupport::HashWithIndifferentAccess.new
99
103
  # hash_1[:key] = 'value'
@@ -103,11 +107,14 @@ module ActiveSupport
103
107
  #
104
108
  # hash_1.update(hash_2) # => {"key"=>"New Value!"}
105
109
  #
106
- # The argument can be either an
110
+ # hash = ActiveSupport::HashWithIndifferentAccess.new
111
+ # hash.update({ "a" => 1 }, { "b" => 2 }) # => { "a" => 1, "b" => 2 }
112
+ #
113
+ # The arguments can be either an
107
114
  # <tt>ActiveSupport::HashWithIndifferentAccess</tt> or a regular +Hash+.
108
115
  # In either case the merge respects the semantics of indifferent access.
109
116
  #
110
- # If the argument is a regular hash with keys +:key+ and +"key"+ only one
117
+ # If the argument is a regular hash with keys +:key+ and <tt>"key"</tt> only one
111
118
  # of the values end up in the receiver, but which one is unspecified.
112
119
  #
113
120
  # When given a block, the value for duplicated keys will be determined
@@ -118,18 +125,15 @@ module ActiveSupport
118
125
  # hash_1[:key] = 10
119
126
  # hash_2['key'] = 12
120
127
  # hash_1.update(hash_2) { |key, old, new| old + new } # => {"key"=>22}
121
- def update(other_hash)
122
- if other_hash.is_a? HashWithIndifferentAccess
123
- super(other_hash)
128
+ def update(*other_hashes, &block)
129
+ if other_hashes.size == 1
130
+ update_with_single_argument(other_hashes.first, block)
124
131
  else
125
- other_hash.to_hash.each_pair do |key, value|
126
- if block_given? && key?(key)
127
- value = yield(convert_key(key), self[key], value)
128
- end
129
- regular_writer(convert_key(key), convert_value(value))
132
+ other_hashes.each do |other_hash|
133
+ update_with_single_argument(other_hash, block)
130
134
  end
131
- self
132
135
  end
136
+ self
133
137
  end
134
138
 
135
139
  alias_method :merge!, :update
@@ -161,6 +165,19 @@ module ActiveSupport
161
165
  super(convert_key(key))
162
166
  end
163
167
 
168
+ # Same as <tt>Hash#assoc</tt> where the key passed as argument can be
169
+ # either a string or a symbol:
170
+ #
171
+ # counters = ActiveSupport::HashWithIndifferentAccess.new
172
+ # counters[:foo] = 1
173
+ #
174
+ # counters.assoc('foo') # => ["foo", 1]
175
+ # counters.assoc(:foo) # => ["foo", 1]
176
+ # counters.assoc(:zoo) # => nil
177
+ def assoc(key)
178
+ super(convert_key(key))
179
+ end
180
+
164
181
  # Same as <tt>Hash#fetch</tt> where the key passed as argument can be
165
182
  # either a string or a symbol:
166
183
  #
@@ -175,20 +192,18 @@ module ActiveSupport
175
192
  super(convert_key(key), *extras)
176
193
  end
177
194
 
178
- if Hash.new.respond_to?(:dig)
179
- # Same as <tt>Hash#dig</tt> where the key passed as argument can be
180
- # either a string or a symbol:
181
- #
182
- # counters = ActiveSupport::HashWithIndifferentAccess.new
183
- # counters[:foo] = { bar: 1 }
184
- #
185
- # counters.dig('foo', 'bar') # => 1
186
- # counters.dig(:foo, :bar) # => 1
187
- # counters.dig(:zoo) # => nil
188
- def dig(*args)
189
- args[0] = convert_key(args[0]) if args.size > 0
190
- super(*args)
191
- end
195
+ # Same as <tt>Hash#dig</tt> where the key passed as argument can be
196
+ # either a string or a symbol:
197
+ #
198
+ # counters = ActiveSupport::HashWithIndifferentAccess.new
199
+ # counters[:foo] = { bar: 1 }
200
+ #
201
+ # counters.dig('foo', 'bar') # => 1
202
+ # counters.dig(:foo, :bar) # => 1
203
+ # counters.dig(:zoo) # => nil
204
+ def dig(*args)
205
+ args[0] = convert_key(args[0]) if args.size > 0
206
+ super(*args)
192
207
  end
193
208
 
194
209
  # Same as <tt>Hash#default</tt> where the key passed as argument can be
@@ -211,8 +226,21 @@ module ActiveSupport
211
226
  # hash[:a] = 'x'
212
227
  # hash[:b] = 'y'
213
228
  # hash.values_at('a', 'b') # => ["x", "y"]
214
- def values_at(*indices)
215
- indices.collect { |key| self[convert_key(key)] }
229
+ def values_at(*keys)
230
+ super(*keys.map { |key| convert_key(key) })
231
+ end
232
+
233
+ # Returns an array of the values at the specified indices, but also
234
+ # raises an exception when one of the keys can't be found.
235
+ #
236
+ # hash = ActiveSupport::HashWithIndifferentAccess.new
237
+ # hash[:a] = 'x'
238
+ # hash[:b] = 'y'
239
+ # hash.fetch_values('a', 'b') # => ["x", "y"]
240
+ # hash.fetch_values('a', 'c') { |key| 'z' } # => ["x", "z"]
241
+ # hash.fetch_values('a', 'c') # => KeyError: key not found: "c"
242
+ def fetch_values(*indices, &block)
243
+ super(*indices.map { |key| convert_key(key) }, &block)
216
244
  end
217
245
 
218
246
  # Returns a shallow copy of the hash.
@@ -232,8 +260,8 @@ module ActiveSupport
232
260
  # This method has the same semantics of +update+, except it does not
233
261
  # modify the receiver but rather returns a new hash with indifferent
234
262
  # access with the result of the merge.
235
- def merge(hash, &block)
236
- dup.update(hash, &block)
263
+ def merge(*hashes, &block)
264
+ dup.update(*hashes, &block)
237
265
  end
238
266
 
239
267
  # Like +merge+ but the other way around: Merges the receiver into the
@@ -245,11 +273,13 @@ module ActiveSupport
245
273
  def reverse_merge(other_hash)
246
274
  super(self.class.new(other_hash))
247
275
  end
276
+ alias_method :with_defaults, :reverse_merge
248
277
 
249
278
  # Same semantics as +reverse_merge+ but modifies the receiver in-place.
250
279
  def reverse_merge!(other_hash)
251
- replace(reverse_merge(other_hash))
280
+ super(self.class.new(other_hash))
252
281
  end
282
+ alias_method :with_defaults!, :reverse_merge!
253
283
 
254
284
  # Replaces the contents of this hash with other_hash.
255
285
  #
@@ -264,6 +294,15 @@ module ActiveSupport
264
294
  super(convert_key(key))
265
295
  end
266
296
 
297
+ # Returns a hash with indifferent access that includes everything except given keys.
298
+ # hash = { a: "x", b: "y", c: 10 }.with_indifferent_access
299
+ # hash.except(:a, "b") # => {c: 10}.with_indifferent_access
300
+ # hash # => { a: "x", b: "y", c: 10 }.with_indifferent_access
301
+ def except(*keys)
302
+ slice(*self.keys - keys.map { |key| convert_key(key) })
303
+ end
304
+ alias_method :without, :except
305
+
267
306
  def stringify_keys!; self end
268
307
  def deep_stringify_keys!; self end
269
308
  def stringify_keys; dup end
@@ -271,6 +310,7 @@ module ActiveSupport
271
310
  undef :symbolize_keys!
272
311
  undef :deep_symbolize_keys!
273
312
  def symbolize_keys; to_hash.symbolize_keys! end
313
+ alias_method :to_options, :symbolize_keys
274
314
  def deep_symbolize_keys; to_hash.deep_symbolize_keys! end
275
315
  def to_options!; self end
276
316
 
@@ -289,6 +329,29 @@ module ActiveSupport
289
329
  dup.tap { |hash| hash.transform_values!(*args, &block) }
290
330
  end
291
331
 
332
+ def transform_keys(*args, &block)
333
+ return to_enum(:transform_keys) unless block_given?
334
+ dup.tap { |hash| hash.transform_keys!(*args, &block) }
335
+ end
336
+
337
+ def transform_keys!
338
+ return enum_for(:transform_keys!) { size } unless block_given?
339
+ keys.each do |key|
340
+ self[yield(key)] = delete(key)
341
+ end
342
+ self
343
+ end
344
+
345
+ def slice(*keys)
346
+ keys.map! { |key| convert_key(key) }
347
+ self.class.new(super)
348
+ end
349
+
350
+ def slice!(*keys)
351
+ keys.map! { |key| convert_key(key) }
352
+ super
353
+ end
354
+
292
355
  def compact
293
356
  dup.tap(&:compact!)
294
357
  end
@@ -299,40 +362,59 @@ module ActiveSupport
299
362
  set_defaults(_new_hash)
300
363
 
301
364
  each do |key, value|
302
- _new_hash[key] = convert_value(value, for: :to_hash)
365
+ _new_hash[key] = convert_value(value, conversion: :to_hash)
303
366
  end
304
367
  _new_hash
305
368
  end
306
369
 
307
370
  private
308
- def convert_key(key) # :doc:
309
- key.kind_of?(Symbol) ? key.to_s : key
371
+ if Symbol.method_defined?(:name)
372
+ def convert_key(key)
373
+ key.kind_of?(Symbol) ? key.name : key
374
+ end
375
+ else
376
+ def convert_key(key)
377
+ key.kind_of?(Symbol) ? key.to_s : key
378
+ end
310
379
  end
311
380
 
312
- def convert_value(value, options = {}) # :doc:
381
+ def convert_value(value, conversion: nil)
313
382
  if value.is_a? Hash
314
- if options[:for] == :to_hash
383
+ if conversion == :to_hash
315
384
  value.to_hash
316
385
  else
317
386
  value.nested_under_indifferent_access
318
387
  end
319
388
  elsif value.is_a?(Array)
320
- if options[:for] != :assignment || value.frozen?
389
+ if conversion != :assignment || value.frozen?
321
390
  value = value.dup
322
391
  end
323
- value.map! { |e| convert_value(e, options) }
392
+ value.map! { |e| convert_value(e, conversion: conversion) }
324
393
  else
325
394
  value
326
395
  end
327
396
  end
328
397
 
329
- def set_defaults(target) # :doc:
398
+ def set_defaults(target)
330
399
  if default_proc
331
400
  target.default_proc = default_proc.dup
332
401
  else
333
402
  target.default = default
334
403
  end
335
404
  end
405
+
406
+ def update_with_single_argument(other_hash, block)
407
+ if other_hash.is_a? HashWithIndifferentAccess
408
+ regular_update(other_hash, &block)
409
+ else
410
+ other_hash.to_hash.each_pair do |key, value|
411
+ if block && key?(key)
412
+ value = block.call(convert_key(key), self[key], value)
413
+ end
414
+ regular_writer(convert_key(key), convert_value(value))
415
+ end
416
+ end
417
+ end
336
418
  end
337
419
  end
338
420
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/hash/deep_merge"
2
4
  require "active_support/core_ext/hash/except"
3
5
  require "active_support/core_ext/hash/slice"
@@ -10,4 +12,5 @@ end
10
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,5 +1,6 @@
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
 
5
6
  # :enddoc:
@@ -11,6 +12,8 @@ module I18n
11
12
  config.i18n.load_path = []
12
13
  config.i18n.fallbacks = ActiveSupport::OrderedOptions.new
13
14
 
15
+ config.eager_load_namespaces << I18n
16
+
14
17
  # Set the i18n configuration after initialization since a lot of
15
18
  # configuration is still usually done in application initializers.
16
19
  config.after_initialize do |app|
@@ -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
@@ -93,10 +102,6 @@ module I18n
93
102
  [I18n.default_locale]
94
103
  end
95
104
 
96
- if args.empty? || args.first.is_a?(Hash)
97
- args.unshift I18n.default_locale
98
- end
99
-
100
105
  I18n.fallbacks = I18n::Locale::Fallbacks.new(*args)
101
106
  end
102
107
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/inflector/inflections"
2
4
 
3
5
  #--
@@ -1,6 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "concurrent/map"
2
- require "active_support/core_ext/array/prepend_and_append"
3
- require "active_support/core_ext/regexp"
4
4
  require "active_support/i18n"
5
5
 
6
6
  module ActiveSupport
@@ -64,17 +64,21 @@ module ActiveSupport
64
64
  @__instance__[locale] ||= new
65
65
  end
66
66
 
67
- 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:
68
70
 
69
71
  def initialize
70
- @plurals, @singulars, @uncountables, @humans, @acronyms, @acronym_regex = [], [], Uncountables.new, [], {}, /(?=a)b/
72
+ @plurals, @singulars, @uncountables, @humans, @acronyms = [], [], Uncountables.new, [], {}
73
+ define_acronym_regex_patterns
71
74
  end
72
75
 
73
76
  # Private, for the test suite.
74
77
  def initialize_dup(orig) # :nodoc:
75
- %w(plurals singulars uncountables humans acronyms acronym_regex).each do |scope|
76
- 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)
77
80
  end
81
+ define_acronym_regex_patterns
78
82
  end
79
83
 
80
84
  # Specifies a new acronym. An acronym must be specified as it will appear
@@ -128,7 +132,7 @@ module ActiveSupport
128
132
  # camelize 'mcdonald' # => 'McDonald'
129
133
  def acronym(word)
130
134
  @acronyms[word.downcase] = word
131
- @acronym_regex = /#{@acronyms.values.join("|")}/
135
+ define_acronym_regex_patterns
132
136
  end
133
137
 
134
138
  # Specifies a new pluralization rule and its replacement. The rule can
@@ -219,10 +223,17 @@ module ActiveSupport
219
223
  case scope
220
224
  when :all
221
225
  @plurals, @singulars, @uncountables, @humans = [], [], Uncountables.new, []
222
- else
226
+ else
223
227
  instance_variable_set "@#{scope}", []
224
228
  end
225
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
226
237
  end
227
238
 
228
239
  # Yields a singleton instance of Inflector::Inflections so you can specify