activesupport 4.0.13 → 5.2.5

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 (264) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +412 -444
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +8 -4
  5. data/lib/active_support/all.rb +5 -3
  6. data/lib/active_support/array_inquirer.rb +48 -0
  7. data/lib/active_support/backtrace_cleaner.rb +14 -12
  8. data/lib/active_support/benchmarkable.rb +6 -14
  9. data/lib/active_support/builder.rb +3 -1
  10. data/lib/active_support/cache/file_store.rb +67 -51
  11. data/lib/active_support/cache/mem_cache_store.rb +95 -97
  12. data/lib/active_support/cache/memory_store.rb +28 -30
  13. data/lib/active_support/cache/null_store.rb +7 -8
  14. data/lib/active_support/cache/redis_cache_store.rb +466 -0
  15. data/lib/active_support/cache/strategy/local_cache.rb +70 -56
  16. data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
  17. data/lib/active_support/cache.rb +331 -206
  18. data/lib/active_support/callbacks.rb +697 -426
  19. data/lib/active_support/concern.rb +32 -10
  20. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +17 -0
  21. data/lib/active_support/concurrency/share_lock.rb +227 -0
  22. data/lib/active_support/configurable.rb +8 -5
  23. data/lib/active_support/core_ext/array/access.rb +39 -1
  24. data/lib/active_support/core_ext/array/conversions.rb +24 -35
  25. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  26. data/lib/active_support/core_ext/array/grouping.rb +23 -13
  27. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  28. data/lib/active_support/core_ext/array/prepend_and_append.rb +7 -5
  29. data/lib/active_support/core_ext/array/wrap.rb +7 -4
  30. data/lib/active_support/core_ext/array.rb +9 -7
  31. data/lib/active_support/core_ext/benchmark.rb +3 -1
  32. data/lib/active_support/core_ext/big_decimal/conversions.rb +9 -26
  33. data/lib/active_support/core_ext/big_decimal.rb +3 -1
  34. data/lib/active_support/core_ext/class/attribute.rb +41 -23
  35. data/lib/active_support/core_ext/class/attribute_accessors.rb +5 -169
  36. data/lib/active_support/core_ext/class/subclasses.rb +20 -8
  37. data/lib/active_support/core_ext/class.rb +4 -4
  38. data/lib/active_support/core_ext/date/acts_like.rb +3 -1
  39. data/lib/active_support/core_ext/date/blank.rb +14 -0
  40. data/lib/active_support/core_ext/date/calculations.rb +21 -9
  41. data/lib/active_support/core_ext/date/conversions.rb +32 -22
  42. data/lib/active_support/core_ext/date/zones.rb +5 -34
  43. data/lib/active_support/core_ext/date.rb +6 -4
  44. data/lib/active_support/core_ext/date_and_time/calculations.rb +199 -57
  45. data/lib/active_support/core_ext/date_and_time/compatibility.rb +16 -0
  46. data/lib/active_support/core_ext/date_and_time/zones.rb +41 -0
  47. data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
  48. data/lib/active_support/core_ext/date_time/blank.rb +14 -0
  49. data/lib/active_support/core_ext/date_time/calculations.rb +78 -37
  50. data/lib/active_support/core_ext/date_time/compatibility.rb +18 -0
  51. data/lib/active_support/core_ext/date_time/conversions.rb +19 -13
  52. data/lib/active_support/core_ext/date_time.rb +7 -4
  53. data/lib/active_support/core_ext/digest/uuid.rb +53 -0
  54. data/lib/active_support/core_ext/digest.rb +3 -0
  55. data/lib/active_support/core_ext/enumerable.rb +113 -29
  56. data/lib/active_support/core_ext/file/atomic.rb +38 -31
  57. data/lib/active_support/core_ext/file.rb +3 -1
  58. data/lib/active_support/core_ext/hash/compact.rb +29 -0
  59. data/lib/active_support/core_ext/hash/conversions.rb +71 -49
  60. data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
  61. data/lib/active_support/core_ext/hash/except.rb +12 -3
  62. data/lib/active_support/core_ext/hash/indifferent_access.rb +5 -3
  63. data/lib/active_support/core_ext/hash/keys.rb +50 -38
  64. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  65. data/lib/active_support/core_ext/hash/slice.rb +12 -6
  66. data/lib/active_support/core_ext/hash/transform_values.rb +32 -0
  67. data/lib/active_support/core_ext/hash.rb +11 -8
  68. data/lib/active_support/core_ext/integer/inflections.rb +3 -1
  69. data/lib/active_support/core_ext/integer/multiple.rb +2 -0
  70. data/lib/active_support/core_ext/integer/time.rb +11 -33
  71. data/lib/active_support/core_ext/integer.rb +5 -3
  72. data/lib/active_support/core_ext/kernel/agnostics.rb +2 -0
  73. data/lib/active_support/core_ext/kernel/concern.rb +14 -0
  74. data/lib/active_support/core_ext/kernel/reporting.rb +5 -74
  75. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  76. data/lib/active_support/core_ext/kernel.rb +6 -4
  77. data/lib/active_support/core_ext/load_error.rb +5 -21
  78. data/lib/active_support/core_ext/marshal.rb +13 -10
  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 -8
  82. data/lib/active_support/core_ext/module/attribute_accessors.rb +170 -21
  83. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +150 -0
  84. data/lib/active_support/core_ext/module/concerning.rb +134 -0
  85. data/lib/active_support/core_ext/module/delegation.rb +135 -45
  86. data/lib/active_support/core_ext/module/deprecation.rb +3 -3
  87. data/lib/active_support/core_ext/module/introspection.rb +9 -25
  88. data/lib/active_support/core_ext/module/reachable.rb +5 -2
  89. data/lib/active_support/core_ext/module/redefine_method.rb +49 -0
  90. data/lib/active_support/core_ext/module/remove_method.rb +8 -3
  91. data/lib/active_support/core_ext/module.rb +14 -10
  92. data/lib/active_support/core_ext/name_error.rb +22 -2
  93. data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
  94. data/lib/active_support/core_ext/numeric/conversions.rb +79 -74
  95. data/lib/active_support/core_ext/numeric/inquiry.rb +28 -0
  96. data/lib/active_support/core_ext/numeric/time.rb +37 -50
  97. data/lib/active_support/core_ext/numeric.rb +6 -3
  98. data/lib/active_support/core_ext/object/acts_like.rb +12 -1
  99. data/lib/active_support/core_ext/object/blank.rb +70 -19
  100. data/lib/active_support/core_ext/object/conversions.rb +6 -4
  101. data/lib/active_support/core_ext/object/deep_dup.rb +19 -10
  102. data/lib/active_support/core_ext/object/duplicable.rb +100 -34
  103. data/lib/active_support/core_ext/object/inclusion.rb +18 -15
  104. data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
  105. data/lib/active_support/core_ext/object/json.rb +227 -0
  106. data/lib/active_support/core_ext/object/to_param.rb +3 -1
  107. data/lib/active_support/core_ext/object/to_query.rb +21 -8
  108. data/lib/active_support/core_ext/object/try.rb +94 -24
  109. data/lib/active_support/core_ext/object/with_options.rb +45 -5
  110. data/lib/active_support/core_ext/object.rb +14 -12
  111. data/lib/active_support/core_ext/range/compare_range.rb +61 -0
  112. data/lib/active_support/core_ext/range/conversions.rb +27 -7
  113. data/lib/active_support/core_ext/range/each.rb +19 -17
  114. data/lib/active_support/core_ext/range/include_range.rb +2 -22
  115. data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
  116. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  117. data/lib/active_support/core_ext/range.rb +7 -4
  118. data/lib/active_support/core_ext/regexp.rb +6 -0
  119. data/lib/active_support/core_ext/securerandom.rb +25 -0
  120. data/lib/active_support/core_ext/string/access.rb +41 -39
  121. data/lib/active_support/core_ext/string/behavior.rb +3 -1
  122. data/lib/active_support/core_ext/string/conversions.rb +17 -13
  123. data/lib/active_support/core_ext/string/exclude.rb +5 -3
  124. data/lib/active_support/core_ext/string/filters.rb +55 -6
  125. data/lib/active_support/core_ext/string/indent.rb +6 -4
  126. data/lib/active_support/core_ext/string/inflections.rb +66 -24
  127. data/lib/active_support/core_ext/string/inquiry.rb +3 -1
  128. data/lib/active_support/core_ext/string/multibyte.rb +15 -7
  129. data/lib/active_support/core_ext/string/output_safety.rb +114 -54
  130. data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
  131. data/lib/active_support/core_ext/string/strip.rb +4 -5
  132. data/lib/active_support/core_ext/string/zones.rb +4 -1
  133. data/lib/active_support/core_ext/string.rb +15 -13
  134. data/lib/active_support/core_ext/time/acts_like.rb +3 -1
  135. data/lib/active_support/core_ext/time/calculations.rb +123 -110
  136. data/lib/active_support/core_ext/time/compatibility.rb +16 -0
  137. data/lib/active_support/core_ext/time/conversions.rb +23 -14
  138. data/lib/active_support/core_ext/time/zones.rb +42 -26
  139. data/lib/active_support/core_ext/time.rb +7 -5
  140. data/lib/active_support/core_ext/uri.rb +6 -8
  141. data/lib/active_support/core_ext.rb +3 -2
  142. data/lib/active_support/current_attributes.rb +195 -0
  143. data/lib/active_support/dependencies/autoload.rb +3 -1
  144. data/lib/active_support/dependencies/interlock.rb +57 -0
  145. data/lib/active_support/dependencies.rb +196 -166
  146. data/lib/active_support/deprecation/behaviors.rb +48 -15
  147. data/lib/active_support/deprecation/constant_accessor.rb +52 -0
  148. data/lib/active_support/deprecation/instance_delegator.rb +17 -2
  149. data/lib/active_support/deprecation/method_wrappers.rb +66 -20
  150. data/lib/active_support/deprecation/proxy_wrappers.rb +56 -28
  151. data/lib/active_support/deprecation/reporting.rb +32 -12
  152. data/lib/active_support/deprecation.rb +14 -11
  153. data/lib/active_support/descendants_tracker.rb +2 -0
  154. data/lib/active_support/digest.rb +20 -0
  155. data/lib/active_support/duration/iso8601_parser.rb +125 -0
  156. data/lib/active_support/duration/iso8601_serializer.rb +55 -0
  157. data/lib/active_support/duration.rb +354 -34
  158. data/lib/active_support/encrypted_configuration.rb +49 -0
  159. data/lib/active_support/encrypted_file.rb +99 -0
  160. data/lib/active_support/evented_file_update_checker.rb +205 -0
  161. data/lib/active_support/execution_wrapper.rb +128 -0
  162. data/lib/active_support/executor.rb +8 -0
  163. data/lib/active_support/file_update_checker.rb +63 -37
  164. data/lib/active_support/gem_version.rb +17 -0
  165. data/lib/active_support/gzip.rb +7 -5
  166. data/lib/active_support/hash_with_indifferent_access.rb +158 -35
  167. data/lib/active_support/i18n.rb +8 -6
  168. data/lib/active_support/i18n_railtie.rb +38 -20
  169. data/lib/active_support/inflections.rb +19 -12
  170. data/lib/active_support/inflector/inflections.rb +79 -30
  171. data/lib/active_support/inflector/methods.rb +197 -129
  172. data/lib/active_support/inflector/transliterate.rb +48 -27
  173. data/lib/active_support/inflector.rb +7 -5
  174. data/lib/active_support/json/decoding.rb +21 -25
  175. data/lib/active_support/json/encoding.rb +84 -292
  176. data/lib/active_support/json.rb +4 -2
  177. data/lib/active_support/key_generator.rb +26 -28
  178. data/lib/active_support/lazy_load_hooks.rb +51 -21
  179. data/lib/active_support/locale/en.yml +2 -0
  180. data/lib/active_support/log_subscriber/test_helper.rb +14 -12
  181. data/lib/active_support/log_subscriber.rb +13 -10
  182. data/lib/active_support/logger.rb +54 -3
  183. data/lib/active_support/logger_silence.rb +12 -7
  184. data/lib/active_support/logger_thread_safe_level.rb +34 -0
  185. data/lib/active_support/message_encryptor.rb +173 -50
  186. data/lib/active_support/message_verifier.rb +159 -22
  187. data/lib/active_support/messages/metadata.rb +71 -0
  188. data/lib/active_support/messages/rotation_configuration.rb +22 -0
  189. data/lib/active_support/messages/rotator.rb +56 -0
  190. data/lib/active_support/multibyte/chars.rb +38 -26
  191. data/lib/active_support/multibyte/unicode.rb +138 -146
  192. data/lib/active_support/multibyte.rb +4 -2
  193. data/lib/active_support/notifications/fanout.rb +23 -16
  194. data/lib/active_support/notifications/instrumenter.rb +29 -8
  195. data/lib/active_support/notifications.rb +22 -13
  196. data/lib/active_support/number_helper/number_converter.rb +184 -0
  197. data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
  198. data/lib/active_support/number_helper/number_to_delimited_converter.rb +29 -0
  199. data/lib/active_support/number_helper/number_to_human_converter.rb +68 -0
  200. data/lib/active_support/number_helper/number_to_human_size_converter.rb +59 -0
  201. data/lib/active_support/number_helper/number_to_percentage_converter.rb +14 -0
  202. data/lib/active_support/number_helper/number_to_phone_converter.rb +58 -0
  203. data/lib/active_support/number_helper/number_to_rounded_converter.rb +54 -0
  204. data/lib/active_support/number_helper/rounding_helper.rb +66 -0
  205. data/lib/active_support/number_helper.rb +125 -391
  206. data/lib/active_support/option_merger.rb +3 -1
  207. data/lib/active_support/ordered_hash.rb +6 -4
  208. data/lib/active_support/ordered_options.rb +31 -5
  209. data/lib/active_support/per_thread_registry.rb +19 -11
  210. data/lib/active_support/proxy_object.rb +2 -0
  211. data/lib/active_support/rails.rb +16 -8
  212. data/lib/active_support/railtie.rb +43 -9
  213. data/lib/active_support/reloader.rb +131 -0
  214. data/lib/active_support/rescuable.rb +108 -53
  215. data/lib/active_support/security_utils.rb +31 -0
  216. data/lib/active_support/string_inquirer.rb +11 -3
  217. data/lib/active_support/subscriber.rb +54 -17
  218. data/lib/active_support/tagged_logging.rb +14 -11
  219. data/lib/active_support/test_case.rb +42 -37
  220. data/lib/active_support/testing/assertions.rb +126 -39
  221. data/lib/active_support/testing/autorun.rb +5 -3
  222. data/lib/active_support/testing/constant_lookup.rb +3 -6
  223. data/lib/active_support/testing/declarative.rb +10 -22
  224. data/lib/active_support/testing/deprecation.rb +14 -10
  225. data/lib/active_support/testing/file_fixtures.rb +36 -0
  226. data/lib/active_support/testing/isolation.rb +55 -86
  227. data/lib/active_support/testing/method_call_assertions.rb +43 -0
  228. data/lib/active_support/testing/setup_and_teardown.rb +30 -10
  229. data/lib/active_support/testing/stream.rb +44 -0
  230. data/lib/active_support/testing/tagged_logging.rb +5 -3
  231. data/lib/active_support/testing/time_helpers.rb +200 -0
  232. data/lib/active_support/time.rb +13 -13
  233. data/lib/active_support/time_with_zone.rb +223 -73
  234. data/lib/active_support/values/time_zone.rb +261 -126
  235. data/lib/active_support/values/unicode_tables.dat +0 -0
  236. data/lib/active_support/version.rb +6 -7
  237. data/lib/active_support/xml_mini/jdom.rb +116 -113
  238. data/lib/active_support/xml_mini/libxml.rb +17 -16
  239. data/lib/active_support/xml_mini/libxmlsax.rb +16 -18
  240. data/lib/active_support/xml_mini/nokogiri.rb +15 -15
  241. data/lib/active_support/xml_mini/nokogirisax.rb +15 -16
  242. data/lib/active_support/xml_mini/rexml.rb +17 -16
  243. data/lib/active_support/xml_mini.rb +69 -51
  244. data/lib/active_support.rb +29 -3
  245. metadata +84 -54
  246. data/lib/active_support/basic_object.rb +0 -11
  247. data/lib/active_support/buffered_logger.rb +0 -21
  248. data/lib/active_support/concurrency/latch.rb +0 -27
  249. data/lib/active_support/core_ext/array/uniq_by.rb +0 -19
  250. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -40
  251. data/lib/active_support/core_ext/date_time/zones.rb +0 -24
  252. data/lib/active_support/core_ext/hash/diff.rb +0 -14
  253. data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
  254. data/lib/active_support/core_ext/logger.rb +0 -67
  255. data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
  256. data/lib/active_support/core_ext/object/to_json.rb +0 -27
  257. data/lib/active_support/core_ext/proc.rb +0 -17
  258. data/lib/active_support/core_ext/string/encoding.rb +0 -8
  259. data/lib/active_support/core_ext/struct.rb +0 -6
  260. data/lib/active_support/core_ext/thread.rb +0 -79
  261. data/lib/active_support/core_ext/time/marshal.rb +0 -30
  262. data/lib/active_support/file_watcher.rb +0 -36
  263. data/lib/active_support/json/variable.rb +0 -18
  264. data/lib/active_support/testing/pending.rb +0 -14
@@ -1,4 +1,7 @@
1
- require 'active_support/core_ext/hash/keys'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/hash/keys"
4
+ require "active_support/core_ext/hash/reverse_merge"
2
5
 
3
6
  module ActiveSupport
4
7
  # Implements a hash where keys <tt>:foo</tt> and <tt>"foo"</tt> are considered
@@ -39,6 +42,12 @@ module ActiveSupport
39
42
  # rgb = { black: '#000000', white: '#FFFFFF' }.with_indifferent_access
40
43
  #
41
44
  # which may be handy.
45
+ #
46
+ # To access this class outside of Rails, require the core extension with:
47
+ #
48
+ # require "active_support/core_ext/hash/indifferent_access"
49
+ #
50
+ # which will, in turn, require this file.
42
51
  class HashWithIndifferentAccess < Hash
43
52
  # Returns +true+ so that <tt>Array#extract_options!</tt> finds members of
44
53
  # this class.
@@ -55,26 +64,15 @@ module ActiveSupport
55
64
  end
56
65
 
57
66
  def initialize(constructor = {})
58
- if constructor.is_a?(Hash)
67
+ if constructor.respond_to?(:to_hash)
59
68
  super()
60
69
  update(constructor)
61
- else
62
- super(constructor)
63
- end
64
- end
65
70
 
66
- def default(key = nil)
67
- if key.is_a?(Symbol) && include?(key = key.to_s)
68
- self[key]
71
+ hash = constructor.to_hash
72
+ self.default = hash.default if hash.default
73
+ self.default_proc = hash.default_proc if hash.default_proc
69
74
  else
70
- super
71
- end
72
- end
73
-
74
- def self.new_from_hash_copying_default(hash)
75
- hash = hash.to_hash
76
- new(hash).tap do |new_hash|
77
- new_hash.default = hash.default
75
+ super(constructor)
78
76
  end
79
77
  end
80
78
 
@@ -90,7 +88,7 @@ module ActiveSupport
90
88
  # hash = ActiveSupport::HashWithIndifferentAccess.new
91
89
  # hash[:key] = 'value'
92
90
  #
93
- # This value can be later fetched using either +:key+ or +'key'+.
91
+ # This value can be later fetched using either +:key+ or <tt>'key'</tt>.
94
92
  def []=(key, value)
95
93
  regular_writer(convert_key(key), convert_value(value, for: :assignment))
96
94
  end
@@ -152,6 +150,32 @@ module ActiveSupport
152
150
  alias_method :has_key?, :key?
153
151
  alias_method :member?, :key?
154
152
 
153
+ # Same as <tt>Hash#[]</tt> where the key passed as argument can be
154
+ # either a string or a symbol:
155
+ #
156
+ # counters = ActiveSupport::HashWithIndifferentAccess.new
157
+ # counters[:foo] = 1
158
+ #
159
+ # counters['foo'] # => 1
160
+ # counters[:foo] # => 1
161
+ # counters[:zoo] # => nil
162
+ def [](key)
163
+ super(convert_key(key))
164
+ end
165
+
166
+ # Same as <tt>Hash#assoc</tt> where the key passed as argument can be
167
+ # either a string or a symbol:
168
+ #
169
+ # counters = ActiveSupport::HashWithIndifferentAccess.new
170
+ # counters[:foo] = 1
171
+ #
172
+ # counters.assoc('foo') # => ["foo", 1]
173
+ # counters.assoc(:foo) # => ["foo", 1]
174
+ # counters.assoc(:zoo) # => nil
175
+ def assoc(key)
176
+ super(convert_key(key))
177
+ end
178
+
155
179
  # Same as <tt>Hash#fetch</tt> where the key passed as argument can be
156
180
  # either a string or a symbol:
157
181
  #
@@ -160,12 +184,42 @@ module ActiveSupport
160
184
  #
161
185
  # counters.fetch('foo') # => 1
162
186
  # counters.fetch(:bar, 0) # => 0
163
- # counters.fetch(:bar) {|key| 0} # => 0
187
+ # counters.fetch(:bar) { |key| 0 } # => 0
164
188
  # counters.fetch(:zoo) # => KeyError: key not found: "zoo"
165
189
  def fetch(key, *extras)
166
190
  super(convert_key(key), *extras)
167
191
  end
168
192
 
193
+ if Hash.new.respond_to?(:dig)
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
+ 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
+
169
223
  # Returns an array of the values at the specified indices:
170
224
  #
171
225
  # hash = ActiveSupport::HashWithIndifferentAccess.new
@@ -173,13 +227,33 @@ module ActiveSupport
173
227
  # hash[:b] = 'y'
174
228
  # hash.values_at('a', 'b') # => ["x", "y"]
175
229
  def values_at(*indices)
176
- indices.collect {|key| self[convert_key(key)]}
230
+ indices.collect { |key| self[convert_key(key)] }
177
231
  end
178
232
 
179
- # Returns an exact copy of the hash.
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
+ indices.collect { |key| fetch(key, &block) }
244
+ end if Hash.method_defined?(:fetch_values)
245
+
246
+ # Returns a shallow copy of the hash.
247
+ #
248
+ # hash = ActiveSupport::HashWithIndifferentAccess.new({ a: { b: 'b' } })
249
+ # dup = hash.dup
250
+ # dup[:a][:c] = 'c'
251
+ #
252
+ # hash[:a][:c] # => "c"
253
+ # dup[:a][:c] # => "c"
180
254
  def dup
181
255
  self.class.new(self).tap do |new_hash|
182
- new_hash.default = default
256
+ set_defaults(new_hash)
183
257
  end
184
258
  end
185
259
 
@@ -187,7 +261,7 @@ module ActiveSupport
187
261
  # modify the receiver but rather returns a new hash with indifferent
188
262
  # access with the result of the merge.
189
263
  def merge(hash, &block)
190
- self.dup.update(hash, &block)
264
+ dup.update(hash, &block)
191
265
  end
192
266
 
193
267
  # Like +merge+ but the other way around: Merges the receiver into the
@@ -197,20 +271,22 @@ module ActiveSupport
197
271
  # hash['a'] = nil
198
272
  # hash.reverse_merge(a: 0, b: 1) # => {"a"=>nil, "b"=>1}
199
273
  def reverse_merge(other_hash)
200
- super(self.class.new_from_hash_copying_default(other_hash))
274
+ super(self.class.new(other_hash))
201
275
  end
276
+ alias_method :with_defaults, :reverse_merge
202
277
 
203
278
  # Same semantics as +reverse_merge+ but modifies the receiver in-place.
204
279
  def reverse_merge!(other_hash)
205
- replace(reverse_merge( other_hash ))
280
+ super(self.class.new(other_hash))
206
281
  end
282
+ alias_method :with_defaults!, :reverse_merge!
207
283
 
208
284
  # Replaces the contents of this hash with other_hash.
209
285
  #
210
286
  # h = { "a" => 100, "b" => 200 }
211
- # h.replace({ "c" => 300, "d" => 400 }) #=> {"c"=>300, "d"=>400}
287
+ # h.replace({ "c" => 300, "d" => 400 }) # => {"c"=>300, "d"=>400}
212
288
  def replace(other_hash)
213
- super(self.class.new_from_hash_copying_default(other_hash))
289
+ super(self.class.new(other_hash))
214
290
  end
215
291
 
216
292
  # Removes the specified key from the hash.
@@ -225,32 +301,69 @@ module ActiveSupport
225
301
  undef :symbolize_keys!
226
302
  undef :deep_symbolize_keys!
227
303
  def symbolize_keys; to_hash.symbolize_keys! end
228
- def deep_symbolize_keys; to_hash.deep_symbolize_keys end
304
+ alias_method :to_options, :symbolize_keys
305
+ def deep_symbolize_keys; to_hash.deep_symbolize_keys! end
229
306
  def to_options!; self end
230
307
 
231
308
  def select(*args, &block)
309
+ return to_enum(:select) unless block_given?
232
310
  dup.tap { |hash| hash.select!(*args, &block) }
233
311
  end
234
312
 
235
313
  def reject(*args, &block)
314
+ return to_enum(:reject) unless block_given?
236
315
  dup.tap { |hash| hash.reject!(*args, &block) }
237
316
  end
238
317
 
318
+ def transform_values(*args, &block)
319
+ return to_enum(:transform_values) unless block_given?
320
+ dup.tap { |hash| hash.transform_values!(*args, &block) }
321
+ end
322
+
323
+ def transform_keys(*args, &block)
324
+ return to_enum(:transform_keys) unless block_given?
325
+ dup.tap { |hash| hash.transform_keys!(*args, &block) }
326
+ end
327
+
328
+ def transform_keys!
329
+ return enum_for(:transform_keys!) { size } unless block_given?
330
+ keys.each do |key|
331
+ self[yield(key)] = delete(key)
332
+ end
333
+ self
334
+ end
335
+
336
+ def slice(*keys)
337
+ keys.map! { |key| convert_key(key) }
338
+ self.class.new(super)
339
+ end
340
+
341
+ def slice!(*keys)
342
+ keys.map! { |key| convert_key(key) }
343
+ super
344
+ end
345
+
346
+ def compact
347
+ dup.tap(&:compact!)
348
+ end
349
+
239
350
  # Convert to a regular hash with string keys.
240
351
  def to_hash
241
- _new_hash= {}
352
+ _new_hash = Hash.new
353
+ set_defaults(_new_hash)
354
+
242
355
  each do |key, value|
243
- _new_hash[convert_key(key)] = convert_value(value, for: :to_hash)
356
+ _new_hash[key] = convert_value(value, for: :to_hash)
244
357
  end
245
- Hash.new(default).merge!(_new_hash)
358
+ _new_hash
246
359
  end
247
360
 
248
- protected
249
- def convert_key(key)
361
+ private
362
+ def convert_key(key) # :doc:
250
363
  key.kind_of?(Symbol) ? key.to_s : key
251
364
  end
252
365
 
253
- def convert_value(value, options = {})
366
+ def convert_value(value, options = {}) # :doc:
254
367
  if value.is_a? Hash
255
368
  if options[:for] == :to_hash
256
369
  value.to_hash
@@ -258,7 +371,7 @@ module ActiveSupport
258
371
  value.nested_under_indifferent_access
259
372
  end
260
373
  elsif value.is_a?(Array)
261
- unless options[:for] == :assignment
374
+ if options[:for] != :assignment || value.frozen?
262
375
  value = value.dup
263
376
  end
264
377
  value.map! { |e| convert_value(e, options) }
@@ -266,7 +379,17 @@ module ActiveSupport
266
379
  value
267
380
  end
268
381
  end
382
+
383
+ def set_defaults(target) # :doc:
384
+ if default_proc
385
+ target.default_proc = default_proc.dup
386
+ else
387
+ target.default = default
388
+ end
389
+ end
269
390
  end
270
391
  end
271
392
 
393
+ # :stopdoc:
394
+
272
395
  HashWithIndifferentAccess = ActiveSupport::HashWithIndifferentAccess
@@ -1,13 +1,15 @@
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"
1
6
  begin
2
- require 'active_support/core_ext/hash/deep_merge'
3
- require 'active_support/core_ext/hash/except'
4
- require 'active_support/core_ext/hash/slice'
5
- require 'i18n'
6
- require 'active_support/lazy_load_hooks'
7
+ require "i18n"
7
8
  rescue LoadError => e
8
9
  $stderr.puts "The i18n gem is not available. Please add it to your Gemfile and run bundle install"
9
10
  raise e
10
11
  end
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__)
@@ -1,15 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support"
2
4
  require "active_support/file_update_checker"
3
5
  require "active_support/core_ext/array/wrap"
4
6
 
7
+ # :enddoc:
8
+
5
9
  module I18n
6
10
  class Railtie < Rails::Railtie
7
11
  config.i18n = ActiveSupport::OrderedOptions.new
8
12
  config.i18n.railties_load_path = []
9
13
  config.i18n.load_path = []
10
14
  config.i18n.fallbacks = ActiveSupport::OrderedOptions.new
11
- # Enforce I18n to check the available locales when setting a locale.
12
- config.i18n.enforce_available_locales = true
13
15
 
14
16
  # Set the i18n configuration after initialization since a lot of
15
17
  # configuration is still usually done in application initializers.
@@ -23,8 +25,6 @@ module I18n
23
25
  I18n::Railtie.initialize_i18n(app)
24
26
  end
25
27
 
26
- protected
27
-
28
28
  @i18n_inited = false
29
29
 
30
30
  # Setup i18n configuration.
@@ -36,17 +36,15 @@ module I18n
36
36
  # Avoid issues with setting the default_locale by disabling available locales
37
37
  # check while configuring.
38
38
  enforce_available_locales = app.config.i18n.delete(:enforce_available_locales)
39
-
40
- if enforce_available_locales.nil?
41
- enforce_available_locales = I18n.enforce_available_locales
42
- end
43
-
39
+ enforce_available_locales = I18n.enforce_available_locales if enforce_available_locales.nil?
44
40
  I18n.enforce_available_locales = false
45
41
 
42
+ reloadable_paths = []
46
43
  app.config.i18n.each do |setting, value|
47
44
  case setting
48
45
  when :railties_load_path
49
- app.config.i18n.load_path.unshift(*value)
46
+ reloadable_paths = value
47
+ app.config.i18n.load_path.unshift(*value.flat_map(&:existent))
50
48
  when :load_path
51
49
  I18n.load_path += value
52
50
  else
@@ -59,28 +57,42 @@ module I18n
59
57
  # Restore available locales check so it will take place from now on.
60
58
  I18n.enforce_available_locales = enforce_available_locales
61
59
 
62
- reloader = ActiveSupport::FileUpdateChecker.new(I18n.load_path.dup){ I18n.reload! }
60
+ directories = watched_dirs_with_extensions(reloadable_paths)
61
+ reloader = app.config.file_watcher.new(I18n.load_path.dup, directories) do
62
+ I18n.load_path.keep_if { |p| File.exist?(p) }
63
+ I18n.load_path |= reloadable_paths.flat_map(&:existent)
64
+
65
+ I18n.reload!
66
+ end
67
+
63
68
  app.reloaders << reloader
64
- ActionDispatch::Reloader.to_prepare { reloader.execute_if_updated }
69
+ app.reloader.to_run do
70
+ reloader.execute_if_updated { require_unload_lock! }
71
+ end
65
72
  reloader.execute
66
73
 
67
74
  @i18n_inited = true
68
75
  end
69
76
 
70
77
  def self.include_fallbacks_module
71
- I18n.backend.class.send(:include, I18n::Backend::Fallbacks)
78
+ I18n.backend.class.include(I18n::Backend::Fallbacks)
72
79
  end
73
80
 
74
81
  def self.init_fallbacks(fallbacks)
75
82
  include_fallbacks_module
76
83
 
77
- args = case fallbacks
78
- when ActiveSupport::OrderedOptions
79
- [*(fallbacks[:defaults] || []) << fallbacks[:map]].compact
80
- when Hash, Array
81
- Array.wrap(fallbacks)
82
- else # TrueClass
83
- []
84
+ args = \
85
+ case fallbacks
86
+ when ActiveSupport::OrderedOptions
87
+ [*(fallbacks[:defaults] || []) << fallbacks[:map]].compact
88
+ when Hash, Array
89
+ Array.wrap(fallbacks)
90
+ else # TrueClass
91
+ [I18n.default_locale]
92
+ end
93
+
94
+ if args.empty? || args.first.is_a?(Hash)
95
+ args.unshift I18n.default_locale
84
96
  end
85
97
 
86
98
  I18n.fallbacks = I18n::Locale::Fallbacks.new(*args)
@@ -96,5 +108,11 @@ module I18n
96
108
  raise "Unexpected fallback type #{fallbacks.inspect}"
97
109
  end
98
110
  end
111
+
112
+ def self.watched_dirs_with_extensions(paths)
113
+ paths.each_with_object({}) do |path, result|
114
+ result[path.absolute_current] = path.extensions
115
+ end
116
+ end
99
117
  end
100
118
  end
@@ -1,9 +1,17 @@
1
- require 'active_support/inflector/inflections'
1
+ # frozen_string_literal: true
2
2
 
3
+ require "active_support/inflector/inflections"
4
+
5
+ #--
6
+ # Defines the standard inflection rules. These are the starting point for
7
+ # new projects and are not considered complete. The current set of inflection
8
+ # rules is frozen. This means, we do not change them to become more complete.
9
+ # This is a safety measure to keep existing applications from breaking.
10
+ #++
3
11
  module ActiveSupport
4
12
  Inflector.inflections(:en) do |inflect|
5
- inflect.plural(/$/, 's')
6
- inflect.plural(/s$/i, 's')
13
+ inflect.plural(/$/, "s")
14
+ inflect.plural(/s$/i, "s")
7
15
  inflect.plural(/^(ax|test)is$/i, '\1es')
8
16
  inflect.plural(/(octop|vir)us$/i, '\1i')
9
17
  inflect.plural(/(octop|vir)i$/i, '\1i')
@@ -12,7 +20,7 @@ module ActiveSupport
12
20
  inflect.plural(/(buffal|tomat)o$/i, '\1oes')
13
21
  inflect.plural(/([ti])um$/i, '\1a')
14
22
  inflect.plural(/([ti])a$/i, '\1a')
15
- inflect.plural(/sis$/i, 'ses')
23
+ inflect.plural(/sis$/i, "ses")
16
24
  inflect.plural(/(?:([^f])fe|([lr])f)$/i, '\1\2ves')
17
25
  inflect.plural(/(hive)$/i, '\1s')
18
26
  inflect.plural(/([^aeiouy]|qu)y$/i, '\1ies')
@@ -24,7 +32,7 @@ module ActiveSupport
24
32
  inflect.plural(/^(oxen)$/i, '\1')
25
33
  inflect.plural(/(quiz)$/i, '\1zes')
26
34
 
27
- inflect.singular(/s$/i, '')
35
+ inflect.singular(/s$/i, "")
28
36
  inflect.singular(/(ss)$/i, '\1')
29
37
  inflect.singular(/(n)ews$/i, '\1ews')
30
38
  inflect.singular(/([ti])a$/i, '\1um')
@@ -52,13 +60,12 @@ module ActiveSupport
52
60
  inflect.singular(/(quiz)zes$/i, '\1')
53
61
  inflect.singular(/(database)s$/i, '\1')
54
62
 
55
- inflect.irregular('person', 'people')
56
- inflect.irregular('man', 'men')
57
- inflect.irregular('child', 'children')
58
- inflect.irregular('sex', 'sexes')
59
- inflect.irregular('move', 'moves')
60
- inflect.irregular('cow', 'kine')
61
- 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")
62
69
 
63
70
  inflect.uncountable(%w(equipment information rice money species series fish sheep jeans police))
64
71
  end