activesupport 1.2.4 → 8.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (309) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +505 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +40 -0
  5. data/lib/active_support/actionable_error.rb +50 -0
  6. data/lib/active_support/all.rb +5 -0
  7. data/lib/active_support/array_inquirer.rb +50 -0
  8. data/lib/active_support/backtrace_cleaner.rb +234 -0
  9. data/lib/active_support/benchmark.rb +21 -0
  10. data/lib/active_support/benchmarkable.rb +53 -0
  11. data/lib/active_support/broadcast_logger.rb +238 -0
  12. data/lib/active_support/builder.rb +8 -0
  13. data/lib/active_support/cache/coder.rb +153 -0
  14. data/lib/active_support/cache/entry.rb +134 -0
  15. data/lib/active_support/cache/file_store.rb +244 -0
  16. data/lib/active_support/cache/mem_cache_store.rb +288 -0
  17. data/lib/active_support/cache/memory_store.rb +264 -0
  18. data/lib/active_support/cache/null_store.rb +62 -0
  19. data/lib/active_support/cache/redis_cache_store.rb +498 -0
  20. data/lib/active_support/cache/serializer_with_fallback.rb +152 -0
  21. data/lib/active_support/cache/strategy/local_cache.rb +246 -0
  22. data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
  23. data/lib/active_support/cache.rb +1170 -0
  24. data/lib/active_support/callbacks.rb +960 -0
  25. data/lib/active_support/class_attribute.rb +33 -0
  26. data/lib/active_support/code_generator.rb +79 -0
  27. data/lib/active_support/concern.rb +217 -0
  28. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +18 -0
  29. data/lib/active_support/concurrency/null_lock.rb +13 -0
  30. data/lib/active_support/concurrency/share_lock.rb +225 -0
  31. data/lib/active_support/concurrency/thread_monitor.rb +55 -0
  32. data/lib/active_support/configurable.rb +193 -0
  33. data/lib/active_support/configuration_file.rb +60 -0
  34. data/lib/active_support/continuous_integration.rb +145 -0
  35. data/lib/active_support/core_ext/array/access.rb +100 -0
  36. data/lib/active_support/core_ext/array/conversions.rb +209 -26
  37. data/lib/active_support/core_ext/array/extract.rb +21 -0
  38. data/lib/active_support/core_ext/array/extract_options.rb +31 -0
  39. data/lib/active_support/core_ext/array/grouping.rb +109 -0
  40. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  41. data/lib/active_support/core_ext/array/wrap.rb +48 -0
  42. data/lib/active_support/core_ext/array.rb +8 -4
  43. data/lib/active_support/core_ext/benchmark.rb +6 -0
  44. data/lib/active_support/core_ext/big_decimal/conversions.rb +14 -0
  45. data/lib/active_support/core_ext/big_decimal.rb +3 -0
  46. data/lib/active_support/core_ext/class/attribute.rb +137 -0
  47. data/lib/active_support/core_ext/class/attribute_accessors.rb +6 -0
  48. data/lib/active_support/core_ext/class/subclasses.rb +24 -0
  49. data/lib/active_support/core_ext/class.rb +4 -0
  50. data/lib/active_support/core_ext/date/acts_like.rb +10 -0
  51. data/lib/active_support/core_ext/date/blank.rb +18 -0
  52. data/lib/active_support/core_ext/date/calculations.rb +161 -0
  53. data/lib/active_support/core_ext/date/conversions.rb +95 -28
  54. data/lib/active_support/core_ext/date/zones.rb +8 -0
  55. data/lib/active_support/core_ext/date.rb +6 -5
  56. data/lib/active_support/core_ext/date_and_time/calculations.rb +374 -0
  57. data/lib/active_support/core_ext/date_and_time/compatibility.rb +23 -0
  58. data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
  59. data/lib/active_support/core_ext/date_time/acts_like.rb +16 -0
  60. data/lib/active_support/core_ext/date_time/blank.rb +18 -0
  61. data/lib/active_support/core_ext/date_time/calculations.rb +215 -0
  62. data/lib/active_support/core_ext/date_time/compatibility.rb +16 -0
  63. data/lib/active_support/core_ext/date_time/conversions.rb +108 -0
  64. data/lib/active_support/core_ext/date_time.rb +7 -0
  65. data/lib/active_support/core_ext/digest/uuid.rb +76 -0
  66. data/lib/active_support/core_ext/digest.rb +3 -0
  67. data/lib/active_support/core_ext/enumerable.rb +277 -7
  68. data/lib/active_support/core_ext/erb/util.rb +201 -0
  69. data/lib/active_support/core_ext/file/atomic.rb +72 -0
  70. data/lib/active_support/core_ext/file.rb +3 -0
  71. data/lib/active_support/core_ext/hash/conversions.rb +262 -0
  72. data/lib/active_support/core_ext/hash/deep_merge.rb +43 -0
  73. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  74. data/lib/active_support/core_ext/hash/except.rb +12 -0
  75. data/lib/active_support/core_ext/hash/indifferent_access.rb +19 -55
  76. data/lib/active_support/core_ext/hash/keys.rb +134 -44
  77. data/lib/active_support/core_ext/hash/reverse_merge.rb +22 -22
  78. data/lib/active_support/core_ext/hash/slice.rb +27 -0
  79. data/lib/active_support/core_ext/hash.rb +9 -8
  80. data/lib/active_support/core_ext/integer/inflections.rb +29 -13
  81. data/lib/active_support/core_ext/integer/multiple.rb +12 -0
  82. data/lib/active_support/core_ext/integer/time.rb +22 -0
  83. data/lib/active_support/core_ext/integer.rb +4 -6
  84. data/lib/active_support/core_ext/kernel/concern.rb +14 -0
  85. data/lib/active_support/core_ext/kernel/reporting.rb +45 -0
  86. data/lib/active_support/core_ext/kernel/singleton_class.rb +8 -0
  87. data/lib/active_support/core_ext/kernel.rb +4 -78
  88. data/lib/active_support/core_ext/load_error.rb +6 -35
  89. data/lib/active_support/core_ext/module/aliasing.rb +31 -0
  90. data/lib/active_support/core_ext/module/anonymous.rb +30 -0
  91. data/lib/active_support/core_ext/module/attr_internal.rb +48 -0
  92. data/lib/active_support/core_ext/module/attribute_accessors.rb +214 -0
  93. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +175 -0
  94. data/lib/active_support/core_ext/module/concerning.rb +140 -0
  95. data/lib/active_support/core_ext/module/delegation.rb +225 -0
  96. data/lib/active_support/core_ext/module/deprecation.rb +25 -0
  97. data/lib/active_support/core_ext/module/introspection.rb +65 -0
  98. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  99. data/lib/active_support/core_ext/module/remove_method.rb +17 -0
  100. data/lib/active_support/core_ext/module.rb +13 -0
  101. data/lib/active_support/core_ext/name_error.rb +59 -0
  102. data/lib/active_support/core_ext/numeric/bytes.rb +73 -42
  103. data/lib/active_support/core_ext/numeric/conversions.rb +145 -0
  104. data/lib/active_support/core_ext/numeric/time.rb +64 -57
  105. data/lib/active_support/core_ext/numeric.rb +4 -6
  106. data/lib/active_support/core_ext/object/acts_like.rb +45 -0
  107. data/lib/active_support/core_ext/object/blank.rb +199 -0
  108. data/lib/active_support/core_ext/object/conversions.rb +6 -0
  109. data/lib/active_support/core_ext/object/deep_dup.rb +71 -0
  110. data/lib/active_support/core_ext/object/duplicable.rb +69 -0
  111. data/lib/active_support/core_ext/object/inclusion.rb +37 -0
  112. data/lib/active_support/core_ext/object/instance_variables.rb +32 -0
  113. data/lib/active_support/core_ext/object/json.rb +267 -0
  114. data/lib/active_support/core_ext/object/to_param.rb +3 -0
  115. data/lib/active_support/core_ext/object/to_query.rb +93 -0
  116. data/lib/active_support/core_ext/object/try.rb +158 -0
  117. data/lib/active_support/core_ext/object/with.rb +46 -0
  118. data/lib/active_support/core_ext/object/with_options.rb +101 -0
  119. data/lib/active_support/core_ext/object.rb +17 -0
  120. data/lib/active_support/core_ext/pathname/blank.rb +20 -0
  121. data/lib/active_support/core_ext/pathname/existence.rb +23 -0
  122. data/lib/active_support/core_ext/pathname.rb +4 -0
  123. data/lib/active_support/core_ext/range/compare_range.rb +57 -0
  124. data/lib/active_support/core_ext/range/conversions.rb +58 -17
  125. data/lib/active_support/core_ext/range/overlap.rb +40 -0
  126. data/lib/active_support/core_ext/range/sole.rb +17 -0
  127. data/lib/active_support/core_ext/range.rb +5 -4
  128. data/lib/active_support/core_ext/regexp.rb +14 -0
  129. data/lib/active_support/core_ext/securerandom.rb +57 -0
  130. data/lib/active_support/core_ext/string/access.rb +93 -56
  131. data/lib/active_support/core_ext/string/behavior.rb +8 -0
  132. data/lib/active_support/core_ext/string/conversions.rb +57 -16
  133. data/lib/active_support/core_ext/string/exclude.rb +13 -0
  134. data/lib/active_support/core_ext/string/filters.rb +151 -0
  135. data/lib/active_support/core_ext/string/indent.rb +45 -0
  136. data/lib/active_support/core_ext/string/inflections.rb +297 -54
  137. data/lib/active_support/core_ext/string/inquiry.rb +16 -0
  138. data/lib/active_support/core_ext/string/multibyte.rb +67 -0
  139. data/lib/active_support/core_ext/string/output_safety.rb +235 -0
  140. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -18
  141. data/lib/active_support/core_ext/string/strip.rb +27 -0
  142. data/lib/active_support/core_ext/string/zones.rb +16 -0
  143. data/lib/active_support/core_ext/string.rb +14 -10
  144. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
  145. data/lib/active_support/core_ext/symbol.rb +3 -0
  146. data/lib/active_support/core_ext/thread/backtrace/location.rb +7 -0
  147. data/lib/active_support/core_ext/time/acts_like.rb +10 -0
  148. data/lib/active_support/core_ext/time/calculations.rb +358 -153
  149. data/lib/active_support/core_ext/time/compatibility.rb +15 -0
  150. data/lib/active_support/core_ext/time/conversions.rb +69 -30
  151. data/lib/active_support/core_ext/time/zones.rb +97 -0
  152. data/lib/active_support/core_ext/time.rb +6 -6
  153. data/lib/active_support/core_ext.rb +5 -1
  154. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  155. data/lib/active_support/current_attributes.rb +243 -0
  156. data/lib/active_support/deep_mergeable.rb +53 -0
  157. data/lib/active_support/delegation.rb +183 -0
  158. data/lib/active_support/dependencies/autoload.rb +72 -0
  159. data/lib/active_support/dependencies/interlock.rb +55 -0
  160. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  161. data/lib/active_support/dependencies.rb +84 -222
  162. data/lib/active_support/deprecation/behaviors.rb +148 -0
  163. data/lib/active_support/deprecation/constant_accessor.rb +74 -0
  164. data/lib/active_support/deprecation/deprecators.rb +104 -0
  165. data/lib/active_support/deprecation/disallowed.rb +54 -0
  166. data/lib/active_support/deprecation/method_wrappers.rb +68 -0
  167. data/lib/active_support/deprecation/proxy_wrappers.rb +189 -0
  168. data/lib/active_support/deprecation/reporting.rb +162 -0
  169. data/lib/active_support/deprecation.rb +81 -0
  170. data/lib/active_support/deprecator.rb +7 -0
  171. data/lib/active_support/descendants_tracker.rb +112 -0
  172. data/lib/active_support/digest.rb +22 -0
  173. data/lib/active_support/duration/iso8601_parser.rb +123 -0
  174. data/lib/active_support/duration/iso8601_serializer.rb +64 -0
  175. data/lib/active_support/duration.rb +524 -0
  176. data/lib/active_support/editor.rb +70 -0
  177. data/lib/active_support/encrypted_configuration.rb +126 -0
  178. data/lib/active_support/encrypted_file.rb +133 -0
  179. data/lib/active_support/environment_inquirer.rb +40 -0
  180. data/lib/active_support/error_reporter/test_helper.rb +15 -0
  181. data/lib/active_support/error_reporter.rb +318 -0
  182. data/lib/active_support/event_reporter/test_helper.rb +32 -0
  183. data/lib/active_support/event_reporter.rb +592 -0
  184. data/lib/active_support/evented_file_update_checker.rb +185 -0
  185. data/lib/active_support/execution_context/test_helper.rb +13 -0
  186. data/lib/active_support/execution_context.rb +110 -0
  187. data/lib/active_support/execution_wrapper.rb +150 -0
  188. data/lib/active_support/executor/test_helper.rb +7 -0
  189. data/lib/active_support/executor.rb +8 -0
  190. data/lib/active_support/file_update_checker.rb +166 -0
  191. data/lib/active_support/fork_tracker.rb +43 -0
  192. data/lib/active_support/gem_version.rb +17 -0
  193. data/lib/active_support/gzip.rb +41 -0
  194. data/lib/active_support/hash_with_indifferent_access.rb +464 -0
  195. data/lib/active_support/html_safe_translation.rb +56 -0
  196. data/lib/active_support/i18n.rb +17 -0
  197. data/lib/active_support/i18n_railtie.rb +140 -0
  198. data/lib/active_support/inflections.rb +68 -49
  199. data/lib/active_support/inflector/inflections.rb +290 -0
  200. data/lib/active_support/inflector/methods.rb +387 -0
  201. data/lib/active_support/inflector/transliterate.rb +147 -0
  202. data/lib/active_support/inflector.rb +7 -164
  203. data/lib/active_support/isolated_execution_state.rb +76 -0
  204. data/lib/active_support/json/decoding.rb +78 -0
  205. data/lib/active_support/json/encoding.rb +256 -0
  206. data/lib/active_support/json.rb +4 -0
  207. data/lib/active_support/key_generator.rb +66 -0
  208. data/lib/active_support/lazy_load_hooks.rb +107 -0
  209. data/lib/active_support/locale/en.rb +33 -0
  210. data/lib/active_support/locale/en.yml +141 -0
  211. data/lib/active_support/log_subscriber/test_helper.rb +106 -0
  212. data/lib/active_support/log_subscriber.rb +188 -0
  213. data/lib/active_support/logger.rb +55 -0
  214. data/lib/active_support/logger_silence.rb +21 -0
  215. data/lib/active_support/logger_thread_safe_level.rb +50 -0
  216. data/lib/active_support/message_encryptor.rb +374 -0
  217. data/lib/active_support/message_encryptors.rb +193 -0
  218. data/lib/active_support/message_pack/cache_serializer.rb +23 -0
  219. data/lib/active_support/message_pack/extensions.rb +310 -0
  220. data/lib/active_support/message_pack/serializer.rb +63 -0
  221. data/lib/active_support/message_pack.rb +50 -0
  222. data/lib/active_support/message_verifier.rb +377 -0
  223. data/lib/active_support/message_verifiers.rb +189 -0
  224. data/lib/active_support/messages/codec.rb +65 -0
  225. data/lib/active_support/messages/metadata.rb +146 -0
  226. data/lib/active_support/messages/rotation_configuration.rb +23 -0
  227. data/lib/active_support/messages/rotation_coordinator.rb +102 -0
  228. data/lib/active_support/messages/rotator.rb +69 -0
  229. data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
  230. data/lib/active_support/multibyte/chars.rb +188 -0
  231. data/lib/active_support/multibyte/unicode.rb +42 -0
  232. data/lib/active_support/multibyte.rb +27 -0
  233. data/lib/active_support/notifications/fanout.rb +467 -0
  234. data/lib/active_support/notifications/instrumenter.rb +240 -0
  235. data/lib/active_support/notifications.rb +281 -0
  236. data/lib/active_support/number_helper/number_converter.rb +190 -0
  237. data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
  238. data/lib/active_support/number_helper/number_to_delimited_converter.rb +30 -0
  239. data/lib/active_support/number_helper/number_to_human_converter.rb +69 -0
  240. data/lib/active_support/number_helper/number_to_human_size_converter.rb +60 -0
  241. data/lib/active_support/number_helper/number_to_percentage_converter.rb +16 -0
  242. data/lib/active_support/number_helper/number_to_phone_converter.rb +60 -0
  243. data/lib/active_support/number_helper/number_to_rounded_converter.rb +59 -0
  244. data/lib/active_support/number_helper/rounding_helper.rb +46 -0
  245. data/lib/active_support/number_helper.rb +479 -0
  246. data/lib/active_support/option_merger.rb +38 -0
  247. data/lib/active_support/ordered_hash.rb +50 -0
  248. data/lib/active_support/ordered_options.rb +141 -25
  249. data/lib/active_support/parameter_filter.rb +157 -0
  250. data/lib/active_support/rails.rb +26 -0
  251. data/lib/active_support/railtie.rb +180 -0
  252. data/lib/active_support/reloader.rb +138 -0
  253. data/lib/active_support/rescuable.rb +176 -0
  254. data/lib/active_support/secure_compare_rotator.rb +58 -0
  255. data/lib/active_support/security_utils.rb +38 -0
  256. data/lib/active_support/string_inquirer.rb +35 -0
  257. data/lib/active_support/structured_event_subscriber.rb +99 -0
  258. data/lib/active_support/subscriber.rb +141 -0
  259. data/lib/active_support/syntax_error_proxy.rb +67 -0
  260. data/lib/active_support/tagged_logging.rb +157 -0
  261. data/lib/active_support/test_case.rb +365 -0
  262. data/lib/active_support/testing/assertions.rb +369 -0
  263. data/lib/active_support/testing/autorun.rb +10 -0
  264. data/lib/active_support/testing/constant_lookup.rb +51 -0
  265. data/lib/active_support/testing/constant_stubbing.rb +54 -0
  266. data/lib/active_support/testing/declarative.rb +28 -0
  267. data/lib/active_support/testing/deprecation.rb +82 -0
  268. data/lib/active_support/testing/error_reporter_assertions.rb +124 -0
  269. data/lib/active_support/testing/event_reporter_assertions.rb +227 -0
  270. data/lib/active_support/testing/file_fixtures.rb +38 -0
  271. data/lib/active_support/testing/isolation.rb +121 -0
  272. data/lib/active_support/testing/method_call_assertions.rb +69 -0
  273. data/lib/active_support/testing/notification_assertions.rb +92 -0
  274. data/lib/active_support/testing/parallelization/server.rb +98 -0
  275. data/lib/active_support/testing/parallelization/worker.rb +107 -0
  276. data/lib/active_support/testing/parallelization.rb +79 -0
  277. data/lib/active_support/testing/parallelize_executor.rb +81 -0
  278. data/lib/active_support/testing/setup_and_teardown.rb +57 -0
  279. data/lib/active_support/testing/stream.rb +41 -0
  280. data/lib/active_support/testing/tagged_logging.rb +27 -0
  281. data/lib/active_support/testing/tests_without_assertions.rb +19 -0
  282. data/lib/active_support/testing/time_helpers.rb +273 -0
  283. data/lib/active_support/time.rb +20 -0
  284. data/lib/active_support/time_with_zone.rb +613 -0
  285. data/lib/active_support/values/time_zone.rb +599 -158
  286. data/lib/active_support/version.rb +7 -6
  287. data/lib/active_support/xml_mini/jdom.rb +175 -0
  288. data/lib/active_support/xml_mini/libxml.rb +80 -0
  289. data/lib/active_support/xml_mini/libxmlsax.rb +83 -0
  290. data/lib/active_support/xml_mini/nokogiri.rb +83 -0
  291. data/lib/active_support/xml_mini/nokogirisax.rb +86 -0
  292. data/lib/active_support/xml_mini/rexml.rb +137 -0
  293. data/lib/active_support/xml_mini.rb +212 -0
  294. data/lib/active_support.rb +122 -10
  295. metadata +524 -93
  296. data/CHANGELOG +0 -283
  297. data/lib/active_support/binding_of_caller.rb +0 -84
  298. data/lib/active_support/breakpoint.rb +0 -523
  299. data/lib/active_support/class_attribute_accessors.rb +0 -57
  300. data/lib/active_support/class_inheritable_attributes.rb +0 -117
  301. data/lib/active_support/clean_logger.rb +0 -36
  302. data/lib/active_support/core_ext/blank.rb +0 -38
  303. data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +0 -14
  304. data/lib/active_support/core_ext/cgi.rb +0 -5
  305. data/lib/active_support/core_ext/exception.rb +0 -29
  306. data/lib/active_support/core_ext/integer/even_odd.rb +0 -24
  307. data/lib/active_support/core_ext/object_and_class.rb +0 -44
  308. data/lib/active_support/module_attribute_accessors.rb +0 -57
  309. data/lib/active_support/whiny_nil.rb +0 -38
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Object
4
+ # Returns true if this object is included in the argument.
5
+ #
6
+ # When argument is a +Range+, +#cover?+ is used to properly handle inclusion
7
+ # check within open ranges. Otherwise, argument must be any object which responds
8
+ # to +#include?+. Usage:
9
+ #
10
+ # characters = ["Konata", "Kagami", "Tsukasa"]
11
+ # "Konata".in?(characters) # => true
12
+ #
13
+ # For non +Range+ arguments, this will throw an +ArgumentError+ if the argument
14
+ # doesn't respond to +#include?+.
15
+ def in?(another_object)
16
+ case another_object
17
+ when Range
18
+ another_object.cover?(self)
19
+ else
20
+ another_object.include?(self)
21
+ end
22
+ rescue NoMethodError
23
+ raise ArgumentError.new("The parameter passed to #in? must respond to #include?")
24
+ end
25
+
26
+ # Returns the receiver if it's included in the argument otherwise returns +nil+.
27
+ # Argument must be any object which responds to +#include?+. Usage:
28
+ #
29
+ # params[:bucket_type].presence_in %w( project calendar )
30
+ #
31
+ # This will throw an +ArgumentError+ if the argument doesn't respond to +#include?+.
32
+ #
33
+ # @return [Object]
34
+ def presence_in(another_object)
35
+ in?(another_object) ? self : nil
36
+ end
37
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Object
4
+ # Returns a hash with string keys that maps instance variable names without "@" to their
5
+ # corresponding values.
6
+ #
7
+ # class C
8
+ # def initialize(x, y)
9
+ # @x, @y = x, y
10
+ # end
11
+ # end
12
+ #
13
+ # C.new(0, 1).instance_values # => {"x" => 0, "y" => 1}
14
+ def instance_values
15
+ instance_variables.to_h do |ivar|
16
+ [ivar[1..-1].freeze, instance_variable_get(ivar)]
17
+ end
18
+ end
19
+
20
+ # Returns an array of instance variable names as strings including "@".
21
+ #
22
+ # class C
23
+ # def initialize(x, y)
24
+ # @x, @y = x, y
25
+ # end
26
+ # end
27
+ #
28
+ # C.new(0, 1).instance_variable_names # => ["@y", "@x"]
29
+ def instance_variable_names
30
+ instance_variables.map(&:name)
31
+ end
32
+ end
@@ -0,0 +1,267 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Hack to load JSON gem first so we can override its to_json.
4
+ require "json"
5
+ require "bigdecimal"
6
+ require "ipaddr"
7
+ require "uri"
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.include(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 Data # :nodoc:
69
+ def as_json(options = nil)
70
+ to_h.as_json(options)
71
+ end
72
+ end
73
+
74
+ class Struct # :nodoc:
75
+ def as_json(options = nil)
76
+ to_h.as_json(options)
77
+ end
78
+ end
79
+
80
+ class TrueClass
81
+ def as_json(options = nil) # :nodoc:
82
+ self
83
+ end
84
+ end
85
+
86
+ class FalseClass
87
+ def as_json(options = nil) # :nodoc:
88
+ self
89
+ end
90
+ end
91
+
92
+ class NilClass
93
+ def as_json(options = nil) # :nodoc:
94
+ self
95
+ end
96
+ end
97
+
98
+ class String
99
+ def as_json(options = nil) # :nodoc:
100
+ self
101
+ end
102
+ end
103
+
104
+ class Symbol
105
+ def as_json(options = nil) # :nodoc:
106
+ name
107
+ end
108
+ end
109
+
110
+ class Numeric
111
+ def as_json(options = nil) # :nodoc:
112
+ self
113
+ end
114
+ end
115
+
116
+ class Float
117
+ # Encoding Infinity or NaN to JSON should return "null". The default returns
118
+ # "Infinity" or "NaN" which are not valid JSON.
119
+ def as_json(options = nil) # :nodoc:
120
+ finite? ? self : nil
121
+ end
122
+ end
123
+
124
+ class BigDecimal
125
+ # A BigDecimal would be naturally represented as a JSON number. Most libraries,
126
+ # however, parse non-integer JSON numbers directly as floats. Clients using
127
+ # those libraries would get in general a wrong number and no way to recover
128
+ # other than manually inspecting the string with the JSON code itself.
129
+ #
130
+ # That's why a JSON string is returned. The JSON literal is not numeric, but
131
+ # if the other end knows by contract that the data is supposed to be a
132
+ # BigDecimal, it still has the chance to post-process the string and get the
133
+ # real value.
134
+ def as_json(options = nil) # :nodoc:
135
+ finite? ? to_s : nil
136
+ end
137
+ end
138
+
139
+ class Regexp
140
+ def as_json(options = nil) # :nodoc:
141
+ to_s
142
+ end
143
+ end
144
+
145
+ module Enumerable
146
+ def as_json(options = nil) # :nodoc:
147
+ to_a.as_json(options)
148
+ end
149
+ end
150
+
151
+ class IO
152
+ def as_json(options = nil) # :nodoc:
153
+ to_s
154
+ end
155
+ end
156
+
157
+ class Range
158
+ def as_json(options = nil) # :nodoc:
159
+ to_s
160
+ end
161
+ end
162
+
163
+ class Array
164
+ def as_json(options = nil) # :nodoc:
165
+ if options
166
+ options = options.dup.freeze unless options.frozen?
167
+ map { |v| v.as_json(options) }
168
+ else
169
+ map { |v| v.as_json }
170
+ end
171
+ end
172
+ end
173
+
174
+ class Hash
175
+ def as_json(options = nil) # :nodoc:
176
+ # create a subset of the hash by applying :only or :except
177
+ subset = if options
178
+ if attrs = options[:only]
179
+ slice(*Array(attrs))
180
+ elsif attrs = options[:except]
181
+ except(*Array(attrs))
182
+ else
183
+ self
184
+ end
185
+ else
186
+ self
187
+ end
188
+
189
+ result = {}
190
+ if options
191
+ options = options.dup.freeze unless options.frozen?
192
+ subset.each { |k, v| result[k.to_s] = v.as_json(options) }
193
+ else
194
+ subset.each { |k, v| result[k.to_s] = v.as_json }
195
+ end
196
+ result
197
+ end
198
+ end
199
+
200
+ class Time
201
+ def as_json(options = nil) # :nodoc:
202
+ if ActiveSupport::JSON::Encoding.use_standard_json_time_format
203
+ xmlschema(ActiveSupport::JSON::Encoding.time_precision)
204
+ else
205
+ %(#{strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)})
206
+ end
207
+ end
208
+ end
209
+
210
+ class Date
211
+ def as_json(options = nil) # :nodoc:
212
+ if ActiveSupport::JSON::Encoding.use_standard_json_time_format
213
+ strftime("%Y-%m-%d")
214
+ else
215
+ strftime("%Y/%m/%d")
216
+ end
217
+ end
218
+ end
219
+
220
+ class DateTime
221
+ def as_json(options = nil) # :nodoc:
222
+ if ActiveSupport::JSON::Encoding.use_standard_json_time_format
223
+ xmlschema(ActiveSupport::JSON::Encoding.time_precision)
224
+ else
225
+ strftime("%Y/%m/%d %H:%M:%S %z")
226
+ end
227
+ end
228
+ end
229
+
230
+ class URI::Generic # :nodoc:
231
+ def as_json(options = nil)
232
+ to_s
233
+ end
234
+ end
235
+
236
+ class Pathname # :nodoc:
237
+ def as_json(options = nil)
238
+ to_s
239
+ end
240
+ end
241
+
242
+ unless IPAddr.method_defined?(:as_json, false)
243
+ # Use `IPAddr#as_json` from the IPAddr gem if the version is 1.2.7 or higher.
244
+ class IPAddr # :nodoc:
245
+ def as_json(options = nil)
246
+ if ipv4? && prefix == 32
247
+ to_s
248
+ elsif ipv6? && prefix == 128
249
+ to_s
250
+ else
251
+ "#{self}/#{prefix}"
252
+ end
253
+ end
254
+ end
255
+ end
256
+
257
+ class Process::Status # :nodoc:
258
+ def as_json(options = nil)
259
+ { exitstatus: exitstatus, pid: pid }
260
+ end
261
+ end
262
+
263
+ class Exception
264
+ def as_json(options = nil)
265
+ to_s
266
+ end
267
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/object/to_query"
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cgi/escape"
4
+ require "cgi/util" if RUBY_VERSION < "3.5"
5
+
6
+ class Object
7
+ # Alias of <tt>to_s</tt>.
8
+ def to_param
9
+ to_s
10
+ end
11
+
12
+ # Converts an object into a string suitable for use as a URL query string,
13
+ # using the given <tt>key</tt> as the param name.
14
+ def to_query(key)
15
+ "#{CGI.escape(key.to_param)}=#{CGI.escape(to_param.to_s)}"
16
+ end
17
+ end
18
+
19
+ class NilClass
20
+ # Returns a CGI-escaped +key+.
21
+ def to_query(key)
22
+ CGI.escape(key.to_param)
23
+ end
24
+
25
+ # Returns +self+.
26
+ def to_param
27
+ self
28
+ end
29
+ end
30
+
31
+ class TrueClass
32
+ # Returns +self+.
33
+ def to_param
34
+ self
35
+ end
36
+ end
37
+
38
+ class FalseClass
39
+ # Returns +self+.
40
+ def to_param
41
+ self
42
+ end
43
+ end
44
+
45
+ class Array
46
+ # Calls <tt>to_param</tt> on all its elements and joins the result with
47
+ # slashes. This is used by <tt>url_for</tt> in Action Pack.
48
+ def to_param
49
+ collect(&:to_param).join "/"
50
+ end
51
+
52
+ # Converts an array into a string suitable for use as a URL query string,
53
+ # using the given +key+ as the param name.
54
+ #
55
+ # ['Rails', 'coding'].to_query('hobbies') # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding"
56
+ def to_query(key)
57
+ prefix = "#{key}[]"
58
+
59
+ if empty?
60
+ nil.to_query(prefix)
61
+ else
62
+ collect { |value| value.to_query(prefix) }.join "&"
63
+ end
64
+ end
65
+ end
66
+
67
+ class Hash
68
+ # Returns a string representation of the receiver suitable for use as a URL
69
+ # query string:
70
+ #
71
+ # {name: 'David', nationality: 'Danish'}.to_query
72
+ # # => "name=David&nationality=Danish"
73
+ #
74
+ # An optional namespace can be passed to enclose key names:
75
+ #
76
+ # {name: 'David', nationality: 'Danish'}.to_query('user')
77
+ # # => "user%5Bname%5D=David&user%5Bnationality%5D=Danish"
78
+ #
79
+ # The string pairs "key=value" that conform the query string
80
+ # are sorted lexicographically in ascending order.
81
+ def to_query(namespace = nil)
82
+ query = filter_map do |key, value|
83
+ unless (value.is_a?(Hash) || value.is_a?(Array)) && value.empty?
84
+ value.to_query(namespace ? "#{namespace}[#{key}]" : key)
85
+ end
86
+ end
87
+
88
+ query.sort! unless namespace.to_s.include?("[]")
89
+ query.join("&")
90
+ end
91
+
92
+ alias_method :to_param, :to_query
93
+ end
@@ -0,0 +1,158 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "delegate"
4
+
5
+ module ActiveSupport
6
+ module Tryable # :nodoc:
7
+ def try(*args, &block)
8
+ if args.empty? && block_given?
9
+ if block.arity == 0
10
+ instance_eval(&block)
11
+ else
12
+ yield self
13
+ end
14
+ elsif respond_to?(args.first)
15
+ public_send(*args, &block)
16
+ end
17
+ end
18
+ ruby2_keywords(:try)
19
+
20
+ def try!(*args, &block)
21
+ if args.empty? && block_given?
22
+ if block.arity == 0
23
+ instance_eval(&block)
24
+ else
25
+ yield self
26
+ end
27
+ else
28
+ public_send(*args, &block)
29
+ end
30
+ end
31
+ ruby2_keywords(:try!)
32
+ end
33
+ end
34
+
35
+ class Object
36
+ include ActiveSupport::Tryable
37
+
38
+ ##
39
+ # :method: try
40
+ #
41
+ # :call-seq:
42
+ # try(*args, &block)
43
+ #
44
+ # Invokes the public method whose name goes as first argument just like
45
+ # +public_send+ does, except that if the receiver does not respond to it the
46
+ # call returns +nil+ rather than raising an exception.
47
+ #
48
+ # This method is defined to be able to write
49
+ #
50
+ # @person.try(:name)
51
+ #
52
+ # instead of
53
+ #
54
+ # @person.name if @person
55
+ #
56
+ # +try+ calls can be chained:
57
+ #
58
+ # @person.try(:spouse).try(:name)
59
+ #
60
+ # instead of
61
+ #
62
+ # @person.spouse.name if @person && @person.spouse
63
+ #
64
+ # +try+ will also return +nil+ if the receiver does not respond to the method:
65
+ #
66
+ # @person.try(:non_existing_method) # => nil
67
+ #
68
+ # instead of
69
+ #
70
+ # @person.non_existing_method if @person.respond_to?(:non_existing_method) # => nil
71
+ #
72
+ # +try+ returns +nil+ when called on +nil+ regardless of whether it responds
73
+ # to the method:
74
+ #
75
+ # nil.try(:to_i) # => nil, rather than 0
76
+ #
77
+ # Arguments and blocks are forwarded to the method if invoked:
78
+ #
79
+ # @posts.try(:each_slice, 2) do |a, b|
80
+ # ...
81
+ # end
82
+ #
83
+ # The number of arguments in the signature must match. If the object responds
84
+ # to the method the call is attempted and +ArgumentError+ is still raised
85
+ # in case of argument mismatch.
86
+ #
87
+ # If +try+ is called without arguments it yields the receiver to a given
88
+ # block unless it is +nil+:
89
+ #
90
+ # @person.try do |p|
91
+ # ...
92
+ # end
93
+ #
94
+ # You can also call try with a block without accepting an argument, and the block
95
+ # will be instance_eval'ed instead:
96
+ #
97
+ # @person.try { upcase.truncate(50) }
98
+ #
99
+ # Please also note that +try+ is defined on +Object+. Therefore, it won't work
100
+ # with instances of classes that do not have +Object+ among their ancestors,
101
+ # like direct subclasses of +BasicObject+.
102
+
103
+ ##
104
+ # :method: try!
105
+ #
106
+ # :call-seq:
107
+ # try!(*args, &block)
108
+ #
109
+ # Same as #try, but raises a +NoMethodError+ exception if the receiver is
110
+ # not +nil+ and does not implement the tried method.
111
+ #
112
+ # "a".try!(:upcase) # => "A"
113
+ # nil.try!(:upcase) # => nil
114
+ # 123.try!(:upcase) # => NoMethodError: undefined method `upcase' for 123:Integer
115
+ end
116
+
117
+ class Delegator
118
+ include ActiveSupport::Tryable
119
+
120
+ ##
121
+ # :method: try
122
+ #
123
+ # :call-seq:
124
+ # try(*args, &block)
125
+ #
126
+ # See Object#try
127
+
128
+ ##
129
+ # :method: try!
130
+ #
131
+ # :call-seq:
132
+ # try!(*args, &block)
133
+ #
134
+ # See Object#try!
135
+ end
136
+
137
+ class NilClass
138
+ # Calling +try+ on +nil+ always returns +nil+.
139
+ # It becomes especially helpful when navigating through associations that may return +nil+.
140
+ #
141
+ # nil.try(:name) # => nil
142
+ #
143
+ # Without +try+
144
+ # @person && @person.children.any? && @person.children.first.name
145
+ #
146
+ # With +try+
147
+ # @person.try(:children).try(:first).try(:name)
148
+ def try(*, &)
149
+ nil
150
+ end
151
+
152
+ # Calling +try!+ on +nil+ always returns +nil+.
153
+ #
154
+ # nil.try!(:name) # => nil
155
+ def try!(*, &)
156
+ nil
157
+ end
158
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Object
4
+ # Set and restore public attributes around a block.
5
+ #
6
+ # client.timeout # => 5
7
+ # client.with(timeout: 1) do |c|
8
+ # c.timeout # => 1
9
+ # end
10
+ # client.timeout # => 5
11
+ #
12
+ # The receiver is yielded to the provided block.
13
+ #
14
+ # This method is a shorthand for the common begin/ensure pattern:
15
+ #
16
+ # old_value = object.attribute
17
+ # begin
18
+ # object.attribute = new_value
19
+ # # do things
20
+ # ensure
21
+ # object.attribute = old_value
22
+ # end
23
+ #
24
+ # It can be used on any object as long as both the reader and writer methods
25
+ # are public.
26
+ def with(**attributes)
27
+ old_values = {}
28
+ begin
29
+ attributes.each do |key, value|
30
+ old_values[key] = public_send(key)
31
+ public_send("#{key}=", value)
32
+ end
33
+ yield self
34
+ ensure
35
+ old_values.each do |key, old_value|
36
+ public_send("#{key}=", old_value)
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ # #with isn't usable on immediates, so we might as well undefine the
43
+ # method in common immediate classes to avoid potential confusion.
44
+ [NilClass, TrueClass, FalseClass, Integer, Float, Symbol].each do |klass|
45
+ klass.undef_method(:with)
46
+ end