activesupport 5.1.7 → 7.0.4.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 (279) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +259 -585
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +6 -5
  5. data/lib/active_support/actionable_error.rb +48 -0
  6. data/lib/active_support/all.rb +2 -0
  7. data/lib/active_support/array_inquirer.rb +4 -2
  8. data/lib/active_support/backtrace_cleaner.rb +33 -5
  9. data/lib/active_support/benchmarkable.rb +5 -3
  10. data/lib/active_support/builder.rb +2 -0
  11. data/lib/active_support/cache/file_store.rb +50 -43
  12. data/lib/active_support/cache/mem_cache_store.rb +194 -67
  13. data/lib/active_support/cache/memory_store.rb +70 -34
  14. data/lib/active_support/cache/null_store.rb +18 -3
  15. data/lib/active_support/cache/redis_cache_store.rb +474 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +73 -50
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +2 -0
  18. data/lib/active_support/cache.rb +556 -220
  19. data/lib/active_support/callbacks.rb +264 -159
  20. data/lib/active_support/code_generator.rb +65 -0
  21. data/lib/active_support/concern.rb +81 -8
  22. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +16 -0
  23. data/lib/active_support/concurrency/share_lock.rb +4 -3
  24. data/lib/active_support/configurable.rb +17 -16
  25. data/lib/active_support/configuration_file.rb +51 -0
  26. data/lib/active_support/core_ext/array/access.rb +18 -8
  27. data/lib/active_support/core_ext/array/conversions.rb +20 -17
  28. data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
  29. data/lib/active_support/core_ext/array/extract.rb +21 -0
  30. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  31. data/lib/active_support/core_ext/array/grouping.rb +8 -6
  32. data/lib/active_support/core_ext/array/inquiry.rb +4 -2
  33. data/lib/active_support/core_ext/array/wrap.rb +2 -0
  34. data/lib/active_support/core_ext/array.rb +4 -1
  35. data/lib/active_support/core_ext/benchmark.rb +4 -2
  36. data/lib/active_support/core_ext/big_decimal/conversions.rb +3 -1
  37. data/lib/active_support/core_ext/big_decimal.rb +2 -0
  38. data/lib/active_support/core_ext/class/attribute.rb +50 -47
  39. data/lib/active_support/core_ext/class/attribute_accessors.rb +2 -0
  40. data/lib/active_support/core_ext/class/subclasses.rb +10 -24
  41. data/lib/active_support/core_ext/class.rb +2 -0
  42. data/lib/active_support/core_ext/date/acts_like.rb +2 -0
  43. data/lib/active_support/core_ext/date/blank.rb +3 -1
  44. data/lib/active_support/core_ext/date/calculations.rb +17 -14
  45. data/lib/active_support/core_ext/date/conversions.rb +24 -22
  46. data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
  47. data/lib/active_support/core_ext/date/zones.rb +2 -0
  48. data/lib/active_support/core_ext/date.rb +3 -0
  49. data/lib/active_support/core_ext/date_and_time/calculations.rb +65 -41
  50. data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -1
  51. data/lib/active_support/core_ext/date_and_time/zones.rb +2 -1
  52. data/lib/active_support/core_ext/date_time/acts_like.rb +2 -0
  53. data/lib/active_support/core_ext/date_time/blank.rb +3 -1
  54. data/lib/active_support/core_ext/date_time/calculations.rb +3 -1
  55. data/lib/active_support/core_ext/date_time/compatibility.rb +7 -5
  56. data/lib/active_support/core_ext/date_time/conversions.rb +15 -14
  57. data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
  58. data/lib/active_support/core_ext/date_time.rb +3 -0
  59. data/lib/active_support/core_ext/digest/uuid.rb +42 -14
  60. data/lib/active_support/core_ext/digest.rb +3 -0
  61. data/lib/active_support/core_ext/enumerable.rb +244 -72
  62. data/lib/active_support/core_ext/file/atomic.rb +6 -2
  63. data/lib/active_support/core_ext/file.rb +2 -0
  64. data/lib/active_support/core_ext/hash/conversions.rb +7 -6
  65. data/lib/active_support/core_ext/hash/deep_merge.rb +8 -12
  66. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  67. data/lib/active_support/core_ext/hash/except.rb +4 -2
  68. data/lib/active_support/core_ext/hash/indifferent_access.rb +5 -3
  69. data/lib/active_support/core_ext/hash/keys.rb +4 -31
  70. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  71. data/lib/active_support/core_ext/hash/slice.rb +8 -29
  72. data/lib/active_support/core_ext/hash.rb +3 -2
  73. data/lib/active_support/core_ext/integer/inflections.rb +2 -0
  74. data/lib/active_support/core_ext/integer/multiple.rb +3 -1
  75. data/lib/active_support/core_ext/integer/time.rb +7 -14
  76. data/lib/active_support/core_ext/integer.rb +2 -0
  77. data/lib/active_support/core_ext/kernel/concern.rb +2 -0
  78. data/lib/active_support/core_ext/kernel/reporting.rb +6 -4
  79. data/lib/active_support/core_ext/kernel/singleton_class.rb +3 -1
  80. data/lib/active_support/core_ext/kernel.rb +2 -1
  81. data/lib/active_support/core_ext/load_error.rb +3 -8
  82. data/lib/active_support/core_ext/module/aliasing.rb +2 -0
  83. data/lib/active_support/core_ext/module/anonymous.rb +2 -0
  84. data/lib/active_support/core_ext/module/attr_internal.rb +4 -2
  85. data/lib/active_support/core_ext/module/attribute_accessors.rb +46 -56
  86. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +36 -27
  87. data/lib/active_support/core_ext/module/concerning.rb +15 -10
  88. data/lib/active_support/core_ext/module/delegation.rb +97 -58
  89. data/lib/active_support/core_ext/module/deprecation.rb +2 -0
  90. data/lib/active_support/core_ext/module/introspection.rb +18 -15
  91. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  92. data/lib/active_support/core_ext/module/remove_method.rb +5 -23
  93. data/lib/active_support/core_ext/module.rb +3 -1
  94. data/lib/active_support/core_ext/name_error.rb +30 -2
  95. data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
  96. data/lib/active_support/core_ext/numeric/conversions.rb +134 -129
  97. data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
  98. data/lib/active_support/core_ext/numeric/time.rb +7 -15
  99. data/lib/active_support/core_ext/numeric.rb +3 -1
  100. data/lib/active_support/core_ext/object/acts_like.rb +41 -6
  101. data/lib/active_support/core_ext/object/blank.rb +15 -5
  102. data/lib/active_support/core_ext/object/conversions.rb +2 -0
  103. data/lib/active_support/core_ext/object/deep_dup.rb +3 -1
  104. data/lib/active_support/core_ext/object/duplicable.rb +16 -110
  105. data/lib/active_support/core_ext/object/inclusion.rb +2 -0
  106. data/lib/active_support/core_ext/object/instance_variables.rb +2 -0
  107. data/lib/active_support/core_ext/object/json.rb +51 -26
  108. data/lib/active_support/core_ext/object/to_param.rb +2 -0
  109. data/lib/active_support/core_ext/object/to_query.rb +4 -2
  110. data/lib/active_support/core_ext/object/try.rb +26 -14
  111. data/lib/active_support/core_ext/object/with_options.rb +24 -3
  112. data/lib/active_support/core_ext/object.rb +2 -0
  113. data/lib/active_support/core_ext/pathname/existence.rb +21 -0
  114. data/lib/active_support/core_ext/pathname.rb +3 -0
  115. data/lib/active_support/core_ext/range/compare_range.rb +57 -0
  116. data/lib/active_support/core_ext/range/conversions.rb +35 -25
  117. data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
  118. data/lib/active_support/core_ext/range/each.rb +6 -3
  119. data/lib/active_support/core_ext/range/include_time_with_zone.rb +7 -0
  120. data/lib/active_support/core_ext/range/overlaps.rb +3 -1
  121. data/lib/active_support/core_ext/range.rb +4 -1
  122. data/lib/active_support/core_ext/regexp.rb +10 -5
  123. data/lib/active_support/core_ext/securerandom.rb +25 -3
  124. data/lib/active_support/core_ext/string/access.rb +7 -16
  125. data/lib/active_support/core_ext/string/behavior.rb +2 -0
  126. data/lib/active_support/core_ext/string/conversions.rb +5 -2
  127. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  128. data/lib/active_support/core_ext/string/filters.rb +44 -1
  129. data/lib/active_support/core_ext/string/indent.rb +2 -0
  130. data/lib/active_support/core_ext/string/inflections.rb +69 -16
  131. data/lib/active_support/core_ext/string/inquiry.rb +4 -1
  132. data/lib/active_support/core_ext/string/multibyte.rb +9 -4
  133. data/lib/active_support/core_ext/string/output_safety.rb +135 -27
  134. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
  135. data/lib/active_support/core_ext/string/strip.rb +5 -1
  136. data/lib/active_support/core_ext/string/zones.rb +2 -0
  137. data/lib/active_support/core_ext/string.rb +2 -0
  138. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
  139. data/lib/active_support/core_ext/symbol.rb +3 -0
  140. data/lib/active_support/core_ext/time/acts_like.rb +2 -0
  141. data/lib/active_support/core_ext/time/calculations.rb +81 -24
  142. data/lib/active_support/core_ext/time/compatibility.rb +4 -2
  143. data/lib/active_support/core_ext/time/conversions.rb +17 -12
  144. data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
  145. data/lib/active_support/core_ext/time/zones.rb +12 -25
  146. data/lib/active_support/core_ext/time.rb +3 -0
  147. data/lib/active_support/core_ext/uri.rb +4 -23
  148. data/lib/active_support/core_ext.rb +4 -1
  149. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  150. data/lib/active_support/current_attributes.rb +226 -0
  151. data/lib/active_support/dependencies/autoload.rb +2 -0
  152. data/lib/active_support/dependencies/interlock.rb +12 -18
  153. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  154. data/lib/active_support/dependencies.rb +59 -715
  155. data/lib/active_support/deprecation/behaviors.rb +48 -13
  156. data/lib/active_support/deprecation/constant_accessor.rb +4 -2
  157. data/lib/active_support/deprecation/disallowed.rb +56 -0
  158. data/lib/active_support/deprecation/instance_delegator.rb +2 -1
  159. data/lib/active_support/deprecation/method_wrappers.rb +29 -21
  160. data/lib/active_support/deprecation/proxy_wrappers.rb +34 -8
  161. data/lib/active_support/deprecation/reporting.rb +54 -9
  162. data/lib/active_support/deprecation.rb +10 -3
  163. data/lib/active_support/descendants_tracker.rb +192 -34
  164. data/lib/active_support/digest.rb +22 -0
  165. data/lib/active_support/duration/iso8601_parser.rb +9 -9
  166. data/lib/active_support/duration/iso8601_serializer.rb +29 -15
  167. data/lib/active_support/duration.rb +158 -72
  168. data/lib/active_support/encrypted_configuration.rb +56 -0
  169. data/lib/active_support/encrypted_file.rb +129 -0
  170. data/lib/active_support/environment_inquirer.rb +20 -0
  171. data/lib/active_support/error_reporter.rb +117 -0
  172. data/lib/active_support/evented_file_update_checker.rb +87 -122
  173. data/lib/active_support/execution_context/test_helper.rb +13 -0
  174. data/lib/active_support/execution_context.rb +53 -0
  175. data/lib/active_support/execution_wrapper.rb +46 -21
  176. data/lib/active_support/executor/test_helper.rb +7 -0
  177. data/lib/active_support/executor.rb +2 -0
  178. data/lib/active_support/file_update_checker.rb +2 -1
  179. data/lib/active_support/fork_tracker.rb +71 -0
  180. data/lib/active_support/gem_version.rb +7 -5
  181. data/lib/active_support/gzip.rb +2 -0
  182. data/lib/active_support/hash_with_indifferent_access.rb +126 -42
  183. data/lib/active_support/html_safe_translation.rb +43 -0
  184. data/lib/active_support/i18n.rb +5 -1
  185. data/lib/active_support/i18n_railtie.rb +19 -14
  186. data/lib/active_support/inflections.rb +2 -0
  187. data/lib/active_support/inflector/inflections.rb +41 -14
  188. data/lib/active_support/inflector/methods.rb +73 -87
  189. data/lib/active_support/inflector/transliterate.rb +56 -18
  190. data/lib/active_support/inflector.rb +2 -0
  191. data/lib/active_support/isolated_execution_state.rb +72 -0
  192. data/lib/active_support/json/decoding.rb +27 -26
  193. data/lib/active_support/json/encoding.rb +16 -6
  194. data/lib/active_support/json.rb +2 -0
  195. data/lib/active_support/key_generator.rb +25 -38
  196. data/lib/active_support/lazy_load_hooks.rb +35 -6
  197. data/lib/active_support/locale/en.rb +33 -0
  198. data/lib/active_support/locale/en.yml +8 -4
  199. data/lib/active_support/log_subscriber/test_helper.rb +4 -2
  200. data/lib/active_support/log_subscriber.rb +54 -13
  201. data/lib/active_support/logger.rb +4 -17
  202. data/lib/active_support/logger_silence.rb +13 -20
  203. data/lib/active_support/logger_thread_safe_level.rb +48 -10
  204. data/lib/active_support/message_encryptor.rb +111 -37
  205. data/lib/active_support/message_verifier.rb +124 -21
  206. data/lib/active_support/messages/metadata.rb +80 -0
  207. data/lib/active_support/messages/rotation_configuration.rb +23 -0
  208. data/lib/active_support/messages/rotator.rb +57 -0
  209. data/lib/active_support/multibyte/chars.rb +19 -76
  210. data/lib/active_support/multibyte/unicode.rb +9 -331
  211. data/lib/active_support/multibyte.rb +3 -1
  212. data/lib/active_support/notifications/fanout.rb +165 -37
  213. data/lib/active_support/notifications/instrumenter.rb +92 -11
  214. data/lib/active_support/notifications.rb +96 -30
  215. data/lib/active_support/number_helper/number_converter.rb +8 -9
  216. data/lib/active_support/number_helper/number_to_currency_converter.rb +14 -12
  217. data/lib/active_support/number_helper/number_to_delimited_converter.rb +6 -3
  218. data/lib/active_support/number_helper/number_to_human_converter.rb +6 -3
  219. data/lib/active_support/number_helper/number_to_human_size_converter.rb +7 -4
  220. data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
  221. data/lib/active_support/number_helper/number_to_phone_converter.rb +6 -3
  222. data/lib/active_support/number_helper/number_to_rounded_converter.rb +14 -27
  223. data/lib/active_support/number_helper/rounding_helper.rb +16 -34
  224. data/lib/active_support/number_helper.rb +38 -12
  225. data/lib/active_support/option_merger.rb +19 -6
  226. data/lib/active_support/ordered_hash.rb +4 -2
  227. data/lib/active_support/ordered_options.rb +18 -6
  228. data/lib/active_support/parameter_filter.rb +138 -0
  229. data/lib/active_support/per_thread_registry.rb +8 -1
  230. data/lib/active_support/proxy_object.rb +2 -0
  231. data/lib/active_support/rails.rb +3 -10
  232. data/lib/active_support/railtie.rb +112 -11
  233. data/lib/active_support/reloader.rb +12 -11
  234. data/lib/active_support/rescuable.rb +19 -18
  235. data/lib/active_support/ruby_features.rb +7 -0
  236. data/lib/active_support/secure_compare_rotator.rb +51 -0
  237. data/lib/active_support/security_utils.rb +26 -15
  238. data/lib/active_support/string_inquirer.rb +4 -3
  239. data/lib/active_support/subscriber.rb +81 -42
  240. data/lib/active_support/tagged_logging.rb +45 -9
  241. data/lib/active_support/test_case.rb +86 -2
  242. data/lib/active_support/testing/assertions.rb +89 -21
  243. data/lib/active_support/testing/autorun.rb +2 -0
  244. data/lib/active_support/testing/constant_lookup.rb +2 -0
  245. data/lib/active_support/testing/declarative.rb +2 -0
  246. data/lib/active_support/testing/deprecation.rb +54 -2
  247. data/lib/active_support/testing/file_fixtures.rb +4 -0
  248. data/lib/active_support/testing/isolation.rb +6 -4
  249. data/lib/active_support/testing/method_call_assertions.rb +34 -5
  250. data/lib/active_support/testing/parallelization/server.rb +82 -0
  251. data/lib/active_support/testing/parallelization/worker.rb +103 -0
  252. data/lib/active_support/testing/parallelization.rb +55 -0
  253. data/lib/active_support/testing/parallelize_executor.rb +76 -0
  254. data/lib/active_support/testing/setup_and_teardown.rb +12 -7
  255. data/lib/active_support/testing/stream.rb +6 -7
  256. data/lib/active_support/testing/tagged_logging.rb +3 -1
  257. data/lib/active_support/testing/time_helpers.rb +91 -15
  258. data/lib/active_support/time.rb +2 -0
  259. data/lib/active_support/time_with_zone.rb +168 -56
  260. data/lib/active_support/values/time_zone.rb +85 -37
  261. data/lib/active_support/version.rb +3 -1
  262. data/lib/active_support/xml_mini/jdom.rb +6 -5
  263. data/lib/active_support/xml_mini/libxml.rb +9 -7
  264. data/lib/active_support/xml_mini/libxmlsax.rb +7 -5
  265. data/lib/active_support/xml_mini/nokogiri.rb +8 -6
  266. data/lib/active_support/xml_mini/nokogirisax.rb +6 -4
  267. data/lib/active_support/xml_mini/rexml.rb +13 -4
  268. data/lib/active_support/xml_mini.rb +10 -15
  269. data/lib/active_support.rb +30 -9
  270. metadata +76 -35
  271. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
  272. data/lib/active_support/core_ext/hash/compact.rb +0 -27
  273. data/lib/active_support/core_ext/hash/transform_values.rb +0 -30
  274. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
  275. data/lib/active_support/core_ext/marshal.rb +0 -22
  276. data/lib/active_support/core_ext/module/reachable.rb +0 -8
  277. data/lib/active_support/core_ext/numeric/inquiry.rb +0 -26
  278. data/lib/active_support/core_ext/range/include_range.rb +0 -23
  279. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,35 +1,13 @@
1
- class Hash
2
- # Slices a hash to include only the given keys. Returns a hash containing
3
- # the given keys.
4
- #
5
- # { a: 1, b: 2, c: 3, d: 4 }.slice(:a, :b)
6
- # # => {:a=>1, :b=>2}
7
- #
8
- # This is useful for limiting an options hash to valid keys before
9
- # passing to a method:
10
- #
11
- # def search(criteria = {})
12
- # criteria.assert_valid_keys(:mass, :velocity, :time)
13
- # end
14
- #
15
- # search(options.slice(:mass, :velocity, :time))
16
- #
17
- # If you have an array of keys you want to limit to, you should splat them:
18
- #
19
- # valid_keys = [:mass, :velocity, :time]
20
- # search(options.slice(*valid_keys))
21
- def slice(*keys)
22
- keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
23
- keys.each_with_object(self.class.new) { |k, hash| hash[k] = self[k] if has_key?(k) }
24
- end
1
+ # frozen_string_literal: true
25
2
 
3
+ class Hash
26
4
  # Replaces the hash with only the given keys.
27
5
  # Returns a hash containing the removed key/value pairs.
28
6
  #
29
- # { a: 1, b: 2, c: 3, d: 4 }.slice!(:a, :b)
30
- # # => {:c=>3, :d=>4}
7
+ # hash = { a: 1, b: 2, c: 3, d: 4 }
8
+ # hash.slice!(:a, :b) # => {:c=>3, :d=>4}
9
+ # hash # => {:a=>1, :b=>2}
31
10
  def slice!(*keys)
32
- keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
33
11
  omit = slice(*self.keys - keys)
34
12
  hash = slice(*keys)
35
13
  hash.default = default
@@ -40,8 +18,9 @@ class Hash
40
18
 
41
19
  # Removes and returns the key/value pairs matching the given keys.
42
20
  #
43
- # { a: 1, b: 2, c: 3, d: 4 }.extract!(:a, :b) # => {:a=>1, :b=>2}
44
- # { a: 1, b: 2 }.extract!(:a, :x) # => {:a=>1}
21
+ # hash = { a: 1, b: 2, c: 3, d: 4 }
22
+ # hash.extract!(:a, :b) # => {:a=>1, :b=>2}
23
+ # hash # => {:c=>3, :d=>4}
45
24
  def extract!(*keys)
46
25
  keys.each_with_object(self.class.new) { |key, result| result[key] = delete(key) if has_key?(key) }
47
26
  end
@@ -1,9 +1,10 @@
1
- require "active_support/core_ext/hash/compact"
1
+ # frozen_string_literal: true
2
+
2
3
  require "active_support/core_ext/hash/conversions"
3
4
  require "active_support/core_ext/hash/deep_merge"
5
+ require "active_support/core_ext/hash/deep_transform_values"
4
6
  require "active_support/core_ext/hash/except"
5
7
  require "active_support/core_ext/hash/indifferent_access"
6
8
  require "active_support/core_ext/hash/keys"
7
9
  require "active_support/core_ext/hash/reverse_merge"
8
10
  require "active_support/core_ext/hash/slice"
9
- require "active_support/core_ext/hash/transform_values"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/inflector"
2
4
 
3
5
  class Integer
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Integer
2
4
  # Check whether the integer is evenly divisible by the argument.
3
5
  #
@@ -5,6 +7,6 @@ class Integer
5
7
  # 6.multiple_of?(5) # => false
6
8
  # 10.multiple_of?(2) # => true
7
9
  def multiple_of?(number)
8
- number != 0 ? self % number == 0 : zero?
10
+ number == 0 ? self == 0 : self % number == 0
9
11
  end
10
12
  end
@@ -1,27 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/duration"
2
4
  require "active_support/core_ext/numeric/time"
3
5
 
4
6
  class Integer
5
- # Enables the use of time calculations and declarations, like <tt>45.minutes +
6
- # 2.hours + 4.years</tt>.
7
- #
8
- # These methods use Time#advance for precise date calculations when using
9
- # <tt>from_now</tt>, +ago+, etc. as well as adding or subtracting their
10
- # results from a Time object.
11
- #
12
- # # equivalent to Time.now.advance(months: 1)
13
- # 1.month.from_now
7
+ # Returns a Duration instance matching the number of months provided.
14
8
  #
15
- # # equivalent to Time.now.advance(years: 2)
16
- # 2.years.from_now
17
- #
18
- # # equivalent to Time.now.advance(months: 4, years: 5)
19
- # (4.months + 5.years).from_now
9
+ # 2.months # => 2 months
20
10
  def months
21
11
  ActiveSupport::Duration.months(self)
22
12
  end
23
13
  alias :month :months
24
14
 
15
+ # Returns a Duration instance matching the number of years provided.
16
+ #
17
+ # 2.years # => 2 years
25
18
  def years
26
19
  ActiveSupport::Duration.years(self)
27
20
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/integer/multiple"
2
4
  require "active_support/core_ext/integer/inflections"
3
5
  require "active_support/core_ext/integer/time"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/module/concerning"
2
4
 
3
5
  module Kernel
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Kernel
2
4
  module_function
3
5
 
@@ -9,14 +11,14 @@ module Kernel
9
11
  # end
10
12
  #
11
13
  # noisy_call # warning voiced
12
- def silence_warnings
13
- with_warnings(nil) { yield }
14
+ def silence_warnings(&block)
15
+ with_warnings(nil, &block)
14
16
  end
15
17
 
16
18
  # Sets $VERBOSE to +true+ for the duration of the block and back to its
17
19
  # original value afterwards.
18
- def enable_warnings
19
- with_warnings(true) { yield }
20
+ def enable_warnings(&block)
21
+ with_warnings(true, &block)
20
22
  end
21
23
 
22
24
  # Sets $VERBOSE for the duration of the block and back to its original
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Kernel
2
- # class_eval on an object acts like singleton_class.class_eval.
4
+ # class_eval on an object acts like +singleton_class.class_eval+.
3
5
  def class_eval(*args, &block)
4
6
  singleton_class.class_eval(*args, &block)
5
7
  end
@@ -1,4 +1,5 @@
1
- require "active_support/core_ext/kernel/agnostics"
1
+ # frozen_string_literal: true
2
+
2
3
  require "active_support/core_ext/kernel/concern"
3
4
  require "active_support/core_ext/kernel/reporting"
4
5
  require "active_support/core_ext/kernel/singleton_class"
@@ -1,14 +1,9 @@
1
- class LoadError
2
- REGEXPS = [
3
- /^no such file to load -- (.+)$/i,
4
- /^Missing \w+ (?:file\s*)?([^\s]+.rb)$/i,
5
- /^Missing API definition file in (.+)$/i,
6
- /^cannot load such file -- (.+)$/i,
7
- ]
1
+ # frozen_string_literal: true
8
2
 
3
+ class LoadError
9
4
  # Returns true if the given path name (except perhaps for the ".rb"
10
5
  # extension) is the missing file which caused the exception to be raised.
11
6
  def is_missing?(location)
12
- location.sub(/\.rb$/, "".freeze) == path.sub(/\.rb$/, "".freeze)
7
+ location.delete_suffix(".rb") == path.to_s.delete_suffix(".rb")
13
8
  end
14
9
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Module
2
4
  # Allows you to make aliases for attributes, which includes
3
5
  # getter, setter, and a predicate.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Module
2
4
  # A module may or may not have a name.
3
5
  #
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Module
2
4
  # Declares an attribute reader backed by an internally-named instance variable.
3
5
  def attr_internal_reader(*attrs)
@@ -26,9 +28,9 @@ class Module
26
28
  end
27
29
 
28
30
  def attr_internal_define(attr_name, type)
29
- internal_name = attr_internal_ivar_name(attr_name).sub(/\A@/, "")
31
+ internal_name = attr_internal_ivar_name(attr_name).delete_prefix("@")
30
32
  # use native attr_* methods as they are faster on some Ruby implementations
31
- send("attr_#{type}", internal_name)
33
+ public_send("attr_#{type}", internal_name)
32
34
  attr_name, internal_name = "#{attr_name}=", "#{internal_name}=" if type == :writer
33
35
  alias_method attr_name, internal_name
34
36
  remove_method internal_name
@@ -1,6 +1,7 @@
1
- require "active_support/core_ext/array/extract_options"
2
- require "active_support/core_ext/regexp"
1
+ # frozen_string_literal: true
3
2
 
3
+ # == Attribute Accessors
4
+ #
4
5
  # Extends the module object with class/module and instance accessors for
5
6
  # class/module attributes, just like the native attr* accessors for instance
6
7
  # attributes.
@@ -25,7 +26,7 @@ class Module
25
26
  # end
26
27
  # # => NameError: invalid attribute name: 1_Badname
27
28
  #
28
- # If you want to opt out the creation on the instance reader method, pass
29
+ # To omit the instance reader method, pass
29
30
  # <tt>instance_reader: false</tt> or <tt>instance_accessor: false</tt>.
30
31
  #
31
32
  # module HairColors
@@ -38,13 +39,10 @@ class Module
38
39
  #
39
40
  # Person.new.hair_colors # => NoMethodError
40
41
  #
41
- #
42
- # Also, you can pass a block to set up the attribute with a default value.
42
+ # You can set a default value for the attribute.
43
43
  #
44
44
  # module HairColors
45
- # mattr_reader :hair_colors do
46
- # [:brown, :black, :blonde, :red]
47
- # end
45
+ # mattr_reader :hair_colors, default: [:brown, :black, :blonde, :red]
48
46
  # end
49
47
  #
50
48
  # class Person
@@ -52,27 +50,25 @@ class Module
52
50
  # end
53
51
  #
54
52
  # Person.new.hair_colors # => [:brown, :black, :blonde, :red]
55
- def mattr_reader(*syms)
56
- options = syms.extract_options!
53
+ def mattr_reader(*syms, instance_reader: true, instance_accessor: true, default: nil, location: nil)
54
+ raise TypeError, "module attributes should be defined directly on class, not singleton" if singleton_class?
55
+ location ||= caller_locations(1, 1).first
56
+
57
+ definition = []
57
58
  syms.each do |sym|
58
59
  raise NameError.new("invalid attribute name: #{sym}") unless /\A[_A-Za-z]\w*\z/.match?(sym)
59
- class_eval(<<-EOS, __FILE__, __LINE__ + 1)
60
- @@#{sym} = nil unless defined? @@#{sym}
61
60
 
62
- def self.#{sym}
63
- @@#{sym}
64
- end
65
- EOS
61
+ definition << "def self.#{sym}; @@#{sym}; end"
66
62
 
67
- unless options[:instance_reader] == false || options[:instance_accessor] == false
68
- class_eval(<<-EOS, __FILE__, __LINE__ + 1)
69
- def #{sym}
70
- @@#{sym}
71
- end
72
- EOS
63
+ if instance_reader && instance_accessor
64
+ definition << "def #{sym}; @@#{sym}; end"
73
65
  end
74
- class_variable_set("@@#{sym}", yield) if block_given?
66
+
67
+ sym_default_value = (block_given? && default.nil?) ? yield : default
68
+ class_variable_set("@@#{sym}", sym_default_value) unless sym_default_value.nil? && class_variable_defined?("@@#{sym}")
75
69
  end
70
+
71
+ module_eval(definition.join(";"), location.path, location.lineno)
76
72
  end
77
73
  alias :cattr_reader :mattr_reader
78
74
 
@@ -94,7 +90,7 @@ class Module
94
90
  # Person.new.hair_colors = [:blonde, :red]
95
91
  # HairColors.class_variable_get("@@hair_colors") # => [:blonde, :red]
96
92
  #
97
- # If you want to opt out the instance writer method, pass
93
+ # To omit the instance writer method, pass
98
94
  # <tt>instance_writer: false</tt> or <tt>instance_accessor: false</tt>.
99
95
  #
100
96
  # module HairColors
@@ -107,12 +103,10 @@ class Module
107
103
  #
108
104
  # Person.new.hair_colors = [:blonde, :red] # => NoMethodError
109
105
  #
110
- # Also, you can pass a block to set up the attribute with a default value.
106
+ # You can set a default value for the attribute.
111
107
  #
112
108
  # module HairColors
113
- # mattr_writer :hair_colors do
114
- # [:brown, :black, :blonde, :red]
115
- # end
109
+ # mattr_writer :hair_colors, default: [:brown, :black, :blonde, :red]
116
110
  # end
117
111
  #
118
112
  # class Person
@@ -120,27 +114,24 @@ class Module
120
114
  # end
121
115
  #
122
116
  # Person.class_variable_get("@@hair_colors") # => [:brown, :black, :blonde, :red]
123
- def mattr_writer(*syms)
124
- options = syms.extract_options!
117
+ def mattr_writer(*syms, instance_writer: true, instance_accessor: true, default: nil, location: nil)
118
+ raise TypeError, "module attributes should be defined directly on class, not singleton" if singleton_class?
119
+ location ||= caller_locations(1, 1).first
120
+
121
+ definition = []
125
122
  syms.each do |sym|
126
123
  raise NameError.new("invalid attribute name: #{sym}") unless /\A[_A-Za-z]\w*\z/.match?(sym)
127
- class_eval(<<-EOS, __FILE__, __LINE__ + 1)
128
- @@#{sym} = nil unless defined? @@#{sym}
129
-
130
- def self.#{sym}=(obj)
131
- @@#{sym} = obj
132
- end
133
- EOS
124
+ definition << "def self.#{sym}=(val); @@#{sym} = val; end"
134
125
 
135
- unless options[:instance_writer] == false || options[:instance_accessor] == false
136
- class_eval(<<-EOS, __FILE__, __LINE__ + 1)
137
- def #{sym}=(obj)
138
- @@#{sym} = obj
139
- end
140
- EOS
126
+ if instance_writer && instance_accessor
127
+ definition << "def #{sym}=(val); @@#{sym} = val; end"
141
128
  end
142
- send("#{sym}=", yield) if block_given?
129
+
130
+ sym_default_value = (block_given? && default.nil?) ? yield : default
131
+ class_variable_set("@@#{sym}", sym_default_value) unless sym_default_value.nil? && class_variable_defined?("@@#{sym}")
143
132
  end
133
+
134
+ module_eval(definition.join(";"), location.path, location.lineno)
144
135
  end
145
136
  alias :cattr_writer :mattr_writer
146
137
 
@@ -164,14 +155,14 @@ class Module
164
155
  # parent class. Similarly if parent class changes the value then that would
165
156
  # change the value of subclasses too.
166
157
  #
167
- # class Male < Person
158
+ # class Citizen < Person
168
159
  # end
169
160
  #
170
- # Male.new.hair_colors << :blue
161
+ # Citizen.new.hair_colors << :blue
171
162
  # Person.new.hair_colors # => [:brown, :black, :blonde, :red, :blue]
172
163
  #
173
- # To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
174
- # To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
164
+ # To omit the instance writer method, pass <tt>instance_writer: false</tt>.
165
+ # To omit the instance reader method, pass <tt>instance_reader: false</tt>.
175
166
  #
176
167
  # module HairColors
177
168
  # mattr_accessor :hair_colors, instance_writer: false, instance_reader: false
@@ -184,7 +175,7 @@ class Module
184
175
  # Person.new.hair_colors = [:brown] # => NoMethodError
185
176
  # Person.new.hair_colors # => NoMethodError
186
177
  #
187
- # Or pass <tt>instance_accessor: false</tt>, to opt out both instance methods.
178
+ # Or pass <tt>instance_accessor: false</tt>, to omit both instance methods.
188
179
  #
189
180
  # module HairColors
190
181
  # mattr_accessor :hair_colors, instance_accessor: false
@@ -197,12 +188,10 @@ class Module
197
188
  # Person.new.hair_colors = [:brown] # => NoMethodError
198
189
  # Person.new.hair_colors # => NoMethodError
199
190
  #
200
- # Also you can pass a block to set up the attribute with a default value.
191
+ # You can set a default value for the attribute.
201
192
  #
202
193
  # module HairColors
203
- # mattr_accessor :hair_colors do
204
- # [:brown, :black, :blonde, :red]
205
- # end
194
+ # mattr_accessor :hair_colors, default: [:brown, :black, :blonde, :red]
206
195
  # end
207
196
  #
208
197
  # class Person
@@ -210,9 +199,10 @@ class Module
210
199
  # end
211
200
  #
212
201
  # Person.class_variable_get("@@hair_colors") # => [:brown, :black, :blonde, :red]
213
- def mattr_accessor(*syms, &blk)
214
- mattr_reader(*syms, &blk)
215
- mattr_writer(*syms)
202
+ def mattr_accessor(*syms, instance_reader: true, instance_writer: true, instance_accessor: true, default: nil, &blk)
203
+ location = caller_locations(1, 1).first
204
+ mattr_reader(*syms, instance_reader: instance_reader, instance_accessor: instance_accessor, default: default, location: location, &blk)
205
+ mattr_writer(*syms, instance_writer: instance_writer, instance_accessor: instance_accessor, default: default, location: location)
216
206
  end
217
207
  alias :cattr_accessor :mattr_accessor
218
208
  end
@@ -1,12 +1,16 @@
1
- require "active_support/core_ext/array/extract_options"
2
- require "active_support/core_ext/regexp"
1
+ # frozen_string_literal: true
3
2
 
3
+ # == Attribute Accessors per Thread
4
+ #
4
5
  # Extends the module object with class/module and instance accessors for
5
6
  # class/module attributes, just like the native attr* accessors for instance
6
7
  # attributes, but does so on a per-thread basis.
7
8
  #
8
9
  # So the values are scoped within the Thread.current space under the class name
9
10
  # of the module.
11
+ #
12
+ # Note that it can also be scoped per-fiber if +Rails.application.config.active_support.isolation_level+
13
+ # is set to +:fiber+.
10
14
  class Module
11
15
  # Defines a per-thread class attribute and creates class and instance reader methods.
12
16
  # The underlying per-thread class variable is set to +nil+, if it is not previously defined.
@@ -15,9 +19,9 @@ class Module
15
19
  # thread_mattr_reader :user
16
20
  # end
17
21
  #
18
- # Current.user # => nil
19
- # Thread.current[:attr_Current_user] = "DHH"
22
+ # Current.user = "DHH"
20
23
  # Current.user # => "DHH"
24
+ # Thread.new { Current.user }.value # => nil
21
25
  #
22
26
  # The attribute name must be a valid method name in Ruby.
23
27
  #
@@ -26,7 +30,7 @@ class Module
26
30
  # end
27
31
  # # => NameError: invalid attribute name: 1_Badname
28
32
  #
29
- # If you want to opt out of the creation of the instance reader method, pass
33
+ # To omit the instance reader method, pass
30
34
  # <tt>instance_reader: false</tt> or <tt>instance_accessor: false</tt>.
31
35
  #
32
36
  # class Current
@@ -34,9 +38,7 @@ class Module
34
38
  # end
35
39
  #
36
40
  # Current.new.user # => NoMethodError
37
- def thread_mattr_reader(*syms) # :nodoc:
38
- options = syms.extract_options!
39
-
41
+ def thread_mattr_reader(*syms, instance_reader: true, instance_accessor: true, default: nil) # :nodoc:
40
42
  syms.each do |sym|
41
43
  raise NameError.new("invalid attribute name: #{sym}") unless /^[_A-Za-z]\w*$/.match?(sym)
42
44
 
@@ -44,17 +46,20 @@ class Module
44
46
  # to work with inheritance via polymorphism.
45
47
  class_eval(<<-EOS, __FILE__, __LINE__ + 1)
46
48
  def self.#{sym}
47
- Thread.current["attr_" + name + "_#{sym}"]
49
+ @__thread_mattr_#{sym} ||= "attr_\#{name}_#{sym}"
50
+ ::ActiveSupport::IsolatedExecutionState[@__thread_mattr_#{sym}]
48
51
  end
49
52
  EOS
50
53
 
51
- unless options[:instance_reader] == false || options[:instance_accessor] == false
54
+ if instance_reader && instance_accessor
52
55
  class_eval(<<-EOS, __FILE__, __LINE__ + 1)
53
56
  def #{sym}
54
57
  self.class.#{sym}
55
58
  end
56
59
  EOS
57
60
  end
61
+
62
+ ::ActiveSupport::IsolatedExecutionState["attr_#{name}_#{sym}"] = default unless default.nil?
58
63
  end
59
64
  end
60
65
  alias :thread_cattr_reader :thread_mattr_reader
@@ -69,7 +74,7 @@ class Module
69
74
  # Current.user = "DHH"
70
75
  # Thread.current[:attr_Current_user] # => "DHH"
71
76
  #
72
- # If you want to opt out of the creation of the instance writer method, pass
77
+ # To omit the instance writer method, pass
73
78
  # <tt>instance_writer: false</tt> or <tt>instance_accessor: false</tt>.
74
79
  #
75
80
  # class Current
@@ -77,8 +82,7 @@ class Module
77
82
  # end
78
83
  #
79
84
  # Current.new.user = "DHH" # => NoMethodError
80
- def thread_mattr_writer(*syms) # :nodoc:
81
- options = syms.extract_options!
85
+ def thread_mattr_writer(*syms, instance_writer: true, instance_accessor: true, default: nil) # :nodoc:
82
86
  syms.each do |sym|
83
87
  raise NameError.new("invalid attribute name: #{sym}") unless /^[_A-Za-z]\w*$/.match?(sym)
84
88
 
@@ -86,17 +90,20 @@ class Module
86
90
  # to work with inheritance via polymorphism.
87
91
  class_eval(<<-EOS, __FILE__, __LINE__ + 1)
88
92
  def self.#{sym}=(obj)
89
- Thread.current["attr_" + name + "_#{sym}"] = obj
93
+ @__thread_mattr_#{sym} ||= "attr_\#{name}_#{sym}"
94
+ ::ActiveSupport::IsolatedExecutionState[@__thread_mattr_#{sym}] = obj
90
95
  end
91
96
  EOS
92
97
 
93
- unless options[:instance_writer] == false || options[:instance_accessor] == false
98
+ if instance_writer && instance_accessor
94
99
  class_eval(<<-EOS, __FILE__, __LINE__ + 1)
95
100
  def #{sym}=(obj)
96
101
  self.class.#{sym} = obj
97
102
  end
98
103
  EOS
99
104
  end
105
+
106
+ public_send("#{sym}=", default) unless default.nil?
100
107
  end
101
108
  end
102
109
  alias :thread_cattr_writer :thread_mattr_writer
@@ -111,19 +118,21 @@ class Module
111
118
  # Account.user # => "DHH"
112
119
  # Account.new.user # => "DHH"
113
120
  #
121
+ # Unlike +mattr_accessor+, values are *not* shared with subclasses or parent classes.
114
122
  # If a subclass changes the value, the parent class' value is not changed.
115
- # Similarly, if the parent class changes the value, the value of subclasses
116
- # is not changed.
123
+ # If the parent class changes the value, the value of subclasses is not changed.
117
124
  #
118
125
  # class Customer < Account
119
126
  # end
120
127
  #
121
- # Customer.user = "Rafael"
122
- # Customer.user # => "Rafael"
123
- # Account.user # => "DHH"
128
+ # Account.user # => "DHH"
129
+ # Customer.user # => nil
130
+ # Customer.user = "Rafael"
131
+ # Customer.user # => "Rafael"
132
+ # Account.user # => "DHH"
124
133
  #
125
- # To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
126
- # To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
134
+ # To omit the instance writer method, pass <tt>instance_writer: false</tt>.
135
+ # To omit the instance reader method, pass <tt>instance_reader: false</tt>.
127
136
  #
128
137
  # class Current
129
138
  # thread_mattr_accessor :user, instance_writer: false, instance_reader: false
@@ -132,17 +141,17 @@ class Module
132
141
  # Current.new.user = "DHH" # => NoMethodError
133
142
  # Current.new.user # => NoMethodError
134
143
  #
135
- # Or pass <tt>instance_accessor: false</tt>, to opt out both instance methods.
144
+ # Or pass <tt>instance_accessor: false</tt>, to omit both instance methods.
136
145
  #
137
146
  # class Current
138
- # mattr_accessor :user, instance_accessor: false
147
+ # thread_mattr_accessor :user, instance_accessor: false
139
148
  # end
140
149
  #
141
150
  # Current.new.user = "DHH" # => NoMethodError
142
151
  # Current.new.user # => NoMethodError
143
- def thread_mattr_accessor(*syms)
144
- thread_mattr_reader(*syms)
145
- thread_mattr_writer(*syms)
152
+ def thread_mattr_accessor(*syms, instance_reader: true, instance_writer: true, instance_accessor: true, default: nil)
153
+ thread_mattr_reader(*syms, instance_reader: instance_reader, instance_accessor: instance_accessor, default: default)
154
+ thread_mattr_writer(*syms, instance_writer: instance_writer, instance_accessor: instance_accessor)
146
155
  end
147
156
  alias :thread_cattr_accessor :thread_mattr_accessor
148
157
  end