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,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Numeric
2
4
  KILOBYTE = 1024
3
5
  MEGABYTE = KILOBYTE * 1024
@@ -7,36 +9,56 @@ class Numeric
7
9
  EXABYTE = PETABYTE * 1024
8
10
 
9
11
  # Enables the use of byte calculations and declarations, like 45.bytes + 2.6.megabytes
12
+ #
13
+ # 2.bytes # => 2
10
14
  def bytes
11
15
  self
12
16
  end
13
17
  alias :byte :bytes
14
18
 
19
+ # Returns the number of bytes equivalent to the kilobytes provided.
20
+ #
21
+ # 2.kilobytes # => 2048
15
22
  def kilobytes
16
23
  self * KILOBYTE
17
24
  end
18
25
  alias :kilobyte :kilobytes
19
26
 
27
+ # Returns the number of bytes equivalent to the megabytes provided.
28
+ #
29
+ # 2.megabytes # => 2_097_152
20
30
  def megabytes
21
31
  self * MEGABYTE
22
32
  end
23
33
  alias :megabyte :megabytes
24
34
 
35
+ # Returns the number of bytes equivalent to the gigabytes provided.
36
+ #
37
+ # 2.gigabytes # => 2_147_483_648
25
38
  def gigabytes
26
39
  self * GIGABYTE
27
40
  end
28
41
  alias :gigabyte :gigabytes
29
42
 
43
+ # Returns the number of bytes equivalent to the terabytes provided.
44
+ #
45
+ # 2.terabytes # => 2_199_023_255_552
30
46
  def terabytes
31
47
  self * TERABYTE
32
48
  end
33
49
  alias :terabyte :terabytes
34
50
 
51
+ # Returns the number of bytes equivalent to the petabytes provided.
52
+ #
53
+ # 2.petabytes # => 2_251_799_813_685_248
35
54
  def petabytes
36
55
  self * PETABYTE
37
56
  end
38
57
  alias :petabyte :petabytes
39
58
 
59
+ # Returns the number of bytes equivalent to the exabytes provided.
60
+ #
61
+ # 2.exabytes # => 2_305_843_009_213_693_952
40
62
  def exabytes
41
63
  self * EXABYTE
42
64
  end
@@ -1,135 +1,143 @@
1
- require 'active_support/core_ext/big_decimal/conversions'
2
- require 'active_support/number_helper'
1
+ # frozen_string_literal: true
3
2
 
4
- class Numeric
3
+ require "active_support/core_ext/big_decimal/conversions"
4
+ require "active_support/number_helper"
5
5
 
6
- # Provides options for converting numbers into formatted strings.
7
- # Options are provided for phone numbers, currency, percentage,
8
- # precision, positional notation, file size and pretty printing.
9
- #
10
- # ==== Options
11
- #
12
- # For details on which formats use which options, see ActiveSupport::NumberHelper
13
- #
14
- # ==== Examples
15
- #
16
- # Phone Numbers:
17
- # 5551234.to_s(:phone) # => 555-1234
18
- # 1235551234.to_s(:phone) # => 123-555-1234
19
- # 1235551234.to_s(:phone, area_code: true) # => (123) 555-1234
20
- # 1235551234.to_s(:phone, delimiter: ' ') # => 123 555 1234
21
- # 1235551234.to_s(:phone, area_code: true, extension: 555) # => (123) 555-1234 x 555
22
- # 1235551234.to_s(:phone, country_code: 1) # => +1-123-555-1234
23
- # 1235551234.to_s(:phone, country_code: 1, extension: 1343, delimiter: '.')
24
- # # => +1.123.555.1234 x 1343
25
- #
26
- # Currency:
27
- # 1234567890.50.to_s(:currency) # => $1,234,567,890.50
28
- # 1234567890.506.to_s(:currency) # => $1,234,567,890.51
29
- # 1234567890.506.to_s(:currency, precision: 3) # => $1,234,567,890.506
30
- # 1234567890.506.to_s(:currency, locale: :fr) # => 1 234 567 890,51 €
31
- # -1234567890.50.to_s(:currency, negative_format: '(%u%n)')
32
- # # => ($1,234,567,890.50)
33
- # 1234567890.50.to_s(:currency, unit: '£', separator: ',', delimiter: '')
34
- # # => £1234567890,50
35
- # 1234567890.50.to_s(:currency, unit: '£', separator: ',', delimiter: '', format: '%n %u')
36
- # # => 1234567890,50 £
37
- #
38
- # Percentage:
39
- # 100.to_s(:percentage) # => 100.000%
40
- # 100.to_s(:percentage, precision: 0) # => 100%
41
- # 1000.to_s(:percentage, delimiter: '.', separator: ',') # => 1.000,000%
42
- # 302.24398923423.to_s(:percentage, precision: 5) # => 302.24399%
43
- # 1000.to_s(:percentage, locale: :fr) # => 1 000,000%
44
- # 100.to_s(:percentage, format: '%n %') # => 100 %
45
- #
46
- # Delimited:
47
- # 12345678.to_s(:delimited) # => 12,345,678
48
- # 12345678.05.to_s(:delimited) # => 12,345,678.05
49
- # 12345678.to_s(:delimited, delimiter: '.') # => 12.345.678
50
- # 12345678.to_s(:delimited, delimiter: ',') # => 12,345,678
51
- # 12345678.05.to_s(:delimited, separator: ' ') # => 12,345,678 05
52
- # 12345678.05.to_s(:delimited, locale: :fr) # => 12 345 678,05
53
- # 98765432.98.to_s(:delimited, delimiter: ' ', separator: ',')
54
- # # => 98 765 432,98
55
- #
56
- # Rounded:
57
- # 111.2345.to_s(:rounded) # => 111.235
58
- # 111.2345.to_s(:rounded, precision: 2) # => 111.23
59
- # 13.to_s(:rounded, precision: 5) # => 13.00000
60
- # 389.32314.to_s(:rounded, precision: 0) # => 389
61
- # 111.2345.to_s(:rounded, significant: true) # => 111
62
- # 111.2345.to_s(:rounded, precision: 1, significant: true) # => 100
63
- # 13.to_s(:rounded, precision: 5, significant: true) # => 13.000
64
- # 111.234.to_s(:rounded, locale: :fr) # => 111,234
65
- # 13.to_s(:rounded, precision: 5, significant: true, strip_insignificant_zeros: true)
66
- # # => 13
67
- # 389.32314.to_s(:rounded, precision: 4, significant: true) # => 389.3
68
- # 1111.2345.to_s(:rounded, precision: 2, separator: ',', delimiter: '.')
69
- # # => 1.111,23
70
- #
71
- # Human-friendly size in Bytes:
72
- # 123.to_s(:human_size) # => 123 Bytes
73
- # 1234.to_s(:human_size) # => 1.21 KB
74
- # 12345.to_s(:human_size) # => 12.1 KB
75
- # 1234567.to_s(:human_size) # => 1.18 MB
76
- # 1234567890.to_s(:human_size) # => 1.15 GB
77
- # 1234567890123.to_s(:human_size) # => 1.12 TB
78
- # 1234567.to_s(:human_size, precision: 2) # => 1.2 MB
79
- # 483989.to_s(:human_size, precision: 2) # => 470 KB
80
- # 1234567.to_s(:human_size, precision: 2, separator: ',') # => 1,2 MB
81
- # 1234567890123.to_s(:human_size, precision: 5) # => "1.1229 TB"
82
- # 524288000.to_s(:human_size, precision: 5) # => "500 MB"
83
- #
84
- # Human-friendly format:
85
- # 123.to_s(:human) # => "123"
86
- # 1234.to_s(:human) # => "1.23 Thousand"
87
- # 12345.to_s(:human) # => "12.3 Thousand"
88
- # 1234567.to_s(:human) # => "1.23 Million"
89
- # 1234567890.to_s(:human) # => "1.23 Billion"
90
- # 1234567890123.to_s(:human) # => "1.23 Trillion"
91
- # 1234567890123456.to_s(:human) # => "1.23 Quadrillion"
92
- # 1234567890123456789.to_s(:human) # => "1230 Quadrillion"
93
- # 489939.to_s(:human, precision: 2) # => "490 Thousand"
94
- # 489939.to_s(:human, precision: 4) # => "489.9 Thousand"
95
- # 1234567.to_s(:human, precision: 4,
96
- # significant: false) # => "1.2346 Million"
97
- # 1234567.to_s(:human, precision: 1,
98
- # separator: ',',
99
- # significant: false) # => "1,2 Million"
100
- def to_formatted_s(format = :default, options = {})
101
- case format
102
- when :phone
103
- return ActiveSupport::NumberHelper.number_to_phone(self, options)
104
- when :currency
105
- return ActiveSupport::NumberHelper.number_to_currency(self, options)
106
- when :percentage
107
- return ActiveSupport::NumberHelper.number_to_percentage(self, options)
108
- when :delimited
109
- return ActiveSupport::NumberHelper.number_to_delimited(self, options)
110
- when :rounded
111
- return ActiveSupport::NumberHelper.number_to_rounded(self, options)
112
- when :human
113
- return ActiveSupport::NumberHelper.number_to_human(self, options)
114
- when :human_size
115
- return ActiveSupport::NumberHelper.number_to_human_size(self, options)
116
- else
117
- self.to_default_s
118
- end
119
- end
120
-
121
- [Float, Fixnum, Bignum, BigDecimal].each do |klass|
122
- klass.send(:alias_method, :to_default_s, :to_s)
6
+ module ActiveSupport
7
+ module NumericWithFormat
8
+ # Provides options for converting numbers into formatted strings.
9
+ # Options are provided for phone numbers, currency, percentage,
10
+ # precision, positional notation, file size and pretty printing.
11
+ #
12
+ # This method is aliased to <tt>to_formatted_s</tt>.
13
+ #
14
+ # ==== Options
15
+ #
16
+ # For details on which formats use which options, see ActiveSupport::NumberHelper
17
+ #
18
+ # ==== Examples
19
+ #
20
+ # Phone Numbers:
21
+ # 5551234.to_fs(:phone) # => "555-1234"
22
+ # 1235551234.to_fs(:phone) # => "123-555-1234"
23
+ # 1235551234.to_fs(:phone, area_code: true) # => "(123) 555-1234"
24
+ # 1235551234.to_fs(:phone, delimiter: ' ') # => "123 555 1234"
25
+ # 1235551234.to_fs(:phone, area_code: true, extension: 555) # => "(123) 555-1234 x 555"
26
+ # 1235551234.to_fs(:phone, country_code: 1) # => "+1-123-555-1234"
27
+ # 1235551234.to_fs(:phone, country_code: 1, extension: 1343, delimiter: '.')
28
+ # # => "+1.123.555.1234 x 1343"
29
+ #
30
+ # Currency:
31
+ # 1234567890.50.to_fs(:currency) # => "$1,234,567,890.50"
32
+ # 1234567890.506.to_fs(:currency) # => "$1,234,567,890.51"
33
+ # 1234567890.506.to_fs(:currency, precision: 3) # => "$1,234,567,890.506"
34
+ # 1234567890.506.to_fs(:currency, round_mode: :down) # => "$1,234,567,890.50"
35
+ # 1234567890.506.to_fs(:currency, locale: :fr) # => "1 234 567 890,51 €"
36
+ # -1234567890.50.to_fs(:currency, negative_format: '(%u%n)')
37
+ # # => "($1,234,567,890.50)"
38
+ # 1234567890.50.to_fs(:currency, unit: '&pound;', separator: ',', delimiter: '')
39
+ # # => "&pound;1234567890,50"
40
+ # 1234567890.50.to_fs(:currency, unit: '&pound;', separator: ',', delimiter: '', format: '%n %u')
41
+ # # => "1234567890,50 &pound;"
42
+ #
43
+ # Percentage:
44
+ # 100.to_fs(:percentage) # => "100.000%"
45
+ # 100.to_fs(:percentage, precision: 0) # => "100%"
46
+ # 1000.to_fs(:percentage, delimiter: '.', separator: ',') # => "1.000,000%"
47
+ # 302.24398923423.to_fs(:percentage, precision: 5) # => "302.24399%"
48
+ # 302.24398923423.to_fs(:percentage, round_mode: :down) # => "302.243%"
49
+ # 1000.to_fs(:percentage, locale: :fr) # => "1 000,000%"
50
+ # 100.to_fs(:percentage, format: '%n %') # => "100.000 %"
51
+ #
52
+ # Delimited:
53
+ # 12345678.to_fs(:delimited) # => "12,345,678"
54
+ # 12345678.05.to_fs(:delimited) # => "12,345,678.05"
55
+ # 12345678.to_fs(:delimited, delimiter: '.') # => "12.345.678"
56
+ # 12345678.to_fs(:delimited, delimiter: ',') # => "12,345,678"
57
+ # 12345678.05.to_fs(:delimited, separator: ' ') # => "12,345,678 05"
58
+ # 12345678.05.to_fs(:delimited, locale: :fr) # => "12 345 678,05"
59
+ # 98765432.98.to_fs(:delimited, delimiter: ' ', separator: ',')
60
+ # # => "98 765 432,98"
61
+ #
62
+ # Rounded:
63
+ # 111.2345.to_fs(:rounded) # => "111.235"
64
+ # 111.2345.to_fs(:rounded, precision: 2) # => "111.23"
65
+ # 111.2345.to_fs(:rounded, precision: 2, round_mode: :up) # => "111.24"
66
+ # 13.to_fs(:rounded, precision: 5) # => "13.00000"
67
+ # 389.32314.to_fs(:rounded, precision: 0) # => "389"
68
+ # 111.2345.to_fs(:rounded, significant: true) # => "111"
69
+ # 111.2345.to_fs(:rounded, precision: 1, significant: true) # => "100"
70
+ # 13.to_fs(:rounded, precision: 5, significant: true) # => "13.000"
71
+ # 111.234.to_fs(:rounded, locale: :fr) # => "111,234"
72
+ # 13.to_fs(:rounded, precision: 5, significant: true, strip_insignificant_zeros: true)
73
+ # # => "13"
74
+ # 389.32314.to_fs(:rounded, precision: 4, significant: true) # => "389.3"
75
+ # 1111.2345.to_fs(:rounded, precision: 2, separator: ',', delimiter: '.')
76
+ # # => "1.111,23"
77
+ #
78
+ # Human-friendly size in Bytes:
79
+ # 123.to_fs(:human_size) # => "123 Bytes"
80
+ # 1234.to_fs(:human_size) # => "1.21 KB"
81
+ # 12345.to_fs(:human_size) # => "12.1 KB"
82
+ # 1234567.to_fs(:human_size) # => "1.18 MB"
83
+ # 1234567890.to_fs(:human_size) # => "1.15 GB"
84
+ # 1234567890123.to_fs(:human_size) # => "1.12 TB"
85
+ # 1234567890123456.to_fs(:human_size) # => "1.1 PB"
86
+ # 1234567890123456789.to_fs(:human_size) # => "1.07 EB"
87
+ # 1234567.to_fs(:human_size, precision: 2) # => "1.2 MB"
88
+ # 1234567.to_fs(:human_size, precision: 2, round_mode: :up) # => "1.3 MB"
89
+ # 483989.to_fs(:human_size, precision: 2) # => "470 KB"
90
+ # 1234567.to_fs(:human_size, precision: 2, separator: ',') # => "1,2 MB"
91
+ # 1234567890123.to_fs(:human_size, precision: 5) # => "1.1228 TB"
92
+ # 524288000.to_fs(:human_size, precision: 5) # => "500 MB"
93
+ #
94
+ # Human-friendly format:
95
+ # 123.to_fs(:human) # => "123"
96
+ # 1234.to_fs(:human) # => "1.23 Thousand"
97
+ # 12345.to_fs(:human) # => "12.3 Thousand"
98
+ # 1234567.to_fs(:human) # => "1.23 Million"
99
+ # 1234567890.to_fs(:human) # => "1.23 Billion"
100
+ # 1234567890123.to_fs(:human) # => "1.23 Trillion"
101
+ # 1234567890123456.to_fs(:human) # => "1.23 Quadrillion"
102
+ # 1234567890123456789.to_fs(:human) # => "1230 Quadrillion"
103
+ # 489939.to_fs(:human, precision: 2) # => "490 Thousand"
104
+ # 489939.to_fs(:human, precision: 2, round_mode: :down) # => "480 Thousand"
105
+ # 489939.to_fs(:human, precision: 4) # => "489.9 Thousand"
106
+ # 1234567.to_fs(:human, precision: 4,
107
+ # significant: false) # => "1.2346 Million"
108
+ # 1234567.to_fs(:human, precision: 1,
109
+ # separator: ',',
110
+ # significant: false) # => "1,2 Million"
111
+ def to_fs(format = nil, options = nil)
112
+ return to_s if format.nil?
123
113
 
124
- klass.send(:define_method, :to_s) do |*args|
125
- if args[0].is_a?(Symbol)
126
- format = args[0]
127
- options = args[1] || {}
128
-
129
- self.to_formatted_s(format, options)
114
+ case format
115
+ when Integer, String
116
+ to_s(format)
117
+ when :phone
118
+ ActiveSupport::NumberHelper.number_to_phone(self, options || {})
119
+ when :currency
120
+ ActiveSupport::NumberHelper.number_to_currency(self, options || {})
121
+ when :percentage
122
+ ActiveSupport::NumberHelper.number_to_percentage(self, options || {})
123
+ when :delimited
124
+ ActiveSupport::NumberHelper.number_to_delimited(self, options || {})
125
+ when :rounded
126
+ ActiveSupport::NumberHelper.number_to_rounded(self, options || {})
127
+ when :human
128
+ ActiveSupport::NumberHelper.number_to_human(self, options || {})
129
+ when :human_size
130
+ ActiveSupport::NumberHelper.number_to_human_size(self, options || {})
131
+ when Symbol
132
+ to_s
130
133
  else
131
- to_default_s(*args)
134
+ to_s(format)
132
135
  end
133
136
  end
137
+ alias_method :to_formatted_s, :to_fs
134
138
  end
135
139
  end
140
+
141
+ Integer.prepend ActiveSupport::NumericWithFormat
142
+ Float.prepend ActiveSupport::NumericWithFormat
143
+ BigDecimal.prepend ActiveSupport::NumericWithFormat
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ module DeprecatedNumericWithFormat # :nodoc:
5
+ def to_s(format = nil, options = nil)
6
+ return super() if format.nil?
7
+
8
+ case format
9
+ when Integer, String
10
+ super(format)
11
+ when :phone
12
+ ActiveSupport::Deprecation.warn(
13
+ "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_fs(#{format.inspect}) instead."
14
+ )
15
+ ActiveSupport::NumberHelper.number_to_phone(self, options || {})
16
+ when :currency
17
+ ActiveSupport::Deprecation.warn(
18
+ "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_fs(#{format.inspect}) instead."
19
+ )
20
+ ActiveSupport::NumberHelper.number_to_currency(self, options || {})
21
+ when :percentage
22
+ ActiveSupport::Deprecation.warn(
23
+ "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_fs(#{format.inspect}) instead."
24
+ )
25
+ ActiveSupport::NumberHelper.number_to_percentage(self, options || {})
26
+ when :delimited
27
+ ActiveSupport::Deprecation.warn(
28
+ "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_fs(#{format.inspect}) instead."
29
+ )
30
+ ActiveSupport::NumberHelper.number_to_delimited(self, options || {})
31
+ when :rounded
32
+ ActiveSupport::Deprecation.warn(
33
+ "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_fs(#{format.inspect}) instead."
34
+ )
35
+ ActiveSupport::NumberHelper.number_to_rounded(self, options || {})
36
+ when :human
37
+ ActiveSupport::Deprecation.warn(
38
+ "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_fs(#{format.inspect}) instead."
39
+ )
40
+ ActiveSupport::NumberHelper.number_to_human(self, options || {})
41
+ when :human_size
42
+ ActiveSupport::Deprecation.warn(
43
+ "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_fs(#{format.inspect}) instead."
44
+ )
45
+ ActiveSupport::NumberHelper.number_to_human_size(self, options || {})
46
+ when Symbol
47
+ ActiveSupport::Deprecation.warn(
48
+ "#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_fs(#{format.inspect}) instead."
49
+ )
50
+ super()
51
+ else
52
+ super(format)
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ Integer.prepend ActiveSupport::DeprecatedNumericWithFormat
59
+ Float.prepend ActiveSupport::DeprecatedNumericWithFormat
60
+ BigDecimal.prepend ActiveSupport::DeprecatedNumericWithFormat
@@ -1,79 +1,66 @@
1
- require 'active_support/duration'
2
- require 'active_support/core_ext/time/calculations'
3
- require 'active_support/core_ext/time/acts_like'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/duration"
4
+ require "active_support/core_ext/time/calculations"
5
+ require "active_support/core_ext/time/acts_like"
6
+ require "active_support/core_ext/date/calculations"
7
+ require "active_support/core_ext/date/acts_like"
4
8
 
5
9
  class Numeric
6
- # Enables the use of time calculations and declarations, like 45.minutes + 2.hours + 4.years.
7
- #
8
- # These methods use Time#advance for precise date calculations when using from_now, ago, etc.
9
- # as well as adding or subtracting their results from a Time object. For example:
10
- #
11
- # # equivalent to Time.current.advance(months: 1)
12
- # 1.month.from_now
13
- #
14
- # # equivalent to Time.current.advance(years: 2)
15
- # 2.years.from_now
16
- #
17
- # # equivalent to Time.current.advance(months: 4, years: 5)
18
- # (4.months + 5.years).from_now
10
+ # Returns a Duration instance matching the number of seconds provided.
19
11
  #
20
- # While these methods provide precise calculation when used as in the examples above, care
21
- # should be taken to note that this is not true if the result of `months', `years', etc is
22
- # converted before use:
23
- #
24
- # # equivalent to 30.days.to_i.from_now
25
- # 1.month.to_i.from_now
26
- #
27
- # # equivalent to 365.25.days.to_f.from_now
28
- # 1.year.to_f.from_now
29
- #
30
- # In such cases, Ruby's core
31
- # Date[http://ruby-doc.org/stdlib/libdoc/date/rdoc/Date.html] and
32
- # Time[http://ruby-doc.org/stdlib/libdoc/time/rdoc/Time.html] should be used for precision
33
- # date and time arithmetic.
12
+ # 2.seconds # => 2 seconds
34
13
  def seconds
35
- ActiveSupport::Duration.new(self, [[:seconds, self]])
14
+ ActiveSupport::Duration.seconds(self)
36
15
  end
37
16
  alias :second :seconds
38
17
 
18
+ # Returns a Duration instance matching the number of minutes provided.
19
+ #
20
+ # 2.minutes # => 2 minutes
39
21
  def minutes
40
- ActiveSupport::Duration.new(self * 60, [[:seconds, self * 60]])
22
+ ActiveSupport::Duration.minutes(self)
41
23
  end
42
24
  alias :minute :minutes
43
25
 
26
+ # Returns a Duration instance matching the number of hours provided.
27
+ #
28
+ # 2.hours # => 2 hours
44
29
  def hours
45
- ActiveSupport::Duration.new(self * 3600, [[:seconds, self * 3600]])
30
+ ActiveSupport::Duration.hours(self)
46
31
  end
47
32
  alias :hour :hours
48
33
 
34
+ # Returns a Duration instance matching the number of days provided.
35
+ #
36
+ # 2.days # => 2 days
49
37
  def days
50
- ActiveSupport::Duration.new(self * 24.hours, [[:days, self]])
38
+ ActiveSupport::Duration.days(self)
51
39
  end
52
40
  alias :day :days
53
41
 
42
+ # Returns a Duration instance matching the number of weeks provided.
43
+ #
44
+ # 2.weeks # => 2 weeks
54
45
  def weeks
55
- ActiveSupport::Duration.new(self * 7.days, [[:days, self * 7]])
46
+ ActiveSupport::Duration.weeks(self)
56
47
  end
57
48
  alias :week :weeks
58
49
 
50
+ # Returns a Duration instance matching the number of fortnights provided.
51
+ #
52
+ # 2.fortnights # => 4 weeks
59
53
  def fortnights
60
- ActiveSupport::Duration.new(self * 2.weeks, [[:days, self * 14]])
54
+ ActiveSupport::Duration.weeks(self * 2)
61
55
  end
62
56
  alias :fortnight :fortnights
63
57
 
64
- # Reads best without arguments: 10.minutes.ago
65
- def ago(time = ::Time.current)
66
- time - self
67
- end
68
-
69
- # Reads best with argument: 10.minutes.until(time)
70
- alias :until :ago
71
-
72
- # Reads best with argument: 10.minutes.since(time)
73
- def since(time = ::Time.current)
74
- time + self
58
+ # Returns the number of milliseconds equivalent to the seconds provided.
59
+ # Used with the standard time durations.
60
+ #
61
+ # 2.in_milliseconds # => 2000
62
+ # 1.hour.in_milliseconds # => 3600000
63
+ def in_milliseconds
64
+ self * 1000
75
65
  end
76
-
77
- # Reads best without arguments: 10.minutes.from_now
78
- alias :from_now :since
79
66
  end
@@ -1,3 +1,6 @@
1
- require 'active_support/core_ext/numeric/bytes'
2
- require 'active_support/core_ext/numeric/time'
3
- require 'active_support/core_ext/numeric/conversions'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/numeric/bytes"
4
+ require "active_support/core_ext/numeric/time"
5
+ require "active_support/core_ext/numeric/conversions"
6
+ require "active_support/core_ext/numeric/deprecated_conversions" unless ENV["RAILS_DISABLE_DEPRECATED_TO_S_CONVERSION"]
@@ -1,10 +1,45 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Object
2
- # A duck-type assistant method. For example, Active Support extends Date
3
- # to define an <tt>acts_like_date?</tt> method, and extends Time to define
4
- # <tt>acts_like_time?</tt>. As a result, we can do <tt>x.acts_like?(:time)</tt> and
5
- # <tt>x.acts_like?(:date)</tt> to do duck-type-safe comparisons, since classes that
6
- # we want to act like Time simply need to define an <tt>acts_like_time?</tt> method.
4
+ # Provides a way to check whether some class acts like some other class based on the existence of
5
+ # an appropriately-named marker method.
6
+ #
7
+ # A class that provides the same interface as <tt>SomeClass</tt> may define a marker method named
8
+ # <tt>acts_like_some_class?</tt> to signal its compatibility to callers of
9
+ # <tt>acts_like?(:some_class)</tt>.
10
+ #
11
+ # For example, Active Support extends <tt>Date</tt> to define an <tt>acts_like_date?</tt> method,
12
+ # and extends <tt>Time</tt> to define <tt>acts_like_time?</tt>. As a result, developers can call
13
+ # <tt>x.acts_like?(:time)</tt> and <tt>x.acts_like?(:date)</tt> to test duck-type compatibility,
14
+ # and classes that are able to act like <tt>Time</tt> can also define an <tt>acts_like_time?</tt>
15
+ # method to interoperate.
16
+ #
17
+ # Note that the marker method is only expected to exist. It isn't called, so its body or return
18
+ # value are irrelevant.
19
+ #
20
+ # ==== Example: A class that provides the same interface as <tt>String</tt>
21
+ #
22
+ # This class may define:
23
+ #
24
+ # class Stringish
25
+ # def acts_like_string?
26
+ # end
27
+ # end
28
+ #
29
+ # Then client code can query for duck-type-safeness this way:
30
+ #
31
+ # Stringish.new.acts_like?(:string) # => true
32
+ #
7
33
  def acts_like?(duck)
8
- respond_to? :"acts_like_#{duck}?"
34
+ case duck
35
+ when :time
36
+ respond_to? :acts_like_time?
37
+ when :date
38
+ respond_to? :acts_like_date?
39
+ when :string
40
+ respond_to? :acts_like_string?
41
+ else
42
+ respond_to? :"acts_like_#{duck}?"
43
+ end
9
44
  end
10
45
  end