activesupport 4.2.11.1 → 6.1.7.3

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 (272) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +464 -391
  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 +50 -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 +61 -55
  12. data/lib/active_support/cache/mem_cache_store.rb +115 -100
  13. data/lib/active_support/cache/memory_store.rb +81 -58
  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 +90 -42
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
  18. data/lib/active_support/cache.rb +386 -225
  19. data/lib/active_support/callbacks.rb +661 -594
  20. data/lib/active_support/concern.rb +80 -7
  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 +16 -17
  24. data/lib/active_support/configuration_file.rb +51 -0
  25. data/lib/active_support/core_ext/array/access.rb +41 -1
  26. data/lib/active_support/core_ext/array/conversions.rb +24 -20
  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 +11 -18
  30. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  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 +5 -3
  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 +52 -48
  37. data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
  38. data/lib/active_support/core_ext/class/subclasses.rb +18 -25
  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 +27 -24
  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 +167 -65
  47. data/lib/active_support/core_ext/date_and_time/compatibility.rb +19 -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 +8 -5
  56. data/lib/active_support/core_ext/digest.rb +3 -0
  57. data/lib/active_support/core_ext/enumerable.rb +186 -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/conversions.rb +62 -41
  61. data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
  62. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  63. data/lib/active_support/core_ext/hash/except.rb +13 -10
  64. data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
  65. data/lib/active_support/core_ext/hash/keys.rb +20 -43
  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 +5 -1
  74. data/lib/active_support/core_ext/kernel/reporting.rb +4 -84
  75. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  76. data/lib/active_support/core_ext/kernel.rb +5 -5
  77. data/lib/active_support/core_ext/load_error.rb +3 -22
  78. data/lib/active_support/core_ext/marshal.rb +10 -8
  79. data/lib/active_support/core_ext/module/aliasing.rb +6 -44
  80. data/lib/active_support/core_ext/module/anonymous.rb +12 -1
  81. data/lib/active_support/core_ext/module/attr_internal.rb +8 -9
  82. data/lib/active_support/core_ext/module/attribute_accessors.rb +63 -69
  83. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +148 -0
  84. data/lib/active_support/core_ext/module/concerning.rb +19 -14
  85. data/lib/active_support/core_ext/module/delegation.rb +164 -51
  86. data/lib/active_support/core_ext/module/deprecation.rb +4 -2
  87. data/lib/active_support/core_ext/module/introspection.rb +23 -22
  88. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  89. data/lib/active_support/core_ext/module/remove_method.rb +8 -3
  90. data/lib/active_support/core_ext/module.rb +13 -11
  91. data/lib/active_support/core_ext/name_error.rb +51 -4
  92. data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
  93. data/lib/active_support/core_ext/numeric/conversions.rb +133 -136
  94. data/lib/active_support/core_ext/numeric/time.rb +35 -23
  95. data/lib/active_support/core_ext/numeric.rb +5 -3
  96. data/lib/active_support/core_ext/object/acts_like.rb +12 -1
  97. data/lib/active_support/core_ext/object/blank.rb +27 -3
  98. data/lib/active_support/core_ext/object/conversions.rb +6 -4
  99. data/lib/active_support/core_ext/object/deep_dup.rb +13 -4
  100. data/lib/active_support/core_ext/object/duplicable.rb +13 -93
  101. data/lib/active_support/core_ext/object/inclusion.rb +5 -3
  102. data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
  103. data/lib/active_support/core_ext/object/json.rb +63 -21
  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 +81 -23
  107. data/lib/active_support/core_ext/object/with_options.rb +16 -3
  108. data/lib/active_support/core_ext/object.rb +14 -13
  109. data/lib/active_support/core_ext/range/compare_range.rb +82 -0
  110. data/lib/active_support/core_ext/range/conversions.rb +37 -15
  111. data/lib/active_support/core_ext/range/each.rb +18 -17
  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 +45 -0
  117. data/lib/active_support/core_ext/string/access.rb +9 -18
  118. data/lib/active_support/core_ext/string/behavior.rb +3 -1
  119. data/lib/active_support/core_ext/string/conversions.rb +8 -4
  120. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  121. data/lib/active_support/core_ext/string/filters.rb +48 -6
  122. data/lib/active_support/core_ext/string/indent.rb +6 -4
  123. data/lib/active_support/core_ext/string/inflections.rb +102 -26
  124. data/lib/active_support/core_ext/string/inquiry.rb +4 -1
  125. data/lib/active_support/core_ext/string/multibyte.rb +18 -9
  126. data/lib/active_support/core_ext/string/output_safety.rb +125 -40
  127. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
  128. data/lib/active_support/core_ext/string/strip.rb +6 -5
  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 +137 -53
  135. data/lib/active_support/core_ext/time/compatibility.rb +4 -2
  136. data/lib/active_support/core_ext/time/conversions.rb +22 -13
  137. data/lib/active_support/core_ext/time/zones.rb +41 -7
  138. data/lib/active_support/core_ext/time.rb +7 -6
  139. data/lib/active_support/core_ext/uri.rb +11 -8
  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 +57 -0
  145. data/lib/active_support/dependencies/zeitwerk_integration.rb +120 -0
  146. data/lib/active_support/dependencies.rb +241 -175
  147. data/lib/active_support/deprecation/behaviors.rb +58 -12
  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 +62 -21
  152. data/lib/active_support/deprecation/proxy_wrappers.rb +81 -30
  153. data/lib/active_support/deprecation/reporting.rb +81 -18
  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 +22 -0
  157. data/lib/active_support/duration/iso8601_parser.rb +123 -0
  158. data/lib/active_support/duration/iso8601_serializer.rb +59 -0
  159. data/lib/active_support/duration.rb +364 -39
  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 +170 -0
  164. data/lib/active_support/execution_wrapper.rb +132 -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/fork_tracker.rb +64 -0
  168. data/lib/active_support/gem_version.rb +7 -5
  169. data/lib/active_support/gzip.rb +7 -5
  170. data/lib/active_support/hash_with_indifferent_access.rb +171 -48
  171. data/lib/active_support/i18n.rb +9 -6
  172. data/lib/active_support/i18n_railtie.rb +47 -16
  173. data/lib/active_support/inflections.rb +13 -11
  174. data/lib/active_support/inflector/inflections.rb +58 -14
  175. data/lib/active_support/inflector/methods.rb +186 -169
  176. data/lib/active_support/inflector/transliterate.rb +83 -33
  177. data/lib/active_support/inflector.rb +7 -5
  178. data/lib/active_support/json/decoding.rb +32 -30
  179. data/lib/active_support/json/encoding.rb +22 -61
  180. data/lib/active_support/json.rb +4 -2
  181. data/lib/active_support/key_generator.rb +11 -43
  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 +9 -3
  185. data/lib/active_support/log_subscriber/test_helper.rb +14 -12
  186. data/lib/active_support/log_subscriber.rb +52 -19
  187. data/lib/active_support/logger.rb +10 -24
  188. data/lib/active_support/logger_silence.rb +14 -20
  189. data/lib/active_support/logger_thread_safe_level.rb +56 -10
  190. data/lib/active_support/message_encryptor.rb +167 -57
  191. data/lib/active_support/message_verifier.rb +151 -18
  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 +35 -80
  196. data/lib/active_support/multibyte/unicode.rb +22 -330
  197. data/lib/active_support/multibyte.rb +4 -2
  198. data/lib/active_support/notifications/fanout.rb +125 -23
  199. data/lib/active_support/notifications/instrumenter.rb +98 -16
  200. data/lib/active_support/notifications.rb +82 -14
  201. data/lib/active_support/number_helper/number_converter.rb +17 -16
  202. data/lib/active_support/number_helper/number_to_currency_converter.rb +9 -14
  203. data/lib/active_support/number_helper/number_to_delimited_converter.rb +11 -4
  204. data/lib/active_support/number_helper/number_to_human_converter.rb +14 -11
  205. data/lib/active_support/number_helper/number_to_human_size_converter.rb +12 -10
  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 +15 -5
  208. data/lib/active_support/number_helper/number_to_rounded_converter.rb +29 -57
  209. data/lib/active_support/number_helper/rounding_helper.rb +50 -0
  210. data/lib/active_support/number_helper.rb +123 -71
  211. data/lib/active_support/option_merger.rb +25 -4
  212. data/lib/active_support/ordered_hash.rb +7 -5
  213. data/lib/active_support/ordered_options.rb +35 -7
  214. data/lib/active_support/parameter_filter.rb +133 -0
  215. data/lib/active_support/per_thread_registry.rb +10 -4
  216. data/lib/active_support/proxy_object.rb +2 -0
  217. data/lib/active_support/rails.rb +10 -11
  218. data/lib/active_support/railtie.rb +66 -10
  219. data/lib/active_support/reloader.rb +130 -0
  220. data/lib/active_support/rescuable.rb +112 -57
  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 +13 -4
  224. data/lib/active_support/subscriber.rb +80 -31
  225. data/lib/active_support/tagged_logging.rb +54 -17
  226. data/lib/active_support/test_case.rb +107 -44
  227. data/lib/active_support/testing/assertions.rb +158 -20
  228. data/lib/active_support/testing/autorun.rb +4 -2
  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 +13 -10
  232. data/lib/active_support/testing/file_fixtures.rb +38 -0
  233. data/lib/active_support/testing/isolation.rb +35 -26
  234. data/lib/active_support/testing/method_call_assertions.rb +70 -0
  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 +43 -0
  240. data/lib/active_support/testing/tagged_logging.rb +3 -1
  241. data/lib/active_support/testing/time_helpers.rb +121 -20
  242. data/lib/active_support/time.rb +14 -12
  243. data/lib/active_support/time_with_zone.rb +215 -51
  244. data/lib/active_support/values/time_zone.rb +223 -71
  245. data/lib/active_support/version.rb +3 -1
  246. data/lib/active_support/xml_mini/jdom.rb +116 -115
  247. data/lib/active_support/xml_mini/libxml.rb +16 -13
  248. data/lib/active_support/xml_mini/libxmlsax.rb +15 -14
  249. data/lib/active_support/xml_mini/nokogiri.rb +14 -12
  250. data/lib/active_support/xml_mini/nokogirisax.rb +14 -13
  251. data/lib/active_support/xml_mini/rexml.rb +18 -9
  252. data/lib/active_support/xml_mini.rb +38 -46
  253. data/lib/active_support.rb +25 -11
  254. metadata +100 -43
  255. data/lib/active_support/concurrency/latch.rb +0 -27
  256. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
  257. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
  258. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
  259. data/lib/active_support/core_ext/date_time/zones.rb +0 -6
  260. data/lib/active_support/core_ext/hash/compact.rb +0 -24
  261. data/lib/active_support/core_ext/hash/transform_values.rb +0 -23
  262. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
  263. data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
  264. data/lib/active_support/core_ext/module/method_transplanting.rb +0 -13
  265. data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
  266. data/lib/active_support/core_ext/module/reachable.rb +0 -8
  267. data/lib/active_support/core_ext/object/itself.rb +0 -15
  268. data/lib/active_support/core_ext/range/include_range.rb +0 -23
  269. data/lib/active_support/core_ext/struct.rb +0 -6
  270. data/lib/active_support/core_ext/thread.rb +0 -86
  271. data/lib/active_support/core_ext/time/marshal.rb +0 -30
  272. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,5 +1,9 @@
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"
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
@@ -40,6 +44,12 @@ module ActiveSupport
40
44
  # rgb = { black: '#000000', white: '#FFFFFF' }.with_indifferent_access
41
45
  #
42
46
  # which may be handy.
47
+ #
48
+ # To access this class outside of Rails, require the core extension with:
49
+ #
50
+ # require "active_support/core_ext/hash/indifferent_access"
51
+ #
52
+ # which will, in turn, require this file.
43
53
  class HashWithIndifferentAccess < Hash
44
54
  # Returns +true+ so that <tt>Array#extract_options!</tt> finds members of
45
55
  # this class.
@@ -59,24 +69,12 @@ module ActiveSupport
59
69
  if constructor.respond_to?(:to_hash)
60
70
  super()
61
71
  update(constructor)
62
- else
63
- super(constructor)
64
- end
65
- end
66
72
 
67
- def default(key = nil)
68
- if key.is_a?(Symbol) && include?(key = key.to_s)
69
- self[key]
73
+ hash = constructor.is_a?(Hash) ? constructor : constructor.to_hash
74
+ self.default = hash.default if hash.default
75
+ self.default_proc = hash.default_proc if hash.default_proc
70
76
  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
77
+ super(constructor)
80
78
  end
81
79
  end
82
80
 
@@ -92,14 +90,14 @@ module ActiveSupport
92
90
  # hash = ActiveSupport::HashWithIndifferentAccess.new
93
91
  # hash[:key] = 'value'
94
92
  #
95
- # This value can be later fetched using either +:key+ or +'key'+.
93
+ # This value can be later fetched using either +:key+ or <tt>'key'</tt>.
96
94
  def []=(key, value)
97
- regular_writer(convert_key(key), convert_value(value, for: :assignment))
95
+ regular_writer(convert_key(key), convert_value(value, conversion: :assignment))
98
96
  end
99
97
 
100
98
  alias_method :store, :[]=
101
99
 
102
- # 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:
103
101
  #
104
102
  # hash_1 = ActiveSupport::HashWithIndifferentAccess.new
105
103
  # hash_1[:key] = 'value'
@@ -109,11 +107,14 @@ module ActiveSupport
109
107
  #
110
108
  # hash_1.update(hash_2) # => {"key"=>"New Value!"}
111
109
  #
112
- # 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
113
114
  # <tt>ActiveSupport::HashWithIndifferentAccess</tt> or a regular +Hash+.
114
115
  # In either case the merge respects the semantics of indifferent access.
115
116
  #
116
- # 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
117
118
  # of the values end up in the receiver, but which one is unspecified.
118
119
  #
119
120
  # When given a block, the value for duplicated keys will be determined
@@ -124,18 +125,15 @@ module ActiveSupport
124
125
  # hash_1[:key] = 10
125
126
  # hash_2['key'] = 12
126
127
  # hash_1.update(hash_2) { |key, old, new| old + new } # => {"key"=>22}
127
- def update(other_hash)
128
- if other_hash.is_a? HashWithIndifferentAccess
129
- super(other_hash)
128
+ def update(*other_hashes, &block)
129
+ if other_hashes.size == 1
130
+ update_with_single_argument(other_hashes.first, block)
130
131
  else
131
- other_hash.to_hash.each_pair do |key, value|
132
- if block_given? && key?(key)
133
- value = yield(convert_key(key), self[key], value)
134
- end
135
- regular_writer(convert_key(key), convert_value(value))
132
+ other_hashes.each do |other_hash|
133
+ update_with_single_argument(other_hash, block)
136
134
  end
137
- self
138
135
  end
136
+ self
139
137
  end
140
138
 
141
139
  alias_method :merge!, :update
@@ -154,6 +152,32 @@ module ActiveSupport
154
152
  alias_method :has_key?, :key?
155
153
  alias_method :member?, :key?
156
154
 
155
+ # Same as <tt>Hash#[]</tt> where the key passed as argument can be
156
+ # either a string or a symbol:
157
+ #
158
+ # counters = ActiveSupport::HashWithIndifferentAccess.new
159
+ # counters[:foo] = 1
160
+ #
161
+ # counters['foo'] # => 1
162
+ # counters[:foo] # => 1
163
+ # counters[:zoo] # => nil
164
+ def [](key)
165
+ super(convert_key(key))
166
+ end
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
+
157
181
  # Same as <tt>Hash#fetch</tt> where the key passed as argument can be
158
182
  # either a string or a symbol:
159
183
  #
@@ -168,14 +192,55 @@ module ActiveSupport
168
192
  super(convert_key(key), *extras)
169
193
  end
170
194
 
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)
207
+ end
208
+
209
+ # Same as <tt>Hash#default</tt> where the key passed as argument can be
210
+ # either a string or a symbol:
211
+ #
212
+ # hash = ActiveSupport::HashWithIndifferentAccess.new(1)
213
+ # hash.default # => 1
214
+ #
215
+ # hash = ActiveSupport::HashWithIndifferentAccess.new { |hash, key| key }
216
+ # hash.default # => nil
217
+ # hash.default('foo') # => 'foo'
218
+ # hash.default(:foo) # => 'foo'
219
+ def default(*args)
220
+ super(*args.map { |arg| convert_key(arg) })
221
+ end
222
+
171
223
  # Returns an array of the values at the specified indices:
172
224
  #
173
225
  # hash = ActiveSupport::HashWithIndifferentAccess.new
174
226
  # hash[:a] = 'x'
175
227
  # hash[:b] = 'y'
176
228
  # hash.values_at('a', 'b') # => ["x", "y"]
177
- def values_at(*indices)
178
- 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)
179
244
  end
180
245
 
181
246
  # Returns a shallow copy of the hash.
@@ -184,7 +249,7 @@ module ActiveSupport
184
249
  # dup = hash.dup
185
250
  # dup[:a][:c] = 'c'
186
251
  #
187
- # hash[:a][:c] # => nil
252
+ # hash[:a][:c] # => "c"
188
253
  # dup[:a][:c] # => "c"
189
254
  def dup
190
255
  self.class.new(self).tap do |new_hash|
@@ -195,8 +260,8 @@ module ActiveSupport
195
260
  # This method has the same semantics of +update+, except it does not
196
261
  # modify the receiver but rather returns a new hash with indifferent
197
262
  # access with the result of the merge.
198
- def merge(hash, &block)
199
- self.dup.update(hash, &block)
263
+ def merge(*hashes, &block)
264
+ dup.update(*hashes, &block)
200
265
  end
201
266
 
202
267
  # Like +merge+ but the other way around: Merges the receiver into the
@@ -206,20 +271,22 @@ module ActiveSupport
206
271
  # hash['a'] = nil
207
272
  # hash.reverse_merge(a: 0, b: 1) # => {"a"=>nil, "b"=>1}
208
273
  def reverse_merge(other_hash)
209
- super(self.class.new_from_hash_copying_default(other_hash))
274
+ super(self.class.new(other_hash))
210
275
  end
276
+ alias_method :with_defaults, :reverse_merge
211
277
 
212
278
  # Same semantics as +reverse_merge+ but modifies the receiver in-place.
213
279
  def reverse_merge!(other_hash)
214
- replace(reverse_merge( other_hash ))
280
+ super(self.class.new(other_hash))
215
281
  end
282
+ alias_method :with_defaults!, :reverse_merge!
216
283
 
217
284
  # Replaces the contents of this hash with other_hash.
218
285
  #
219
286
  # h = { "a" => 100, "b" => 200 }
220
287
  # h.replace({ "c" => 300, "d" => 400 }) # => {"c"=>300, "d"=>400}
221
288
  def replace(other_hash)
222
- super(self.class.new_from_hash_copying_default(other_hash))
289
+ super(self.class.new(other_hash))
223
290
  end
224
291
 
225
292
  # Removes the specified key from the hash.
@@ -227,6 +294,15 @@ module ActiveSupport
227
294
  super(convert_key(key))
228
295
  end
229
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
+
230
306
  def stringify_keys!; self end
231
307
  def deep_stringify_keys!; self end
232
308
  def stringify_keys; dup end
@@ -234,14 +310,17 @@ module ActiveSupport
234
310
  undef :symbolize_keys!
235
311
  undef :deep_symbolize_keys!
236
312
  def symbolize_keys; to_hash.symbolize_keys! end
313
+ alias_method :to_options, :symbolize_keys
237
314
  def deep_symbolize_keys; to_hash.deep_symbolize_keys! end
238
315
  def to_options!; self end
239
316
 
240
317
  def select(*args, &block)
318
+ return to_enum(:select) unless block_given?
241
319
  dup.tap { |hash| hash.select!(*args, &block) }
242
320
  end
243
321
 
244
322
  def reject(*args, &block)
323
+ return to_enum(:reject) unless block_given?
245
324
  dup.tap { |hash| hash.reject!(*args, &block) }
246
325
  end
247
326
 
@@ -250,6 +329,29 @@ module ActiveSupport
250
329
  dup.tap { |hash| hash.transform_values!(*args, &block) }
251
330
  end
252
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
+
253
355
  def compact
254
356
  dup.tap(&:compact!)
255
357
  end
@@ -260,28 +362,34 @@ module ActiveSupport
260
362
  set_defaults(_new_hash)
261
363
 
262
364
  each do |key, value|
263
- _new_hash[key] = convert_value(value, for: :to_hash)
365
+ _new_hash[key] = convert_value(value, conversion: :to_hash)
264
366
  end
265
367
  _new_hash
266
368
  end
267
369
 
268
- protected
269
- def convert_key(key)
270
- key.kind_of?(Symbol) ? key.to_s : key
370
+ private
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
271
379
  end
272
380
 
273
- def convert_value(value, options = {})
381
+ def convert_value(value, conversion: nil)
274
382
  if value.is_a? Hash
275
- if options[:for] == :to_hash
383
+ if conversion == :to_hash
276
384
  value.to_hash
277
385
  else
278
386
  value.nested_under_indifferent_access
279
387
  end
280
388
  elsif value.is_a?(Array)
281
- if options[:for] != :assignment || value.frozen?
389
+ if conversion != :assignment || value.frozen?
282
390
  value = value.dup
283
391
  end
284
- value.map! { |e| convert_value(e, options) }
392
+ value.map! { |e| convert_value(e, conversion: conversion) }
285
393
  else
286
394
  value
287
395
  end
@@ -294,7 +402,22 @@ module ActiveSupport
294
402
  target.default = default
295
403
  end
296
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
297
418
  end
298
419
  end
299
420
 
421
+ # :stopdoc:
422
+
300
423
  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.
@@ -37,14 +40,18 @@ module I18n
37
40
  enforce_available_locales = I18n.enforce_available_locales if enforce_available_locales.nil?
38
41
  I18n.enforce_available_locales = false
39
42
 
43
+ reloadable_paths = []
40
44
  app.config.i18n.each do |setting, value|
41
45
  case setting
42
46
  when :railties_load_path
43
- app.config.i18n.load_path.unshift(*value)
47
+ reloadable_paths = value
48
+ app.config.i18n.load_path.unshift(*value.flat_map(&:existent))
44
49
  when :load_path
45
50
  I18n.load_path += value
51
+ when :raise_on_missing_translations
52
+ forward_raise_on_missing_translations_config(app)
46
53
  else
47
- I18n.send("#{setting}=", value)
54
+ I18n.public_send("#{setting}=", value)
48
55
  end
49
56
  end
50
57
 
@@ -53,29 +60,47 @@ 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
+ end
68
+
57
69
  app.reloaders << reloader
58
- ActionDispatch::Reloader.to_prepare { reloader.execute_if_updated }
70
+ app.reloader.to_run do
71
+ reloader.execute_if_updated { require_unload_lock! }
72
+ end
59
73
  reloader.execute
60
74
 
61
75
  @i18n_inited = true
62
76
  end
63
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
+
64
88
  def self.include_fallbacks_module
65
- I18n.backend.class.send(:include, I18n::Backend::Fallbacks)
89
+ I18n.backend.class.include(I18n::Backend::Fallbacks)
66
90
  end
67
91
 
68
92
  def self.init_fallbacks(fallbacks)
69
93
  include_fallbacks_module
70
94
 
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
- []
78
- 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
79
104
 
80
105
  I18n.fallbacks = I18n::Locale::Fallbacks.new(*args)
81
106
  end
@@ -90,5 +115,11 @@ module I18n
90
115
  raise "Unexpected fallback type #{fallbacks.inspect}"
91
116
  end
92
117
  end
118
+
119
+ def self.watched_dirs_with_extensions(paths)
120
+ paths.each_with_object({}) do |path, result|
121
+ result[path.absolute_current] = path.extensions
122
+ end
123
+ end
93
124
  end
94
125
  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