activesupport 4.0.12 → 7.0.2.4

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 (295) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +249 -501
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +10 -5
  5. data/lib/active_support/actionable_error.rb +48 -0
  6. data/lib/active_support/all.rb +5 -3
  7. data/lib/active_support/array_inquirer.rb +48 -0
  8. data/lib/active_support/backtrace_cleaner.rb +41 -13
  9. data/lib/active_support/benchmarkable.rb +7 -15
  10. data/lib/active_support/builder.rb +3 -1
  11. data/lib/active_support/cache/file_store.rb +96 -74
  12. data/lib/active_support/cache/mem_cache_store.rb +211 -103
  13. data/lib/active_support/cache/memory_store.rb +90 -58
  14. data/lib/active_support/cache/null_store.rb +19 -7
  15. data/lib/active_support/cache/redis_cache_store.rb +468 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +86 -83
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
  18. data/lib/active_support/cache.rb +580 -241
  19. data/lib/active_support/callbacks.rb +812 -425
  20. data/lib/active_support/code_generator.rb +65 -0
  21. data/lib/active_support/concern.rb +103 -14
  22. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +33 -0
  23. data/lib/active_support/concurrency/share_lock.rb +226 -0
  24. data/lib/active_support/configurable.rb +21 -19
  25. data/lib/active_support/configuration_file.rb +51 -0
  26. data/lib/active_support/core_ext/array/access.rb +47 -1
  27. data/lib/active_support/core_ext/array/conversions.rb +35 -44
  28. data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
  29. data/lib/active_support/core_ext/array/extract.rb +21 -0
  30. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  31. data/lib/active_support/core_ext/array/grouping.rb +26 -16
  32. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  33. data/lib/active_support/core_ext/array/wrap.rb +7 -4
  34. data/lib/active_support/core_ext/array.rb +10 -7
  35. data/lib/active_support/core_ext/benchmark.rb +5 -3
  36. data/lib/active_support/core_ext/big_decimal/conversions.rb +9 -26
  37. data/lib/active_support/core_ext/big_decimal.rb +3 -1
  38. data/lib/active_support/core_ext/class/attribute.rb +52 -49
  39. data/lib/active_support/core_ext/class/attribute_accessors.rb +5 -169
  40. data/lib/active_support/core_ext/class/subclasses.rb +25 -26
  41. data/lib/active_support/core_ext/class.rb +4 -4
  42. data/lib/active_support/core_ext/date/acts_like.rb +3 -1
  43. data/lib/active_support/core_ext/date/blank.rb +14 -0
  44. data/lib/active_support/core_ext/date/calculations.rb +31 -18
  45. data/lib/active_support/core_ext/date/conversions.rb +43 -32
  46. data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
  47. data/lib/active_support/core_ext/date/zones.rb +5 -34
  48. data/lib/active_support/core_ext/date.rb +7 -4
  49. data/lib/active_support/core_ext/date_and_time/calculations.rb +198 -66
  50. data/lib/active_support/core_ext/date_and_time/compatibility.rb +31 -0
  51. data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
  52. data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
  53. data/lib/active_support/core_ext/date_time/blank.rb +14 -0
  54. data/lib/active_support/core_ext/date_time/calculations.rb +79 -38
  55. data/lib/active_support/core_ext/date_time/compatibility.rb +18 -0
  56. data/lib/active_support/core_ext/date_time/conversions.rb +31 -26
  57. data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
  58. data/lib/active_support/core_ext/date_time.rb +8 -4
  59. data/lib/active_support/core_ext/digest/uuid.rb +79 -0
  60. data/lib/active_support/core_ext/digest.rb +3 -0
  61. data/lib/active_support/core_ext/enumerable.rb +249 -17
  62. data/lib/active_support/core_ext/file/atomic.rb +41 -32
  63. data/lib/active_support/core_ext/file.rb +3 -1
  64. data/lib/active_support/core_ext/hash/conversions.rb +71 -49
  65. data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
  66. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  67. data/lib/active_support/core_ext/hash/except.rb +14 -5
  68. data/lib/active_support/core_ext/hash/indifferent_access.rb +5 -3
  69. data/lib/active_support/core_ext/hash/keys.rb +39 -56
  70. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  71. data/lib/active_support/core_ext/hash/slice.rb +8 -23
  72. data/lib/active_support/core_ext/hash.rb +10 -8
  73. data/lib/active_support/core_ext/integer/inflections.rb +3 -1
  74. data/lib/active_support/core_ext/integer/multiple.rb +3 -1
  75. data/lib/active_support/core_ext/integer/time.rb +11 -33
  76. data/lib/active_support/core_ext/integer.rb +5 -3
  77. data/lib/active_support/core_ext/kernel/concern.rb +14 -0
  78. data/lib/active_support/core_ext/kernel/reporting.rb +9 -78
  79. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  80. data/lib/active_support/core_ext/kernel.rb +5 -4
  81. data/lib/active_support/core_ext/load_error.rb +5 -21
  82. data/lib/active_support/core_ext/module/aliasing.rb +6 -44
  83. data/lib/active_support/core_ext/module/anonymous.rb +12 -1
  84. data/lib/active_support/core_ext/module/attr_internal.rb +8 -8
  85. data/lib/active_support/core_ext/module/attribute_accessors.rb +186 -44
  86. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +157 -0
  87. data/lib/active_support/core_ext/module/concerning.rb +140 -0
  88. data/lib/active_support/core_ext/module/delegation.rb +172 -45
  89. data/lib/active_support/core_ext/module/deprecation.rb +3 -3
  90. data/lib/active_support/core_ext/module/introspection.rb +23 -38
  91. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  92. data/lib/active_support/core_ext/module/remove_method.rb +8 -3
  93. data/lib/active_support/core_ext/module.rb +13 -10
  94. data/lib/active_support/core_ext/name_error.rb +45 -4
  95. data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
  96. data/lib/active_support/core_ext/numeric/conversions.rb +135 -127
  97. data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
  98. data/lib/active_support/core_ext/numeric/time.rb +37 -50
  99. data/lib/active_support/core_ext/numeric.rb +6 -3
  100. data/lib/active_support/core_ext/object/acts_like.rb +41 -6
  101. data/lib/active_support/core_ext/object/blank.rb +70 -20
  102. data/lib/active_support/core_ext/object/conversions.rb +6 -4
  103. data/lib/active_support/core_ext/object/deep_dup.rb +19 -10
  104. data/lib/active_support/core_ext/object/duplicable.rb +17 -47
  105. data/lib/active_support/core_ext/object/inclusion.rb +18 -15
  106. data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
  107. data/lib/active_support/core_ext/object/json.rb +244 -0
  108. data/lib/active_support/core_ext/object/to_param.rb +3 -1
  109. data/lib/active_support/core_ext/object/to_query.rb +21 -8
  110. data/lib/active_support/core_ext/object/try.rb +106 -26
  111. data/lib/active_support/core_ext/object/with_options.rb +64 -5
  112. data/lib/active_support/core_ext/object.rb +14 -12
  113. data/lib/active_support/core_ext/pathname/existence.rb +21 -0
  114. data/lib/active_support/core_ext/pathname.rb +3 -0
  115. data/lib/active_support/core_ext/range/compare_range.rb +57 -0
  116. data/lib/active_support/core_ext/range/conversions.rb +37 -15
  117. data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
  118. data/lib/active_support/core_ext/range/each.rb +18 -17
  119. data/lib/active_support/core_ext/range/include_time_with_zone.rb +7 -0
  120. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  121. data/lib/active_support/core_ext/range.rb +7 -4
  122. data/lib/active_support/core_ext/regexp.rb +10 -1
  123. data/lib/active_support/core_ext/securerandom.rb +45 -0
  124. data/lib/active_support/core_ext/string/access.rb +42 -51
  125. data/lib/active_support/core_ext/string/behavior.rb +3 -1
  126. data/lib/active_support/core_ext/string/conversions.rb +18 -13
  127. data/lib/active_support/core_ext/string/exclude.rb +5 -3
  128. data/lib/active_support/core_ext/string/filters.rb +97 -7
  129. data/lib/active_support/core_ext/string/indent.rb +6 -4
  130. data/lib/active_support/core_ext/string/inflections.rb +106 -25
  131. data/lib/active_support/core_ext/string/inquiry.rb +4 -1
  132. data/lib/active_support/core_ext/string/multibyte.rb +18 -9
  133. data/lib/active_support/core_ext/string/output_safety.rb +227 -54
  134. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
  135. data/lib/active_support/core_ext/string/strip.rb +6 -5
  136. data/lib/active_support/core_ext/string/zones.rb +4 -1
  137. data/lib/active_support/core_ext/string.rb +15 -13
  138. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
  139. data/lib/active_support/core_ext/symbol.rb +3 -0
  140. data/lib/active_support/core_ext/time/acts_like.rb +3 -1
  141. data/lib/active_support/core_ext/time/calculations.rb +178 -116
  142. data/lib/active_support/core_ext/time/compatibility.rb +16 -0
  143. data/lib/active_support/core_ext/time/conversions.rb +37 -25
  144. data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
  145. data/lib/active_support/core_ext/time/zones.rb +44 -42
  146. data/lib/active_support/core_ext/time.rb +8 -5
  147. data/lib/active_support/core_ext/uri.rb +4 -25
  148. data/lib/active_support/core_ext.rb +4 -2
  149. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  150. data/lib/active_support/current_attributes.rb +226 -0
  151. data/lib/active_support/dependencies/autoload.rb +3 -1
  152. data/lib/active_support/dependencies/interlock.rb +49 -0
  153. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  154. data/lib/active_support/dependencies.rb +71 -696
  155. data/lib/active_support/deprecation/behaviors.rb +65 -16
  156. data/lib/active_support/deprecation/constant_accessor.rb +52 -0
  157. data/lib/active_support/deprecation/disallowed.rb +56 -0
  158. data/lib/active_support/deprecation/instance_delegator.rb +16 -2
  159. data/lib/active_support/deprecation/method_wrappers.rb +62 -21
  160. data/lib/active_support/deprecation/proxy_wrappers.rb +82 -31
  161. data/lib/active_support/deprecation/reporting.rb +81 -18
  162. data/lib/active_support/deprecation.rb +19 -11
  163. data/lib/active_support/descendants_tracker.rb +192 -34
  164. data/lib/active_support/digest.rb +22 -0
  165. data/lib/active_support/duration/iso8601_parser.rb +123 -0
  166. data/lib/active_support/duration/iso8601_serializer.rb +67 -0
  167. data/lib/active_support/duration.rb +437 -39
  168. data/lib/active_support/encrypted_configuration.rb +56 -0
  169. data/lib/active_support/encrypted_file.rb +117 -0
  170. data/lib/active_support/environment_inquirer.rb +20 -0
  171. data/lib/active_support/error_reporter.rb +117 -0
  172. data/lib/active_support/evented_file_update_checker.rb +170 -0
  173. data/lib/active_support/execution_context/test_helper.rb +13 -0
  174. data/lib/active_support/execution_context.rb +53 -0
  175. data/lib/active_support/execution_wrapper.rb +151 -0
  176. data/lib/active_support/executor/test_helper.rb +7 -0
  177. data/lib/active_support/executor.rb +8 -0
  178. data/lib/active_support/file_update_checker.rb +62 -37
  179. data/lib/active_support/fork_tracker.rb +71 -0
  180. data/lib/active_support/gem_version.rb +17 -0
  181. data/lib/active_support/gzip.rb +7 -5
  182. data/lib/active_support/hash_with_indifferent_access.rb +207 -54
  183. data/lib/active_support/html_safe_translation.rb +43 -0
  184. data/lib/active_support/i18n.rb +10 -6
  185. data/lib/active_support/i18n_railtie.rb +48 -19
  186. data/lib/active_support/inflections.rb +19 -12
  187. data/lib/active_support/inflector/inflections.rb +97 -37
  188. data/lib/active_support/inflector/methods.rb +192 -157
  189. data/lib/active_support/inflector/transliterate.rb +83 -33
  190. data/lib/active_support/inflector.rb +7 -5
  191. data/lib/active_support/isolated_execution_state.rb +64 -0
  192. data/lib/active_support/json/decoding.rb +37 -42
  193. data/lib/active_support/json/encoding.rb +93 -293
  194. data/lib/active_support/json.rb +4 -2
  195. data/lib/active_support/key_generator.rb +30 -47
  196. data/lib/active_support/lazy_load_hooks.rb +54 -21
  197. data/lib/active_support/locale/en.rb +33 -0
  198. data/lib/active_support/locale/en.yml +10 -4
  199. data/lib/active_support/log_subscriber/test_helper.rb +14 -12
  200. data/lib/active_support/log_subscriber.rb +61 -18
  201. data/lib/active_support/logger.rb +40 -4
  202. data/lib/active_support/logger_silence.rb +17 -20
  203. data/lib/active_support/logger_thread_safe_level.rb +69 -0
  204. data/lib/active_support/message_encryptor.rb +178 -55
  205. data/lib/active_support/message_verifier.rb +195 -26
  206. data/lib/active_support/messages/metadata.rb +80 -0
  207. data/lib/active_support/messages/rotation_configuration.rb +23 -0
  208. data/lib/active_support/messages/rotator.rb +57 -0
  209. data/lib/active_support/multibyte/chars.rb +45 -92
  210. data/lib/active_support/multibyte/unicode.rb +44 -377
  211. data/lib/active_support/multibyte.rb +5 -3
  212. data/lib/active_support/notifications/fanout.rb +177 -44
  213. data/lib/active_support/notifications/instrumenter.rb +117 -17
  214. data/lib/active_support/notifications.rb +106 -39
  215. data/lib/active_support/number_helper/number_converter.rb +181 -0
  216. data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
  217. data/lib/active_support/number_helper/number_to_delimited_converter.rb +30 -0
  218. data/lib/active_support/number_helper/number_to_human_converter.rb +69 -0
  219. data/lib/active_support/number_helper/number_to_human_size_converter.rb +60 -0
  220. data/lib/active_support/number_helper/number_to_percentage_converter.rb +16 -0
  221. data/lib/active_support/number_helper/number_to_phone_converter.rb +59 -0
  222. data/lib/active_support/number_helper/number_to_rounded_converter.rb +59 -0
  223. data/lib/active_support/number_helper/rounding_helper.rb +46 -0
  224. data/lib/active_support/number_helper.rb +152 -394
  225. data/lib/active_support/option_merger.rb +18 -5
  226. data/lib/active_support/ordered_hash.rb +8 -6
  227. data/lib/active_support/ordered_options.rb +43 -7
  228. data/lib/active_support/parameter_filter.rb +138 -0
  229. data/lib/active_support/per_thread_registry.rb +24 -11
  230. data/lib/active_support/proxy_object.rb +2 -0
  231. data/lib/active_support/rails.rb +10 -11
  232. data/lib/active_support/railtie.rb +118 -12
  233. data/lib/active_support/reloader.rb +130 -0
  234. data/lib/active_support/rescuable.rb +112 -57
  235. data/lib/active_support/ruby_features.rb +7 -0
  236. data/lib/active_support/secure_compare_rotator.rb +51 -0
  237. data/lib/active_support/security_utils.rb +38 -0
  238. data/lib/active_support/string_inquirer.rb +11 -4
  239. data/lib/active_support/subscriber.rb +109 -39
  240. data/lib/active_support/tagged_logging.rb +54 -17
  241. data/lib/active_support/test_case.rb +121 -37
  242. data/lib/active_support/testing/assertions.rb +177 -39
  243. data/lib/active_support/testing/autorun.rb +5 -3
  244. data/lib/active_support/testing/constant_lookup.rb +3 -6
  245. data/lib/active_support/testing/declarative.rb +10 -22
  246. data/lib/active_support/testing/deprecation.rb +65 -11
  247. data/lib/active_support/testing/file_fixtures.rb +38 -0
  248. data/lib/active_support/testing/isolation.rb +56 -87
  249. data/lib/active_support/testing/method_call_assertions.rb +70 -0
  250. data/lib/active_support/testing/parallelization/server.rb +82 -0
  251. data/lib/active_support/testing/parallelization/worker.rb +103 -0
  252. data/lib/active_support/testing/parallelization.rb +55 -0
  253. data/lib/active_support/testing/parallelize_executor.rb +76 -0
  254. data/lib/active_support/testing/setup_and_teardown.rb +30 -10
  255. data/lib/active_support/testing/stream.rb +41 -0
  256. data/lib/active_support/testing/tagged_logging.rb +6 -4
  257. data/lib/active_support/testing/time_helpers.rb +246 -0
  258. data/lib/active_support/time.rb +13 -13
  259. data/lib/active_support/time_with_zone.rb +315 -90
  260. data/lib/active_support/values/time_zone.rb +306 -135
  261. data/lib/active_support/version.rb +6 -7
  262. data/lib/active_support/xml_mini/jdom.rb +117 -115
  263. data/lib/active_support/xml_mini/libxml.rb +22 -21
  264. data/lib/active_support/xml_mini/libxmlsax.rb +17 -19
  265. data/lib/active_support/xml_mini/nokogiri.rb +19 -19
  266. data/lib/active_support/xml_mini/nokogirisax.rb +16 -17
  267. data/lib/active_support/xml_mini/rexml.rb +25 -17
  268. data/lib/active_support/xml_mini.rb +67 -56
  269. data/lib/active_support.rb +58 -3
  270. metadata +125 -66
  271. data/lib/active_support/basic_object.rb +0 -11
  272. data/lib/active_support/buffered_logger.rb +0 -21
  273. data/lib/active_support/concurrency/latch.rb +0 -27
  274. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
  275. data/lib/active_support/core_ext/array/uniq_by.rb +0 -19
  276. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -40
  277. data/lib/active_support/core_ext/date_time/zones.rb +0 -24
  278. data/lib/active_support/core_ext/hash/diff.rb +0 -14
  279. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
  280. data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
  281. data/lib/active_support/core_ext/logger.rb +0 -67
  282. data/lib/active_support/core_ext/marshal.rb +0 -21
  283. data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
  284. data/lib/active_support/core_ext/module/reachable.rb +0 -8
  285. data/lib/active_support/core_ext/object/to_json.rb +0 -27
  286. data/lib/active_support/core_ext/proc.rb +0 -17
  287. data/lib/active_support/core_ext/range/include_range.rb +0 -23
  288. data/lib/active_support/core_ext/string/encoding.rb +0 -8
  289. data/lib/active_support/core_ext/struct.rb +0 -6
  290. data/lib/active_support/core_ext/thread.rb +0 -79
  291. data/lib/active_support/core_ext/time/marshal.rb +0 -30
  292. data/lib/active_support/file_watcher.rb +0 -36
  293. data/lib/active_support/json/variable.rb +0 -18
  294. data/lib/active_support/testing/pending.rb +0 -14
  295. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,39 +1,47 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
3
+ require "concurrent/map"
2
4
 
3
5
  class Object
4
6
  # An object is blank if it's false, empty, or a whitespace string.
5
- # For example, '', ' ', +nil+, [], and {} are all blank.
7
+ # For example, +nil+, '', ' ', [], {}, and +false+ are all blank.
8
+ #
9
+ # This simplifies
6
10
  #
7
- # This simplifies:
11
+ # !address || address.empty?
8
12
  #
9
- # if address.nil? || address.empty?
13
+ # to
10
14
  #
11
- # ...to:
15
+ # address.blank?
12
16
  #
13
- # if address.blank?
17
+ # @return [true, false]
14
18
  def blank?
15
- respond_to?(:empty?) ? empty? : !self
19
+ respond_to?(:empty?) ? !!empty? : !self
16
20
  end
17
21
 
18
- # An object is present if it's not <tt>blank?</tt>.
22
+ # An object is present if it's not blank.
23
+ #
24
+ # @return [true, false]
19
25
  def present?
20
26
  !blank?
21
27
  end
22
28
 
23
- # Returns object if it's <tt>present?</tt> otherwise returns +nil+.
24
- # <tt>object.presence</tt> is equivalent to <tt>object.present? ? object : nil</tt>.
29
+ # Returns the receiver if it's present otherwise returns +nil+.
30
+ # <tt>object.presence</tt> is equivalent to
25
31
  #
26
- # This is handy for any representation of objects where blank is the same
27
- # as not present at all. For example, this simplifies a common check for
28
- # HTTP POST/query parameters:
32
+ # object.present? ? object : nil
33
+ #
34
+ # For example, something like
29
35
  #
30
36
  # state = params[:state] if params[:state].present?
31
37
  # country = params[:country] if params[:country].present?
32
38
  # region = state || country || 'US'
33
39
  #
34
- # ...becomes:
40
+ # becomes
35
41
  #
36
42
  # region = params[:state].presence || params[:country].presence || 'US'
43
+ #
44
+ # @return [Object]
37
45
  def presence
38
46
  self if present?
39
47
  end
@@ -43,6 +51,8 @@ class NilClass
43
51
  # +nil+ is blank:
44
52
  #
45
53
  # nil.blank? # => true
54
+ #
55
+ # @return [true]
46
56
  def blank?
47
57
  true
48
58
  end
@@ -52,6 +62,8 @@ class FalseClass
52
62
  # +false+ is blank:
53
63
  #
54
64
  # false.blank? # => true
65
+ #
66
+ # @return [true]
55
67
  def blank?
56
68
  true
57
69
  end
@@ -61,6 +73,8 @@ class TrueClass
61
73
  # +true+ is not blank:
62
74
  #
63
75
  # true.blank? # => false
76
+ #
77
+ # @return [false]
64
78
  def blank?
65
79
  false
66
80
  end
@@ -71,6 +85,8 @@ class Array
71
85
  #
72
86
  # [].blank? # => true
73
87
  # [1,2,3].blank? # => false
88
+ #
89
+ # @return [true, false]
74
90
  alias_method :blank?, :empty?
75
91
  end
76
92
 
@@ -79,26 +95,60 @@ class Hash
79
95
  #
80
96
  # {}.blank? # => true
81
97
  # { key: 'value' }.blank? # => false
98
+ #
99
+ # @return [true, false]
82
100
  alias_method :blank?, :empty?
83
101
  end
84
102
 
85
103
  class String
104
+ BLANK_RE = /\A[[:space:]]*\z/
105
+ ENCODED_BLANKS = Concurrent::Map.new do |h, enc|
106
+ h[enc] = Regexp.new(BLANK_RE.source.encode(enc), BLANK_RE.options | Regexp::FIXEDENCODING)
107
+ end
108
+
86
109
  # A string is blank if it's empty or contains whitespaces only:
87
110
  #
88
- # ''.blank? # => true
89
- # ' '.blank? # => true
90
- # ' '.blank? # => true
91
- # ' something here '.blank? # => false
111
+ # ''.blank? # => true
112
+ # ' '.blank? # => true
113
+ # "\t\n\r".blank? # => true
114
+ # ' blah '.blank? # => false
115
+ #
116
+ # Unicode whitespace is supported:
117
+ #
118
+ # "\u00a0".blank? # => true
119
+ #
120
+ # @return [true, false]
92
121
  def blank?
93
- self !~ /[^[:space:]]/
122
+ # The regexp that matches blank strings is expensive. For the case of empty
123
+ # strings we can speed up this method (~3.5x) with an empty? call. The
124
+ # penalty for the rest of strings is marginal.
125
+ empty? ||
126
+ begin
127
+ BLANK_RE.match?(self)
128
+ rescue Encoding::CompatibilityError
129
+ ENCODED_BLANKS[self.encoding].match?(self)
130
+ end
94
131
  end
95
132
  end
96
133
 
97
- class Numeric #:nodoc:
134
+ class Numeric # :nodoc:
98
135
  # No number is blank:
99
136
  #
100
137
  # 1.blank? # => false
101
138
  # 0.blank? # => false
139
+ #
140
+ # @return [false]
141
+ def blank?
142
+ false
143
+ end
144
+ end
145
+
146
+ class Time # :nodoc:
147
+ # No Time is blank:
148
+ #
149
+ # Time.now.blank? # => false
150
+ #
151
+ # @return [false]
102
152
  def blank?
103
153
  false
104
154
  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
@@ -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 ::String === key || ::Symbol === 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,72 +21,40 @@
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
26
28
  end
27
29
  end
28
30
 
29
- 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
36
- end
37
- end
38
-
39
- class FalseClass
40
- # +false+ is not duplicable:
31
+ class Method
32
+ # Methods are not duplicable:
41
33
  #
42
- # false.duplicable? # => false
43
- # false.dup # => TypeError: can't dup FalseClass
34
+ # method(:puts).duplicable? # => false
35
+ # method(:puts).dup # => TypeError: allocator undefined for Method
44
36
  def duplicable?
45
37
  false
46
38
  end
47
39
  end
48
40
 
49
- class TrueClass
50
- # +true+ is not duplicable:
41
+ class UnboundMethod
42
+ # Unbound methods are not duplicable:
51
43
  #
52
- # true.duplicable? # => false
53
- # true.dup # => TypeError: can't dup TrueClass
44
+ # method(:puts).unbind.duplicable? # => false
45
+ # method(:puts).unbind.dup # => TypeError: allocator undefined for UnboundMethod
54
46
  def duplicable?
55
47
  false
56
48
  end
57
49
  end
58
50
 
59
- class Symbol
60
- # Symbols are not duplicable:
61
- #
62
- # :my_symbol.duplicable? # => false
63
- # :my_symbol.dup # => TypeError: can't dup Symbol
64
- def duplicable?
65
- false
66
- end
67
- end
51
+ require "singleton"
68
52
 
69
- class Numeric
70
- # Numbers are not duplicable:
53
+ module Singleton
54
+ # Singleton instances are not duplicable:
71
55
  #
72
- # 3.duplicable? # => false
73
- # 3.dup # => TypeError: can't dup Fixnum
56
+ # Class.new.include(Singleton).instance.dup # TypeError (can't dup instance of singleton
74
57
  def duplicable?
75
58
  false
76
59
  end
77
60
  end
78
-
79
- require 'bigdecimal'
80
- class BigDecimal
81
- begin
82
- BigDecimal.new('4.56').dup
83
-
84
- def duplicable?
85
- true
86
- end
87
- rescue TypeError
88
- # can't dup, so use superclass implementation
89
- end
90
- 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,244 @@
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 "ipaddr"
7
+ require "uri/generic"
8
+ require "pathname"
9
+ require "active_support/core_ext/big_decimal/conversions" # for #to_s
10
+ require "active_support/core_ext/hash/except"
11
+ require "active_support/core_ext/hash/slice"
12
+ require "active_support/core_ext/object/instance_variables"
13
+ require "time"
14
+ require "active_support/core_ext/time/conversions"
15
+ require "active_support/core_ext/date_time/conversions"
16
+ require "active_support/core_ext/date/conversions"
17
+
18
+ #--
19
+ # The JSON gem adds a few modules to Ruby core classes containing :to_json definition, overwriting
20
+ # their default behavior. That said, we need to define the basic to_json method in all of them,
21
+ # otherwise they will always use to_json gem implementation, which is backwards incompatible in
22
+ # several cases (for instance, the JSON implementation for Hash does not work) with inheritance.
23
+ #
24
+ # On the other hand, we should avoid conflict with ::JSON.{generate,dump}(obj). Unfortunately, the
25
+ # JSON gem's encoder relies on its own to_json implementation to encode objects. Since it always
26
+ # passes a ::JSON::State object as the only argument to to_json, we can detect that and forward the
27
+ # calls to the original to_json method.
28
+ #
29
+ # It should be noted that when using ::JSON.{generate,dump} directly, ActiveSupport's encoder is
30
+ # bypassed completely. This means that as_json won't be invoked and the JSON gem will simply
31
+ # ignore any options it does not natively understand. This also means that ::JSON.{generate,dump}
32
+ # should give exactly the same results with or without active support.
33
+
34
+ module ActiveSupport
35
+ module ToJsonWithActiveSupportEncoder # :nodoc:
36
+ def to_json(options = nil)
37
+ if options.is_a?(::JSON::State)
38
+ # Called from JSON.{generate,dump}, forward it to JSON gem's to_json
39
+ super(options)
40
+ else
41
+ # to_json is being invoked directly, use ActiveSupport's encoder
42
+ ActiveSupport::JSON.encode(self, options)
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ [Enumerable, Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass].reverse_each do |klass|
49
+ klass.prepend(ActiveSupport::ToJsonWithActiveSupportEncoder)
50
+ end
51
+
52
+ class Module
53
+ def as_json(options = nil) # :nodoc:
54
+ name
55
+ end
56
+ end
57
+
58
+ class Object
59
+ def as_json(options = nil) # :nodoc:
60
+ if respond_to?(:to_hash)
61
+ to_hash.as_json(options)
62
+ else
63
+ instance_values.as_json(options)
64
+ end
65
+ end
66
+ end
67
+
68
+ class Struct # :nodoc:
69
+ def as_json(options = nil)
70
+ Hash[members.zip(values)].as_json(options)
71
+ end
72
+ end
73
+
74
+ class TrueClass
75
+ def as_json(options = nil) # :nodoc:
76
+ self
77
+ end
78
+ end
79
+
80
+ class FalseClass
81
+ def as_json(options = nil) # :nodoc:
82
+ self
83
+ end
84
+ end
85
+
86
+ class NilClass
87
+ def as_json(options = nil) # :nodoc:
88
+ self
89
+ end
90
+ end
91
+
92
+ class String
93
+ def as_json(options = nil) # :nodoc:
94
+ self
95
+ end
96
+ end
97
+
98
+ class Symbol
99
+ def as_json(options = nil) # :nodoc:
100
+ to_s
101
+ end
102
+ end
103
+
104
+ class Numeric
105
+ def as_json(options = nil) # :nodoc:
106
+ self
107
+ end
108
+ end
109
+
110
+ class Float
111
+ # Encoding Infinity or NaN to JSON should return "null". The default returns
112
+ # "Infinity" or "NaN" which are not valid JSON.
113
+ def as_json(options = nil) # :nodoc:
114
+ finite? ? self : nil
115
+ end
116
+ end
117
+
118
+ class BigDecimal
119
+ # A BigDecimal would be naturally represented as a JSON number. Most libraries,
120
+ # however, parse non-integer JSON numbers directly as floats. Clients using
121
+ # those libraries would get in general a wrong number and no way to recover
122
+ # other than manually inspecting the string with the JSON code itself.
123
+ #
124
+ # That's why a JSON string is returned. The JSON literal is not numeric, but
125
+ # if the other end knows by contract that the data is supposed to be a
126
+ # BigDecimal, it still has the chance to post-process the string and get the
127
+ # real value.
128
+ def as_json(options = nil) # :nodoc:
129
+ finite? ? to_s : nil
130
+ end
131
+ end
132
+
133
+ class Regexp
134
+ def as_json(options = nil) # :nodoc:
135
+ to_s
136
+ end
137
+ end
138
+
139
+ module Enumerable
140
+ def as_json(options = nil) # :nodoc:
141
+ to_a.as_json(options)
142
+ end
143
+ end
144
+
145
+ class IO
146
+ def as_json(options = nil) # :nodoc:
147
+ to_s
148
+ end
149
+ end
150
+
151
+ class Range
152
+ def as_json(options = nil) # :nodoc:
153
+ to_s
154
+ end
155
+ end
156
+
157
+ class Array
158
+ def as_json(options = nil) # :nodoc:
159
+ map { |v| options ? v.as_json(options.dup) : v.as_json }
160
+ end
161
+ end
162
+
163
+ class Hash
164
+ def as_json(options = nil) # :nodoc:
165
+ # create a subset of the hash by applying :only or :except
166
+ subset = if options
167
+ if attrs = options[:only]
168
+ slice(*Array(attrs))
169
+ elsif attrs = options[:except]
170
+ except(*Array(attrs))
171
+ else
172
+ self
173
+ end
174
+ else
175
+ self
176
+ end
177
+
178
+ result = {}
179
+ subset.each do |k, v|
180
+ result[k.to_s] = options ? v.as_json(options.dup) : v.as_json
181
+ end
182
+ result
183
+ end
184
+ end
185
+
186
+ class Time
187
+ def as_json(options = nil) # :nodoc:
188
+ if ActiveSupport::JSON::Encoding.use_standard_json_time_format
189
+ xmlschema(ActiveSupport::JSON::Encoding.time_precision)
190
+ else
191
+ %(#{strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)})
192
+ end
193
+ end
194
+ end
195
+
196
+ class Date
197
+ def as_json(options = nil) # :nodoc:
198
+ if ActiveSupport::JSON::Encoding.use_standard_json_time_format
199
+ strftime("%Y-%m-%d")
200
+ else
201
+ strftime("%Y/%m/%d")
202
+ end
203
+ end
204
+ end
205
+
206
+ class DateTime
207
+ def as_json(options = nil) # :nodoc:
208
+ if ActiveSupport::JSON::Encoding.use_standard_json_time_format
209
+ xmlschema(ActiveSupport::JSON::Encoding.time_precision)
210
+ else
211
+ strftime("%Y/%m/%d %H:%M:%S %z")
212
+ end
213
+ end
214
+ end
215
+
216
+ class URI::Generic # :nodoc:
217
+ def as_json(options = nil)
218
+ to_s
219
+ end
220
+ end
221
+
222
+ class Pathname # :nodoc:
223
+ def as_json(options = nil)
224
+ to_s
225
+ end
226
+ end
227
+
228
+ class IPAddr # :nodoc:
229
+ def as_json(options = nil)
230
+ to_s
231
+ end
232
+ end
233
+
234
+ class Process::Status # :nodoc:
235
+ def as_json(options = nil)
236
+ { exitstatus: exitstatus, pid: pid }
237
+ end
238
+ end
239
+
240
+ class Exception
241
+ def as_json(options = nil)
242
+ to_s
243
+ end
244
+ 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"