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,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,4 +1,4 @@
1
- require 'active_support/core_ext/object/try'
1
+ # frozen_string_literal: true
2
2
 
3
3
  class String
4
4
  # Strips indentation in heredocs.
@@ -17,10 +17,9 @@ class String
17
17
  #
18
18
  # the user would see the usage message aligned against the left margin.
19
19
  #
20
- # Technically, it looks for the least indented line in the whole string, and removes
21
- # that amount of leading whitespace.
20
+ # Technically, it looks for the least indented non-empty line
21
+ # in the whole string, and removes that amount of leading whitespace.
22
22
  def strip_heredoc
23
- indent = scan(/^[ \t]*(?=\S)/).min.try(:size) || 0
24
- gsub(/^[ \t]{#{indent}}/, '')
23
+ gsub(/^#{scan(/^[ \t]*(?=\S)/).min}/, "".freeze)
25
24
  end
26
25
  end
@@ -1,4 +1,7 @@
1
- require 'active_support/core_ext/time/zones'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/string/conversions"
4
+ require "active_support/core_ext/time/zones"
2
5
 
3
6
  class String
4
7
  # Converts String to a TimeWithZone in the current zone if Time.zone or Time.zone_default
@@ -1,13 +1,15 @@
1
- require 'active_support/core_ext/string/conversions'
2
- require 'active_support/core_ext/string/filters'
3
- require 'active_support/core_ext/string/multibyte'
4
- require 'active_support/core_ext/string/starts_ends_with'
5
- require 'active_support/core_ext/string/inflections'
6
- require 'active_support/core_ext/string/access'
7
- require 'active_support/core_ext/string/behavior'
8
- require 'active_support/core_ext/string/output_safety'
9
- require 'active_support/core_ext/string/exclude'
10
- require 'active_support/core_ext/string/strip'
11
- require 'active_support/core_ext/string/inquiry'
12
- require 'active_support/core_ext/string/indent'
13
- require 'active_support/core_ext/string/zones'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/string/conversions"
4
+ require "active_support/core_ext/string/filters"
5
+ require "active_support/core_ext/string/multibyte"
6
+ require "active_support/core_ext/string/starts_ends_with"
7
+ require "active_support/core_ext/string/inflections"
8
+ require "active_support/core_ext/string/access"
9
+ require "active_support/core_ext/string/behavior"
10
+ require "active_support/core_ext/string/output_safety"
11
+ require "active_support/core_ext/string/exclude"
12
+ require "active_support/core_ext/string/strip"
13
+ require "active_support/core_ext/string/inquiry"
14
+ require "active_support/core_ext/string/indent"
15
+ require "active_support/core_ext/string/zones"
@@ -1,4 +1,6 @@
1
- require 'active_support/core_ext/object/acts_like'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/object/acts_like"
2
4
 
3
5
  class Time
4
6
  # Duck-types as a Time-like class. See Object#acts_like?.
@@ -1,9 +1,11 @@
1
- require 'active_support/duration'
2
- require 'active_support/core_ext/time/conversions'
3
- require 'active_support/time_with_zone'
4
- require 'active_support/core_ext/time/zones'
5
- require 'active_support/core_ext/date_and_time/calculations'
6
- require 'active_support/deprecation'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/duration"
4
+ require "active_support/core_ext/time/conversions"
5
+ require "active_support/time_with_zone"
6
+ require "active_support/core_ext/time/zones"
7
+ require "active_support/core_ext/date_and_time/calculations"
8
+ require "active_support/core_ext/date/calculations"
7
9
 
8
10
  class Time
9
11
  include DateAndTime::Calculations
@@ -16,9 +18,9 @@ class Time
16
18
  super || (self == Time && other.is_a?(ActiveSupport::TimeWithZone))
17
19
  end
18
20
 
19
- # Return the number of days in the given month.
21
+ # Returns the number of days in the given month.
20
22
  # If no year is specified, it will use the current year.
21
- def days_in_month(month, year = now.year)
23
+ def days_in_month(month, year = current.year)
22
24
  if month == 2 && ::Date.gregorian_leap?(year)
23
25
  29
24
26
  else
@@ -26,39 +28,10 @@ class Time
26
28
  end
27
29
  end
28
30
 
29
- # *DEPRECATED*: Use +Time#utc+ or +Time#local+ instead.
30
- #
31
- # Returns a new Time if requested year can be accommodated by Ruby's Time class
32
- # (i.e., if year is within either 1970..2038 or 1902..2038, depending on system architecture);
33
- # otherwise returns a DateTime.
34
- def time_with_datetime_fallback(utc_or_local, year, month=1, day=1, hour=0, min=0, sec=0, usec=0)
35
- ActiveSupport::Deprecation.warn 'time_with_datetime_fallback is deprecated. Use Time#utc or Time#local instead', caller
36
- time = ::Time.send(utc_or_local, year, month, day, hour, min, sec, usec)
37
-
38
- # This check is needed because Time.utc(y) returns a time object in the 2000s for 0 <= y <= 138.
39
- if time.year == year
40
- time
41
- else
42
- ::DateTime.civil_from_format(utc_or_local, year, month, day, hour, min, sec)
43
- end
44
- rescue
45
- ::DateTime.civil_from_format(utc_or_local, year, month, day, hour, min, sec)
46
- end
47
-
48
- # *DEPRECATED*: Use +Time#utc+ instead.
49
- #
50
- # Wraps class method +time_with_datetime_fallback+ with +utc_or_local+ set to <tt>:utc</tt>.
51
- def utc_time(*args)
52
- ActiveSupport::Deprecation.warn 'utc_time is deprecated. Use Time#utc instead', caller
53
- time_with_datetime_fallback(:utc, *args)
54
- end
55
-
56
- # *DEPRECATED*: Use +Time#local+ instead.
57
- #
58
- # Wraps class method +time_with_datetime_fallback+ with +utc_or_local+ set to <tt>:local</tt>.
59
- def local_time(*args)
60
- ActiveSupport::Deprecation.warn 'local_time is deprecated. Use Time#local instead', caller
61
- time_with_datetime_fallback(:local, *args)
31
+ # Returns the number of days in the given year.
32
+ # If no year is specified, it will use the current year.
33
+ def days_in_year(year = current.year)
34
+ days_in_month(2, year) + 337
62
35
  end
63
36
 
64
37
  # Returns <tt>Time.zone.now</tt> when <tt>Time.zone</tt> or <tt>config.time_zone</tt> are set, otherwise just returns <tt>Time.now</tt>.
@@ -82,11 +55,38 @@ class Time
82
55
  end
83
56
  alias_method :at_without_coercion, :at
84
57
  alias_method :at, :at_with_coercion
58
+
59
+ # Creates a +Time+ instance from an RFC 3339 string.
60
+ #
61
+ # Time.rfc3339('1999-12-31T14:00:00-10:00') # => 2000-01-01 00:00:00 -1000
62
+ #
63
+ # If the time or offset components are missing then an +ArgumentError+ will be raised.
64
+ #
65
+ # Time.rfc3339('1999-12-31') # => ArgumentError: invalid date
66
+ def rfc3339(str)
67
+ parts = Date._rfc3339(str)
68
+
69
+ raise ArgumentError, "invalid date" if parts.empty?
70
+
71
+ Time.new(
72
+ parts.fetch(:year),
73
+ parts.fetch(:mon),
74
+ parts.fetch(:mday),
75
+ parts.fetch(:hour),
76
+ parts.fetch(:min),
77
+ parts.fetch(:sec) + parts.fetch(:sec_fraction, 0),
78
+ parts.fetch(:offset)
79
+ )
80
+ end
85
81
  end
86
82
 
87
- # Seconds since midnight: Time.now.seconds_since_midnight
83
+ # Returns the number of seconds since 00:00:00.
84
+ #
85
+ # Time.new(2012, 8, 29, 0, 0, 0).seconds_since_midnight # => 0.0
86
+ # Time.new(2012, 8, 29, 12, 34, 56).seconds_since_midnight # => 45296.0
87
+ # Time.new(2012, 8, 29, 23, 59, 59).seconds_since_midnight # => 86399.0
88
88
  def seconds_since_midnight
89
- to_i - change(:hour => 0).to_i + (usec / 1.0e+6)
89
+ to_i - change(hour: 0).to_i + (usec / 1.0e+6)
90
90
  end
91
91
 
92
92
  # Returns the number of seconds until 23:59:59.
@@ -98,39 +98,67 @@ class Time
98
98
  end_of_day.to_i - to_i
99
99
  end
100
100
 
101
+ # Returns the fraction of a second as a +Rational+
102
+ #
103
+ # Time.new(2012, 8, 29, 0, 0, 0.5).sec_fraction # => (1/2)
104
+ def sec_fraction
105
+ subsec
106
+ end
107
+
101
108
  # Returns a new Time where one or more of the elements have been changed according
102
109
  # to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
103
- # <tt>:sec</tt>, <tt>:usec</tt>) reset cascadingly, so if only the hour is passed,
104
- # then minute, sec, and usec is set to 0. If the hour and minute is passed, then
105
- # sec and usec is set to 0. The +options+ parameter takes a hash with any of these
106
- # keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>, <tt>:hour</tt>, <tt>:min</tt>,
107
- # <tt>:sec</tt>, <tt>:usec</tt>.
110
+ # <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly, so if only
111
+ # the hour is passed, then minute, sec, usec and nsec is set to 0. If the hour
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.
108
116
  #
109
117
  # Time.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => Time.new(2012, 8, 1, 22, 35, 0)
110
118
  # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => Time.new(1981, 8, 1, 22, 35, 0)
111
119
  # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => Time.new(1981, 8, 29, 0, 0, 0)
112
120
  def change(options)
113
- new_year = options.fetch(:year, year)
114
- new_month = options.fetch(:month, month)
115
- new_day = options.fetch(:day, day)
116
- new_hour = options.fetch(:hour, hour)
117
- new_min = options.fetch(:min, options[:hour] ? 0 : min)
118
- new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
119
- new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
120
-
121
- if utc?
122
- ::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec)
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)
128
+
129
+ if new_nsec = options[:nsec]
130
+ raise ArgumentError, "Can't change both :nsec and :usec at the same time: #{options.inspect}" if options[:usec]
131
+ new_usec = Rational(new_nsec, 1000)
132
+ else
133
+ new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
134
+ end
135
+
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)
123
144
  elsif zone
124
- ::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)
125
146
  else
126
- ::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)
127
148
  end
128
149
  end
129
150
 
130
- # Uses Date to provide precise Time calculations for years, months, and days.
131
- # The +options+ parameter takes a hash with any of these keys: <tt>:years</tt>,
132
- # <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>,
133
- # <tt>:minutes</tt>, <tt>:seconds</tt>.
151
+ # Uses Date to provide precise Time calculations for years, months, and days
152
+ # according to the proleptic Gregorian calendar. The +options+ parameter
153
+ # takes a hash with any of these keys: <tt>:years</tt>, <tt>:months</tt>,
154
+ # <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>, <tt>:minutes</tt>,
155
+ # <tt>:seconds</tt>.
156
+ #
157
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(seconds: 1) # => 2015-08-01 14:35:01 -0700
158
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(minutes: 1) # => 2015-08-01 14:36:00 -0700
159
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(hours: 1) # => 2015-08-01 15:35:00 -0700
160
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(days: 1) # => 2015-08-02 14:35:00 -0700
161
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(weeks: 1) # => 2015-08-08 14:35:00 -0700
134
162
  def advance(options)
135
163
  unless options[:weeks].nil?
136
164
  options[:weeks], partial_weeks = options[:weeks].divmod(1)
@@ -143,7 +171,8 @@ class Time
143
171
  end
144
172
 
145
173
  d = to_date.advance(options)
146
- time_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
174
+ d = d.gregorian if d.julian?
175
+ time_advanced_by_date = change(year: d.year, month: d.month, day: d.day)
147
176
  seconds_to_advance = \
148
177
  options.fetch(:seconds, 0) +
149
178
  options.fetch(:minutes, 0) * 60 +
@@ -171,81 +200,64 @@ class Time
171
200
 
172
201
  # Returns a new Time representing the start of the day (0:00)
173
202
  def beginning_of_day
174
- #(self - seconds_since_midnight).change(usec: 0)
175
- change(:hour => 0)
203
+ change(hour: 0)
176
204
  end
177
205
  alias :midnight :beginning_of_day
178
206
  alias :at_midnight :beginning_of_day
179
207
  alias :at_beginning_of_day :beginning_of_day
180
208
 
181
- # Returns a new Time representing the end of the day, 23:59:59.999999 (.999999999 in ruby1.9)
209
+ # Returns a new Time representing the middle of the day (12:00)
210
+ def middle_of_day
211
+ change(hour: 12)
212
+ end
213
+ alias :midday :middle_of_day
214
+ alias :noon :middle_of_day
215
+ alias :at_midday :middle_of_day
216
+ alias :at_noon :middle_of_day
217
+ alias :at_middle_of_day :middle_of_day
218
+
219
+ # Returns a new Time representing the end of the day, 23:59:59.999999
182
220
  def end_of_day
183
221
  change(
184
- :hour => 23,
185
- :min => 59,
186
- :sec => 59,
187
- :usec => Rational(999999999, 1000)
222
+ hour: 23,
223
+ min: 59,
224
+ sec: 59,
225
+ usec: Rational(999999999, 1000)
188
226
  )
189
227
  end
190
228
  alias :at_end_of_day :end_of_day
191
229
 
192
230
  # Returns a new Time representing the start of the hour (x:00)
193
231
  def beginning_of_hour
194
- change(:min => 0)
232
+ change(min: 0)
195
233
  end
196
234
  alias :at_beginning_of_hour :beginning_of_hour
197
235
 
198
- # Returns a new Time representing the end of the hour, x:59:59.999999 (.999999999 in ruby1.9)
236
+ # Returns a new Time representing the end of the hour, x:59:59.999999
199
237
  def end_of_hour
200
238
  change(
201
- :min => 59,
202
- :sec => 59,
203
- :usec => Rational(999999999, 1000)
239
+ min: 59,
240
+ sec: 59,
241
+ usec: Rational(999999999, 1000)
204
242
  )
205
243
  end
206
244
  alias :at_end_of_hour :end_of_hour
207
245
 
208
246
  # Returns a new Time representing the start of the minute (x:xx:00)
209
247
  def beginning_of_minute
210
- change(:sec => 0)
248
+ change(sec: 0)
211
249
  end
212
250
  alias :at_beginning_of_minute :beginning_of_minute
213
251
 
214
- # Returns a new Time representing the end of the minute, x:xx:59.999999 (.999999999 in ruby1.9)
252
+ # Returns a new Time representing the end of the minute, x:xx:59.999999
215
253
  def end_of_minute
216
254
  change(
217
- :sec => 59,
218
- :usec => Rational(999999999, 1000)
255
+ sec: 59,
256
+ usec: Rational(999999999, 1000)
219
257
  )
220
258
  end
221
259
  alias :at_end_of_minute :end_of_minute
222
260
 
223
- # Returns a Range representing the whole day of the current time.
224
- def all_day
225
- beginning_of_day..end_of_day
226
- end
227
-
228
- # Returns a Range representing the whole week of the current time.
229
- # Week starts on start_day, default is <tt>Date.week_start</tt> or <tt>config.week_start</tt> when set.
230
- def all_week(start_day = Date.beginning_of_week)
231
- beginning_of_week(start_day)..end_of_week(start_day)
232
- end
233
-
234
- # Returns a Range representing the whole month of the current time.
235
- def all_month
236
- beginning_of_month..end_of_month
237
- end
238
-
239
- # Returns a Range representing the whole quarter of the current time.
240
- def all_quarter
241
- beginning_of_quarter..end_of_quarter
242
- end
243
-
244
- # Returns a Range representing the whole year of the current time.
245
- def all_year
246
- beginning_of_year..end_of_year
247
- end
248
-
249
261
  def plus_with_duration(other) #:nodoc:
250
262
  if ActiveSupport::Duration === other
251
263
  other.since(self)
@@ -279,8 +291,10 @@ class Time
279
291
  # Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
280
292
  # can be chronologically compared with a Time
281
293
  def compare_with_coercion(other)
282
- # we're avoiding Time#to_datetime cause it's expensive
283
- if other.is_a?(Time)
294
+ # we're avoiding Time#to_datetime and Time#to_time because they're expensive
295
+ if other.class == Time
296
+ compare_without_coercion(other)
297
+ elsif other.is_a?(Time)
284
298
  compare_without_coercion(other.to_time)
285
299
  else
286
300
  to_datetime <=> other
@@ -298,5 +312,4 @@ class Time
298
312
  end
299
313
  alias_method :eql_without_coercion, :eql?
300
314
  alias_method :eql?, :eql_with_coercion
301
-
302
315
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/date_and_time/compatibility"
4
+ require "active_support/core_ext/module/redefine_method"
5
+
6
+ class Time
7
+ include DateAndTime::Compatibility
8
+
9
+ silence_redefinition_of_method :to_time
10
+
11
+ # Either return +self+ or the time in the local system timezone depending
12
+ # on the setting of +ActiveSupport.to_time_preserves_timezone+.
13
+ def to_time
14
+ preserve_timezone ? self : getlocal
15
+ end
16
+ end
@@ -1,29 +1,33 @@
1
- require 'active_support/inflector/methods'
2
- require 'active_support/values/time_zone'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/inflector/methods"
4
+ require "active_support/values/time_zone"
3
5
 
4
6
  class Time
5
7
  DATE_FORMATS = {
6
- :db => '%Y-%m-%d %H:%M:%S',
7
- :number => '%Y%m%d%H%M%S',
8
- :nsec => '%Y%m%d%H%M%S%9N',
9
- :time => '%H:%M',
10
- :short => '%d %b %H:%M',
11
- :long => '%B %d, %Y %H:%M',
12
- :long_ordinal => lambda { |time|
8
+ db: "%Y-%m-%d %H:%M:%S",
9
+ number: "%Y%m%d%H%M%S",
10
+ nsec: "%Y%m%d%H%M%S%9N",
11
+ usec: "%Y%m%d%H%M%S%6N",
12
+ time: "%H:%M",
13
+ short: "%d %b %H:%M",
14
+ long: "%B %d, %Y %H:%M",
15
+ long_ordinal: lambda { |time|
13
16
  day_format = ActiveSupport::Inflector.ordinalize(time.day)
14
17
  time.strftime("%B #{day_format}, %Y %H:%M")
15
18
  },
16
- :rfc822 => lambda { |time|
19
+ rfc822: lambda { |time|
17
20
  offset_format = time.formatted_offset(false)
18
21
  time.strftime("%a, %d %b %Y %H:%M:%S #{offset_format}")
19
- }
22
+ },
23
+ iso8601: lambda { |time| time.iso8601 }
20
24
  }
21
25
 
22
- # Converts to a formatted string. See DATE_FORMATS for builtin formats.
26
+ # Converts to a formatted string. See DATE_FORMATS for built-in formats.
23
27
  #
24
28
  # This method is aliased to <tt>to_s</tt>.
25
29
  #
26
- # time = Time.now # => Thu Jan 18 06:10:17 CST 2007
30
+ # time = Time.now # => 2007-01-18 06:10:17 -06:00
27
31
  #
28
32
  # time.to_formatted_s(:time) # => "06:10"
29
33
  # time.to_s(:time) # => "06:10"
@@ -34,6 +38,7 @@ class Time
34
38
  # time.to_formatted_s(:long) # => "January 18, 2007 06:10"
35
39
  # time.to_formatted_s(:long_ordinal) # => "January 18th, 2007 06:10"
36
40
  # time.to_formatted_s(:rfc822) # => "Thu, 18 Jan 2007 06:10:17 -0600"
41
+ # time.to_formatted_s(:iso8601) # => "2007-01-18T06:10:17-06:00"
37
42
  #
38
43
  # == Adding your own time formats to +to_formatted_s+
39
44
  # You can add your own formats to the Time::DATE_FORMATS hash.
@@ -53,11 +58,15 @@ class Time
53
58
  alias_method :to_default_s, :to_s
54
59
  alias_method :to_s, :to_formatted_s
55
60
 
56
- # Returns the UTC offset as an +HH:MM formatted string.
61
+ # Returns a formatted string of the offset from UTC, or an alternative
62
+ # string if the time zone is already UTC.
57
63
  #
58
64
  # Time.local(2000).formatted_offset # => "-06:00"
59
65
  # Time.local(2000).formatted_offset(false) # => "-0600"
60
66
  def formatted_offset(colon = true, alternate_utc_string = nil)
61
67
  utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon)
62
68
  end
69
+
70
+ # Aliased to +xmlschema+ for compatibility with +DateTime+
71
+ alias_method :rfc3339, :xmlschema
63
72
  end
@@ -1,7 +1,11 @@
1
- require 'active_support/time_with_zone'
2
- require 'active_support/core_ext/time/acts_like'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/time_with_zone"
4
+ require "active_support/core_ext/time/acts_like"
5
+ require "active_support/core_ext/date_and_time/zones"
3
6
 
4
7
  class Time
8
+ include DateAndTime::Zones
5
9
  class << self
6
10
  attr_accessor :zone_default
7
11
 
@@ -24,7 +28,7 @@ class Time
24
28
  # <tt>current_user.time_zone</tt> just needs to return a string identifying the user's preferred time zone:
25
29
  #
26
30
  # class ApplicationController < ActionController::Base
27
- # around_filter :set_time_zone
31
+ # around_action :set_time_zone
28
32
  #
29
33
  # def set_time_zone
30
34
  # if logged_in?
@@ -38,7 +42,23 @@ class Time
38
42
  Thread.current[:time_zone] = find_zone!(time_zone)
39
43
  end
40
44
 
41
- # Allows override of <tt>Time.zone</tt> locally inside supplied block; resets <tt>Time.zone</tt> to existing value when done.
45
+ # Allows override of <tt>Time.zone</tt> locally inside supplied block;
46
+ # resets <tt>Time.zone</tt> to existing value when done.
47
+ #
48
+ # class ApplicationController < ActionController::Base
49
+ # around_action :set_time_zone
50
+ #
51
+ # private
52
+ #
53
+ # def set_time_zone
54
+ # Time.use_zone(current_user.timezone) { yield }
55
+ # end
56
+ # end
57
+ #
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.
42
62
  def use_zone(time_zone)
43
63
  new_zone = find_zone!(time_zone)
44
64
  begin
@@ -49,12 +69,22 @@ class Time
49
69
  end
50
70
  end
51
71
 
52
- # Returns a TimeZone instance or nil, or raises an ArgumentError for invalid timezones.
72
+ # Returns a TimeZone instance matching the time zone provided.
73
+ # Accepts the time zone in any format supported by <tt>Time.zone=</tt>.
74
+ # Raises an +ArgumentError+ for invalid time zones.
75
+ #
76
+ # Time.find_zone! "America/New_York" # => #<ActiveSupport::TimeZone @name="America/New_York" ...>
77
+ # Time.find_zone! "EST" # => #<ActiveSupport::TimeZone @name="EST" ...>
78
+ # Time.find_zone! -5.hours # => #<ActiveSupport::TimeZone @name="Bogota" ...>
79
+ # Time.find_zone! nil # => nil
80
+ # Time.find_zone! false # => false
81
+ # Time.find_zone! "NOT-A-TIMEZONE" # => ArgumentError: Invalid Timezone: NOT-A-TIMEZONE
53
82
  def find_zone!(time_zone)
54
83
  if !time_zone || time_zone.is_a?(ActiveSupport::TimeZone)
55
84
  time_zone
56
85
  else
57
- # lookup timezone based on identifier (unless we've been passed a TZInfo::Timezone)
86
+ # Look up the timezone based on the identifier (unless we've been
87
+ # passed a TZInfo::Timezone)
58
88
  unless time_zone.respond_to?(:period_for_local)
59
89
  time_zone = ActiveSupport::TimeZone[time_zone] || TZInfo::Timezone.get(time_zone)
60
90
  end
@@ -70,28 +100,14 @@ class Time
70
100
  raise ArgumentError, "Invalid Timezone: #{time_zone}"
71
101
  end
72
102
 
103
+ # Returns a TimeZone instance matching the time zone provided.
104
+ # Accepts the time zone in any format supported by <tt>Time.zone=</tt>.
105
+ # Returns +nil+ for invalid time zones.
106
+ #
107
+ # Time.find_zone "America/New_York" # => #<ActiveSupport::TimeZone @name="America/New_York" ...>
108
+ # Time.find_zone "NOT-A-TIMEZONE" # => nil
73
109
  def find_zone(time_zone)
74
110
  find_zone!(time_zone) rescue nil
75
111
  end
76
112
  end
77
-
78
- # Returns the simultaneous time in <tt>Time.zone</tt>.
79
- #
80
- # Time.zone = 'Hawaii' # => 'Hawaii'
81
- # Time.utc(2000).in_time_zone # => Fri, 31 Dec 1999 14:00:00 HST -10:00
82
- #
83
- # This method is similar to Time#localtime, except that it uses <tt>Time.zone</tt> as the local zone
84
- # instead of the operating system's time zone.
85
- #
86
- # You can also pass in a TimeZone instance or string that identifies a TimeZone as an argument,
87
- # and the conversion will be based on that zone instead of <tt>Time.zone</tt>.
88
- #
89
- # Time.utc(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
90
- def in_time_zone(zone = ::Time.zone)
91
- if zone
92
- ActiveSupport::TimeWithZone.new(utc? ? self : getutc, ::Time.find_zone!(zone))
93
- else
94
- self
95
- end
96
- end
97
113
  end
@@ -1,5 +1,7 @@
1
- require 'active_support/core_ext/time/acts_like'
2
- require 'active_support/core_ext/time/calculations'
3
- require 'active_support/core_ext/time/conversions'
4
- require 'active_support/core_ext/time/marshal'
5
- require 'active_support/core_ext/time/zones'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/time/acts_like"
4
+ require "active_support/core_ext/time/calculations"
5
+ require "active_support/core_ext/time/compatibility"
6
+ require "active_support/core_ext/time/conversions"
7
+ require "active_support/core_ext/time/zones"
@@ -1,18 +1,16 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- require 'uri'
4
- str = "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E" # Ni-ho-nn-go in UTF-8, means Japanese.
5
- parser = URI::Parser.new
6
-
7
- unless str == parser.unescape(parser.escape(str))
3
+ require "uri"
4
+ if RUBY_VERSION < "2.6.0"
5
+ require "active_support/core_ext/module/redefine_method"
8
6
  URI::Parser.class_eval do
9
- remove_method :unescape
7
+ silence_redefinition_of_method :unescape
10
8
  def unescape(str, escaped = /%[a-fA-F\d]{2}/)
11
9
  # TODO: Are we actually sure that ASCII == UTF-8?
12
10
  # YK: My initial experiments say yes, but let's be sure please
13
11
  enc = str.encoding
14
12
  enc = Encoding::UTF_8 if enc == Encoding::US_ASCII
15
- str.gsub(escaped) { [$&[1, 2].hex].pack('C') }.force_encoding(enc)
13
+ str.dup.force_encoding(Encoding::ASCII_8BIT).gsub(escaped) { |match| [match[1, 2].hex].pack("C") }.force_encoding(enc)
16
14
  end
17
15
  end
18
16
  end
@@ -1,4 +1,5 @@
1
- Dir["#{File.dirname(__FILE__)}/core_ext/*.rb"].each do |path|
2
- next if File.basename(path, '.rb') == 'logger'
1
+ # frozen_string_literal: true
2
+
3
+ Dir.glob(File.expand_path("core_ext/*.rb", __dir__)).each do |path|
3
4
  require path
4
5
  end