activesupport 4.2.11.1 → 6.0.3.1

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 (263) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +399 -411
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +7 -7
  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 +48 -0
  8. data/lib/active_support/backtrace_cleaner.rb +34 -6
  9. data/lib/active_support/benchmarkable.rb +6 -4
  10. data/lib/active_support/builder.rb +3 -1
  11. data/lib/active_support/cache/file_store.rb +58 -53
  12. data/lib/active_support/cache/mem_cache_store.rb +95 -91
  13. data/lib/active_support/cache/memory_store.rb +39 -36
  14. data/lib/active_support/cache/null_store.rb +11 -7
  15. data/lib/active_support/cache/redis_cache_store.rb +493 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +75 -42
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
  18. data/lib/active_support/cache.rb +331 -217
  19. data/lib/active_support/callbacks.rb +650 -592
  20. data/lib/active_support/concern.rb +35 -6
  21. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +35 -0
  22. data/lib/active_support/concurrency/share_lock.rb +226 -0
  23. data/lib/active_support/configurable.rb +13 -14
  24. data/lib/active_support/core_ext/array/access.rb +41 -1
  25. data/lib/active_support/core_ext/array/conversions.rb +24 -20
  26. data/lib/active_support/core_ext/array/extract.rb +21 -0
  27. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  28. data/lib/active_support/core_ext/array/grouping.rb +11 -18
  29. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  30. data/lib/active_support/core_ext/array/prepend_and_append.rb +4 -6
  31. data/lib/active_support/core_ext/array/wrap.rb +7 -4
  32. data/lib/active_support/core_ext/array.rb +9 -6
  33. data/lib/active_support/core_ext/benchmark.rb +3 -1
  34. data/lib/active_support/core_ext/big_decimal/conversions.rb +10 -12
  35. data/lib/active_support/core_ext/big_decimal.rb +3 -1
  36. data/lib/active_support/core_ext/class/attribute.rb +45 -31
  37. data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
  38. data/lib/active_support/core_ext/class/subclasses.rb +20 -6
  39. data/lib/active_support/core_ext/class.rb +4 -3
  40. data/lib/active_support/core_ext/date/acts_like.rb +3 -1
  41. data/lib/active_support/core_ext/date/blank.rb +14 -0
  42. data/lib/active_support/core_ext/date/calculations.rb +17 -14
  43. data/lib/active_support/core_ext/date/conversions.rb +25 -23
  44. data/lib/active_support/core_ext/date/zones.rb +4 -2
  45. data/lib/active_support/core_ext/date.rb +6 -4
  46. data/lib/active_support/core_ext/date_and_time/calculations.rb +154 -65
  47. data/lib/active_support/core_ext/date_and_time/compatibility.rb +4 -3
  48. data/lib/active_support/core_ext/date_and_time/zones.rb +12 -13
  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 +14 -0
  51. data/lib/active_support/core_ext/date_time/calculations.rb +37 -19
  52. data/lib/active_support/core_ext/date_time/compatibility.rb +8 -6
  53. data/lib/active_support/core_ext/date_time/conversions.rb +16 -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 +114 -22
  58. data/lib/active_support/core_ext/file/atomic.rb +38 -31
  59. data/lib/active_support/core_ext/file.rb +3 -1
  60. data/lib/active_support/core_ext/hash/compact.rb +4 -23
  61. data/lib/active_support/core_ext/hash/conversions.rb +62 -41
  62. data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
  63. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  64. data/lib/active_support/core_ext/hash/except.rb +12 -9
  65. data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
  66. data/lib/active_support/core_ext/hash/keys.rb +19 -42
  67. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  68. data/lib/active_support/core_ext/hash/slice.rb +5 -27
  69. data/lib/active_support/core_ext/hash/transform_values.rb +4 -22
  70. data/lib/active_support/core_ext/hash.rb +10 -9
  71. data/lib/active_support/core_ext/integer/inflections.rb +3 -1
  72. data/lib/active_support/core_ext/integer/multiple.rb +3 -1
  73. data/lib/active_support/core_ext/integer/time.rb +11 -18
  74. data/lib/active_support/core_ext/integer.rb +5 -3
  75. data/lib/active_support/core_ext/kernel/concern.rb +5 -1
  76. data/lib/active_support/core_ext/kernel/reporting.rb +4 -84
  77. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  78. data/lib/active_support/core_ext/kernel.rb +5 -5
  79. data/lib/active_support/core_ext/load_error.rb +3 -22
  80. data/lib/active_support/core_ext/marshal.rb +8 -8
  81. data/lib/active_support/core_ext/module/aliasing.rb +6 -44
  82. data/lib/active_support/core_ext/module/anonymous.rb +12 -1
  83. data/lib/active_support/core_ext/module/attr_internal.rb +8 -9
  84. data/lib/active_support/core_ext/module/attribute_accessors.rb +46 -46
  85. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +144 -0
  86. data/lib/active_support/core_ext/module/concerning.rb +11 -12
  87. data/lib/active_support/core_ext/module/delegation.rb +133 -30
  88. data/lib/active_support/core_ext/module/deprecation.rb +4 -2
  89. data/lib/active_support/core_ext/module/introspection.rb +44 -19
  90. data/lib/active_support/core_ext/module/reachable.rb +5 -7
  91. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  92. data/lib/active_support/core_ext/module/remove_method.rb +8 -3
  93. data/lib/active_support/core_ext/module.rb +13 -11
  94. data/lib/active_support/core_ext/name_error.rb +22 -2
  95. data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
  96. data/lib/active_support/core_ext/numeric/conversions.rb +129 -136
  97. data/lib/active_support/core_ext/numeric/inquiry.rb +5 -0
  98. data/lib/active_support/core_ext/numeric/time.rb +35 -23
  99. data/lib/active_support/core_ext/numeric.rb +5 -3
  100. data/lib/active_support/core_ext/object/acts_like.rb +12 -1
  101. data/lib/active_support/core_ext/object/blank.rb +27 -3
  102. data/lib/active_support/core_ext/object/conversions.rb +6 -4
  103. data/lib/active_support/core_ext/object/deep_dup.rb +13 -4
  104. data/lib/active_support/core_ext/object/duplicable.rb +13 -93
  105. data/lib/active_support/core_ext/object/inclusion.rb +5 -3
  106. data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
  107. data/lib/active_support/core_ext/object/json.rb +51 -20
  108. data/lib/active_support/core_ext/object/to_param.rb +3 -1
  109. data/lib/active_support/core_ext/object/to_query.rb +10 -5
  110. data/lib/active_support/core_ext/object/try.rb +81 -23
  111. data/lib/active_support/core_ext/object/with_options.rb +16 -3
  112. data/lib/active_support/core_ext/object.rb +14 -13
  113. data/lib/active_support/core_ext/range/compare_range.rb +76 -0
  114. data/lib/active_support/core_ext/range/conversions.rb +37 -15
  115. data/lib/active_support/core_ext/range/each.rb +18 -17
  116. data/lib/active_support/core_ext/range/include_range.rb +7 -21
  117. data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
  118. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  119. data/lib/active_support/core_ext/range.rb +7 -4
  120. data/lib/active_support/core_ext/regexp.rb +2 -0
  121. data/lib/active_support/core_ext/securerandom.rb +45 -0
  122. data/lib/active_support/core_ext/string/access.rb +16 -6
  123. data/lib/active_support/core_ext/string/behavior.rb +3 -1
  124. data/lib/active_support/core_ext/string/conversions.rb +7 -4
  125. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  126. data/lib/active_support/core_ext/string/filters.rb +48 -6
  127. data/lib/active_support/core_ext/string/indent.rb +6 -4
  128. data/lib/active_support/core_ext/string/inflections.rb +66 -24
  129. data/lib/active_support/core_ext/string/inquiry.rb +3 -1
  130. data/lib/active_support/core_ext/string/multibyte.rb +16 -7
  131. data/lib/active_support/core_ext/string/output_safety.rb +93 -40
  132. data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
  133. data/lib/active_support/core_ext/string/strip.rb +6 -5
  134. data/lib/active_support/core_ext/string/zones.rb +4 -2
  135. data/lib/active_support/core_ext/string.rb +15 -13
  136. data/lib/active_support/core_ext/time/acts_like.rb +3 -1
  137. data/lib/active_support/core_ext/time/calculations.rb +115 -52
  138. data/lib/active_support/core_ext/time/compatibility.rb +4 -2
  139. data/lib/active_support/core_ext/time/conversions.rb +20 -13
  140. data/lib/active_support/core_ext/time/zones.rb +41 -7
  141. data/lib/active_support/core_ext/time.rb +7 -6
  142. data/lib/active_support/core_ext/uri.rb +6 -7
  143. data/lib/active_support/core_ext.rb +3 -1
  144. data/lib/active_support/current_attributes.rb +203 -0
  145. data/lib/active_support/dependencies/autoload.rb +2 -0
  146. data/lib/active_support/dependencies/interlock.rb +57 -0
  147. data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
  148. data/lib/active_support/dependencies.rb +208 -166
  149. data/lib/active_support/deprecation/behaviors.rb +44 -11
  150. data/lib/active_support/deprecation/constant_accessor.rb +52 -0
  151. data/lib/active_support/deprecation/instance_delegator.rb +17 -2
  152. data/lib/active_support/deprecation/method_wrappers.rb +61 -21
  153. data/lib/active_support/deprecation/proxy_wrappers.rb +81 -30
  154. data/lib/active_support/deprecation/reporting.rb +32 -12
  155. data/lib/active_support/deprecation.rb +12 -9
  156. data/lib/active_support/descendants_tracker.rb +57 -9
  157. data/lib/active_support/digest.rb +20 -0
  158. data/lib/active_support/duration/iso8601_parser.rb +123 -0
  159. data/lib/active_support/duration/iso8601_serializer.rb +53 -0
  160. data/lib/active_support/duration.rb +315 -40
  161. data/lib/active_support/encrypted_configuration.rb +45 -0
  162. data/lib/active_support/encrypted_file.rb +100 -0
  163. data/lib/active_support/evented_file_update_checker.rb +234 -0
  164. data/lib/active_support/execution_wrapper.rb +129 -0
  165. data/lib/active_support/executor.rb +8 -0
  166. data/lib/active_support/file_update_checker.rb +62 -37
  167. data/lib/active_support/gem_version.rb +6 -4
  168. data/lib/active_support/gzip.rb +7 -5
  169. data/lib/active_support/hash_with_indifferent_access.rb +129 -30
  170. data/lib/active_support/i18n.rb +9 -6
  171. data/lib/active_support/i18n_railtie.rb +50 -14
  172. data/lib/active_support/inflections.rb +13 -11
  173. data/lib/active_support/inflector/inflections.rb +58 -13
  174. data/lib/active_support/inflector/methods.rb +159 -145
  175. data/lib/active_support/inflector/transliterate.rb +84 -34
  176. data/lib/active_support/inflector.rb +7 -5
  177. data/lib/active_support/json/decoding.rb +32 -30
  178. data/lib/active_support/json/encoding.rb +17 -60
  179. data/lib/active_support/json.rb +4 -2
  180. data/lib/active_support/key_generator.rb +11 -43
  181. data/lib/active_support/lazy_load_hooks.rb +53 -20
  182. data/lib/active_support/locale/en.rb +33 -0
  183. data/lib/active_support/locale/en.yml +2 -0
  184. data/lib/active_support/log_subscriber/test_helper.rb +14 -12
  185. data/lib/active_support/log_subscriber.rb +44 -19
  186. data/lib/active_support/logger.rb +9 -23
  187. data/lib/active_support/logger_silence.rb +32 -14
  188. data/lib/active_support/logger_thread_safe_level.rb +32 -8
  189. data/lib/active_support/message_encryptor.rb +166 -53
  190. data/lib/active_support/message_verifier.rb +149 -16
  191. data/lib/active_support/messages/metadata.rb +72 -0
  192. data/lib/active_support/messages/rotation_configuration.rb +22 -0
  193. data/lib/active_support/messages/rotator.rb +56 -0
  194. data/lib/active_support/multibyte/chars.rb +56 -63
  195. data/lib/active_support/multibyte/unicode.rb +56 -290
  196. data/lib/active_support/multibyte.rb +4 -2
  197. data/lib/active_support/notifications/fanout.rb +109 -22
  198. data/lib/active_support/notifications/instrumenter.rb +107 -16
  199. data/lib/active_support/notifications.rb +51 -10
  200. data/lib/active_support/number_helper/number_converter.rb +16 -15
  201. data/lib/active_support/number_helper/number_to_currency_converter.rb +14 -15
  202. data/lib/active_support/number_helper/number_to_delimited_converter.rb +11 -4
  203. data/lib/active_support/number_helper/number_to_human_converter.rb +13 -10
  204. data/lib/active_support/number_helper/number_to_human_size_converter.rb +11 -9
  205. data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
  206. data/lib/active_support/number_helper/number_to_phone_converter.rb +15 -5
  207. data/lib/active_support/number_helper/number_to_rounded_converter.rb +25 -57
  208. data/lib/active_support/number_helper/rounding_helper.rb +66 -0
  209. data/lib/active_support/number_helper.rb +105 -68
  210. data/lib/active_support/option_merger.rb +24 -4
  211. data/lib/active_support/ordered_hash.rb +7 -5
  212. data/lib/active_support/ordered_options.rb +27 -5
  213. data/lib/active_support/parameter_filter.rb +128 -0
  214. data/lib/active_support/per_thread_registry.rb +9 -4
  215. data/lib/active_support/proxy_object.rb +2 -0
  216. data/lib/active_support/rails.rb +10 -8
  217. data/lib/active_support/railtie.rb +43 -9
  218. data/lib/active_support/reloader.rb +130 -0
  219. data/lib/active_support/rescuable.rb +108 -53
  220. data/lib/active_support/security_utils.rb +15 -11
  221. data/lib/active_support/string_inquirer.rb +11 -4
  222. data/lib/active_support/subscriber.rb +74 -30
  223. data/lib/active_support/tagged_logging.rb +25 -13
  224. data/lib/active_support/test_case.rb +107 -44
  225. data/lib/active_support/testing/assertions.rb +151 -20
  226. data/lib/active_support/testing/autorun.rb +4 -2
  227. data/lib/active_support/testing/constant_lookup.rb +2 -1
  228. data/lib/active_support/testing/declarative.rb +3 -1
  229. data/lib/active_support/testing/deprecation.rb +13 -10
  230. data/lib/active_support/testing/file_fixtures.rb +38 -0
  231. data/lib/active_support/testing/isolation.rb +35 -26
  232. data/lib/active_support/testing/method_call_assertions.rb +70 -0
  233. data/lib/active_support/testing/parallelization.rb +134 -0
  234. data/lib/active_support/testing/setup_and_teardown.rb +13 -8
  235. data/lib/active_support/testing/stream.rb +43 -0
  236. data/lib/active_support/testing/tagged_logging.rb +3 -1
  237. data/lib/active_support/testing/time_helpers.rb +84 -20
  238. data/lib/active_support/time.rb +14 -12
  239. data/lib/active_support/time_with_zone.rb +179 -39
  240. data/lib/active_support/values/time_zone.rb +203 -63
  241. data/lib/active_support/version.rb +3 -1
  242. data/lib/active_support/xml_mini/jdom.rb +116 -115
  243. data/lib/active_support/xml_mini/libxml.rb +16 -13
  244. data/lib/active_support/xml_mini/libxmlsax.rb +15 -14
  245. data/lib/active_support/xml_mini/nokogiri.rb +14 -12
  246. data/lib/active_support/xml_mini/nokogirisax.rb +14 -13
  247. data/lib/active_support/xml_mini/rexml.rb +11 -9
  248. data/lib/active_support/xml_mini.rb +38 -46
  249. data/lib/active_support.rb +13 -11
  250. metadata +84 -26
  251. data/lib/active_support/concurrency/latch.rb +0 -27
  252. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
  253. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
  254. data/lib/active_support/core_ext/date_time/zones.rb +0 -6
  255. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
  256. data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
  257. data/lib/active_support/core_ext/module/method_transplanting.rb +0 -13
  258. data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
  259. data/lib/active_support/core_ext/object/itself.rb +0 -15
  260. data/lib/active_support/core_ext/struct.rb +0 -6
  261. data/lib/active_support/core_ext/thread.rb +0 -86
  262. data/lib/active_support/core_ext/time/marshal.rb +0 -30
  263. 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.
@@ -59,24 +68,12 @@ module ActiveSupport
59
68
  if constructor.respond_to?(:to_hash)
60
69
  super()
61
70
  update(constructor)
62
- else
63
- super(constructor)
64
- end
65
- end
66
71
 
67
- def default(key = nil)
68
- if key.is_a?(Symbol) && include?(key = key.to_s)
69
- self[key]
72
+ hash = constructor.to_hash
73
+ self.default = hash.default if hash.default
74
+ self.default_proc = hash.default_proc if hash.default_proc
70
75
  else
71
- super
72
- end
73
- end
74
-
75
- def self.new_from_hash_copying_default(hash)
76
- hash = hash.to_hash
77
- new(hash).tap do |new_hash|
78
- new_hash.default = hash.default
79
- new_hash.default_proc = hash.default_proc if hash.default_proc
76
+ super(constructor)
80
77
  end
81
78
  end
82
79
 
@@ -92,7 +89,7 @@ module ActiveSupport
92
89
  # hash = ActiveSupport::HashWithIndifferentAccess.new
93
90
  # hash[:key] = 'value'
94
91
  #
95
- # This value can be later fetched using either +:key+ or +'key'+.
92
+ # This value can be later fetched using either +:key+ or <tt>'key'</tt>.
96
93
  def []=(key, value)
97
94
  regular_writer(convert_key(key), convert_value(value, for: :assignment))
98
95
  end
@@ -154,6 +151,32 @@ module ActiveSupport
154
151
  alias_method :has_key?, :key?
155
152
  alias_method :member?, :key?
156
153
 
154
+ # Same as <tt>Hash#[]</tt> where the key passed as argument can be
155
+ # either a string or a symbol:
156
+ #
157
+ # counters = ActiveSupport::HashWithIndifferentAccess.new
158
+ # counters[:foo] = 1
159
+ #
160
+ # counters['foo'] # => 1
161
+ # counters[:foo] # => 1
162
+ # counters[:zoo] # => nil
163
+ def [](key)
164
+ super(convert_key(key))
165
+ end
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
+
157
180
  # Same as <tt>Hash#fetch</tt> where the key passed as argument can be
158
181
  # either a string or a symbol:
159
182
  #
@@ -168,14 +191,55 @@ module ActiveSupport
168
191
  super(convert_key(key), *extras)
169
192
  end
170
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
+
171
222
  # Returns an array of the values at the specified indices:
172
223
  #
173
224
  # hash = ActiveSupport::HashWithIndifferentAccess.new
174
225
  # hash[:a] = 'x'
175
226
  # hash[:b] = 'y'
176
227
  # hash.values_at('a', 'b') # => ["x", "y"]
177
- def values_at(*indices)
178
- 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)
179
243
  end
180
244
 
181
245
  # Returns a shallow copy of the hash.
@@ -184,7 +248,7 @@ module ActiveSupport
184
248
  # dup = hash.dup
185
249
  # dup[:a][:c] = 'c'
186
250
  #
187
- # hash[:a][:c] # => nil
251
+ # hash[:a][:c] # => "c"
188
252
  # dup[:a][:c] # => "c"
189
253
  def dup
190
254
  self.class.new(self).tap do |new_hash|
@@ -196,7 +260,7 @@ module ActiveSupport
196
260
  # modify the receiver but rather returns a new hash with indifferent
197
261
  # access with the result of the merge.
198
262
  def merge(hash, &block)
199
- self.dup.update(hash, &block)
263
+ dup.update(hash, &block)
200
264
  end
201
265
 
202
266
  # Like +merge+ but the other way around: Merges the receiver into the
@@ -206,20 +270,22 @@ module ActiveSupport
206
270
  # hash['a'] = nil
207
271
  # hash.reverse_merge(a: 0, b: 1) # => {"a"=>nil, "b"=>1}
208
272
  def reverse_merge(other_hash)
209
- super(self.class.new_from_hash_copying_default(other_hash))
273
+ super(self.class.new(other_hash))
210
274
  end
275
+ alias_method :with_defaults, :reverse_merge
211
276
 
212
277
  # Same semantics as +reverse_merge+ but modifies the receiver in-place.
213
278
  def reverse_merge!(other_hash)
214
- replace(reverse_merge( other_hash ))
279
+ super(self.class.new(other_hash))
215
280
  end
281
+ alias_method :with_defaults!, :reverse_merge!
216
282
 
217
283
  # Replaces the contents of this hash with other_hash.
218
284
  #
219
285
  # h = { "a" => 100, "b" => 200 }
220
286
  # h.replace({ "c" => 300, "d" => 400 }) # => {"c"=>300, "d"=>400}
221
287
  def replace(other_hash)
222
- super(self.class.new_from_hash_copying_default(other_hash))
288
+ super(self.class.new(other_hash))
223
289
  end
224
290
 
225
291
  # Removes the specified key from the hash.
@@ -227,6 +293,11 @@ module ActiveSupport
227
293
  super(convert_key(key))
228
294
  end
229
295
 
296
+ def except(*keys)
297
+ slice(*self.keys - keys.map { |key| convert_key(key) })
298
+ end
299
+ alias_method :without, :except
300
+
230
301
  def stringify_keys!; self end
231
302
  def deep_stringify_keys!; self end
232
303
  def stringify_keys; dup end
@@ -234,14 +305,17 @@ module ActiveSupport
234
305
  undef :symbolize_keys!
235
306
  undef :deep_symbolize_keys!
236
307
  def symbolize_keys; to_hash.symbolize_keys! end
308
+ alias_method :to_options, :symbolize_keys
237
309
  def deep_symbolize_keys; to_hash.deep_symbolize_keys! end
238
310
  def to_options!; self end
239
311
 
240
312
  def select(*args, &block)
313
+ return to_enum(:select) unless block_given?
241
314
  dup.tap { |hash| hash.select!(*args, &block) }
242
315
  end
243
316
 
244
317
  def reject(*args, &block)
318
+ return to_enum(:reject) unless block_given?
245
319
  dup.tap { |hash| hash.reject!(*args, &block) }
246
320
  end
247
321
 
@@ -250,6 +324,29 @@ module ActiveSupport
250
324
  dup.tap { |hash| hash.transform_values!(*args, &block) }
251
325
  end
252
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
+
253
350
  def compact
254
351
  dup.tap(&:compact!)
255
352
  end
@@ -265,12 +362,12 @@ module ActiveSupport
265
362
  _new_hash
266
363
  end
267
364
 
268
- protected
269
- def convert_key(key)
365
+ private
366
+ def convert_key(key) # :doc:
270
367
  key.kind_of?(Symbol) ? key.to_s : key
271
368
  end
272
369
 
273
- def convert_value(value, options = {})
370
+ def convert_value(value, options = {}) # :doc:
274
371
  if value.is_a? Hash
275
372
  if options[:for] == :to_hash
276
373
  value.to_hash
@@ -287,7 +384,7 @@ module ActiveSupport
287
384
  end
288
385
  end
289
386
 
290
- def set_defaults(target)
387
+ def set_defaults(target) # :doc:
291
388
  if default_proc
292
389
  target.default_proc = default_proc.dup
293
390
  else
@@ -297,4 +394,6 @@ module ActiveSupport
297
394
  end
298
395
  end
299
396
 
397
+ # :stopdoc:
398
+
300
399
  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,10 @@ module I18n
9
12
  config.i18n.load_path = []
10
13
  config.i18n.fallbacks = ActiveSupport::OrderedOptions.new
11
14
 
15
+ if I18n.respond_to?(:eager_load!)
16
+ config.eager_load_namespaces << I18n
17
+ end
18
+
12
19
  # Set the i18n configuration after initialization since a lot of
13
20
  # configuration is still usually done in application initializers.
14
21
  config.after_initialize do |app|
@@ -21,8 +28,6 @@ module I18n
21
28
  I18n::Railtie.initialize_i18n(app)
22
29
  end
23
30
 
24
- protected
25
-
26
31
  @i18n_inited = false
27
32
 
28
33
  # Setup i18n configuration.
@@ -37,10 +42,12 @@ module I18n
37
42
  enforce_available_locales = I18n.enforce_available_locales if enforce_available_locales.nil?
38
43
  I18n.enforce_available_locales = false
39
44
 
45
+ reloadable_paths = []
40
46
  app.config.i18n.each do |setting, value|
41
47
  case setting
42
48
  when :railties_load_path
43
- app.config.i18n.load_path.unshift(*value)
49
+ reloadable_paths = value
50
+ app.config.i18n.load_path.unshift(*value.flat_map(&:existent))
44
51
  when :load_path
45
52
  I18n.load_path += value
46
53
  else
@@ -53,28 +60,51 @@ module I18n
53
60
  # Restore available locales check so it will take place from now on.
54
61
  I18n.enforce_available_locales = enforce_available_locales
55
62
 
56
- reloader = ActiveSupport::FileUpdateChecker.new(I18n.load_path.dup){ I18n.reload! }
63
+ directories = watched_dirs_with_extensions(reloadable_paths)
64
+ reloader = app.config.file_watcher.new(I18n.load_path.dup, directories) do
65
+ I18n.load_path.keep_if { |p| File.exist?(p) }
66
+ I18n.load_path |= reloadable_paths.flat_map(&:existent)
67
+
68
+ I18n.reload!
69
+ end
70
+
57
71
  app.reloaders << reloader
58
- ActionDispatch::Reloader.to_prepare { reloader.execute_if_updated }
72
+ app.reloader.to_run do
73
+ reloader.execute_if_updated { require_unload_lock! }
74
+ end
59
75
  reloader.execute
60
76
 
61
77
  @i18n_inited = true
62
78
  end
63
79
 
64
80
  def self.include_fallbacks_module
65
- I18n.backend.class.send(:include, I18n::Backend::Fallbacks)
81
+ I18n.backend.class.include(I18n::Backend::Fallbacks)
66
82
  end
67
83
 
68
84
  def self.init_fallbacks(fallbacks)
69
85
  include_fallbacks_module
70
86
 
71
- args = case fallbacks
72
- when ActiveSupport::OrderedOptions
73
- [*(fallbacks[:defaults] || []) << fallbacks[:map]].compact
74
- when Hash, Array
75
- Array.wrap(fallbacks)
76
- else # TrueClass
77
- []
87
+ args = \
88
+ case fallbacks
89
+ when ActiveSupport::OrderedOptions
90
+ [*(fallbacks[:defaults] || []) << fallbacks[:map]].compact
91
+ when Hash, Array
92
+ Array.wrap(fallbacks)
93
+ else # TrueClass
94
+ [I18n.default_locale]
95
+ end
96
+
97
+ if args.empty? || args.first.is_a?(Hash)
98
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
99
+ Using I18n fallbacks with an empty `defaults` sets the defaults to
100
+ include the `default_locale`. This behavior will change in Rails 6.1.
101
+ If you desire the default locale to be included in the defaults, please
102
+ explicitly configure it with `config.i18n.fallbacks.defaults =
103
+ [I18n.default_locale]` or `config.i18n.fallbacks = [I18n.default_locale,
104
+ {...}]`. If you want to opt-in to the new behavior, use
105
+ `config.i18n.fallbacks.defaults = [nil, {...}]`.
106
+ MSG
107
+ args.unshift I18n.default_locale
78
108
  end
79
109
 
80
110
  I18n.fallbacks = I18n::Locale::Fallbacks.new(*args)
@@ -90,5 +120,11 @@ module I18n
90
120
  raise "Unexpected fallback type #{fallbacks.inspect}"
91
121
  end
92
122
  end
123
+
124
+ def self.watched_dirs_with_extensions(paths)
125
+ paths.each_with_object({}) do |path, result|
126
+ result[path.absolute_current] = path.extensions
127
+ end
128
+ end
93
129
  end
94
130
  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,8 @@
1
- require 'thread_safe'
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"
5
+ require "active_support/deprecation"
4
6
 
5
7
  module ActiveSupport
6
8
  module Inflector
@@ -25,23 +27,59 @@ module ActiveSupport
25
27
  # singularization rules that is runs. This guarantees that your rules run
26
28
  # before any of the rules that may already have been loaded.
27
29
  class Inflections
28
- @__instance__ = ThreadSafe::Cache.new
30
+ @__instance__ = Concurrent::Map.new
31
+
32
+ class Uncountables < Array
33
+ def initialize
34
+ @regex_array = []
35
+ super
36
+ end
37
+
38
+ def delete(entry)
39
+ super entry
40
+ @regex_array.delete(to_regex(entry))
41
+ end
42
+
43
+ def <<(*word)
44
+ add(word)
45
+ end
46
+
47
+ def add(words)
48
+ words = words.flatten.map(&:downcase)
49
+ concat(words)
50
+ @regex_array += words.map { |word| to_regex(word) }
51
+ self
52
+ end
53
+
54
+ def uncountable?(str)
55
+ @regex_array.any? { |regex| regex.match? str }
56
+ end
57
+
58
+ private
59
+ def to_regex(string)
60
+ /\b#{::Regexp.escape(string)}\Z/i
61
+ end
62
+ end
29
63
 
30
64
  def self.instance(locale = :en)
31
65
  @__instance__[locale] ||= new
32
66
  end
33
67
 
34
- attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms, :acronym_regex
68
+ attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms
69
+
70
+ attr_reader :acronyms_camelize_regex, :acronyms_underscore_regex # :nodoc:
35
71
 
36
72
  def initialize
37
- @plurals, @singulars, @uncountables, @humans, @acronyms, @acronym_regex = [], [], [], [], {}, /(?=a)b/
73
+ @plurals, @singulars, @uncountables, @humans, @acronyms = [], [], Uncountables.new, [], {}
74
+ define_acronym_regex_patterns
38
75
  end
39
76
 
40
77
  # Private, for the test suite.
41
78
  def initialize_dup(orig) # :nodoc:
42
- %w(plurals singulars uncountables humans acronyms acronym_regex).each do |scope|
79
+ %w(plurals singulars uncountables humans acronyms).each do |scope|
43
80
  instance_variable_set("@#{scope}", orig.send(scope).dup)
44
81
  end
82
+ define_acronym_regex_patterns
45
83
  end
46
84
 
47
85
  # Specifies a new acronym. An acronym must be specified as it will appear
@@ -95,7 +133,7 @@ module ActiveSupport
95
133
  # camelize 'mcdonald' # => 'McDonald'
96
134
  def acronym(word)
97
135
  @acronyms[word.downcase] = word
98
- @acronym_regex = /#{@acronyms.values.join("|")}/
136
+ define_acronym_regex_patterns
99
137
  end
100
138
 
101
139
  # Specifies a new pluralization rule and its replacement. The rule can
@@ -160,7 +198,7 @@ module ActiveSupport
160
198
  # uncountable 'money', 'information'
161
199
  # uncountable %w( money information rice )
162
200
  def uncountable(*words)
163
- @uncountables += words.flatten.map(&:downcase)
201
+ @uncountables.add(words)
164
202
  end
165
203
 
166
204
  # Specifies a humanized form of a string by a regular expression rule or
@@ -184,12 +222,19 @@ module ActiveSupport
184
222
  # clear :plurals
185
223
  def clear(scope = :all)
186
224
  case scope
187
- when :all
188
- @plurals, @singulars, @uncountables, @humans = [], [], [], []
189
- else
190
- instance_variable_set "@#{scope}", []
225
+ when :all
226
+ @plurals, @singulars, @uncountables, @humans = [], [], Uncountables.new, []
227
+ else
228
+ instance_variable_set "@#{scope}", []
191
229
  end
192
230
  end
231
+
232
+ private
233
+ def define_acronym_regex_patterns
234
+ @acronym_regex = @acronyms.empty? ? /(?=a)b/ : /#{@acronyms.values.join("|")}/
235
+ @acronyms_camelize_regex = /^(?:#{@acronym_regex}(?=\b|[A-Z_])|\w)/
236
+ @acronyms_underscore_regex = /(?:(?<=([A-Za-z\d]))|\b)(#{@acronym_regex})(?=\b|[^a-z])/
237
+ end
193
238
  end
194
239
 
195
240
  # Yields a singleton instance of Inflector::Inflections so you can specify