activesupport 5.1.7 → 5.2.0.beta1

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 (238) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +303 -617
  3. data/README.rdoc +1 -1
  4. data/lib/active_support.rb +3 -12
  5. data/lib/active_support/all.rb +2 -0
  6. data/lib/active_support/array_inquirer.rb +2 -0
  7. data/lib/active_support/backtrace_cleaner.rb +2 -0
  8. data/lib/active_support/benchmarkable.rb +2 -0
  9. data/lib/active_support/builder.rb +2 -0
  10. data/lib/active_support/cache.rb +127 -58
  11. data/lib/active_support/cache/file_store.rb +4 -3
  12. data/lib/active_support/cache/mem_cache_store.rb +12 -4
  13. data/lib/active_support/cache/memory_store.rb +2 -0
  14. data/lib/active_support/cache/null_store.rb +2 -0
  15. data/lib/active_support/cache/redis_cache_store.rb +404 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +9 -2
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +2 -0
  18. data/lib/active_support/callbacks.rb +26 -37
  19. data/lib/active_support/concern.rb +3 -1
  20. data/lib/active_support/concurrency/share_lock.rb +2 -0
  21. data/lib/active_support/configurable.rb +2 -0
  22. data/lib/active_support/core_ext.rb +3 -1
  23. data/lib/active_support/core_ext/array.rb +2 -0
  24. data/lib/active_support/core_ext/array/access.rb +4 -2
  25. data/lib/active_support/core_ext/array/conversions.rb +2 -0
  26. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  27. data/lib/active_support/core_ext/array/grouping.rb +2 -0
  28. data/lib/active_support/core_ext/array/inquiry.rb +2 -0
  29. data/lib/active_support/core_ext/array/prepend_and_append.rb +4 -2
  30. data/lib/active_support/core_ext/array/wrap.rb +2 -0
  31. data/lib/active_support/core_ext/benchmark.rb +2 -0
  32. data/lib/active_support/core_ext/big_decimal.rb +2 -0
  33. data/lib/active_support/core_ext/big_decimal/conversions.rb +2 -0
  34. data/lib/active_support/core_ext/class.rb +2 -0
  35. data/lib/active_support/core_ext/class/attribute.rb +34 -16
  36. data/lib/active_support/core_ext/class/attribute_accessors.rb +2 -0
  37. data/lib/active_support/core_ext/class/subclasses.rb +1 -2
  38. data/lib/active_support/core_ext/date.rb +2 -0
  39. data/lib/active_support/core_ext/date/acts_like.rb +2 -0
  40. data/lib/active_support/core_ext/date/blank.rb +2 -0
  41. data/lib/active_support/core_ext/date/calculations.rb +2 -0
  42. data/lib/active_support/core_ext/date/conversions.rb +10 -9
  43. data/lib/active_support/core_ext/date/zones.rb +2 -0
  44. data/lib/active_support/core_ext/date_and_time/calculations.rb +42 -16
  45. data/lib/active_support/core_ext/date_and_time/compatibility.rb +3 -1
  46. data/lib/active_support/core_ext/date_and_time/zones.rb +2 -0
  47. data/lib/active_support/core_ext/date_time.rb +2 -0
  48. data/lib/active_support/core_ext/date_time/acts_like.rb +2 -0
  49. data/lib/active_support/core_ext/date_time/blank.rb +2 -0
  50. data/lib/active_support/core_ext/date_time/calculations.rb +2 -0
  51. data/lib/active_support/core_ext/date_time/compatibility.rb +6 -4
  52. data/lib/active_support/core_ext/date_time/conversions.rb +2 -0
  53. data/lib/active_support/core_ext/digest/uuid.rb +3 -1
  54. data/lib/active_support/core_ext/enumerable.rb +3 -1
  55. data/lib/active_support/core_ext/file.rb +2 -0
  56. data/lib/active_support/core_ext/file/atomic.rb +2 -0
  57. data/lib/active_support/core_ext/hash.rb +2 -0
  58. data/lib/active_support/core_ext/hash/compact.rb +2 -0
  59. data/lib/active_support/core_ext/hash/conversions.rb +2 -0
  60. data/lib/active_support/core_ext/hash/deep_merge.rb +8 -12
  61. data/lib/active_support/core_ext/hash/except.rb +2 -0
  62. data/lib/active_support/core_ext/hash/indifferent_access.rb +2 -0
  63. data/lib/active_support/core_ext/hash/keys.rb +2 -0
  64. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  65. data/lib/active_support/core_ext/hash/slice.rb +4 -4
  66. data/lib/active_support/core_ext/hash/transform_values.rb +2 -0
  67. data/lib/active_support/core_ext/integer.rb +2 -0
  68. data/lib/active_support/core_ext/integer/inflections.rb +2 -0
  69. data/lib/active_support/core_ext/integer/multiple.rb +2 -0
  70. data/lib/active_support/core_ext/integer/time.rb +7 -14
  71. data/lib/active_support/core_ext/kernel.rb +2 -0
  72. data/lib/active_support/core_ext/kernel/agnostics.rb +2 -0
  73. data/lib/active_support/core_ext/kernel/concern.rb +2 -0
  74. data/lib/active_support/core_ext/kernel/reporting.rb +2 -0
  75. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  76. data/lib/active_support/core_ext/load_error.rb +2 -7
  77. data/lib/active_support/core_ext/marshal.rb +2 -0
  78. data/lib/active_support/core_ext/module.rb +3 -0
  79. data/lib/active_support/core_ext/module/aliasing.rb +2 -0
  80. data/lib/active_support/core_ext/module/anonymous.rb +2 -0
  81. data/lib/active_support/core_ext/module/attr_internal.rb +2 -0
  82. data/lib/active_support/core_ext/module/attribute_accessors.rb +21 -24
  83. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +2 -0
  84. data/lib/active_support/core_ext/module/concerning.rb +2 -0
  85. data/lib/active_support/core_ext/module/delegation.rb +29 -24
  86. data/lib/active_support/core_ext/module/deprecation.rb +2 -0
  87. data/lib/active_support/core_ext/module/introspection.rb +2 -0
  88. data/lib/active_support/core_ext/module/reachable.rb +3 -0
  89. data/lib/active_support/core_ext/module/redefine_method.rb +49 -0
  90. data/lib/active_support/core_ext/module/remove_method.rb +5 -23
  91. data/lib/active_support/core_ext/name_error.rb +2 -0
  92. data/lib/active_support/core_ext/numeric.rb +2 -0
  93. data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
  94. data/lib/active_support/core_ext/numeric/conversions.rb +9 -7
  95. data/lib/active_support/core_ext/numeric/inquiry.rb +2 -0
  96. data/lib/active_support/core_ext/numeric/time.rb +7 -15
  97. data/lib/active_support/core_ext/object.rb +2 -0
  98. data/lib/active_support/core_ext/object/acts_like.rb +12 -1
  99. data/lib/active_support/core_ext/object/blank.rb +2 -0
  100. data/lib/active_support/core_ext/object/conversions.rb +2 -0
  101. data/lib/active_support/core_ext/object/deep_dup.rb +2 -0
  102. data/lib/active_support/core_ext/object/duplicable.rb +10 -8
  103. data/lib/active_support/core_ext/object/inclusion.rb +2 -0
  104. data/lib/active_support/core_ext/object/instance_variables.rb +2 -0
  105. data/lib/active_support/core_ext/object/json.rb +8 -0
  106. data/lib/active_support/core_ext/object/to_param.rb +2 -0
  107. data/lib/active_support/core_ext/object/to_query.rb +4 -5
  108. data/lib/active_support/core_ext/object/try.rb +2 -0
  109. data/lib/active_support/core_ext/object/with_options.rb +3 -1
  110. data/lib/active_support/core_ext/range.rb +3 -0
  111. data/lib/active_support/core_ext/range/conversions.rb +9 -1
  112. data/lib/active_support/core_ext/range/each.rb +5 -1
  113. data/lib/active_support/core_ext/range/include_range.rb +2 -0
  114. data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
  115. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  116. data/lib/active_support/core_ext/regexp.rb +2 -0
  117. data/lib/active_support/core_ext/securerandom.rb +2 -0
  118. data/lib/active_support/core_ext/string.rb +2 -0
  119. data/lib/active_support/core_ext/string/access.rb +2 -0
  120. data/lib/active_support/core_ext/string/behavior.rb +2 -0
  121. data/lib/active_support/core_ext/string/conversions.rb +2 -0
  122. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  123. data/lib/active_support/core_ext/string/filters.rb +2 -0
  124. data/lib/active_support/core_ext/string/indent.rb +2 -0
  125. data/lib/active_support/core_ext/string/inflections.rb +26 -12
  126. data/lib/active_support/core_ext/string/inquiry.rb +2 -0
  127. data/lib/active_support/core_ext/string/multibyte.rb +2 -0
  128. data/lib/active_support/core_ext/string/output_safety.rb +6 -7
  129. data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
  130. data/lib/active_support/core_ext/string/strip.rb +2 -0
  131. data/lib/active_support/core_ext/string/zones.rb +2 -0
  132. data/lib/active_support/core_ext/time.rb +2 -0
  133. data/lib/active_support/core_ext/time/acts_like.rb +2 -0
  134. data/lib/active_support/core_ext/time/calculations.rb +23 -15
  135. data/lib/active_support/core_ext/time/compatibility.rb +4 -2
  136. data/lib/active_support/core_ext/time/conversions.rb +2 -0
  137. data/lib/active_support/core_ext/time/zones.rb +6 -4
  138. data/lib/active_support/core_ext/uri.rb +4 -1
  139. data/lib/active_support/current_attributes.rb +195 -0
  140. data/lib/active_support/dependencies.rb +15 -25
  141. data/lib/active_support/dependencies/autoload.rb +2 -0
  142. data/lib/active_support/dependencies/interlock.rb +2 -0
  143. data/lib/active_support/deprecation.rb +4 -2
  144. data/lib/active_support/deprecation/behaviors.rb +23 -8
  145. data/lib/active_support/deprecation/constant_accessor.rb +3 -1
  146. data/lib/active_support/deprecation/instance_delegator.rb +2 -0
  147. data/lib/active_support/deprecation/method_wrappers.rb +2 -7
  148. data/lib/active_support/deprecation/proxy_wrappers.rb +4 -1
  149. data/lib/active_support/deprecation/reporting.rb +4 -2
  150. data/lib/active_support/descendants_tracker.rb +2 -0
  151. data/lib/active_support/duration.rb +8 -14
  152. data/lib/active_support/duration/iso8601_parser.rb +4 -2
  153. data/lib/active_support/duration/iso8601_serializer.rb +4 -2
  154. data/lib/active_support/encrypted_configuration.rb +48 -0
  155. data/lib/active_support/encrypted_file.rb +99 -0
  156. data/lib/active_support/evented_file_update_checker.rb +2 -0
  157. data/lib/active_support/execution_wrapper.rb +2 -0
  158. data/lib/active_support/executor.rb +2 -0
  159. data/lib/active_support/file_update_checker.rb +2 -0
  160. data/lib/active_support/gem_version.rb +5 -3
  161. data/lib/active_support/gzip.rb +2 -0
  162. data/lib/active_support/hash_with_indifferent_access.rb +33 -1
  163. data/lib/active_support/i18n.rb +3 -1
  164. data/lib/active_support/i18n_railtie.rb +5 -11
  165. data/lib/active_support/inflections.rb +2 -0
  166. data/lib/active_support/inflector.rb +2 -0
  167. data/lib/active_support/inflector/inflections.rb +19 -3
  168. data/lib/active_support/inflector/methods.rb +40 -23
  169. data/lib/active_support/inflector/transliterate.rb +17 -8
  170. data/lib/active_support/json.rb +2 -0
  171. data/lib/active_support/json/decoding.rb +2 -0
  172. data/lib/active_support/json/encoding.rb +2 -0
  173. data/lib/active_support/key_generator.rb +3 -1
  174. data/lib/active_support/lazy_load_hooks.rb +2 -0
  175. data/lib/active_support/log_subscriber.rb +3 -2
  176. data/lib/active_support/log_subscriber/test_helper.rb +2 -0
  177. data/lib/active_support/logger.rb +2 -0
  178. data/lib/active_support/logger_silence.rb +3 -2
  179. data/lib/active_support/logger_thread_safe_level.rb +2 -0
  180. data/lib/active_support/message_encryptor.rb +94 -22
  181. data/lib/active_support/message_verifier.rb +78 -7
  182. data/lib/active_support/messages/metadata.rb +71 -0
  183. data/lib/active_support/messages/rotation_configuration.rb +22 -0
  184. data/lib/active_support/messages/rotator.rb +56 -0
  185. data/lib/active_support/multibyte.rb +2 -0
  186. data/lib/active_support/multibyte/chars.rb +2 -0
  187. data/lib/active_support/multibyte/unicode.rb +3 -1
  188. data/lib/active_support/notifications.rb +2 -0
  189. data/lib/active_support/notifications/fanout.rb +2 -0
  190. data/lib/active_support/notifications/instrumenter.rb +2 -0
  191. data/lib/active_support/number_helper.rb +2 -0
  192. data/lib/active_support/number_helper/number_converter.rb +2 -0
  193. data/lib/active_support/number_helper/number_to_currency_converter.rb +2 -0
  194. data/lib/active_support/number_helper/number_to_delimited_converter.rb +2 -0
  195. data/lib/active_support/number_helper/number_to_human_converter.rb +2 -0
  196. data/lib/active_support/number_helper/number_to_human_size_converter.rb +2 -0
  197. data/lib/active_support/number_helper/number_to_percentage_converter.rb +2 -0
  198. data/lib/active_support/number_helper/number_to_phone_converter.rb +3 -1
  199. data/lib/active_support/number_helper/number_to_rounded_converter.rb +2 -20
  200. data/lib/active_support/number_helper/rounding_helper.rb +5 -3
  201. data/lib/active_support/option_merger.rb +2 -0
  202. data/lib/active_support/ordered_hash.rb +2 -0
  203. data/lib/active_support/ordered_options.rb +4 -2
  204. data/lib/active_support/per_thread_registry.rb +2 -0
  205. data/lib/active_support/proxy_object.rb +2 -0
  206. data/lib/active_support/rails.rb +2 -0
  207. data/lib/active_support/railtie.rb +27 -8
  208. data/lib/active_support/reloader.rb +7 -5
  209. data/lib/active_support/rescuable.rb +3 -2
  210. data/lib/active_support/security_utils.rb +15 -11
  211. data/lib/active_support/string_inquirer.rb +2 -0
  212. data/lib/active_support/subscriber.rb +2 -0
  213. data/lib/active_support/tagged_logging.rb +2 -0
  214. data/lib/active_support/test_case.rb +2 -1
  215. data/lib/active_support/testing/assertions.rb +6 -4
  216. data/lib/active_support/testing/autorun.rb +2 -0
  217. data/lib/active_support/testing/constant_lookup.rb +2 -0
  218. data/lib/active_support/testing/declarative.rb +2 -0
  219. data/lib/active_support/testing/deprecation.rb +2 -0
  220. data/lib/active_support/testing/file_fixtures.rb +2 -0
  221. data/lib/active_support/testing/isolation.rb +5 -5
  222. data/lib/active_support/testing/method_call_assertions.rb +2 -0
  223. data/lib/active_support/testing/setup_and_teardown.rb +2 -0
  224. data/lib/active_support/testing/stream.rb +2 -0
  225. data/lib/active_support/testing/tagged_logging.rb +2 -0
  226. data/lib/active_support/testing/time_helpers.rb +31 -2
  227. data/lib/active_support/time.rb +2 -0
  228. data/lib/active_support/time_with_zone.rb +38 -0
  229. data/lib/active_support/values/time_zone.rb +20 -12
  230. data/lib/active_support/version.rb +2 -0
  231. data/lib/active_support/xml_mini.rb +2 -0
  232. data/lib/active_support/xml_mini/jdom.rb +4 -2
  233. data/lib/active_support/xml_mini/libxml.rb +3 -1
  234. data/lib/active_support/xml_mini/libxmlsax.rb +4 -2
  235. data/lib/active_support/xml_mini/nokogiri.rb +3 -1
  236. data/lib/active_support/xml_mini/nokogirisax.rb +3 -1
  237. data/lib/active_support/xml_mini/rexml.rb +3 -1
  238. metadata +19 -15
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/string_inquirer"
2
4
 
3
5
  class String
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/multibyte"
2
4
 
3
5
  class String
@@ -1,5 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "erb"
2
4
  require "active_support/core_ext/kernel/singleton_class"
5
+ require "active_support/core_ext/module/redefine_method"
3
6
  require "active_support/multibyte/unicode"
4
7
 
5
8
  class ERB
@@ -12,22 +15,18 @@ class ERB
12
15
  # A utility method for escaping HTML tag characters.
13
16
  # This method is also aliased as <tt>h</tt>.
14
17
  #
15
- # In your ERB templates, use this method to escape any unsafe content. For example:
16
- # <%= h @person.name %>
17
- #
18
18
  # puts html_escape('is a > 0 & a < 10?')
19
19
  # # => is a &gt; 0 &amp; a &lt; 10?
20
20
  def html_escape(s)
21
21
  unwrapped_html_escape(s).html_safe
22
22
  end
23
23
 
24
- # Aliasing twice issues a warning "discarding old...". Remove first to avoid it.
25
- remove_method(:h)
24
+ silence_redefinition_of_method :h
26
25
  alias h html_escape
27
26
 
28
27
  module_function :h
29
28
 
30
- singleton_class.send(:remove_method, :html_escape)
29
+ singleton_class.silence_redefinition_of_method :html_escape
31
30
  module_function :html_escape
32
31
 
33
32
  # HTML escapes strings but doesn't wrap them with an ActiveSupport::SafeBuffer.
@@ -251,7 +250,7 @@ class String
251
250
  # Marks a string as trusted safe. It will be inserted into HTML with no
252
251
  # additional escaping performed. It is your responsibility to ensure that the
253
252
  # string contains no malicious content. This method is equivalent to the
254
- # `raw` helper in views. It is recommended that you use `sanitize` instead of
253
+ # +raw+ helper in views. It is recommended that you use +sanitize+ instead of
255
254
  # this method. It should never be called on user input.
256
255
  def html_safe
257
256
  ActiveSupport::SafeBuffer.new(self)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class String
2
4
  alias_method :starts_with?, :start_with?
3
5
  alias_method :ends_with?, :end_with?
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class String
2
4
  # Strips indentation in heredocs.
3
5
  #
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/string/conversions"
2
4
  require "active_support/core_ext/time/zones"
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/time/acts_like"
2
4
  require "active_support/core_ext/time/calculations"
3
5
  require "active_support/core_ext/time/compatibility"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/object/acts_like"
2
4
 
3
5
  class Time
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/duration"
2
4
  require "active_support/core_ext/time/conversions"
3
5
  require "active_support/time_with_zone"
@@ -107,21 +109,22 @@ class Time
107
109
  # to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
108
110
  # <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly, so if only
109
111
  # the hour is passed, then minute, sec, usec and nsec is set to 0. If the hour
110
- # and minute is passed, then sec, usec and nsec is set to 0. The +options+
111
- # parameter takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>,
112
- # <tt>:day</tt>, <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>
113
- # <tt>:nsec</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
112
+ # and minute is passed, then sec, usec and nsec is set to 0. The +options+ parameter
113
+ # takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>,
114
+ # <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>,
115
+ # <tt>:offset</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
114
116
  #
115
117
  # Time.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => Time.new(2012, 8, 1, 22, 35, 0)
116
118
  # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => Time.new(1981, 8, 1, 22, 35, 0)
117
119
  # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => Time.new(1981, 8, 29, 0, 0, 0)
118
120
  def change(options)
119
- new_year = options.fetch(:year, year)
120
- new_month = options.fetch(:month, month)
121
- new_day = options.fetch(:day, day)
122
- new_hour = options.fetch(:hour, hour)
123
- new_min = options.fetch(:min, options[:hour] ? 0 : min)
124
- new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
121
+ new_year = options.fetch(:year, year)
122
+ new_month = options.fetch(:month, month)
123
+ new_day = options.fetch(:day, day)
124
+ new_hour = options.fetch(:hour, hour)
125
+ new_min = options.fetch(:min, options[:hour] ? 0 : min)
126
+ new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
127
+ new_offset = options.fetch(:offset, nil)
125
128
 
126
129
  if new_nsec = options[:nsec]
127
130
  raise ArgumentError, "Can't change both :nsec and :usec at the same time: #{options.inspect}" if options[:usec]
@@ -130,13 +133,18 @@ class Time
130
133
  new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
131
134
  end
132
135
 
133
- if utc?
134
- ::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec)
136
+ raise ArgumentError, "argument out of range" if new_usec >= 1000000
137
+
138
+ new_sec += Rational(new_usec, 1000000)
139
+
140
+ if new_offset
141
+ ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, new_offset)
142
+ elsif utc?
143
+ ::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec)
135
144
  elsif zone
136
- ::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec)
145
+ ::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec)
137
146
  else
138
- raise ArgumentError, "argument out of range" if new_usec >= 1000000
139
- ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec + (new_usec.to_r / 1000000), utc_offset)
147
+ ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, utc_offset)
140
148
  end
141
149
  end
142
150
 
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/date_and_time/compatibility"
2
- require "active_support/core_ext/module/remove_method"
4
+ require "active_support/core_ext/module/redefine_method"
3
5
 
4
6
  class Time
5
7
  include DateAndTime::Compatibility
6
8
 
7
- remove_possible_method :to_time
9
+ silence_redefinition_of_method :to_time
8
10
 
9
11
  # Either return +self+ or the time in the local system timezone depending
10
12
  # on the setting of +ActiveSupport.to_time_preserves_timezone+.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/inflector/methods"
2
4
  require "active_support/values/time_zone"
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/time_with_zone"
2
4
  require "active_support/core_ext/time/acts_like"
3
5
  require "active_support/core_ext/date_and_time/zones"
@@ -53,10 +55,10 @@ class Time
53
55
  # end
54
56
  # end
55
57
  #
56
- # NOTE: This won't affect any <tt>ActiveSupport::TimeWithZone</tt>
57
- # objects that have already been created, e.g. any model timestamp
58
- # attributes that have been read before the block will remain in
59
- # the application's default timezone.
58
+ # NOTE: This won't affect any <tt>ActiveSupport::TimeWithZone</tt>
59
+ # objects that have already been created, e.g. any model timestamp
60
+ # attributes that have been read before the block will remain in
61
+ # the application's default timezone.
60
62
  def use_zone(time_zone)
61
63
  new_zone = find_zone!(time_zone)
62
64
  begin
@@ -1,10 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "uri"
2
4
  str = "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E" # Ni-ho-nn-go in UTF-8, means Japanese.
3
5
  parser = URI::Parser.new
4
6
 
5
7
  unless str == parser.unescape(parser.escape(str))
8
+ require "active_support/core_ext/module/redefine_method"
6
9
  URI::Parser.class_eval do
7
- remove_method :unescape
10
+ silence_redefinition_of_method :unescape
8
11
  def unescape(str, escaped = /%[a-fA-F\d]{2}/)
9
12
  # TODO: Are we actually sure that ASCII == UTF-8?
10
13
  # YK: My initial experiments say yes, but let's be sure please
@@ -0,0 +1,195 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ # Abstract super class that provides a thread-isolated attributes singleton, which resets automatically
5
+ # before and after each request. This allows you to keep all the per-request attributes easily
6
+ # available to the whole system.
7
+ #
8
+ # The following full app-like example demonstrates how to use a Current class to
9
+ # facilitate easy access to the global, per-request attributes without passing them deeply
10
+ # around everywhere:
11
+ #
12
+ # # app/models/current.rb
13
+ # class Current < ActiveSupport::CurrentAttributes
14
+ # attribute :account, :user
15
+ # attribute :request_id, :user_agent, :ip_address
16
+ #
17
+ # resets { Time.zone = nil }
18
+ #
19
+ # def user=(user)
20
+ # super
21
+ # self.account = user.account
22
+ # Time.zone = user.time_zone
23
+ # end
24
+ # end
25
+ #
26
+ # # app/controllers/concerns/authentication.rb
27
+ # module Authentication
28
+ # extend ActiveSupport::Concern
29
+ #
30
+ # included do
31
+ # before_action :authenticate
32
+ # end
33
+ #
34
+ # private
35
+ # def authenticate
36
+ # if authenticated_user = User.find_by(id: cookies.encrypted[:user_id])
37
+ # Current.user = authenticated_user
38
+ # else
39
+ # redirect_to new_session_url
40
+ # end
41
+ # end
42
+ # end
43
+ #
44
+ # # app/controllers/concerns/set_current_request_details.rb
45
+ # module SetCurrentRequestDetails
46
+ # extend ActiveSupport::Concern
47
+ #
48
+ # included do
49
+ # before_action do
50
+ # Current.request_id = request.uuid
51
+ # Current.user_agent = request.user_agent
52
+ # Current.ip_address = request.ip
53
+ # end
54
+ # end
55
+ # end
56
+ #
57
+ # class ApplicationController < ActionController::Base
58
+ # include Authentication
59
+ # include SetCurrentRequestDetails
60
+ # end
61
+ #
62
+ # class MessagesController < ApplicationController
63
+ # def create
64
+ # Current.account.messages.create(message_params)
65
+ # end
66
+ # end
67
+ #
68
+ # class Message < ApplicationRecord
69
+ # belongs_to :creator, default: -> { Current.user }
70
+ # after_create { |message| Event.create(record: message) }
71
+ # end
72
+ #
73
+ # class Event < ApplicationRecord
74
+ # before_create do
75
+ # self.request_id = Current.request_id
76
+ # self.user_agent = Current.user_agent
77
+ # self.ip_address = Current.ip_address
78
+ # end
79
+ # end
80
+ #
81
+ # A word of caution: It's easy to overdo a global singleton like Current and tangle your model as a result.
82
+ # Current should only be used for a few, top-level globals, like account, user, and request details.
83
+ # The attributes stuck in Current should be used by more or less all actions on all requests. If you start
84
+ # sticking controller-specific attributes in there, you're going to create a mess.
85
+ class CurrentAttributes
86
+ include ActiveSupport::Callbacks
87
+ define_callbacks :reset
88
+
89
+ class << self
90
+ # Returns singleton instance for this class in this thread. If none exists, one is created.
91
+ def instance
92
+ current_instances[name] ||= new
93
+ end
94
+
95
+ # Declares one or more attributes that will be given both class and instance accessor methods.
96
+ def attribute(*names)
97
+ generated_attribute_methods.module_eval do
98
+ names.each do |name|
99
+ define_method(name) do
100
+ attributes[name.to_sym]
101
+ end
102
+
103
+ define_method("#{name}=") do |attribute|
104
+ attributes[name.to_sym] = attribute
105
+ end
106
+ end
107
+ end
108
+
109
+ names.each do |name|
110
+ define_singleton_method(name) do
111
+ instance.public_send(name)
112
+ end
113
+
114
+ define_singleton_method("#{name}=") do |attribute|
115
+ instance.public_send("#{name}=", attribute)
116
+ end
117
+ end
118
+ end
119
+
120
+ # Calls this block after #reset is called on the instance. Used for resetting external collaborators, like Time.zone.
121
+ def resets(&block)
122
+ set_callback :reset, :after, &block
123
+ end
124
+
125
+ delegate :set, :reset, to: :instance
126
+
127
+ def reset_all # :nodoc:
128
+ current_instances.each_value(&:reset)
129
+ end
130
+
131
+ def clear_all # :nodoc:
132
+ reset_all
133
+ current_instances.clear
134
+ end
135
+
136
+ private
137
+ def generated_attribute_methods
138
+ @generated_attribute_methods ||= Module.new.tap { |mod| include mod }
139
+ end
140
+
141
+ def current_instances
142
+ Thread.current[:current_attributes_instances] ||= {}
143
+ end
144
+
145
+ def method_missing(name, *args, &block)
146
+ # Caches the method definition as a singleton method of the receiver.
147
+ #
148
+ # By letting #delegate handle it, we avoid an enclosure that'll capture args.
149
+ singleton_class.delegate name, to: :instance
150
+
151
+ send(name, *args, &block)
152
+ end
153
+ end
154
+
155
+ attr_accessor :attributes
156
+
157
+ def initialize
158
+ @attributes = {}
159
+ end
160
+
161
+ # Expose one or more attributes within a block. Old values are returned after the block concludes.
162
+ # Example demonstrating the common use of needing to set Current attributes outside the request-cycle:
163
+ #
164
+ # class Chat::PublicationJob < ApplicationJob
165
+ # def perform(attributes, room_number, creator)
166
+ # Current.set(person: creator) do
167
+ # Chat::Publisher.publish(attributes: attributes, room_number: room_number)
168
+ # end
169
+ # end
170
+ # end
171
+ def set(set_attributes)
172
+ old_attributes = compute_attributes(set_attributes.keys)
173
+ assign_attributes(set_attributes)
174
+ yield
175
+ ensure
176
+ assign_attributes(old_attributes)
177
+ end
178
+
179
+ # Reset all attributes. Should be called before and after actions, when used as a per-request singleton.
180
+ def reset
181
+ run_callbacks :reset do
182
+ self.attributes = {}
183
+ end
184
+ end
185
+
186
+ private
187
+ def assign_attributes(new_attributes)
188
+ new_attributes.each { |key, value| public_send("#{key}=", value) }
189
+ end
190
+
191
+ def compute_attributes(keys)
192
+ keys.collect { |key| [ key, public_send(key) ] }.to_h
193
+ end
194
+ end
195
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "set"
2
4
  require "thread"
3
5
  require "concurrent/map"
@@ -18,8 +20,7 @@ module ActiveSupport #:nodoc:
18
20
  module Dependencies #:nodoc:
19
21
  extend self
20
22
 
21
- mattr_accessor :interlock
22
- self.interlock = Interlock.new
23
+ mattr_accessor :interlock, default: Interlock.new
23
24
 
24
25
  # :doc:
25
26
 
@@ -46,46 +47,37 @@ module ActiveSupport #:nodoc:
46
47
  # :nodoc:
47
48
 
48
49
  # Should we turn on Ruby warnings on the first load of dependent files?
49
- mattr_accessor :warnings_on_first_load
50
- self.warnings_on_first_load = false
50
+ mattr_accessor :warnings_on_first_load, default: false
51
51
 
52
52
  # All files ever loaded.
53
- mattr_accessor :history
54
- self.history = Set.new
53
+ mattr_accessor :history, default: Set.new
55
54
 
56
55
  # All files currently loaded.
57
- mattr_accessor :loaded
58
- self.loaded = Set.new
56
+ mattr_accessor :loaded, default: Set.new
59
57
 
60
58
  # Stack of files being loaded.
61
- mattr_accessor :loading
62
- self.loading = []
59
+ mattr_accessor :loading, default: []
63
60
 
64
61
  # Should we load files or require them?
65
- mattr_accessor :mechanism
66
- self.mechanism = ENV["NO_RELOAD"] ? :require : :load
62
+ mattr_accessor :mechanism, default: ENV["NO_RELOAD"] ? :require : :load
67
63
 
68
64
  # The set of directories from which we may automatically load files. Files
69
65
  # under these directories will be reloaded on each request in development mode,
70
66
  # unless the directory also appears in autoload_once_paths.
71
- mattr_accessor :autoload_paths
72
- self.autoload_paths = []
67
+ mattr_accessor :autoload_paths, default: []
73
68
 
74
69
  # The set of directories from which automatically loaded constants are loaded
75
70
  # only once. All directories in this set must also be present in +autoload_paths+.
76
- mattr_accessor :autoload_once_paths
77
- self.autoload_once_paths = []
71
+ mattr_accessor :autoload_once_paths, default: []
78
72
 
79
73
  # An array of qualified constant names that have been loaded. Adding a name
80
74
  # to this array will cause it to be unloaded the next time Dependencies are
81
75
  # cleared.
82
- mattr_accessor :autoloaded_constants
83
- self.autoloaded_constants = []
76
+ mattr_accessor :autoloaded_constants, default: []
84
77
 
85
78
  # An array of constant names that need to be unloaded on every request. Used
86
79
  # to allow arbitrary constants to be marked for unloading.
87
- mattr_accessor :explicitly_unloadable_constants
88
- self.explicitly_unloadable_constants = []
80
+ mattr_accessor :explicitly_unloadable_constants, default: []
89
81
 
90
82
  # The WatchStack keeps a stack of the modules being watched as files are
91
83
  # loaded. If a file in the process of being loaded (parent.rb) triggers the
@@ -93,7 +85,7 @@ module ActiveSupport #:nodoc:
93
85
  # handles the new constants.
94
86
  #
95
87
  # If child.rb is being autoloaded, its constants will be added to
96
- # autoloaded_constants. If it was being `require`d, they will be discarded.
88
+ # autoloaded_constants. If it was being required, they will be discarded.
97
89
  #
98
90
  # This is handled by walking back up the watch stack and adding the constants
99
91
  # found by child.rb to the list of original constants in parent.rb.
@@ -175,8 +167,7 @@ module ActiveSupport #:nodoc:
175
167
  end
176
168
 
177
169
  # An internal stack used to record which constants are loaded by any block.
178
- mattr_accessor :constant_watch_stack
179
- self.constant_watch_stack = WatchStack.new
170
+ mattr_accessor :constant_watch_stack, default: WatchStack.new
180
171
 
181
172
  # Module includes this module.
182
173
  module ModuleConstMissing #:nodoc:
@@ -456,7 +447,6 @@ module ActiveSupport #:nodoc:
456
447
  mod = Module.new
457
448
  into.const_set const_name, mod
458
449
  autoloaded_constants << qualified_name unless autoload_once_paths.include?(base_path)
459
- autoloaded_constants.uniq!
460
450
  mod
461
451
  end
462
452
 
@@ -625,7 +615,7 @@ module ActiveSupport #:nodoc:
625
615
  return false if desc.is_a?(Module) && desc.anonymous?
626
616
  name = to_constant_name desc
627
617
  return false unless qualified_const_defined?(name)
628
- return autoloaded_constants.include?(name)
618
+ autoloaded_constants.include?(name)
629
619
  end
630
620
 
631
621
  # Will the provided constant descriptor be unloaded?