activesupport 4.2.11.3 → 5.2.8.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 (256) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +435 -403
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +4 -5
  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 +7 -5
  8. data/lib/active_support/benchmarkable.rb +6 -4
  9. data/lib/active_support/builder.rb +3 -1
  10. data/lib/active_support/cache/file_store.rb +41 -35
  11. data/lib/active_support/cache/mem_cache_store.rb +91 -91
  12. data/lib/active_support/cache/memory_store.rb +27 -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 +67 -34
  16. data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
  17. data/lib/active_support/cache.rb +287 -196
  18. data/lib/active_support/callbacks.rb +640 -590
  19. data/lib/active_support/concern.rb +11 -5
  20. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +35 -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 +29 -1
  24. data/lib/active_support/core_ext/array/conversions.rb +22 -18
  25. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  26. data/lib/active_support/core_ext/array/grouping.rb +11 -18
  27. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  28. data/lib/active_support/core_ext/array/prepend_and_append.rb +5 -3
  29. data/lib/active_support/core_ext/array/wrap.rb +7 -4
  30. data/lib/active_support/core_ext/array.rb +9 -6
  31. data/lib/active_support/core_ext/benchmark.rb +3 -1
  32. data/lib/active_support/core_ext/big_decimal/conversions.rb +10 -12
  33. data/lib/active_support/core_ext/big_decimal.rb +3 -1
  34. data/lib/active_support/core_ext/class/attribute.rb +41 -22
  35. data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
  36. data/lib/active_support/core_ext/class/subclasses.rb +20 -6
  37. data/lib/active_support/core_ext/class.rb +4 -3
  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 +11 -9
  41. data/lib/active_support/core_ext/date/conversions.rb +25 -23
  42. data/lib/active_support/core_ext/date/zones.rb +4 -2
  43. data/lib/active_support/core_ext/date.rb +6 -4
  44. data/lib/active_support/core_ext/date_and_time/calculations.rb +170 -58
  45. data/lib/active_support/core_ext/date_and_time/compatibility.rb +4 -3
  46. data/lib/active_support/core_ext/date_and_time/zones.rb +12 -12
  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 +36 -18
  50. data/lib/active_support/core_ext/date_time/compatibility.rb +8 -6
  51. data/lib/active_support/core_ext/date_time/conversions.rb +16 -12
  52. data/lib/active_support/core_ext/date_time.rb +7 -5
  53. data/lib/active_support/core_ext/digest/uuid.rb +7 -5
  54. data/lib/active_support/core_ext/digest.rb +3 -0
  55. data/lib/active_support/core_ext/enumerable.rb +101 -33
  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 +14 -9
  59. data/lib/active_support/core_ext/hash/conversions.rb +62 -41
  60. data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
  61. data/lib/active_support/core_ext/hash/except.rb +11 -8
  62. data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
  63. data/lib/active_support/core_ext/hash/keys.rb +33 -27
  64. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  65. data/lib/active_support/core_ext/hash/slice.rb +8 -8
  66. data/lib/active_support/core_ext/hash/transform_values.rb +14 -5
  67. data/lib/active_support/core_ext/hash.rb +11 -9
  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 -18
  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 +5 -1
  74. data/lib/active_support/core_ext/kernel/reporting.rb +4 -84
  75. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  76. data/lib/active_support/core_ext/kernel.rb +6 -5
  77. data/lib/active_support/core_ext/load_error.rb +3 -22
  78. data/lib/active_support/core_ext/marshal.rb +8 -8
  79. data/lib/active_support/core_ext/module/aliasing.rb +6 -44
  80. data/lib/active_support/core_ext/module/anonymous.rb +12 -1
  81. data/lib/active_support/core_ext/module/attr_internal.rb +8 -9
  82. data/lib/active_support/core_ext/module/attribute_accessors.rb +43 -40
  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 +11 -12
  85. data/lib/active_support/core_ext/module/delegation.rb +98 -36
  86. data/lib/active_support/core_ext/module/deprecation.rb +4 -2
  87. data/lib/active_support/core_ext/module/introspection.rb +9 -9
  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 -11
  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 +78 -81
  95. data/lib/active_support/core_ext/numeric/inquiry.rb +28 -0
  96. data/lib/active_support/core_ext/numeric/time.rb +35 -23
  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 +27 -2
  100. data/lib/active_support/core_ext/object/conversions.rb +6 -4
  101. data/lib/active_support/core_ext/object/deep_dup.rb +13 -4
  102. data/lib/active_support/core_ext/object/duplicable.rb +41 -14
  103. data/lib/active_support/core_ext/object/inclusion.rb +5 -3
  104. data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
  105. data/lib/active_support/core_ext/object/json.rb +49 -19
  106. data/lib/active_support/core_ext/object/to_param.rb +3 -1
  107. data/lib/active_support/core_ext/object/to_query.rb +10 -5
  108. data/lib/active_support/core_ext/object/try.rb +69 -21
  109. data/lib/active_support/core_ext/object/with_options.rb +16 -3
  110. data/lib/active_support/core_ext/object.rb +14 -13
  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 +8 -6
  121. data/lib/active_support/core_ext/string/behavior.rb +3 -1
  122. data/lib/active_support/core_ext/string/conversions.rb +7 -4
  123. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  124. data/lib/active_support/core_ext/string/filters.rb +6 -5
  125. data/lib/active_support/core_ext/string/indent.rb +6 -4
  126. data/lib/active_support/core_ext/string/inflections.rb +61 -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 +62 -38
  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 -2
  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 +85 -51
  136. data/lib/active_support/core_ext/time/compatibility.rb +4 -2
  137. data/lib/active_support/core_ext/time/conversions.rb +20 -13
  138. data/lib/active_support/core_ext/time/zones.rb +41 -7
  139. data/lib/active_support/core_ext/time.rb +7 -6
  140. data/lib/active_support/core_ext/uri.rb +6 -8
  141. data/lib/active_support/core_ext.rb +3 -1
  142. data/lib/active_support/current_attributes.rb +195 -0
  143. data/lib/active_support/dependencies/autoload.rb +2 -0
  144. data/lib/active_support/dependencies/interlock.rb +57 -0
  145. data/lib/active_support/dependencies.rb +152 -161
  146. data/lib/active_support/deprecation/behaviors.rb +44 -11
  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 +12 -9
  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 +314 -38
  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 +131 -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 +6 -4
  165. data/lib/active_support/gzip.rb +7 -5
  166. data/lib/active_support/hash_with_indifferent_access.rb +123 -28
  167. data/lib/active_support/i18n.rb +8 -6
  168. data/lib/active_support/i18n_railtie.rb +37 -13
  169. data/lib/active_support/inflections.rb +13 -11
  170. data/lib/active_support/inflector/inflections.rb +61 -12
  171. data/lib/active_support/inflector/methods.rb +163 -136
  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 +16 -13
  175. data/lib/active_support/json/encoding.rb +11 -58
  176. data/lib/active_support/json.rb +4 -2
  177. data/lib/active_support/key_generator.rb +25 -25
  178. data/lib/active_support/lazy_load_hooks.rb +50 -20
  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 +8 -7
  183. data/lib/active_support/logger_silence.rb +6 -4
  184. data/lib/active_support/logger_thread_safe_level.rb +7 -5
  185. data/lib/active_support/message_encryptor.rb +168 -53
  186. data/lib/active_support/message_verifier.rb +150 -17
  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 +36 -23
  191. data/lib/active_support/multibyte/unicode.rb +100 -96
  192. data/lib/active_support/multibyte.rb +4 -2
  193. data/lib/active_support/notifications/fanout.rb +11 -9
  194. data/lib/active_support/notifications/instrumenter.rb +27 -7
  195. data/lib/active_support/notifications.rb +11 -7
  196. data/lib/active_support/number_helper/number_converter.rb +13 -11
  197. data/lib/active_support/number_helper/number_to_currency_converter.rb +9 -9
  198. data/lib/active_support/number_helper/number_to_delimited_converter.rb +9 -3
  199. data/lib/active_support/number_helper/number_to_human_converter.rb +11 -9
  200. data/lib/active_support/number_helper/number_to_human_size_converter.rb +9 -8
  201. data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
  202. data/lib/active_support/number_helper/number_to_phone_converter.rb +13 -4
  203. data/lib/active_support/number_helper/number_to_rounded_converter.rb +23 -56
  204. data/lib/active_support/number_helper/rounding_helper.rb +66 -0
  205. data/lib/active_support/number_helper.rb +94 -68
  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 +23 -5
  209. data/lib/active_support/per_thread_registry.rb +9 -4
  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 +15 -11
  216. data/lib/active_support/string_inquirer.rb +11 -3
  217. data/lib/active_support/subscriber.rb +21 -16
  218. data/lib/active_support/tagged_logging.rb +14 -11
  219. data/lib/active_support/test_case.rb +19 -47
  220. data/lib/active_support/testing/assertions.rb +137 -20
  221. data/lib/active_support/testing/autorun.rb +4 -2
  222. data/lib/active_support/testing/constant_lookup.rb +2 -1
  223. data/lib/active_support/testing/declarative.rb +3 -1
  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 +34 -25
  227. data/lib/active_support/testing/method_call_assertions.rb +43 -0
  228. data/lib/active_support/testing/setup_and_teardown.rb +13 -8
  229. data/lib/active_support/testing/stream.rb +44 -0
  230. data/lib/active_support/testing/tagged_logging.rb +3 -1
  231. data/lib/active_support/testing/time_helpers.rb +81 -15
  232. data/lib/active_support/time.rb +14 -12
  233. data/lib/active_support/time_with_zone.rb +169 -39
  234. data/lib/active_support/values/time_zone.rb +196 -61
  235. data/lib/active_support/values/unicode_tables.dat +0 -0
  236. data/lib/active_support/version.rb +3 -1
  237. data/lib/active_support/xml_mini/jdom.rb +116 -114
  238. data/lib/active_support/xml_mini/libxml.rb +16 -13
  239. data/lib/active_support/xml_mini/libxmlsax.rb +15 -14
  240. data/lib/active_support/xml_mini/nokogiri.rb +14 -12
  241. data/lib/active_support/xml_mini/nokogirisax.rb +14 -13
  242. data/lib/active_support/xml_mini/rexml.rb +11 -9
  243. data/lib/active_support/xml_mini.rb +37 -37
  244. data/lib/active_support.rb +12 -11
  245. metadata +57 -27
  246. data/lib/active_support/concurrency/latch.rb +0 -27
  247. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
  248. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
  249. data/lib/active_support/core_ext/date_time/zones.rb +0 -6
  250. data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
  251. data/lib/active_support/core_ext/module/method_transplanting.rb +0 -13
  252. data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
  253. data/lib/active_support/core_ext/object/itself.rb +0 -15
  254. data/lib/active_support/core_ext/struct.rb +0 -6
  255. data/lib/active_support/core_ext/thread.rb +0 -86
  256. data/lib/active_support/core_ext/time/marshal.rb +0 -30
@@ -1,4 +1,7 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/regexp"
4
+ require "concurrent/map"
2
5
 
3
6
  class Object
4
7
  # An object is blank if it's false, empty, or a whitespace string.
@@ -100,6 +103,9 @@ end
100
103
 
101
104
  class String
102
105
  BLANK_RE = /\A[[:space:]]*\z/
106
+ ENCODED_BLANKS = Concurrent::Map.new do |h, enc|
107
+ h[enc] = Regexp.new(BLANK_RE.source.encode(enc), BLANK_RE.options | Regexp::FIXEDENCODING)
108
+ end
103
109
 
104
110
  # A string is blank if it's empty or contains whitespaces only:
105
111
  #
@@ -114,7 +120,15 @@ class String
114
120
  #
115
121
  # @return [true, false]
116
122
  def blank?
117
- BLANK_RE === self
123
+ # The regexp that matches blank strings is expensive. For the case of empty
124
+ # strings we can speed up this method (~3.5x) with an empty? call. The
125
+ # penalty for the rest of strings is marginal.
126
+ empty? ||
127
+ begin
128
+ BLANK_RE.match?(self)
129
+ rescue Encoding::CompatibilityError
130
+ ENCODED_BLANKS[self.encoding].match?(self)
131
+ end
118
132
  end
119
133
  end
120
134
 
@@ -129,3 +143,14 @@ class Numeric #:nodoc:
129
143
  false
130
144
  end
131
145
  end
146
+
147
+ class Time #:nodoc:
148
+ # No Time is blank:
149
+ #
150
+ # Time.now.blank? # => false
151
+ #
152
+ # @return [false]
153
+ def blank?
154
+ false
155
+ end
156
+ end
@@ -1,4 +1,6 @@
1
- require 'active_support/core_ext/object/to_param'
2
- require 'active_support/core_ext/object/to_query'
3
- require 'active_support/core_ext/array/conversions'
4
- require 'active_support/core_ext/hash/conversions'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/object/to_param"
4
+ require "active_support/core_ext/object/to_query"
5
+ require "active_support/core_ext/array/conversions"
6
+ require "active_support/core_ext/hash/conversions"
@@ -1,4 +1,6 @@
1
- require 'active_support/core_ext/object/duplicable'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/object/duplicable"
2
4
 
3
5
  class Object
4
6
  # Returns a deep copy of object if it's duplicable. If it's
@@ -25,7 +27,7 @@ class Array
25
27
  # array[1][2] # => nil
26
28
  # dup[1][2] # => 4
27
29
  def deep_dup
28
- map { |it| it.deep_dup }
30
+ map(&:deep_dup)
29
31
  end
30
32
  end
31
33
 
@@ -39,8 +41,15 @@ class Hash
39
41
  # hash[:a][:c] # => nil
40
42
  # dup[:a][:c] # => "c"
41
43
  def deep_dup
42
- each_with_object(dup) do |(key, value), hash|
43
- hash[key.deep_dup] = value.deep_dup
44
+ hash = dup
45
+ each_pair do |key, value|
46
+ if key.frozen? && ::String === key
47
+ hash[key] = value.deep_dup
48
+ else
49
+ hash.delete(key)
50
+ hash[key.deep_dup] = value.deep_dup
51
+ end
44
52
  end
53
+ hash
45
54
  end
46
55
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #--
2
4
  # Most objects are cloneable, but not all. For example you can't dup methods:
3
5
  #
@@ -19,7 +21,7 @@
19
21
  class Object
20
22
  # Can you safely dup this object?
21
23
  #
22
- # False for +nil+, +false+, +true+, symbol, number and BigDecimal(in 1.9.x) objects;
24
+ # False for method objects;
23
25
  # true otherwise.
24
26
  def duplicable?
25
27
  true
@@ -74,7 +76,7 @@ end
74
76
  class Symbol
75
77
  begin
76
78
  :symbol.dup # Ruby 2.4.x.
77
- 'symbol_from_string'.to_sym.dup # Some symbols can't `dup` in Ruby 2.4.0.
79
+ "symbol_from_string".to_sym.dup # Some symbols can't `dup` in Ruby 2.4.0.
78
80
  rescue TypeError
79
81
 
80
82
  # Symbols are not duplicable:
@@ -102,19 +104,14 @@ class Numeric
102
104
  end
103
105
  end
104
106
 
105
- require 'bigdecimal'
107
+ require "bigdecimal"
106
108
  class BigDecimal
107
- # Needed to support Ruby 1.9.x, as it doesn't allow dup on BigDecimal, instead
108
- # raises TypeError exception. Checking here on the runtime whether BigDecimal
109
- # will allow dup or not.
110
- begin
111
- BigDecimal.new('4.56').dup
112
-
113
- def duplicable?
114
- true
115
- end
116
- rescue TypeError
117
- # can't dup, so use superclass implementation
109
+ # BigDecimals are duplicable:
110
+ #
111
+ # BigDecimal("1.2").duplicable? # => true
112
+ # BigDecimal("1.2").dup # => #<BigDecimal:...,'0.12E1',18(18)>
113
+ def duplicable?
114
+ true
118
115
  end
119
116
  end
120
117
 
@@ -127,3 +124,33 @@ class Method
127
124
  false
128
125
  end
129
126
  end
127
+
128
+ class Complex
129
+ begin
130
+ Complex(1).dup
131
+ rescue TypeError
132
+
133
+ # Complexes are not duplicable:
134
+ #
135
+ # Complex(1).duplicable? # => false
136
+ # Complex(1).dup # => TypeError: can't copy Complex
137
+ def duplicable?
138
+ false
139
+ end
140
+ end
141
+ end
142
+
143
+ class Rational
144
+ begin
145
+ Rational(1).dup
146
+ rescue TypeError
147
+
148
+ # Rationals are not duplicable:
149
+ #
150
+ # Rational(1).duplicable? # => false
151
+ # Rational(1).dup # => TypeError: can't copy Rational
152
+ def duplicable?
153
+ false
154
+ end
155
+ end
156
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Object
2
4
  # Returns true if this object is included in the argument. Argument must be
3
5
  # any object which responds to +#include?+. Usage:
@@ -5,7 +7,7 @@ class Object
5
7
  # characters = ["Konata", "Kagami", "Tsukasa"]
6
8
  # "Konata".in?(characters) # => true
7
9
  #
8
- # This will throw an ArgumentError if the argument doesn't respond
10
+ # This will throw an +ArgumentError+ if the argument doesn't respond
9
11
  # to +#include?+.
10
12
  def in?(another_object)
11
13
  another_object.include?(self)
@@ -18,10 +20,10 @@ class Object
18
20
  #
19
21
  # params[:bucket_type].presence_in %w( project calendar )
20
22
  #
21
- # This will throw an ArgumentError if the argument doesn't respond to +#include?+.
23
+ # This will throw an +ArgumentError+ if the argument doesn't respond to +#include?+.
22
24
  #
23
25
  # @return [Object]
24
26
  def presence_in(another_object)
25
- self.in?(another_object) ? self : nil
27
+ in?(another_object) ? self : nil
26
28
  end
27
29
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Object
2
4
  # Returns a hash with string keys that maps instance variable names without "@" to their
3
5
  # corresponding values.
@@ -23,6 +25,6 @@ class Object
23
25
  #
24
26
  # C.new(0, 1).instance_variable_names # => ["@y", "@x"]
25
27
  def instance_variable_names
26
- instance_variables.map { |var| var.to_s }
28
+ instance_variables.map(&:to_s)
27
29
  end
28
30
  end
@@ -1,15 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Hack to load json gem first so we can overwrite its to_json.
2
- require 'json'
3
- require 'bigdecimal'
4
- require 'active_support/core_ext/big_decimal/conversions' # for #to_s
5
- require 'active_support/core_ext/hash/except'
6
- require 'active_support/core_ext/hash/slice'
7
- require 'active_support/core_ext/object/instance_variables'
8
- require 'time'
9
- require 'active_support/core_ext/time/conversions'
10
- require 'active_support/core_ext/date_time/conversions'
11
- require 'active_support/core_ext/date/conversions'
12
- require 'active_support/core_ext/module/aliasing'
4
+ require "json"
5
+ require "bigdecimal"
6
+ require "uri/generic"
7
+ require "pathname"
8
+ require "active_support/core_ext/big_decimal/conversions" # for #to_s
9
+ require "active_support/core_ext/hash/except"
10
+ require "active_support/core_ext/hash/slice"
11
+ require "active_support/core_ext/object/instance_variables"
12
+ require "time"
13
+ require "active_support/core_ext/time/conversions"
14
+ require "active_support/core_ext/date_time/conversions"
15
+ require "active_support/core_ext/date/conversions"
13
16
 
14
17
  # The JSON gem adds a few modules to Ruby core classes containing :to_json definition, overwriting
15
18
  # their default behavior. That said, we need to define the basic to_json method in all of them,
@@ -26,22 +29,25 @@ require 'active_support/core_ext/module/aliasing'
26
29
  # bypassed completely. This means that as_json won't be invoked and the JSON gem will simply
27
30
  # ignore any options it does not natively understand. This also means that ::JSON.{generate,dump}
28
31
  # should give exactly the same results with or without active support.
29
- [Enumerable, Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass].each do |klass|
30
- klass.class_eval do
31
- def to_json_with_active_support_encoder(options = nil) # :nodoc:
32
+
33
+ module ActiveSupport
34
+ module ToJsonWithActiveSupportEncoder # :nodoc:
35
+ def to_json(options = nil)
32
36
  if options.is_a?(::JSON::State)
33
37
  # Called from JSON.{generate,dump}, forward it to JSON gem's to_json
34
- self.to_json_without_active_support_encoder(options)
38
+ super(options)
35
39
  else
36
40
  # to_json is being invoked directly, use ActiveSupport's encoder
37
41
  ActiveSupport::JSON.encode(self, options)
38
42
  end
39
43
  end
40
-
41
- alias_method_chain :to_json, :active_support_encoder
42
44
  end
43
45
  end
44
46
 
47
+ [Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass, Enumerable].reverse_each do |klass|
48
+ klass.prepend(ActiveSupport::ToJsonWithActiveSupportEncoder)
49
+ end
50
+
45
51
  class Object
46
52
  def as_json(options = nil) #:nodoc:
47
53
  if respond_to?(:to_hash)
@@ -129,6 +135,12 @@ module Enumerable
129
135
  end
130
136
  end
131
137
 
138
+ class IO
139
+ def as_json(options = nil) #:nodoc:
140
+ to_s
141
+ end
142
+ end
143
+
132
144
  class Range
133
145
  def as_json(options = nil) #:nodoc:
134
146
  to_s
@@ -185,13 +197,31 @@ class DateTime
185
197
  if ActiveSupport::JSON::Encoding.use_standard_json_time_format
186
198
  xmlschema(ActiveSupport::JSON::Encoding.time_precision)
187
199
  else
188
- strftime('%Y/%m/%d %H:%M:%S %z')
200
+ strftime("%Y/%m/%d %H:%M:%S %z")
189
201
  end
190
202
  end
191
203
  end
192
204
 
205
+ class URI::Generic #:nodoc:
206
+ def as_json(options = nil)
207
+ to_s
208
+ end
209
+ end
210
+
211
+ class Pathname #:nodoc:
212
+ def as_json(options = nil)
213
+ to_s
214
+ end
215
+ end
216
+
193
217
  class Process::Status #:nodoc:
194
218
  def as_json(options = nil)
195
- { :exitstatus => exitstatus, :pid => pid }
219
+ { exitstatus: exitstatus, pid: pid }
220
+ end
221
+ end
222
+
223
+ class Exception
224
+ def as_json(options = nil)
225
+ to_s
196
226
  end
197
227
  end
@@ -1 +1,3 @@
1
- require 'active_support/core_ext/object/to_query'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/object/to_query"
@@ -1,4 +1,6 @@
1
- require 'cgi'
1
+ # frozen_string_literal: true
2
+
3
+ require "cgi"
2
4
 
3
5
  class Object
4
6
  # Alias of <tt>to_s</tt>.
@@ -38,7 +40,7 @@ class Array
38
40
  # Calls <tt>to_param</tt> on all its elements and joins the result with
39
41
  # slashes. This is used by <tt>url_for</tt> in Action Pack.
40
42
  def to_param
41
- collect { |e| e.to_param }.join '/'
43
+ collect(&:to_param).join "/"
42
44
  end
43
45
 
44
46
  # Converts an array into a string suitable for use as a URL query string,
@@ -51,7 +53,7 @@ class Array
51
53
  if empty?
52
54
  nil.to_query(prefix)
53
55
  else
54
- collect { |value| value.to_query(prefix) }.join '&'
56
+ collect { |value| value.to_query(prefix) }.join "&"
55
57
  end
56
58
  end
57
59
  end
@@ -73,11 +75,14 @@ class Hash
73
75
  #
74
76
  # This method is also aliased as +to_param+.
75
77
  def to_query(namespace = nil)
76
- collect do |key, value|
78
+ query = collect do |key, value|
77
79
  unless (value.is_a?(Hash) || value.is_a?(Array)) && value.empty?
78
80
  value.to_query(namespace ? "#{namespace}[#{key}]" : key)
79
81
  end
80
- end.compact.sort! * '&'
82
+ end.compact
83
+
84
+ query.sort! unless namespace.to_s.include?("[]")
85
+ query.join("&")
81
86
  end
82
87
 
83
88
  alias_method :to_param, :to_query
@@ -1,4 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "delegate"
4
+
5
+ module ActiveSupport
6
+ module Tryable #:nodoc:
7
+ def try(*a, &b)
8
+ try!(*a, &b) if a.empty? || respond_to?(a.first)
9
+ end
10
+
11
+ def try!(*a, &b)
12
+ if a.empty? && block_given?
13
+ if b.arity == 0
14
+ instance_eval(&b)
15
+ else
16
+ yield self
17
+ end
18
+ else
19
+ public_send(*a, &b)
20
+ end
21
+ end
22
+ end
23
+ end
24
+
1
25
  class Object
26
+ include ActiveSupport::Tryable
27
+
28
+ ##
29
+ # :method: try
30
+ #
31
+ # :call-seq:
32
+ # try(*a, &b)
33
+ #
2
34
  # Invokes the public method whose name goes as first argument just like
3
35
  # +public_send+ does, except that if the receiver does not respond to it the
4
36
  # call returns +nil+ rather than raising an exception.
@@ -21,11 +53,11 @@ class Object
21
53
  #
22
54
  # +try+ will also return +nil+ if the receiver does not respond to the method:
23
55
  #
24
- # @person.try(:non_existing_method) #=> nil
56
+ # @person.try(:non_existing_method) # => nil
25
57
  #
26
58
  # instead of
27
59
  #
28
- # @person.non_existing_method if @person.respond_to?(:non_existing_method) #=> nil
60
+ # @person.non_existing_method if @person.respond_to?(:non_existing_method) # => nil
29
61
  #
30
62
  # +try+ returns +nil+ when called on +nil+ regardless of whether it responds
31
63
  # to the method:
@@ -56,27 +88,40 @@ class Object
56
88
  #
57
89
  # Please also note that +try+ is defined on +Object+. Therefore, it won't work
58
90
  # with instances of classes that do not have +Object+ among their ancestors,
59
- # like direct subclasses of +BasicObject+. For example, using +try+ with
60
- # +SimpleDelegator+ will delegate +try+ to the target instead of calling it on
61
- # the delegator itself.
62
- def try(*a, &b)
63
- try!(*a, &b) if a.empty? || respond_to?(a.first)
64
- end
91
+ # like direct subclasses of +BasicObject+.
65
92
 
66
- # Same as #try, but will raise a NoMethodError exception if the receiver is not +nil+ and
67
- # does not implement the tried method.
93
+ ##
94
+ # :method: try!
95
+ #
96
+ # :call-seq:
97
+ # try!(*a, &b)
98
+ #
99
+ # Same as #try, but raises a +NoMethodError+ exception if the receiver is
100
+ # not +nil+ and does not implement the tried method.
101
+ #
102
+ # "a".try!(:upcase) # => "A"
103
+ # nil.try!(:upcase) # => nil
104
+ # 123.try!(:upcase) # => NoMethodError: undefined method `upcase' for 123:Integer
105
+ end
68
106
 
69
- def try!(*a, &b)
70
- if a.empty? && block_given?
71
- if b.arity == 0
72
- instance_eval(&b)
73
- else
74
- yield self
75
- end
76
- else
77
- public_send(*a, &b)
78
- end
79
- end
107
+ class Delegator
108
+ include ActiveSupport::Tryable
109
+
110
+ ##
111
+ # :method: try
112
+ #
113
+ # :call-seq:
114
+ # try(a*, &b)
115
+ #
116
+ # See Object#try
117
+
118
+ ##
119
+ # :method: try!
120
+ #
121
+ # :call-seq:
122
+ # try!(a*, &b)
123
+ #
124
+ # See Object#try!
80
125
  end
81
126
 
82
127
  class NilClass
@@ -94,6 +139,9 @@ class NilClass
94
139
  nil
95
140
  end
96
141
 
142
+ # Calling +try!+ on +nil+ always returns +nil+.
143
+ #
144
+ # nil.try!(:name) # => nil
97
145
  def try!(*args)
98
146
  nil
99
147
  end
@@ -1,4 +1,6 @@
1
- require 'active_support/option_merger'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/option_merger"
2
4
 
3
5
  class Object
4
6
  # An elegant way to factor duplication out of options passed to a series of
@@ -7,7 +9,7 @@ class Object
7
9
  # provided. Each method called on the block variable must take an options
8
10
  # hash as its final argument.
9
11
  #
10
- # Without <tt>with_options></tt>, this code contains duplication:
12
+ # Without <tt>with_options</tt>, this code contains duplication:
11
13
  #
12
14
  # class Account < ActiveRecord::Base
13
15
  # has_many :customers, dependent: :destroy
@@ -60,7 +62,18 @@ class Object
60
62
  #
61
63
  # validates :content, length: { minimum: 50 }, if: -> { content.present? }
62
64
  #
63
- # Hence the inherited default for `if` key is ignored.
65
+ # Hence the inherited default for +if+ key is ignored.
66
+ #
67
+ # NOTE: You cannot call class methods implicitly inside of with_options.
68
+ # You can access these methods using the class name instead:
69
+ #
70
+ # class Phone < ActiveRecord::Base
71
+ # enum phone_number_type: [home: 0, office: 1, mobile: 2]
72
+ #
73
+ # with_options presence: true do
74
+ # validates :phone_number_type, inclusion: { in: Phone.phone_number_types.keys }
75
+ # end
76
+ # end
64
77
  #
65
78
  def with_options(options, &block)
66
79
  option_merger = ActiveSupport::OptionMerger.new(self, options)
@@ -1,15 +1,16 @@
1
- require 'active_support/core_ext/object/acts_like'
2
- require 'active_support/core_ext/object/blank'
3
- require 'active_support/core_ext/object/duplicable'
4
- require 'active_support/core_ext/object/deep_dup'
5
- require 'active_support/core_ext/object/itself'
6
- require 'active_support/core_ext/object/try'
7
- require 'active_support/core_ext/object/inclusion'
1
+ # frozen_string_literal: true
8
2
 
9
- require 'active_support/core_ext/object/conversions'
10
- require 'active_support/core_ext/object/instance_variables'
3
+ require "active_support/core_ext/object/acts_like"
4
+ require "active_support/core_ext/object/blank"
5
+ require "active_support/core_ext/object/duplicable"
6
+ require "active_support/core_ext/object/deep_dup"
7
+ require "active_support/core_ext/object/try"
8
+ require "active_support/core_ext/object/inclusion"
11
9
 
12
- require 'active_support/core_ext/object/json'
13
- require 'active_support/core_ext/object/to_param'
14
- require 'active_support/core_ext/object/to_query'
15
- require 'active_support/core_ext/object/with_options'
10
+ require "active_support/core_ext/object/conversions"
11
+ require "active_support/core_ext/object/instance_variables"
12
+
13
+ require "active_support/core_ext/object/json"
14
+ require "active_support/core_ext/object/to_param"
15
+ require "active_support/core_ext/object/to_query"
16
+ require "active_support/core_ext/object/with_options"
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ module CompareWithRange #:nodoc:
5
+ # Extends the default Range#=== to support range comparisons.
6
+ # (1..5) === (1..5) # => true
7
+ # (1..5) === (2..3) # => true
8
+ # (1..5) === (2..6) # => false
9
+ #
10
+ # The native Range#=== behavior is untouched.
11
+ # ('a'..'f') === ('c') # => true
12
+ # (5..9) === (11) # => false
13
+ def ===(value)
14
+ if value.is_a?(::Range)
15
+ # 1...10 includes 1..9 but it does not include 1..10.
16
+ operator = exclude_end? && !value.exclude_end? ? :< : :<=
17
+ super(value.first) && value.last.send(operator, last)
18
+ else
19
+ super
20
+ end
21
+ end
22
+
23
+ # Extends the default Range#include? to support range comparisons.
24
+ # (1..5).include?(1..5) # => true
25
+ # (1..5).include?(2..3) # => true
26
+ # (1..5).include?(2..6) # => false
27
+ #
28
+ # The native Range#include? behavior is untouched.
29
+ # ('a'..'f').include?('c') # => true
30
+ # (5..9).include?(11) # => false
31
+ def include?(value)
32
+ if value.is_a?(::Range)
33
+ # 1...10 includes 1..9 but it does not include 1..10.
34
+ operator = exclude_end? && !value.exclude_end? ? :< : :<=
35
+ super(value.first) && value.last.send(operator, last)
36
+ else
37
+ super
38
+ end
39
+ end
40
+
41
+ # Extends the default Range#cover? to support range comparisons.
42
+ # (1..5).cover?(1..5) # => true
43
+ # (1..5).cover?(2..3) # => true
44
+ # (1..5).cover?(2..6) # => false
45
+ #
46
+ # The native Range#cover? behavior is untouched.
47
+ # ('a'..'f').cover?('c') # => true
48
+ # (5..9).cover?(11) # => false
49
+ def cover?(value)
50
+ if value.is_a?(::Range)
51
+ # 1...10 covers 1..9 but it does not cover 1..10.
52
+ operator = exclude_end? && !value.exclude_end? ? :< : :<=
53
+ super(value.first) && value.last.send(operator, last)
54
+ else
55
+ super
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ Range.prepend(ActiveSupport::CompareWithRange)
@@ -1,19 +1,39 @@
1
- class Range
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport::RangeWithFormat
2
4
  RANGE_FORMATS = {
3
- :db => Proc.new { |start, stop| "BETWEEN '#{start.to_s(:db)}' AND '#{stop.to_s(:db)}'" }
5
+ db: -> (start, stop) do
6
+ case start
7
+ when String then "BETWEEN '#{start}' AND '#{stop}'"
8
+ else
9
+ "BETWEEN '#{start.to_s(:db)}' AND '#{stop.to_s(:db)}'"
10
+ end
11
+ end
4
12
  }
5
13
 
6
- # Gives a human readable format of the range.
14
+ # Convert range to a formatted string. See RANGE_FORMATS for predefined formats.
15
+ #
16
+ # range = (1..100) # => 1..100
7
17
  #
8
- # (1..100).to_formatted_s # => "1..100"
9
- def to_formatted_s(format = :default)
18
+ # range.to_s # => "1..100"
19
+ # range.to_s(:db) # => "BETWEEN '1' AND '100'"
20
+ #
21
+ # == Adding your own range formats to to_s
22
+ # You can add your own formats to the Range::RANGE_FORMATS hash.
23
+ # Use the format name as the hash key and a Proc instance.
24
+ #
25
+ # # config/initializers/range_formats.rb
26
+ # Range::RANGE_FORMATS[:short] = ->(start, stop) { "Between #{start.to_s(:db)} and #{stop.to_s(:db)}" }
27
+ def to_s(format = :default)
10
28
  if formatter = RANGE_FORMATS[format]
11
29
  formatter.call(first, last)
12
30
  else
13
- to_default_s
31
+ super()
14
32
  end
15
33
  end
16
34
 
17
35
  alias_method :to_default_s, :to_s
18
- alias_method :to_s, :to_formatted_s
36
+ alias_method :to_formatted_s, :to_s
19
37
  end
38
+
39
+ Range.prepend(ActiveSupport::RangeWithFormat)