activesupport 4.0.13 → 5.2.5

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activesupport might be problematic. Click here for more details.

Files changed (264) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +412 -444
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +8 -4
  5. data/lib/active_support/all.rb +5 -3
  6. data/lib/active_support/array_inquirer.rb +48 -0
  7. data/lib/active_support/backtrace_cleaner.rb +14 -12
  8. data/lib/active_support/benchmarkable.rb +6 -14
  9. data/lib/active_support/builder.rb +3 -1
  10. data/lib/active_support/cache/file_store.rb +67 -51
  11. data/lib/active_support/cache/mem_cache_store.rb +95 -97
  12. data/lib/active_support/cache/memory_store.rb +28 -30
  13. data/lib/active_support/cache/null_store.rb +7 -8
  14. data/lib/active_support/cache/redis_cache_store.rb +466 -0
  15. data/lib/active_support/cache/strategy/local_cache.rb +70 -56
  16. data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
  17. data/lib/active_support/cache.rb +331 -206
  18. data/lib/active_support/callbacks.rb +697 -426
  19. data/lib/active_support/concern.rb +32 -10
  20. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +17 -0
  21. data/lib/active_support/concurrency/share_lock.rb +227 -0
  22. data/lib/active_support/configurable.rb +8 -5
  23. data/lib/active_support/core_ext/array/access.rb +39 -1
  24. data/lib/active_support/core_ext/array/conversions.rb +24 -35
  25. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  26. data/lib/active_support/core_ext/array/grouping.rb +23 -13
  27. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  28. data/lib/active_support/core_ext/array/prepend_and_append.rb +7 -5
  29. data/lib/active_support/core_ext/array/wrap.rb +7 -4
  30. data/lib/active_support/core_ext/array.rb +9 -7
  31. data/lib/active_support/core_ext/benchmark.rb +3 -1
  32. data/lib/active_support/core_ext/big_decimal/conversions.rb +9 -26
  33. data/lib/active_support/core_ext/big_decimal.rb +3 -1
  34. data/lib/active_support/core_ext/class/attribute.rb +41 -23
  35. data/lib/active_support/core_ext/class/attribute_accessors.rb +5 -169
  36. data/lib/active_support/core_ext/class/subclasses.rb +20 -8
  37. data/lib/active_support/core_ext/class.rb +4 -4
  38. data/lib/active_support/core_ext/date/acts_like.rb +3 -1
  39. data/lib/active_support/core_ext/date/blank.rb +14 -0
  40. data/lib/active_support/core_ext/date/calculations.rb +21 -9
  41. data/lib/active_support/core_ext/date/conversions.rb +32 -22
  42. data/lib/active_support/core_ext/date/zones.rb +5 -34
  43. data/lib/active_support/core_ext/date.rb +6 -4
  44. data/lib/active_support/core_ext/date_and_time/calculations.rb +199 -57
  45. data/lib/active_support/core_ext/date_and_time/compatibility.rb +16 -0
  46. data/lib/active_support/core_ext/date_and_time/zones.rb +41 -0
  47. data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
  48. data/lib/active_support/core_ext/date_time/blank.rb +14 -0
  49. data/lib/active_support/core_ext/date_time/calculations.rb +78 -37
  50. data/lib/active_support/core_ext/date_time/compatibility.rb +18 -0
  51. data/lib/active_support/core_ext/date_time/conversions.rb +19 -13
  52. data/lib/active_support/core_ext/date_time.rb +7 -4
  53. data/lib/active_support/core_ext/digest/uuid.rb +53 -0
  54. data/lib/active_support/core_ext/digest.rb +3 -0
  55. data/lib/active_support/core_ext/enumerable.rb +113 -29
  56. data/lib/active_support/core_ext/file/atomic.rb +38 -31
  57. data/lib/active_support/core_ext/file.rb +3 -1
  58. data/lib/active_support/core_ext/hash/compact.rb +29 -0
  59. data/lib/active_support/core_ext/hash/conversions.rb +71 -49
  60. data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
  61. data/lib/active_support/core_ext/hash/except.rb +12 -3
  62. data/lib/active_support/core_ext/hash/indifferent_access.rb +5 -3
  63. data/lib/active_support/core_ext/hash/keys.rb +50 -38
  64. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  65. data/lib/active_support/core_ext/hash/slice.rb +12 -6
  66. data/lib/active_support/core_ext/hash/transform_values.rb +32 -0
  67. data/lib/active_support/core_ext/hash.rb +11 -8
  68. data/lib/active_support/core_ext/integer/inflections.rb +3 -1
  69. data/lib/active_support/core_ext/integer/multiple.rb +2 -0
  70. data/lib/active_support/core_ext/integer/time.rb +11 -33
  71. data/lib/active_support/core_ext/integer.rb +5 -3
  72. data/lib/active_support/core_ext/kernel/agnostics.rb +2 -0
  73. data/lib/active_support/core_ext/kernel/concern.rb +14 -0
  74. data/lib/active_support/core_ext/kernel/reporting.rb +5 -74
  75. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  76. data/lib/active_support/core_ext/kernel.rb +6 -4
  77. data/lib/active_support/core_ext/load_error.rb +5 -21
  78. data/lib/active_support/core_ext/marshal.rb +13 -10
  79. data/lib/active_support/core_ext/module/aliasing.rb +6 -44
  80. data/lib/active_support/core_ext/module/anonymous.rb +12 -1
  81. data/lib/active_support/core_ext/module/attr_internal.rb +8 -8
  82. data/lib/active_support/core_ext/module/attribute_accessors.rb +170 -21
  83. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +150 -0
  84. data/lib/active_support/core_ext/module/concerning.rb +134 -0
  85. data/lib/active_support/core_ext/module/delegation.rb +135 -45
  86. data/lib/active_support/core_ext/module/deprecation.rb +3 -3
  87. data/lib/active_support/core_ext/module/introspection.rb +9 -25
  88. data/lib/active_support/core_ext/module/reachable.rb +5 -2
  89. data/lib/active_support/core_ext/module/redefine_method.rb +49 -0
  90. data/lib/active_support/core_ext/module/remove_method.rb +8 -3
  91. data/lib/active_support/core_ext/module.rb +14 -10
  92. data/lib/active_support/core_ext/name_error.rb +22 -2
  93. data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
  94. data/lib/active_support/core_ext/numeric/conversions.rb +79 -74
  95. data/lib/active_support/core_ext/numeric/inquiry.rb +28 -0
  96. data/lib/active_support/core_ext/numeric/time.rb +37 -50
  97. data/lib/active_support/core_ext/numeric.rb +6 -3
  98. data/lib/active_support/core_ext/object/acts_like.rb +12 -1
  99. data/lib/active_support/core_ext/object/blank.rb +70 -19
  100. data/lib/active_support/core_ext/object/conversions.rb +6 -4
  101. data/lib/active_support/core_ext/object/deep_dup.rb +19 -10
  102. data/lib/active_support/core_ext/object/duplicable.rb +100 -34
  103. data/lib/active_support/core_ext/object/inclusion.rb +18 -15
  104. data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
  105. data/lib/active_support/core_ext/object/json.rb +227 -0
  106. data/lib/active_support/core_ext/object/to_param.rb +3 -1
  107. data/lib/active_support/core_ext/object/to_query.rb +21 -8
  108. data/lib/active_support/core_ext/object/try.rb +94 -24
  109. data/lib/active_support/core_ext/object/with_options.rb +45 -5
  110. data/lib/active_support/core_ext/object.rb +14 -12
  111. data/lib/active_support/core_ext/range/compare_range.rb +61 -0
  112. data/lib/active_support/core_ext/range/conversions.rb +27 -7
  113. data/lib/active_support/core_ext/range/each.rb +19 -17
  114. data/lib/active_support/core_ext/range/include_range.rb +2 -22
  115. data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
  116. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  117. data/lib/active_support/core_ext/range.rb +7 -4
  118. data/lib/active_support/core_ext/regexp.rb +6 -0
  119. data/lib/active_support/core_ext/securerandom.rb +25 -0
  120. data/lib/active_support/core_ext/string/access.rb +41 -39
  121. data/lib/active_support/core_ext/string/behavior.rb +3 -1
  122. data/lib/active_support/core_ext/string/conversions.rb +17 -13
  123. data/lib/active_support/core_ext/string/exclude.rb +5 -3
  124. data/lib/active_support/core_ext/string/filters.rb +55 -6
  125. data/lib/active_support/core_ext/string/indent.rb +6 -4
  126. data/lib/active_support/core_ext/string/inflections.rb +66 -24
  127. data/lib/active_support/core_ext/string/inquiry.rb +3 -1
  128. data/lib/active_support/core_ext/string/multibyte.rb +15 -7
  129. data/lib/active_support/core_ext/string/output_safety.rb +114 -54
  130. data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
  131. data/lib/active_support/core_ext/string/strip.rb +4 -5
  132. data/lib/active_support/core_ext/string/zones.rb +4 -1
  133. data/lib/active_support/core_ext/string.rb +15 -13
  134. data/lib/active_support/core_ext/time/acts_like.rb +3 -1
  135. data/lib/active_support/core_ext/time/calculations.rb +123 -110
  136. data/lib/active_support/core_ext/time/compatibility.rb +16 -0
  137. data/lib/active_support/core_ext/time/conversions.rb +23 -14
  138. data/lib/active_support/core_ext/time/zones.rb +42 -26
  139. data/lib/active_support/core_ext/time.rb +7 -5
  140. data/lib/active_support/core_ext/uri.rb +6 -8
  141. data/lib/active_support/core_ext.rb +3 -2
  142. data/lib/active_support/current_attributes.rb +195 -0
  143. data/lib/active_support/dependencies/autoload.rb +3 -1
  144. data/lib/active_support/dependencies/interlock.rb +57 -0
  145. data/lib/active_support/dependencies.rb +196 -166
  146. data/lib/active_support/deprecation/behaviors.rb +48 -15
  147. data/lib/active_support/deprecation/constant_accessor.rb +52 -0
  148. data/lib/active_support/deprecation/instance_delegator.rb +17 -2
  149. data/lib/active_support/deprecation/method_wrappers.rb +66 -20
  150. data/lib/active_support/deprecation/proxy_wrappers.rb +56 -28
  151. data/lib/active_support/deprecation/reporting.rb +32 -12
  152. data/lib/active_support/deprecation.rb +14 -11
  153. data/lib/active_support/descendants_tracker.rb +2 -0
  154. data/lib/active_support/digest.rb +20 -0
  155. data/lib/active_support/duration/iso8601_parser.rb +125 -0
  156. data/lib/active_support/duration/iso8601_serializer.rb +55 -0
  157. data/lib/active_support/duration.rb +354 -34
  158. data/lib/active_support/encrypted_configuration.rb +49 -0
  159. data/lib/active_support/encrypted_file.rb +99 -0
  160. data/lib/active_support/evented_file_update_checker.rb +205 -0
  161. data/lib/active_support/execution_wrapper.rb +128 -0
  162. data/lib/active_support/executor.rb +8 -0
  163. data/lib/active_support/file_update_checker.rb +63 -37
  164. data/lib/active_support/gem_version.rb +17 -0
  165. data/lib/active_support/gzip.rb +7 -5
  166. data/lib/active_support/hash_with_indifferent_access.rb +158 -35
  167. data/lib/active_support/i18n.rb +8 -6
  168. data/lib/active_support/i18n_railtie.rb +38 -20
  169. data/lib/active_support/inflections.rb +19 -12
  170. data/lib/active_support/inflector/inflections.rb +79 -30
  171. data/lib/active_support/inflector/methods.rb +197 -129
  172. data/lib/active_support/inflector/transliterate.rb +48 -27
  173. data/lib/active_support/inflector.rb +7 -5
  174. data/lib/active_support/json/decoding.rb +21 -25
  175. data/lib/active_support/json/encoding.rb +84 -292
  176. data/lib/active_support/json.rb +4 -2
  177. data/lib/active_support/key_generator.rb +26 -28
  178. data/lib/active_support/lazy_load_hooks.rb +51 -21
  179. data/lib/active_support/locale/en.yml +2 -0
  180. data/lib/active_support/log_subscriber/test_helper.rb +14 -12
  181. data/lib/active_support/log_subscriber.rb +13 -10
  182. data/lib/active_support/logger.rb +54 -3
  183. data/lib/active_support/logger_silence.rb +12 -7
  184. data/lib/active_support/logger_thread_safe_level.rb +34 -0
  185. data/lib/active_support/message_encryptor.rb +173 -50
  186. data/lib/active_support/message_verifier.rb +159 -22
  187. data/lib/active_support/messages/metadata.rb +71 -0
  188. data/lib/active_support/messages/rotation_configuration.rb +22 -0
  189. data/lib/active_support/messages/rotator.rb +56 -0
  190. data/lib/active_support/multibyte/chars.rb +38 -26
  191. data/lib/active_support/multibyte/unicode.rb +138 -146
  192. data/lib/active_support/multibyte.rb +4 -2
  193. data/lib/active_support/notifications/fanout.rb +23 -16
  194. data/lib/active_support/notifications/instrumenter.rb +29 -8
  195. data/lib/active_support/notifications.rb +22 -13
  196. data/lib/active_support/number_helper/number_converter.rb +184 -0
  197. data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
  198. data/lib/active_support/number_helper/number_to_delimited_converter.rb +29 -0
  199. data/lib/active_support/number_helper/number_to_human_converter.rb +68 -0
  200. data/lib/active_support/number_helper/number_to_human_size_converter.rb +59 -0
  201. data/lib/active_support/number_helper/number_to_percentage_converter.rb +14 -0
  202. data/lib/active_support/number_helper/number_to_phone_converter.rb +58 -0
  203. data/lib/active_support/number_helper/number_to_rounded_converter.rb +54 -0
  204. data/lib/active_support/number_helper/rounding_helper.rb +66 -0
  205. data/lib/active_support/number_helper.rb +125 -391
  206. data/lib/active_support/option_merger.rb +3 -1
  207. data/lib/active_support/ordered_hash.rb +6 -4
  208. data/lib/active_support/ordered_options.rb +31 -5
  209. data/lib/active_support/per_thread_registry.rb +19 -11
  210. data/lib/active_support/proxy_object.rb +2 -0
  211. data/lib/active_support/rails.rb +16 -8
  212. data/lib/active_support/railtie.rb +43 -9
  213. data/lib/active_support/reloader.rb +131 -0
  214. data/lib/active_support/rescuable.rb +108 -53
  215. data/lib/active_support/security_utils.rb +31 -0
  216. data/lib/active_support/string_inquirer.rb +11 -3
  217. data/lib/active_support/subscriber.rb +54 -17
  218. data/lib/active_support/tagged_logging.rb +14 -11
  219. data/lib/active_support/test_case.rb +42 -37
  220. data/lib/active_support/testing/assertions.rb +126 -39
  221. data/lib/active_support/testing/autorun.rb +5 -3
  222. data/lib/active_support/testing/constant_lookup.rb +3 -6
  223. data/lib/active_support/testing/declarative.rb +10 -22
  224. data/lib/active_support/testing/deprecation.rb +14 -10
  225. data/lib/active_support/testing/file_fixtures.rb +36 -0
  226. data/lib/active_support/testing/isolation.rb +55 -86
  227. data/lib/active_support/testing/method_call_assertions.rb +43 -0
  228. data/lib/active_support/testing/setup_and_teardown.rb +30 -10
  229. data/lib/active_support/testing/stream.rb +44 -0
  230. data/lib/active_support/testing/tagged_logging.rb +5 -3
  231. data/lib/active_support/testing/time_helpers.rb +200 -0
  232. data/lib/active_support/time.rb +13 -13
  233. data/lib/active_support/time_with_zone.rb +223 -73
  234. data/lib/active_support/values/time_zone.rb +261 -126
  235. data/lib/active_support/values/unicode_tables.dat +0 -0
  236. data/lib/active_support/version.rb +6 -7
  237. data/lib/active_support/xml_mini/jdom.rb +116 -113
  238. data/lib/active_support/xml_mini/libxml.rb +17 -16
  239. data/lib/active_support/xml_mini/libxmlsax.rb +16 -18
  240. data/lib/active_support/xml_mini/nokogiri.rb +15 -15
  241. data/lib/active_support/xml_mini/nokogirisax.rb +15 -16
  242. data/lib/active_support/xml_mini/rexml.rb +17 -16
  243. data/lib/active_support/xml_mini.rb +69 -51
  244. data/lib/active_support.rb +29 -3
  245. metadata +84 -54
  246. data/lib/active_support/basic_object.rb +0 -11
  247. data/lib/active_support/buffered_logger.rb +0 -21
  248. data/lib/active_support/concurrency/latch.rb +0 -27
  249. data/lib/active_support/core_ext/array/uniq_by.rb +0 -19
  250. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -40
  251. data/lib/active_support/core_ext/date_time/zones.rb +0 -24
  252. data/lib/active_support/core_ext/hash/diff.rb +0 -14
  253. data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
  254. data/lib/active_support/core_ext/logger.rb +0 -67
  255. data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
  256. data/lib/active_support/core_ext/object/to_json.rb +0 -27
  257. data/lib/active_support/core_ext/proc.rb +0 -17
  258. data/lib/active_support/core_ext/string/encoding.rb +0 -8
  259. data/lib/active_support/core_ext/struct.rb +0 -6
  260. data/lib/active_support/core_ext/thread.rb +0 -79
  261. data/lib/active_support/core_ext/time/marshal.rb +0 -30
  262. data/lib/active_support/file_watcher.rb +0 -36
  263. data/lib/active_support/json/variable.rb +0 -18
  264. data/lib/active_support/testing/pending.rb +0 -14
@@ -1,4 +1,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
@@ -8,8 +10,8 @@ class Object
8
10
  # dup = object.deep_dup
9
11
  # dup.instance_variable_set(:@a, 1)
10
12
  #
11
- # object.instance_variable_defined?(:@a) #=> false
12
- # dup.instance_variable_defined?(:@a) #=> true
13
+ # object.instance_variable_defined?(:@a) # => false
14
+ # dup.instance_variable_defined?(:@a) # => true
13
15
  def deep_dup
14
16
  duplicable? ? dup : self
15
17
  end
@@ -22,10 +24,10 @@ class Array
22
24
  # dup = array.deep_dup
23
25
  # dup[1][2] = 4
24
26
  #
25
- # array[1][2] #=> nil
26
- # dup[1][2] #=> 4
27
+ # array[1][2] # => nil
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
 
@@ -36,11 +38,18 @@ class Hash
36
38
  # dup = hash.deep_dup
37
39
  # dup[:a][:c] = 'c'
38
40
  #
39
- # hash[:a][:c] #=> nil
40
- # dup[:a][:c] #=> "c"
41
+ # hash[:a][:c] # => nil
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,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #--
2
- # Most objects are cloneable, but not all. For example you can't dup +nil+:
4
+ # Most objects are cloneable, but not all. For example you can't dup methods:
3
5
  #
4
- # nil.dup # => TypeError: can't dup NilClass
6
+ # method(:puts).dup # => TypeError: allocator undefined for Method
5
7
  #
6
8
  # Classes may signal their instances are not duplicable removing +dup+/+clone+
7
9
  # or raising exceptions from them. So, to dup an arbitrary object you normally
@@ -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, and number objects;
24
+ # False for method objects;
23
25
  # true otherwise.
24
26
  def duplicable?
25
27
  true
@@ -27,64 +29,128 @@ class Object
27
29
  end
28
30
 
29
31
  class NilClass
30
- # +nil+ is not duplicable:
31
- #
32
- # nil.duplicable? # => false
33
- # nil.dup # => TypeError: can't dup NilClass
34
- def duplicable?
35
- false
32
+ begin
33
+ nil.dup
34
+ rescue TypeError
35
+
36
+ # +nil+ is not duplicable:
37
+ #
38
+ # nil.duplicable? # => false
39
+ # nil.dup # => TypeError: can't dup NilClass
40
+ def duplicable?
41
+ false
42
+ end
36
43
  end
37
44
  end
38
45
 
39
46
  class FalseClass
40
- # +false+ is not duplicable:
41
- #
42
- # false.duplicable? # => false
43
- # false.dup # => TypeError: can't dup FalseClass
44
- def duplicable?
45
- false
47
+ begin
48
+ false.dup
49
+ rescue TypeError
50
+
51
+ # +false+ is not duplicable:
52
+ #
53
+ # false.duplicable? # => false
54
+ # false.dup # => TypeError: can't dup FalseClass
55
+ def duplicable?
56
+ false
57
+ end
46
58
  end
47
59
  end
48
60
 
49
61
  class TrueClass
50
- # +true+ is not duplicable:
51
- #
52
- # true.duplicable? # => false
53
- # true.dup # => TypeError: can't dup TrueClass
54
- def duplicable?
55
- false
62
+ begin
63
+ true.dup
64
+ rescue TypeError
65
+
66
+ # +true+ is not duplicable:
67
+ #
68
+ # true.duplicable? # => false
69
+ # true.dup # => TypeError: can't dup TrueClass
70
+ def duplicable?
71
+ false
72
+ end
56
73
  end
57
74
  end
58
75
 
59
76
  class Symbol
60
- # Symbols are not duplicable:
77
+ begin
78
+ :symbol.dup # Ruby 2.4.x.
79
+ "symbol_from_string".to_sym.dup # Some symbols can't `dup` in Ruby 2.4.0.
80
+ rescue TypeError
81
+
82
+ # Symbols are not duplicable:
83
+ #
84
+ # :my_symbol.duplicable? # => false
85
+ # :my_symbol.dup # => TypeError: can't dup Symbol
86
+ def duplicable?
87
+ false
88
+ end
89
+ end
90
+ end
91
+
92
+ class Numeric
93
+ begin
94
+ 1.dup
95
+ rescue TypeError
96
+
97
+ # Numbers are not duplicable:
98
+ #
99
+ # 3.duplicable? # => false
100
+ # 3.dup # => TypeError: can't dup Integer
101
+ def duplicable?
102
+ false
103
+ end
104
+ end
105
+ end
106
+
107
+ require "bigdecimal"
108
+ class BigDecimal
109
+ # BigDecimals are duplicable:
61
110
  #
62
- # :my_symbol.duplicable? # => false
63
- # :my_symbol.dup # => TypeError: can't dup Symbol
111
+ # BigDecimal("1.2").duplicable? # => true
112
+ # BigDecimal("1.2").dup # => #<BigDecimal:...,'0.12E1',18(18)>
64
113
  def duplicable?
65
- false
114
+ true
66
115
  end
67
116
  end
68
117
 
69
- class Numeric
70
- # Numbers are not duplicable:
118
+ class Method
119
+ # Methods are not duplicable:
71
120
  #
72
- # 3.duplicable? # => false
73
- # 3.dup # => TypeError: can't dup Fixnum
121
+ # method(:puts).duplicable? # => false
122
+ # method(:puts).dup # => TypeError: allocator undefined for Method
74
123
  def duplicable?
75
124
  false
76
125
  end
77
126
  end
78
127
 
79
- require 'bigdecimal'
80
- class BigDecimal
128
+ class Complex
81
129
  begin
82
- BigDecimal.new('4.56').dup
130
+ Complex(1).dup
131
+ rescue TypeError
83
132
 
133
+ # Complexes are not duplicable:
134
+ #
135
+ # Complex(1).duplicable? # => false
136
+ # Complex(1).dup # => TypeError: can't copy Complex
84
137
  def duplicable?
85
- true
138
+ false
86
139
  end
140
+ end
141
+ end
142
+
143
+ class Rational
144
+ begin
145
+ Rational(1).dup
87
146
  rescue TypeError
88
- # can't dup, so use superclass implementation
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
89
155
  end
90
156
  end
@@ -1,4 +1,4 @@
1
- require 'active_support/deprecation'
1
+ # frozen_string_literal: true
2
2
 
3
3
  class Object
4
4
  # Returns true if this object is included in the argument. Argument must be
@@ -7,20 +7,23 @@ class Object
7
7
  # characters = ["Konata", "Kagami", "Tsukasa"]
8
8
  # "Konata".in?(characters) # => true
9
9
  #
10
- # This will throw an ArgumentError if the argument doesn't respond
10
+ # This will throw an +ArgumentError+ if the argument doesn't respond
11
11
  # to +#include?+.
12
- def in?(*args)
13
- if args.length > 1
14
- ActiveSupport::Deprecation.warn "Calling #in? with multiple arguments is" \
15
- " deprecated, please pass in an object that responds to #include? instead."
16
- args.include? self
17
- else
18
- another_object = args.first
19
- if another_object.respond_to? :include?
20
- another_object.include? self
21
- else
22
- raise ArgumentError.new 'The single parameter passed to #in? must respond to #include?'
23
- end
24
- end
12
+ def in?(another_object)
13
+ another_object.include?(self)
14
+ rescue NoMethodError
15
+ raise ArgumentError.new("The parameter passed to #in? must respond to #include?")
16
+ end
17
+
18
+ # Returns the receiver if it's included in the argument otherwise returns +nil+.
19
+ # Argument must be any object which responds to +#include?+. Usage:
20
+ #
21
+ # params[:bucket_type].presence_in %w( project calendar )
22
+ #
23
+ # This will throw an +ArgumentError+ if the argument doesn't respond to +#include?+.
24
+ #
25
+ # @return [Object]
26
+ def presence_in(another_object)
27
+ in?(another_object) ? self : nil
25
28
  end
26
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
@@ -0,0 +1,227 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Hack to load json gem first so we can overwrite its to_json.
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"
16
+
17
+ # The JSON gem adds a few modules to Ruby core classes containing :to_json definition, overwriting
18
+ # their default behavior. That said, we need to define the basic to_json method in all of them,
19
+ # otherwise they will always use to_json gem implementation, which is backwards incompatible in
20
+ # several cases (for instance, the JSON implementation for Hash does not work) with inheritance
21
+ # and consequently classes as ActiveSupport::OrderedHash cannot be serialized to json.
22
+ #
23
+ # On the other hand, we should avoid conflict with ::JSON.{generate,dump}(obj). Unfortunately, the
24
+ # JSON gem's encoder relies on its own to_json implementation to encode objects. Since it always
25
+ # passes a ::JSON::State object as the only argument to to_json, we can detect that and forward the
26
+ # calls to the original to_json method.
27
+ #
28
+ # It should be noted that when using ::JSON.{generate,dump} directly, ActiveSupport's encoder is
29
+ # bypassed completely. This means that as_json won't be invoked and the JSON gem will simply
30
+ # ignore any options it does not natively understand. This also means that ::JSON.{generate,dump}
31
+ # should give exactly the same results with or without active support.
32
+
33
+ module ActiveSupport
34
+ module ToJsonWithActiveSupportEncoder # :nodoc:
35
+ def to_json(options = nil)
36
+ if options.is_a?(::JSON::State)
37
+ # Called from JSON.{generate,dump}, forward it to JSON gem's to_json
38
+ super(options)
39
+ else
40
+ # to_json is being invoked directly, use ActiveSupport's encoder
41
+ ActiveSupport::JSON.encode(self, options)
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ [Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass, Enumerable].reverse_each do |klass|
48
+ klass.prepend(ActiveSupport::ToJsonWithActiveSupportEncoder)
49
+ end
50
+
51
+ class Object
52
+ def as_json(options = nil) #:nodoc:
53
+ if respond_to?(:to_hash)
54
+ to_hash.as_json(options)
55
+ else
56
+ instance_values.as_json(options)
57
+ end
58
+ end
59
+ end
60
+
61
+ class Struct #:nodoc:
62
+ def as_json(options = nil)
63
+ Hash[members.zip(values)].as_json(options)
64
+ end
65
+ end
66
+
67
+ class TrueClass
68
+ def as_json(options = nil) #:nodoc:
69
+ self
70
+ end
71
+ end
72
+
73
+ class FalseClass
74
+ def as_json(options = nil) #:nodoc:
75
+ self
76
+ end
77
+ end
78
+
79
+ class NilClass
80
+ def as_json(options = nil) #:nodoc:
81
+ self
82
+ end
83
+ end
84
+
85
+ class String
86
+ def as_json(options = nil) #:nodoc:
87
+ self
88
+ end
89
+ end
90
+
91
+ class Symbol
92
+ def as_json(options = nil) #:nodoc:
93
+ to_s
94
+ end
95
+ end
96
+
97
+ class Numeric
98
+ def as_json(options = nil) #:nodoc:
99
+ self
100
+ end
101
+ end
102
+
103
+ class Float
104
+ # Encoding Infinity or NaN to JSON should return "null". The default returns
105
+ # "Infinity" or "NaN" which are not valid JSON.
106
+ def as_json(options = nil) #:nodoc:
107
+ finite? ? self : nil
108
+ end
109
+ end
110
+
111
+ class BigDecimal
112
+ # A BigDecimal would be naturally represented as a JSON number. Most libraries,
113
+ # however, parse non-integer JSON numbers directly as floats. Clients using
114
+ # those libraries would get in general a wrong number and no way to recover
115
+ # other than manually inspecting the string with the JSON code itself.
116
+ #
117
+ # That's why a JSON string is returned. The JSON literal is not numeric, but
118
+ # if the other end knows by contract that the data is supposed to be a
119
+ # BigDecimal, it still has the chance to post-process the string and get the
120
+ # real value.
121
+ def as_json(options = nil) #:nodoc:
122
+ finite? ? to_s : nil
123
+ end
124
+ end
125
+
126
+ class Regexp
127
+ def as_json(options = nil) #:nodoc:
128
+ to_s
129
+ end
130
+ end
131
+
132
+ module Enumerable
133
+ def as_json(options = nil) #:nodoc:
134
+ to_a.as_json(options)
135
+ end
136
+ end
137
+
138
+ class IO
139
+ def as_json(options = nil) #:nodoc:
140
+ to_s
141
+ end
142
+ end
143
+
144
+ class Range
145
+ def as_json(options = nil) #:nodoc:
146
+ to_s
147
+ end
148
+ end
149
+
150
+ class Array
151
+ def as_json(options = nil) #:nodoc:
152
+ map { |v| options ? v.as_json(options.dup) : v.as_json }
153
+ end
154
+ end
155
+
156
+ class Hash
157
+ def as_json(options = nil) #:nodoc:
158
+ # create a subset of the hash by applying :only or :except
159
+ subset = if options
160
+ if attrs = options[:only]
161
+ slice(*Array(attrs))
162
+ elsif attrs = options[:except]
163
+ except(*Array(attrs))
164
+ else
165
+ self
166
+ end
167
+ else
168
+ self
169
+ end
170
+
171
+ Hash[subset.map { |k, v| [k.to_s, options ? v.as_json(options.dup) : v.as_json] }]
172
+ end
173
+ end
174
+
175
+ class Time
176
+ def as_json(options = nil) #:nodoc:
177
+ if ActiveSupport::JSON::Encoding.use_standard_json_time_format
178
+ xmlschema(ActiveSupport::JSON::Encoding.time_precision)
179
+ else
180
+ %(#{strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)})
181
+ end
182
+ end
183
+ end
184
+
185
+ class Date
186
+ def as_json(options = nil) #:nodoc:
187
+ if ActiveSupport::JSON::Encoding.use_standard_json_time_format
188
+ strftime("%Y-%m-%d")
189
+ else
190
+ strftime("%Y/%m/%d")
191
+ end
192
+ end
193
+ end
194
+
195
+ class DateTime
196
+ def as_json(options = nil) #:nodoc:
197
+ if ActiveSupport::JSON::Encoding.use_standard_json_time_format
198
+ xmlschema(ActiveSupport::JSON::Encoding.time_precision)
199
+ else
200
+ strftime("%Y/%m/%d %H:%M:%S %z")
201
+ end
202
+ end
203
+ end
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
+
217
+ class Process::Status #:nodoc:
218
+ def as_json(options = nil)
219
+ { exitstatus: exitstatus, pid: pid }
220
+ end
221
+ end
222
+
223
+ class Exception
224
+ def as_json(options = nil)
225
+ to_s
226
+ end
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,3 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cgi"
4
+
1
5
  class Object
2
6
  # Alias of <tt>to_s</tt>.
3
7
  def to_param
@@ -7,7 +11,6 @@ class Object
7
11
  # Converts an object into a string suitable for use as a URL query string,
8
12
  # using the given <tt>key</tt> as the param name.
9
13
  def to_query(key)
10
- require 'cgi' unless defined?(CGI) && defined?(CGI::escape)
11
14
  "#{CGI.escape(key.to_param)}=#{CGI.escape(to_param.to_s)}"
12
15
  end
13
16
  end
@@ -37,7 +40,7 @@ class Array
37
40
  # Calls <tt>to_param</tt> on all its elements and joins the result with
38
41
  # slashes. This is used by <tt>url_for</tt> in Action Pack.
39
42
  def to_param
40
- collect { |e| e.to_param }.join '/'
43
+ collect(&:to_param).join "/"
41
44
  end
42
45
 
43
46
  # Converts an array into a string suitable for use as a URL query string,
@@ -46,7 +49,12 @@ class Array
46
49
  # ['Rails', 'coding'].to_query('hobbies') # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding"
47
50
  def to_query(key)
48
51
  prefix = "#{key}[]"
49
- collect { |value| value.to_query(prefix) }.join '&'
52
+
53
+ if empty?
54
+ nil.to_query(prefix)
55
+ else
56
+ collect { |value| value.to_query(prefix) }.join "&"
57
+ end
50
58
  end
51
59
  end
52
60
 
@@ -57,19 +65,24 @@ class Hash
57
65
  # {name: 'David', nationality: 'Danish'}.to_query
58
66
  # # => "name=David&nationality=Danish"
59
67
  #
60
- # An optional namespace can be passed to enclose the param names:
68
+ # An optional namespace can be passed to enclose key names:
61
69
  #
62
70
  # {name: 'David', nationality: 'Danish'}.to_query('user')
63
- # # => "user[name]=David&user[nationality]=Danish"
71
+ # # => "user%5Bname%5D=David&user%5Bnationality%5D=Danish"
64
72
  #
65
73
  # The string pairs "key=value" that conform the query string
66
74
  # are sorted lexicographically in ascending order.
67
75
  #
68
76
  # This method is also aliased as +to_param+.
69
77
  def to_query(namespace = nil)
70
- collect do |key, value|
71
- value.to_query(namespace ? "#{namespace}[#{key}]" : key)
72
- end.sort * '&'
78
+ query = collect do |key, value|
79
+ unless (value.is_a?(Hash) || value.is_a?(Array)) && value.empty?
80
+ value.to_query(namespace ? "#{namespace}[#{key}]" : key)
81
+ end
82
+ end.compact
83
+
84
+ query.sort! unless namespace.to_s.include?("[]")
85
+ query.join("&")
73
86
  end
74
87
 
75
88
  alias_method :to_param, :to_query