activesupport 2.3.18 → 3.0.0.beta

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 (403) hide show
  1. data/CHANGELOG +30 -53
  2. data/lib/active_support.rb +43 -31
  3. data/lib/active_support/all.rb +3 -7
  4. data/lib/active_support/backtrace_cleaner.rb +24 -8
  5. data/lib/active_support/base64.rb +9 -0
  6. data/lib/active_support/benchmarkable.rb +60 -0
  7. data/lib/active_support/buffered_logger.rb +12 -9
  8. data/lib/active_support/cache.rb +75 -55
  9. data/lib/active_support/cache/compressed_mem_cache_store.rb +2 -0
  10. data/lib/active_support/cache/file_store.rb +35 -17
  11. data/lib/active_support/cache/mem_cache_store.rb +29 -20
  12. data/lib/active_support/cache/memory_store.rb +18 -17
  13. data/lib/active_support/cache/strategy/local_cache.rb +9 -1
  14. data/lib/active_support/callbacks.rb +490 -169
  15. data/lib/active_support/concern.rb +29 -0
  16. data/lib/active_support/configurable.rb +35 -0
  17. data/lib/active_support/core_ext.rb +2 -7
  18. data/lib/active_support/core_ext/array.rb +2 -10
  19. data/lib/active_support/core_ext/array/access.rb +39 -46
  20. data/lib/active_support/core_ext/array/conversions.rb +146 -182
  21. data/lib/active_support/core_ext/array/extract_options.rb +12 -18
  22. data/lib/active_support/core_ext/array/grouping.rb +87 -93
  23. data/lib/active_support/core_ext/array/random_access.rb +4 -40
  24. data/lib/active_support/core_ext/array/uniq_by.rb +17 -0
  25. data/lib/active_support/core_ext/array/wrap.rb +22 -0
  26. data/lib/active_support/core_ext/big_decimal.rb +1 -0
  27. data/lib/active_support/core_ext/big_decimal/conversions.rb +27 -0
  28. data/lib/active_support/core_ext/cgi.rb +0 -4
  29. data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +16 -20
  30. data/lib/active_support/core_ext/class.rb +0 -2
  31. data/lib/active_support/core_ext/class/attribute.rb +8 -39
  32. data/lib/active_support/core_ext/class/attribute_accessors.rb +31 -35
  33. data/lib/active_support/core_ext/class/delegating_attributes.rb +34 -40
  34. data/lib/active_support/core_ext/class/inheritable_attributes.rb +100 -16
  35. data/lib/active_support/core_ext/date/acts_like.rb +8 -0
  36. data/lib/active_support/core_ext/date/calculations.rb +218 -238
  37. data/lib/active_support/core_ext/date/conversions.rb +87 -96
  38. data/lib/active_support/core_ext/date/freeze.rb +31 -0
  39. data/lib/active_support/core_ext/date_time/acts_like.rb +13 -0
  40. data/lib/active_support/core_ext/date_time/calculations.rb +97 -110
  41. data/lib/active_support/core_ext/date_time/conversions.rb +83 -95
  42. data/lib/active_support/core_ext/date_time/zones.rb +17 -0
  43. data/lib/active_support/core_ext/enumerable.rb +14 -15
  44. data/lib/active_support/core_ext/exception.rb +1 -43
  45. data/lib/active_support/core_ext/file.rb +0 -4
  46. data/lib/active_support/core_ext/file/atomic.rb +34 -41
  47. data/lib/active_support/core_ext/float.rb +0 -6
  48. data/lib/active_support/core_ext/float/rounding.rb +15 -20
  49. data/lib/active_support/core_ext/hash.rb +8 -14
  50. data/lib/active_support/core_ext/hash/conversions.rb +236 -236
  51. data/lib/active_support/core_ext/hash/deep_merge.rb +12 -19
  52. data/lib/active_support/core_ext/hash/diff.rb +11 -17
  53. data/lib/active_support/core_ext/hash/except.rb +21 -22
  54. data/lib/active_support/core_ext/hash/indifferent_access.rb +8 -137
  55. data/lib/active_support/core_ext/hash/keys.rb +38 -45
  56. data/lib/active_support/core_ext/hash/reverse_merge.rb +25 -32
  57. data/lib/active_support/core_ext/hash/slice.rb +35 -37
  58. data/lib/active_support/core_ext/integer.rb +1 -7
  59. data/lib/active_support/core_ext/integer/inflections.rb +10 -16
  60. data/lib/active_support/core_ext/integer/multiple.rb +6 -0
  61. data/lib/active_support/core_ext/integer/time.rb +36 -42
  62. data/lib/active_support/core_ext/kernel/reporting.rb +9 -7
  63. data/lib/active_support/core_ext/kernel/requires.rb +3 -1
  64. data/lib/active_support/core_ext/load_error.rb +16 -33
  65. data/lib/active_support/core_ext/logger.rb +3 -2
  66. data/lib/active_support/core_ext/module.rb +3 -16
  67. data/lib/active_support/core_ext/module/aliasing.rb +64 -68
  68. data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +1 -1
  69. data/lib/active_support/core_ext/module/attr_internal.rb +4 -4
  70. data/lib/active_support/core_ext/module/attribute_accessors.rb +36 -41
  71. data/lib/active_support/core_ext/module/delegation.rb +1 -1
  72. data/lib/active_support/core_ext/module/deprecation.rb +9 -0
  73. data/lib/active_support/core_ext/module/introspection.rb +77 -79
  74. data/lib/active_support/core_ext/module/loading.rb +2 -0
  75. data/lib/active_support/core_ext/module/synchronization.rb +4 -1
  76. data/lib/active_support/core_ext/name_error.rb +3 -4
  77. data/lib/active_support/core_ext/numeric.rb +1 -8
  78. data/lib/active_support/core_ext/numeric/bytes.rb +35 -41
  79. data/lib/active_support/core_ext/numeric/time.rb +70 -74
  80. data/lib/active_support/core_ext/object.rb +4 -2
  81. data/lib/active_support/core_ext/object/acts_like.rb +10 -0
  82. data/lib/active_support/core_ext/object/conversions.rb +4 -15
  83. data/lib/active_support/core_ext/object/duplicable.rb +65 -0
  84. data/lib/active_support/core_ext/object/instance_variables.rb +0 -7
  85. data/lib/active_support/core_ext/object/metaclass.rb +5 -6
  86. data/lib/active_support/core_ext/object/misc.rb +2 -93
  87. data/lib/active_support/core_ext/object/returning.rb +42 -0
  88. data/lib/active_support/core_ext/object/to_param.rb +49 -0
  89. data/lib/active_support/core_ext/object/to_query.rb +27 -0
  90. data/lib/active_support/core_ext/{try.rb → object/try.rb} +4 -4
  91. data/lib/active_support/core_ext/object/with_options.rb +24 -0
  92. data/lib/active_support/core_ext/proc.rb +6 -4
  93. data/lib/active_support/core_ext/process/daemon.rb +17 -19
  94. data/lib/active_support/core_ext/range.rb +2 -9
  95. data/lib/active_support/core_ext/range/blockless_step.rb +24 -27
  96. data/lib/active_support/core_ext/range/conversions.rb +17 -23
  97. data/lib/active_support/core_ext/range/include_range.rb +18 -27
  98. data/lib/active_support/core_ext/range/overlaps.rb +6 -13
  99. data/lib/active_support/core_ext/regexp.rb +5 -0
  100. data/lib/active_support/core_ext/rexml.rb +12 -7
  101. data/lib/active_support/core_ext/string.rb +6 -19
  102. data/lib/active_support/core_ext/string/access.rb +88 -95
  103. data/lib/active_support/core_ext/string/behavior.rb +6 -12
  104. data/lib/active_support/core_ext/string/conversions.rb +19 -21
  105. data/lib/active_support/core_ext/string/exclude.rb +6 -0
  106. data/lib/active_support/core_ext/string/filters.rb +17 -23
  107. data/lib/active_support/core_ext/string/inflections.rb +146 -153
  108. data/lib/active_support/{vendor/i18n-0.4.1/i18n/core_ext/string/interpolate.rb → core_ext/string/interpolation.rb} +8 -15
  109. data/lib/active_support/core_ext/string/multibyte.rb +68 -74
  110. data/lib/active_support/core_ext/string/output_safety.rb +21 -17
  111. data/lib/active_support/core_ext/string/starts_ends_with.rb +3 -32
  112. data/lib/active_support/core_ext/string/xchar.rb +10 -3
  113. data/lib/active_support/core_ext/time/acts_like.rb +8 -0
  114. data/lib/active_support/core_ext/time/calculations.rb +276 -308
  115. data/lib/active_support/core_ext/time/conversions.rb +78 -84
  116. data/lib/active_support/core_ext/time/marshal_with_utc_flag.rb +22 -0
  117. data/lib/active_support/core_ext/time/publicize_conversion_methods.rb +10 -0
  118. data/lib/active_support/core_ext/time/zones.rb +73 -81
  119. data/lib/active_support/core_ext/uri.rb +2 -1
  120. data/lib/active_support/dependencies.rb +38 -48
  121. data/lib/active_support/dependencies/autoload.rb +49 -0
  122. data/lib/active_support/deprecation.rb +9 -195
  123. data/lib/active_support/deprecation/behaviors.rb +38 -0
  124. data/lib/active_support/deprecation/method_wrappers.rb +29 -0
  125. data/lib/active_support/deprecation/proxy_wrappers.rb +74 -0
  126. data/lib/active_support/deprecation/reporting.rb +55 -0
  127. data/lib/active_support/duration.rb +6 -2
  128. data/lib/active_support/hash_with_indifferent_access.rb +137 -0
  129. data/lib/active_support/i18n.rb +2 -0
  130. data/lib/active_support/inflections.rb +1 -1
  131. data/lib/active_support/inflector.rb +4 -406
  132. data/lib/active_support/inflector/inflections.rb +211 -0
  133. data/lib/active_support/inflector/methods.rb +139 -0
  134. data/lib/active_support/inflector/transliterate.rb +61 -0
  135. data/lib/active_support/json/backends/jsongem.rb +16 -10
  136. data/lib/active_support/json/backends/yaml.rb +72 -2
  137. data/lib/active_support/json/decoding.rb +2 -16
  138. data/lib/active_support/json/encoding.rb +153 -33
  139. data/lib/active_support/json/variable.rb +4 -3
  140. data/lib/active_support/locale/en.yml +1 -4
  141. data/lib/active_support/memoizable.rb +7 -6
  142. data/lib/active_support/message_encryptor.rb +1 -0
  143. data/lib/active_support/message_verifier.rb +12 -29
  144. data/lib/active_support/multibyte.rb +9 -4
  145. data/lib/active_support/multibyte/chars.rb +25 -17
  146. data/lib/active_support/multibyte/unicode_database.rb +5 -5
  147. data/lib/active_support/multibyte/utils.rb +1 -1
  148. data/lib/active_support/notifications.rb +77 -0
  149. data/lib/active_support/notifications/fanout.rb +69 -0
  150. data/lib/active_support/notifications/instrumenter.rb +50 -0
  151. data/lib/active_support/option_merger.rb +2 -0
  152. data/lib/active_support/ordered_hash.rb +33 -37
  153. data/lib/active_support/ordered_options.rb +3 -1
  154. data/lib/active_support/railtie.rb +64 -0
  155. data/lib/active_support/rescuable.rb +11 -6
  156. data/lib/active_support/ruby/shim.rb +19 -0
  157. data/lib/active_support/test_case.rb +8 -1
  158. data/lib/active_support/testing/assertions.rb +2 -14
  159. data/lib/active_support/testing/declarative.rb +31 -12
  160. data/lib/active_support/testing/deprecation.rb +8 -10
  161. data/lib/active_support/testing/isolation.rb +153 -0
  162. data/lib/active_support/testing/pending.rb +48 -0
  163. data/lib/active_support/testing/performance.rb +342 -339
  164. data/lib/active_support/testing/setup_and_teardown.rb +48 -31
  165. data/lib/active_support/time.rb +34 -0
  166. data/lib/active_support/time/autoload.rb +5 -0
  167. data/lib/active_support/time_with_zone.rb +18 -12
  168. data/lib/active_support/values/time_zone.rb +97 -93
  169. data/lib/active_support/version.rb +3 -3
  170. data/lib/active_support/whiny_nil.rb +1 -4
  171. data/lib/active_support/xml_mini.rb +2 -0
  172. data/lib/active_support/xml_mini/jdom.rb +13 -7
  173. data/lib/active_support/xml_mini/libxml.rb +19 -12
  174. data/lib/active_support/xml_mini/libxmlsax.rb +19 -9
  175. data/lib/active_support/xml_mini/nokogiri.rb +18 -12
  176. data/lib/active_support/xml_mini/nokogirisax.rb +15 -6
  177. data/lib/active_support/xml_mini/rexml.rb +24 -9
  178. metadata +94 -244
  179. data/lib/active_support/cache/drb_store.rb +0 -14
  180. data/lib/active_support/core_ext/array/wrapper.rb +0 -24
  181. data/lib/active_support/core_ext/base64.rb +0 -4
  182. data/lib/active_support/core_ext/base64/encoding.rb +0 -16
  183. data/lib/active_support/core_ext/bigdecimal.rb +0 -6
  184. data/lib/active_support/core_ext/bigdecimal/conversions.rb +0 -37
  185. data/lib/active_support/core_ext/blank.rb +0 -2
  186. data/lib/active_support/core_ext/class/removal.rb +0 -50
  187. data/lib/active_support/core_ext/date.rb +0 -10
  188. data/lib/active_support/core_ext/date/behavior.rb +0 -42
  189. data/lib/active_support/core_ext/date_time.rb +0 -12
  190. data/lib/active_support/core_ext/duplicable.rb +0 -43
  191. data/lib/active_support/core_ext/float/time.rb +0 -27
  192. data/lib/active_support/core_ext/integer/even_odd.rb +0 -29
  193. data/lib/active_support/core_ext/kernel/singleton_class.rb +0 -13
  194. data/lib/active_support/core_ext/module/model_naming.rb +0 -25
  195. data/lib/active_support/core_ext/module/remove_method.rb +0 -6
  196. data/lib/active_support/core_ext/numeric/conversions.rb +0 -19
  197. data/lib/active_support/core_ext/object/extending.rb +0 -80
  198. data/lib/active_support/core_ext/object/singleton_class.rb +0 -13
  199. data/lib/active_support/core_ext/pathname.rb +0 -7
  200. data/lib/active_support/core_ext/pathname/clean_within.rb +0 -14
  201. data/lib/active_support/core_ext/string/bytesize.rb +0 -5
  202. data/lib/active_support/core_ext/string/iterators.rb +0 -23
  203. data/lib/active_support/core_ext/symbol.rb +0 -14
  204. data/lib/active_support/core_ext/time.rb +0 -46
  205. data/lib/active_support/core_ext/time/behavior.rb +0 -13
  206. data/lib/active_support/json/backends/okjson.rb +0 -644
  207. data/lib/active_support/json/backends/yajl.rb +0 -40
  208. data/lib/active_support/json/encoders/date.rb +0 -22
  209. data/lib/active_support/json/encoders/date_time.rb +0 -22
  210. data/lib/active_support/json/encoders/enumerable.rb +0 -17
  211. data/lib/active_support/json/encoders/false_class.rb +0 -7
  212. data/lib/active_support/json/encoders/hash.rb +0 -56
  213. data/lib/active_support/json/encoders/nil_class.rb +0 -7
  214. data/lib/active_support/json/encoders/numeric.rb +0 -21
  215. data/lib/active_support/json/encoders/object.rb +0 -10
  216. data/lib/active_support/json/encoders/regexp.rb +0 -9
  217. data/lib/active_support/json/encoders/string.rb +0 -9
  218. data/lib/active_support/json/encoders/symbol.rb +0 -5
  219. data/lib/active_support/json/encoders/time.rb +0 -22
  220. data/lib/active_support/json/encoders/true_class.rb +0 -7
  221. data/lib/active_support/vendor.rb +0 -36
  222. data/lib/active_support/vendor/builder-2.1.2/blankslate.rb +0 -113
  223. data/lib/active_support/vendor/builder-2.1.2/builder.rb +0 -13
  224. data/lib/active_support/vendor/builder-2.1.2/builder/blankslate.rb +0 -20
  225. data/lib/active_support/vendor/builder-2.1.2/builder/css.rb +0 -250
  226. data/lib/active_support/vendor/builder-2.1.2/builder/xchar.rb +0 -115
  227. data/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb +0 -139
  228. data/lib/active_support/vendor/builder-2.1.2/builder/xmlevents.rb +0 -63
  229. data/lib/active_support/vendor/builder-2.1.2/builder/xmlmarkup.rb +0 -328
  230. data/lib/active_support/vendor/i18n-0.4.1/i18n.rb +0 -322
  231. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend.rb +0 -20
  232. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/active_record.rb +0 -61
  233. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/active_record/missing.rb +0 -65
  234. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/active_record/store_procs.rb +0 -38
  235. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/active_record/translation.rb +0 -93
  236. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/base.rb +0 -237
  237. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/cache.rb +0 -77
  238. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/cascade.rb +0 -57
  239. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/chain.rb +0 -77
  240. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/cldr.rb +0 -100
  241. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/fallbacks.rb +0 -69
  242. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/flatten.rb +0 -113
  243. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/gettext.rb +0 -75
  244. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/interpolation_compiler.rb +0 -123
  245. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/key_value.rb +0 -102
  246. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/memoize.rb +0 -48
  247. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/metadata.rb +0 -65
  248. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/pluralization.rb +0 -57
  249. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/simple.rb +0 -87
  250. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/transliterator.rb +0 -98
  251. data/lib/active_support/vendor/i18n-0.4.1/i18n/config.rb +0 -84
  252. data/lib/active_support/vendor/i18n-0.4.1/i18n/core_ext/hash.rb +0 -29
  253. data/lib/active_support/vendor/i18n-0.4.1/i18n/exceptions.rb +0 -61
  254. data/lib/active_support/vendor/i18n-0.4.1/i18n/gettext.rb +0 -27
  255. data/lib/active_support/vendor/i18n-0.4.1/i18n/gettext/helpers.rb +0 -65
  256. data/lib/active_support/vendor/i18n-0.4.1/i18n/gettext/po_parser.rb +0 -329
  257. data/lib/active_support/vendor/i18n-0.4.1/i18n/locale.rb +0 -6
  258. data/lib/active_support/vendor/i18n-0.4.1/i18n/locale/fallbacks.rb +0 -98
  259. data/lib/active_support/vendor/i18n-0.4.1/i18n/locale/tag.rb +0 -28
  260. data/lib/active_support/vendor/i18n-0.4.1/i18n/locale/tag/parents.rb +0 -24
  261. data/lib/active_support/vendor/i18n-0.4.1/i18n/locale/tag/rfc4646.rb +0 -76
  262. data/lib/active_support/vendor/i18n-0.4.1/i18n/locale/tag/simple.rb +0 -41
  263. data/lib/active_support/vendor/i18n-0.4.1/i18n/version.rb +0 -3
  264. data/lib/active_support/vendor/memcache-client-1.7.4/memcache.rb +0 -1107
  265. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo.rb +0 -33
  266. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/data_timezone.rb +0 -47
  267. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/data_timezone_info.rb +0 -228
  268. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Algiers.rb +0 -55
  269. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Cairo.rb +0 -219
  270. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Casablanca.rb +0 -40
  271. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Harare.rb +0 -18
  272. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Johannesburg.rb +0 -25
  273. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Monrovia.rb +0 -22
  274. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Africa/Nairobi.rb +0 -23
  275. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Argentina/Buenos_Aires.rb +0 -166
  276. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Argentina/San_Juan.rb +0 -86
  277. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Bogota.rb +0 -23
  278. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Caracas.rb +0 -23
  279. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Chicago.rb +0 -283
  280. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Chihuahua.rb +0 -136
  281. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Denver.rb +0 -204
  282. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Godthab.rb +0 -161
  283. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Guatemala.rb +0 -27
  284. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Halifax.rb +0 -274
  285. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Indiana/Indianapolis.rb +0 -149
  286. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Juneau.rb +0 -194
  287. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/La_Paz.rb +0 -22
  288. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Lima.rb +0 -35
  289. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Los_Angeles.rb +0 -232
  290. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Mazatlan.rb +0 -139
  291. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Mexico_City.rb +0 -144
  292. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Monterrey.rb +0 -131
  293. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/New_York.rb +0 -282
  294. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Phoenix.rb +0 -30
  295. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Regina.rb +0 -74
  296. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Santiago.rb +0 -205
  297. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Sao_Paulo.rb +0 -171
  298. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/St_Johns.rb +0 -288
  299. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/America/Tijuana.rb +0 -196
  300. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Almaty.rb +0 -67
  301. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Baghdad.rb +0 -73
  302. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Baku.rb +0 -161
  303. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Bangkok.rb +0 -20
  304. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Chongqing.rb +0 -33
  305. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Colombo.rb +0 -30
  306. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Dhaka.rb +0 -27
  307. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Hong_Kong.rb +0 -87
  308. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Irkutsk.rb +0 -165
  309. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Jakarta.rb +0 -30
  310. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Jerusalem.rb +0 -163
  311. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kabul.rb +0 -20
  312. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kamchatka.rb +0 -163
  313. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Karachi.rb +0 -30
  314. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Katmandu.rb +0 -20
  315. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kolkata.rb +0 -25
  316. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Krasnoyarsk.rb +0 -163
  317. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kuala_Lumpur.rb +0 -31
  318. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Kuwait.rb +0 -18
  319. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Magadan.rb +0 -163
  320. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Muscat.rb +0 -18
  321. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Novosibirsk.rb +0 -164
  322. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Rangoon.rb +0 -24
  323. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Riyadh.rb +0 -18
  324. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Seoul.rb +0 -34
  325. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Shanghai.rb +0 -35
  326. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Singapore.rb +0 -33
  327. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Taipei.rb +0 -59
  328. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tashkent.rb +0 -47
  329. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tbilisi.rb +0 -78
  330. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tehran.rb +0 -121
  331. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Tokyo.rb +0 -30
  332. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Ulaanbaatar.rb +0 -65
  333. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Urumqi.rb +0 -33
  334. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Vladivostok.rb +0 -164
  335. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Yakutsk.rb +0 -163
  336. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Yekaterinburg.rb +0 -165
  337. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Asia/Yerevan.rb +0 -165
  338. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Atlantic/Azores.rb +0 -270
  339. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Atlantic/Cape_Verde.rb +0 -23
  340. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Atlantic/South_Georgia.rb +0 -18
  341. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Adelaide.rb +0 -187
  342. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Brisbane.rb +0 -35
  343. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Darwin.rb +0 -29
  344. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Hobart.rb +0 -193
  345. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Melbourne.rb +0 -185
  346. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Perth.rb +0 -37
  347. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Australia/Sydney.rb +0 -185
  348. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Etc/UTC.rb +0 -16
  349. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Amsterdam.rb +0 -228
  350. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Athens.rb +0 -185
  351. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Belgrade.rb +0 -163
  352. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Berlin.rb +0 -188
  353. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Bratislava.rb +0 -13
  354. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Brussels.rb +0 -232
  355. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Bucharest.rb +0 -181
  356. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Budapest.rb +0 -197
  357. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Copenhagen.rb +0 -179
  358. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Dublin.rb +0 -276
  359. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Helsinki.rb +0 -163
  360. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Istanbul.rb +0 -218
  361. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Kiev.rb +0 -168
  362. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Lisbon.rb +0 -268
  363. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Ljubljana.rb +0 -13
  364. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/London.rb +0 -288
  365. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Madrid.rb +0 -211
  366. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Minsk.rb +0 -170
  367. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Moscow.rb +0 -181
  368. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Paris.rb +0 -232
  369. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Prague.rb +0 -187
  370. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Riga.rb +0 -176
  371. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Rome.rb +0 -215
  372. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Sarajevo.rb +0 -13
  373. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Skopje.rb +0 -13
  374. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Sofia.rb +0 -173
  375. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Stockholm.rb +0 -165
  376. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Tallinn.rb +0 -172
  377. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Vienna.rb +0 -183
  378. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Vilnius.rb +0 -170
  379. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Warsaw.rb +0 -212
  380. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Europe/Zagreb.rb +0 -13
  381. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Auckland.rb +0 -202
  382. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Fiji.rb +0 -23
  383. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Guam.rb +0 -22
  384. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Honolulu.rb +0 -28
  385. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Majuro.rb +0 -20
  386. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Midway.rb +0 -25
  387. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Noumea.rb +0 -25
  388. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Pago_Pago.rb +0 -26
  389. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Port_Moresby.rb +0 -20
  390. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/definitions/Pacific/Tongatapu.rb +0 -27
  391. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/info_timezone.rb +0 -52
  392. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/linked_timezone.rb +0 -51
  393. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/linked_timezone_info.rb +0 -44
  394. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/offset_rationals.rb +0 -98
  395. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/ruby_core_support.rb +0 -56
  396. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/time_or_datetime.rb +0 -292
  397. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone.rb +0 -508
  398. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_definition.rb +0 -56
  399. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_info.rb +0 -40
  400. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_offset_info.rb +0 -94
  401. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb +0 -198
  402. data/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_transition_info.rb +0 -129
  403. data/lib/activesupport.rb +0 -2
@@ -1,80 +1,74 @@
1
1
  # encoding: utf-8
2
+ require 'active_support/multibyte'
2
3
 
3
- module ActiveSupport #:nodoc:
4
- module CoreExtensions #:nodoc:
5
- module String #:nodoc:
6
- # Implements multibyte methods for easier access to multibyte characters in a String instance.
7
- module Multibyte
8
- unless '1.9'.respond_to?(:force_encoding)
9
- # == Multibyte proxy
10
- #
11
- # +mb_chars+ is a multibyte safe proxy for string methods.
12
- #
13
- # In Ruby 1.8 and older it creates and returns an instance of the ActiveSupport::Multibyte::Chars class which
14
- # encapsulates the original string. A Unicode safe version of all the String methods are defined on this proxy
15
- # class. If the proxy class doesn't respond to a certain method, it's forwarded to the encapsuled string.
16
- #
17
- # name = 'Claus Müller'
18
- # name.reverse #=> "rell??M sualC"
19
- # name.length #=> 13
20
- #
21
- # name.mb_chars.reverse.to_s #=> "rellüM sualC"
22
- # name.mb_chars.length #=> 12
23
- #
24
- # In Ruby 1.9 and newer +mb_chars+ returns +self+ because String is (mostly) encoding aware. This means that
25
- # it becomes easy to run one version of your code on multiple Ruby versions.
26
- #
27
- # == Method chaining
28
- #
29
- # All the methods on the Chars proxy which normally return a string will return a Chars object. This allows
30
- # method chaining on the result of any of these methods.
31
- #
32
- # name.mb_chars.reverse.length #=> 12
33
- #
34
- # == Interoperability and configuration
35
- #
36
- # The Chars object tries to be as interchangeable with String objects as possible: sorting and comparing between
37
- # String and Char work like expected. The bang! methods change the internal string representation in the Chars
38
- # object. Interoperability problems can be resolved easily with a +to_s+ call.
39
- #
40
- # For more information about the methods defined on the Chars proxy see ActiveSupport::Multibyte::Chars. For
41
- # information about how to change the default Multibyte behaviour see ActiveSupport::Multibyte.
42
- def mb_chars
43
- if ActiveSupport::Multibyte.proxy_class.wants?(self)
44
- ActiveSupport::Multibyte.proxy_class.new(self)
45
- else
46
- self
47
- end
48
- end
49
-
50
- # Returns true if the string has UTF-8 semantics (a String used for purely byte resources is unlikely to have
51
- # them), returns false otherwise.
52
- def is_utf8?
53
- ActiveSupport::Multibyte::Chars.consumes?(self)
54
- end
4
+ class String
5
+ unless '1.9'.respond_to?(:force_encoding)
6
+ # == Multibyte proxy
7
+ #
8
+ # +mb_chars+ is a multibyte safe proxy for string methods.
9
+ #
10
+ # In Ruby 1.8 and older it creates and returns an instance of the ActiveSupport::Multibyte::Chars class which
11
+ # encapsulates the original string. A Unicode safe version of all the String methods are defined on this proxy
12
+ # class. If the proxy class doesn't respond to a certain method, it's forwarded to the encapsuled string.
13
+ #
14
+ # name = 'Claus Müller'
15
+ # name.reverse #=> "rell??M sualC"
16
+ # name.length #=> 13
17
+ #
18
+ # name.mb_chars.reverse.to_s #=> "rellüM sualC"
19
+ # name.mb_chars.length #=> 12
20
+ #
21
+ # In Ruby 1.9 and newer +mb_chars+ returns +self+ because String is (mostly) encoding aware. This means that
22
+ # it becomes easy to run one version of your code on multiple Ruby versions.
23
+ #
24
+ # == Method chaining
25
+ #
26
+ # All the methods on the Chars proxy which normally return a string will return a Chars object. This allows
27
+ # method chaining on the result of any of these methods.
28
+ #
29
+ # name.mb_chars.reverse.length #=> 12
30
+ #
31
+ # == Interoperability and configuration
32
+ #
33
+ # The Chars object tries to be as interchangeable with String objects as possible: sorting and comparing between
34
+ # String and Char work like expected. The bang! methods change the internal string representation in the Chars
35
+ # object. Interoperability problems can be resolved easily with a +to_s+ call.
36
+ #
37
+ # For more information about the methods defined on the Chars proxy see ActiveSupport::Multibyte::Chars. For
38
+ # information about how to change the default Multibyte behaviour see ActiveSupport::Multibyte.
39
+ def mb_chars
40
+ if ActiveSupport::Multibyte.proxy_class.wants?(self)
41
+ ActiveSupport::Multibyte.proxy_class.new(self)
42
+ else
43
+ self
44
+ end
45
+ end
46
+
47
+ # Returns true if the string has UTF-8 semantics (a String used for purely byte resources is unlikely to have
48
+ # them), returns false otherwise.
49
+ def is_utf8?
50
+ ActiveSupport::Multibyte::Chars.consumes?(self)
51
+ end
55
52
 
56
- unless '1.8.7 and later'.respond_to?(:chars)
57
- def chars
58
- ActiveSupport::Deprecation.warn('String#chars has been deprecated in favor of String#mb_chars.', caller)
59
- mb_chars
60
- end
61
- end
62
- else
63
- def mb_chars #:nodoc
64
- self
65
- end
66
-
67
- def is_utf8? #:nodoc
68
- case encoding
69
- when Encoding::UTF_8
70
- valid_encoding?
71
- when Encoding::ASCII_8BIT, Encoding::US_ASCII
72
- dup.force_encoding(Encoding::UTF_8).valid_encoding?
73
- else
74
- false
75
- end
76
- end
77
- end
53
+ unless '1.8.7 and later'.respond_to?(:chars)
54
+ def chars
55
+ ActiveSupport::Deprecation.warn('String#chars has been deprecated in favor of String#mb_chars.', caller)
56
+ mb_chars
57
+ end
58
+ end
59
+ else
60
+ def mb_chars #:nodoc
61
+ self
62
+ end
63
+
64
+ def is_utf8? #:nodoc
65
+ case encoding
66
+ when Encoding::UTF_8
67
+ valid_encoding?
68
+ when Encoding::ASCII_8BIT, Encoding::US_ASCII
69
+ dup.force_encoding(Encoding::UTF_8).valid_encoding?
70
+ else
71
+ false
78
72
  end
79
73
  end
80
74
  end
@@ -1,14 +1,14 @@
1
- require 'erb'
1
+ require "erb"
2
2
 
3
3
  class ERB
4
4
  module Util
5
- HTML_ESCAPE = { '&' => '&amp;', '>' => '&gt;', '<' => '&lt;', '"' => '&quot;', "'" => '&#39;' }
5
+ HTML_ESCAPE = { '&' => '&amp;', '>' => '&gt;', '<' => '&lt;', '"' => '&quot;' }
6
6
  JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003E', '<' => '\u003C' }
7
7
 
8
8
  # A utility method for escaping HTML tag characters.
9
9
  # This method is also aliased as <tt>h</tt>.
10
10
  #
11
- # In your ERB templates, use this method to escape any unsafe content. For example:
11
+ # In your ERb templates, use this method to escape any unsafe content. For example:
12
12
  # <%=h @person.name %>
13
13
  #
14
14
  # ==== Example:
@@ -19,7 +19,7 @@ class ERB
19
19
  if s.html_safe?
20
20
  s
21
21
  else
22
- s.gsub(/[&"'><]/n) { |special| HTML_ESCAPE[special] }.html_safe
22
+ s.gsub(/[&"><]/) { |special| HTML_ESCAPE[special] }.html_safe
23
23
  end
24
24
  end
25
25
 
@@ -62,10 +62,24 @@ end
62
62
 
63
63
  module ActiveSupport #:nodoc:
64
64
  class SafeBuffer < String
65
+ alias safe_concat concat
66
+
67
+ def concat(value)
68
+ if value.html_safe?
69
+ super(value)
70
+ else
71
+ super(ERB::Util.h(value))
72
+ end
73
+ end
74
+
65
75
  def +(other)
66
76
  dup.concat(other)
67
77
  end
68
78
 
79
+ def <<(value)
80
+ self.concat(value)
81
+ end
82
+
69
83
  def html_safe?
70
84
  true
71
85
  end
@@ -77,25 +91,15 @@ module ActiveSupport #:nodoc:
77
91
  def to_s
78
92
  self
79
93
  end
80
-
81
- def to_yaml(*args)
82
- to_str.to_yaml(*args)
83
- end
84
94
  end
85
95
  end
86
96
 
87
97
  class String
88
- alias safe_concat concat
89
-
90
- def as_str
91
- self
98
+ def html_safe!
99
+ raise "You can't call html_safe! on a String"
92
100
  end
93
101
 
94
102
  def html_safe
95
103
  ActiveSupport::SafeBuffer.new(self)
96
104
  end
97
-
98
- def html_safe?
99
- false
100
- end
101
- end
105
+ end
@@ -1,33 +1,4 @@
1
- module ActiveSupport #:nodoc:
2
- module CoreExtensions #:nodoc:
3
- module String #:nodoc:
4
- # Additional string tests.
5
- module StartsEndsWith
6
- def self.append_features(base)
7
- if '1.8.7 and up'.respond_to?(:start_with?)
8
- base.class_eval do
9
- alias_method :starts_with?, :start_with?
10
- alias_method :ends_with?, :end_with?
11
- end
12
- else
13
- super
14
- base.class_eval do
15
- alias_method :start_with?, :starts_with?
16
- alias_method :end_with?, :ends_with?
17
- end
18
- end
19
- end
20
-
21
- # Does the string start with the specified +prefix+?
22
- def starts_with?(prefix)
23
- prefix.respond_to?(:to_str) && self[0, prefix.length] == prefix
24
- end
25
-
26
- # Does the string end with the specified +suffix+?
27
- def ends_with?(suffix)
28
- suffix.respond_to?(:to_str) && self[-suffix.length, suffix.length] == suffix
29
- end
30
- end
31
- end
32
- end
1
+ class String
2
+ alias_method :starts_with?, :start_with?
3
+ alias_method :ends_with?, :end_with?
33
4
  end
@@ -1,11 +1,18 @@
1
1
  begin
2
- # See http://bogomips.org/fast_xs/ by Eric Wong
2
+ # See http://bogomips.org/fast_xs/ by Eric Wong.
3
+ # Also included with hpricot.
3
4
  require 'fast_xs'
5
+ rescue LoadError
6
+ # fast_xs extension unavailable
7
+ else
8
+ begin
9
+ require 'builder'
10
+ rescue LoadError
11
+ # builder demands the first shot at defining String#to_xs
12
+ end
4
13
 
5
14
  class String
6
15
  alias_method :original_xs, :to_xs if method_defined?(:to_xs)
7
16
  alias_method :to_xs, :fast_xs
8
17
  end
9
- rescue LoadError
10
- # fast_xs extension unavailable.
11
18
  end
@@ -0,0 +1,8 @@
1
+ require 'active_support/core_ext/object/acts_like'
2
+
3
+ class Time
4
+ # Duck-types as a Time-like class. See Object#acts_like?.
5
+ def acts_like_time?
6
+ true
7
+ end
8
+ end
@@ -1,313 +1,281 @@
1
1
  require 'active_support/duration'
2
+ require 'active_support/core_ext/date/acts_like'
3
+ require 'active_support/core_ext/date/calculations'
2
4
 
3
- module ActiveSupport #:nodoc:
4
- module CoreExtensions #:nodoc:
5
- module Time #:nodoc:
6
- # Enables the use of time calculations within Time itself
7
- module Calculations
8
- def self.included(base) #:nodoc:
9
- base.extend ClassMethods
10
-
11
- base.class_eval do
12
- alias_method :plus_without_duration, :+
13
- alias_method :+, :plus_with_duration
14
-
15
- alias_method :minus_without_duration, :-
16
- alias_method :-, :minus_with_duration
17
-
18
- alias_method :minus_without_coercion, :-
19
- alias_method :-, :minus_with_coercion
20
-
21
- alias_method :compare_without_coercion, :<=>
22
- alias_method :<=>, :compare_with_coercion
23
- end
24
- end
25
-
26
- COMMON_YEAR_DAYS_IN_MONTH = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
27
-
28
- module ClassMethods
29
- # Overriding case equality method so that it returns true for ActiveSupport::TimeWithZone instances
30
- def ===(other)
31
- other.is_a?(::Time)
32
- end
33
-
34
- # Return the number of days in the given month.
35
- # If no year is specified, it will use the current year.
36
- def days_in_month(month, year = now.year)
37
- return 29 if month == 2 && ::Date.gregorian_leap?(year)
38
- COMMON_YEAR_DAYS_IN_MONTH[month]
39
- end
40
-
41
- # Returns a new Time if requested year can be accommodated by Ruby's Time class
42
- # (i.e., if year is within either 1970..2038 or 1902..2038, depending on system architecture);
43
- # otherwise returns a DateTime
44
- def time_with_datetime_fallback(utc_or_local, year, month=1, day=1, hour=0, min=0, sec=0, usec=0)
45
- ::Time.send(utc_or_local, year, month, day, hour, min, sec, usec)
46
- rescue
47
- offset = utc_or_local.to_sym == :local ? ::DateTime.local_offset : 0
48
- ::DateTime.civil(year, month, day, hour, min, sec, offset)
49
- end
50
-
51
- # Wraps class method +time_with_datetime_fallback+ with +utc_or_local+ set to <tt>:utc</tt>.
52
- def utc_time(*args)
53
- time_with_datetime_fallback(:utc, *args)
54
- end
55
-
56
- # Wraps class method +time_with_datetime_fallback+ with +utc_or_local+ set to <tt>:local</tt>.
57
- def local_time(*args)
58
- time_with_datetime_fallback(:local, *args)
59
- end
60
- end
61
-
62
- # Tells whether the Time object's time lies in the past
63
- def past?
64
- self < ::Time.current
65
- end
66
-
67
- # Tells whether the Time object's time is today
68
- def today?
69
- self.to_date == ::Date.current
70
- end
71
-
72
- # Tells whether the Time object's time lies in the future
73
- def future?
74
- self > ::Time.current
75
- end
76
-
77
- # Seconds since midnight: Time.now.seconds_since_midnight
78
- def seconds_since_midnight
79
- self.to_i - self.change(:hour => 0).to_i + (self.usec/1.0e+6)
80
- end
81
-
82
- # Returns a new Time where one or more of the elements have been changed according to the +options+ parameter. The time options
83
- # (hour, minute, sec, usec) reset cascadingly, so if only the hour is passed, then minute, sec, and usec is set to 0. If the hour and
84
- # minute is passed, then sec and usec is set to 0.
85
- def change(options)
86
- ::Time.send(
87
- self.utc? ? :utc_time : :local_time,
88
- options[:year] || self.year,
89
- options[:month] || self.month,
90
- options[:day] || self.day,
91
- options[:hour] || self.hour,
92
- options[:min] || (options[:hour] ? 0 : self.min),
93
- options[:sec] || ((options[:hour] || options[:min]) ? 0 : self.sec),
94
- options[:usec] || ((options[:hour] || options[:min] || options[:sec]) ? 0 : self.usec)
95
- )
96
- end
97
-
98
- # Uses Date to provide precise Time calculations for years, months, and days.
99
- # The +options+ parameter takes a hash with any of these keys: <tt>:years</tt>,
100
- # <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>,
101
- # <tt>:minutes</tt>, <tt>:seconds</tt>.
102
- def advance(options)
103
- unless options[:weeks].nil?
104
- options[:weeks], partial_weeks = options[:weeks].divmod(1)
105
- options[:days] = (options[:days] || 0) + 7 * partial_weeks
106
- end
107
-
108
- unless options[:days].nil?
109
- options[:days], partial_days = options[:days].divmod(1)
110
- options[:hours] = (options[:hours] || 0) + 24 * partial_days
111
- end
112
-
113
- d = to_date.advance(options)
114
- time_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
115
- seconds_to_advance = (options[:seconds] || 0) + (options[:minutes] || 0) * 60 + (options[:hours] || 0) * 3600
116
- seconds_to_advance == 0 ? time_advanced_by_date : time_advanced_by_date.since(seconds_to_advance)
117
- end
118
-
119
- # Returns a new Time representing the time a number of seconds ago, this is basically a wrapper around the Numeric extension
120
- def ago(seconds)
121
- self.since(-seconds)
122
- end
123
-
124
- # Returns a new Time representing the time a number of seconds since the instance time, this is basically a wrapper around
125
- # the Numeric extension.
126
- def since(seconds)
127
- f = seconds.since(self)
128
- if ActiveSupport::Duration === seconds
129
- f
130
- else
131
- initial_dst = self.dst? ? 1 : 0
132
- final_dst = f.dst? ? 1 : 0
133
- (seconds.abs >= 86400 && initial_dst != final_dst) ? f + (initial_dst - final_dst).hours : f
134
- end
135
- rescue
136
- self.to_datetime.since(seconds)
137
- end
138
- alias :in :since
139
-
140
- # Returns a new Time representing the time a number of specified months ago
141
- def months_ago(months)
142
- advance(:months => -months)
143
- end
144
-
145
- # Returns a new Time representing the time a number of specified months in the future
146
- def months_since(months)
147
- advance(:months => months)
148
- end
149
-
150
- # Returns a new Time representing the time a number of specified years ago
151
- def years_ago(years)
152
- advance(:years => -years)
153
- end
154
-
155
- # Returns a new Time representing the time a number of specified years in the future
156
- def years_since(years)
157
- advance(:years => years)
158
- end
159
-
160
- def last_year # :nodoc:
161
- ActiveSupport::Deprecation.warn("Time#last_year is deprecated and has been removed in Rails 3, please use Time#prev_year instead", caller)
162
- prev_year
163
- end
164
-
165
- # Short-hand for years_ago(1)
166
- def prev_year
167
- years_ago(1)
168
- end
169
-
170
- # Short-hand for years_since(1)
171
- def next_year
172
- years_since(1)
173
- end
174
-
175
- def last_month # :nodoc:
176
- ActiveSupport::Deprecation.warn("Time#last_month is deprecated and has been removed in Rails 3, please use Time#prev_month instead", caller)
177
- prev_month
178
- end
179
-
180
- # Short-hand for months_ago(1)
181
- def prev_month
182
- months_ago(1)
183
- end
184
-
185
- # Short-hand for months_since(1)
186
- def next_month
187
- months_since(1)
188
- end
189
-
190
- # Returns a new Time representing the "start" of this week (Monday, 0:00)
191
- def beginning_of_week
192
- days_to_monday = self.wday!=0 ? self.wday-1 : 6
193
- (self - days_to_monday.days).midnight
194
- end
195
- alias :monday :beginning_of_week
196
- alias :at_beginning_of_week :beginning_of_week
197
-
198
- # Returns a new Time representing the end of this week (Sunday, 23:59:59)
199
- def end_of_week
200
- days_to_sunday = self.wday!=0 ? 7-self.wday : 0
201
- (self + days_to_sunday.days).end_of_day
202
- end
203
- alias :at_end_of_week :end_of_week
204
-
205
- # Returns a new Time representing the start of the given day in next week (default is Monday).
206
- def next_week(day = :monday)
207
- days_into_week = { :monday => 0, :tuesday => 1, :wednesday => 2, :thursday => 3, :friday => 4, :saturday => 5, :sunday => 6}
208
- since(1.week).beginning_of_week.since(days_into_week[day].day).change(:hour => 0)
209
- end
210
-
211
- # Returns a new Time representing the start of the day (0:00)
212
- def beginning_of_day
213
- #(self - seconds_since_midnight).change(:usec => 0)
214
- change(:hour => 0, :min => 0, :sec => 0, :usec => 0)
215
- end
216
- alias :midnight :beginning_of_day
217
- alias :at_midnight :beginning_of_day
218
- alias :at_beginning_of_day :beginning_of_day
219
-
220
- # Returns a new Time representing the end of the day, 23:59:59.999999 (.999999999 in ruby1.9)
221
- def end_of_day
222
- change(:hour => 23, :min => 59, :sec => 59, :usec => 999999.999)
223
- end
224
-
225
- # Returns a new Time representing the start of the month (1st of the month, 0:00)
226
- def beginning_of_month
227
- #self - ((self.mday-1).days + self.seconds_since_midnight)
228
- change(:day => 1,:hour => 0, :min => 0, :sec => 0, :usec => 0)
229
- end
230
- alias :at_beginning_of_month :beginning_of_month
231
-
232
- # Returns a new Time representing the end of the month (end of the last day of the month)
233
- def end_of_month
234
- #self - ((self.mday-1).days + self.seconds_since_midnight)
235
- last_day = ::Time.days_in_month( self.month, self.year )
236
- change(:day => last_day, :hour => 23, :min => 59, :sec => 59, :usec => 999999.999)
237
- end
238
- alias :at_end_of_month :end_of_month
239
-
240
- # Returns a new Time representing the start of the quarter (1st of january, april, july, october, 0:00)
241
- def beginning_of_quarter
242
- beginning_of_month.change(:month => [10, 7, 4, 1].detect { |m| m <= self.month })
243
- end
244
- alias :at_beginning_of_quarter :beginning_of_quarter
245
-
246
- # Returns a new Time representing the end of the quarter (end of the last day of march, june, september, december)
247
- def end_of_quarter
248
- beginning_of_month.change(:month => [3, 6, 9, 12].detect { |m| m >= self.month }).end_of_month
249
- end
250
- alias :at_end_of_quarter :end_of_quarter
251
-
252
- # Returns a new Time representing the start of the year (1st of january, 0:00)
253
- def beginning_of_year
254
- change(:month => 1,:day => 1,:hour => 0, :min => 0, :sec => 0, :usec => 0)
255
- end
256
- alias :at_beginning_of_year :beginning_of_year
257
-
258
- # Returns a new Time representing the end of the year (end of the 31st of december)
259
- def end_of_year
260
- change(:month => 12, :day => 31, :hour => 23, :min => 59, :sec => 59, :usec => 999999.999)
261
- end
262
- alias :at_end_of_year :end_of_year
263
-
264
- # Convenience method which returns a new Time representing the time 1 day ago
265
- def yesterday
266
- advance(:days => -1)
267
- end
268
-
269
- # Convenience method which returns a new Time representing the time 1 day since the instance time
270
- def tomorrow
271
- advance(:days => 1)
272
- end
273
-
274
- def plus_with_duration(other) #:nodoc:
275
- if ActiveSupport::Duration === other
276
- other.since(self)
277
- else
278
- plus_without_duration(other)
279
- end
280
- end
281
-
282
- def minus_with_duration(other) #:nodoc:
283
- if ActiveSupport::Duration === other
284
- other.until(self)
285
- else
286
- minus_without_duration(other)
287
- end
288
- end
289
-
290
- # Time#- can also be used to determine the number of seconds between two Time instances.
291
- # We're layering on additional behavior so that ActiveSupport::TimeWithZone instances
292
- # are coerced into values that Time#- will recognize
293
- def minus_with_coercion(other)
294
- other = other.comparable_time if other.respond_to?(:comparable_time)
295
- other.is_a?(::DateTime) ? to_f - other.to_f : minus_without_coercion(other)
296
- end
297
-
298
- # Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
299
- # can be chronologically compared with a Time
300
- def compare_with_coercion(other)
301
- # if other is an ActiveSupport::TimeWithZone, coerce a Time instance from it so we can do <=> comparison
302
- other = other.comparable_time if other.respond_to?(:comparable_time)
303
- if other.acts_like?(:date)
304
- # other is a Date/DateTime, so coerce self #to_datetime and hand off to DateTime#<=>
305
- to_datetime.compare_without_coercion(other)
306
- else
307
- compare_without_coercion(other)
308
- end
309
- end
310
- end
5
+ class Time
6
+ COMMON_YEAR_DAYS_IN_MONTH = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
7
+ DAYS_INTO_WEEK = { :monday => 0, :tuesday => 1, :wednesday => 2, :thursday => 3, :friday => 4, :saturday => 5, :sunday => 6 }
8
+
9
+ class << self
10
+ # Overriding case equality method so that it returns true for ActiveSupport::TimeWithZone instances
11
+ def ===(other)
12
+ other.is_a?(::Time)
13
+ end
14
+
15
+ # Return the number of days in the given month.
16
+ # If no year is specified, it will use the current year.
17
+ def days_in_month(month, year = now.year)
18
+ return 29 if month == 2 && ::Date.gregorian_leap?(year)
19
+ COMMON_YEAR_DAYS_IN_MONTH[month]
20
+ end
21
+
22
+ # Returns a new Time if requested year can be accommodated by Ruby's Time class
23
+ # (i.e., if year is within either 1970..2038 or 1902..2038, depending on system architecture);
24
+ # otherwise returns a DateTime
25
+ def time_with_datetime_fallback(utc_or_local, year, month=1, day=1, hour=0, min=0, sec=0, usec=0)
26
+ ::Time.send(utc_or_local, year, month, day, hour, min, sec, usec)
27
+ rescue
28
+ offset = utc_or_local.to_sym == :local ? ::DateTime.local_offset : 0
29
+ ::DateTime.civil(year, month, day, hour, min, sec, offset)
30
+ end
31
+
32
+ # Wraps class method +time_with_datetime_fallback+ with +utc_or_local+ set to <tt>:utc</tt>.
33
+ def utc_time(*args)
34
+ time_with_datetime_fallback(:utc, *args)
35
+ end
36
+
37
+ # Wraps class method +time_with_datetime_fallback+ with +utc_or_local+ set to <tt>:local</tt>.
38
+ def local_time(*args)
39
+ time_with_datetime_fallback(:local, *args)
40
+ end
41
+ end
42
+
43
+ # Tells whether the Time object's time lies in the past
44
+ def past?
45
+ self < ::Time.current
46
+ end
47
+
48
+ # Tells whether the Time object's time is today
49
+ def today?
50
+ to_date == ::Date.current
51
+ end
52
+
53
+ # Tells whether the Time object's time lies in the future
54
+ def future?
55
+ self > ::Time.current
56
+ end
57
+
58
+ # Seconds since midnight: Time.now.seconds_since_midnight
59
+ def seconds_since_midnight
60
+ to_i - change(:hour => 0).to_i + (usec / 1.0e+6)
61
+ end
62
+
63
+ # Returns a new Time where one or more of the elements have been changed according to the +options+ parameter. The time options
64
+ # (hour, minute, sec, usec) reset cascadingly, so if only the hour is passed, then minute, sec, and usec is set to 0. If the hour and
65
+ # minute is passed, then sec and usec is set to 0.
66
+ def change(options)
67
+ ::Time.send(
68
+ utc? ? :utc_time : :local_time,
69
+ options[:year] || year,
70
+ options[:month] || month,
71
+ options[:day] || day,
72
+ options[:hour] || hour,
73
+ options[:min] || (options[:hour] ? 0 : min),
74
+ options[:sec] || ((options[:hour] || options[:min]) ? 0 : sec),
75
+ options[:usec] || ((options[:hour] || options[:min] || options[:sec]) ? 0 : usec)
76
+ )
77
+ end
78
+
79
+ # Uses Date to provide precise Time calculations for years, months, and days.
80
+ # The +options+ parameter takes a hash with any of these keys: <tt>:years</tt>,
81
+ # <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>,
82
+ # <tt>:minutes</tt>, <tt>:seconds</tt>.
83
+ def advance(options)
84
+ unless options[:weeks].nil?
85
+ options[:weeks], partial_weeks = options[:weeks].divmod(1)
86
+ options[:days] = (options[:days] || 0) + 7 * partial_weeks
87
+ end
88
+
89
+ unless options[:days].nil?
90
+ options[:days], partial_days = options[:days].divmod(1)
91
+ options[:hours] = (options[:hours] || 0) + 24 * partial_days
92
+ end
93
+
94
+ d = to_date.advance(options)
95
+ time_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
96
+ seconds_to_advance = (options[:seconds] || 0) + (options[:minutes] || 0) * 60 + (options[:hours] || 0) * 3600
97
+ seconds_to_advance == 0 ? time_advanced_by_date : time_advanced_by_date.since(seconds_to_advance)
98
+ end
99
+
100
+ # Returns a new Time representing the time a number of seconds ago, this is basically a wrapper around the Numeric extension
101
+ def ago(seconds)
102
+ since(-seconds)
103
+ end
104
+
105
+ # Returns a new Time representing the time a number of seconds since the instance time
106
+ def since(seconds)
107
+ self + seconds
108
+ rescue
109
+ to_datetime.since(seconds)
110
+ end
111
+ alias :in :since
112
+
113
+ # Returns a new Time representing the time a number of specified months ago
114
+ def months_ago(months)
115
+ advance(:months => -months)
116
+ end
117
+
118
+ # Returns a new Time representing the time a number of specified months in the future
119
+ def months_since(months)
120
+ advance(:months => months)
121
+ end
122
+
123
+ # Returns a new Time representing the time a number of specified years ago
124
+ def years_ago(years)
125
+ advance(:years => -years)
126
+ end
127
+
128
+ # Returns a new Time representing the time a number of specified years in the future
129
+ def years_since(years)
130
+ advance(:years => years)
131
+ end
132
+
133
+ # Short-hand for years_ago(1)
134
+ def last_year
135
+ years_ago(1)
136
+ end
137
+
138
+ # Short-hand for years_since(1)
139
+ def next_year
140
+ years_since(1)
141
+ end
142
+
143
+
144
+ # Short-hand for months_ago(1)
145
+ def last_month
146
+ months_ago(1)
147
+ end
148
+
149
+ # Short-hand for months_since(1)
150
+ def next_month
151
+ months_since(1)
152
+ end
153
+
154
+ # Returns a new Time representing the "start" of this week (Monday, 0:00)
155
+ def beginning_of_week
156
+ days_to_monday = wday!=0 ? wday-1 : 6
157
+ (self - days_to_monday.days).midnight
158
+ end
159
+ alias :monday :beginning_of_week
160
+ alias :at_beginning_of_week :beginning_of_week
161
+
162
+ # Returns a new Time representing the end of this week, (end of Sunday)
163
+ def end_of_week
164
+ days_to_sunday = wday!=0 ? 7-wday : 0
165
+ (self + days_to_sunday.days).end_of_day
166
+ end
167
+ alias :at_end_of_week :end_of_week
168
+
169
+ # Returns a new Time representing the start of the given day in next week (default is Monday).
170
+ def next_week(day = :monday)
171
+ since(1.week).beginning_of_week.since(DAYS_INTO_WEEK[day].day).change(:hour => 0)
172
+ end
173
+
174
+ # Returns a new Time representing the start of the day (0:00)
175
+ def beginning_of_day
176
+ #(self - seconds_since_midnight).change(:usec => 0)
177
+ change(:hour => 0, :min => 0, :sec => 0, :usec => 0)
178
+ end
179
+ alias :midnight :beginning_of_day
180
+ alias :at_midnight :beginning_of_day
181
+ alias :at_beginning_of_day :beginning_of_day
182
+
183
+ # Returns a new Time representing the end of the day, 23:59:59.999999 (.999999999 in ruby1.9)
184
+ def end_of_day
185
+ change(:hour => 23, :min => 59, :sec => 59, :usec => 999999.999)
186
+ end
187
+
188
+ # Returns a new Time representing the start of the month (1st of the month, 0:00)
189
+ def beginning_of_month
190
+ #self - ((self.mday-1).days + self.seconds_since_midnight)
191
+ change(:day => 1,:hour => 0, :min => 0, :sec => 0, :usec => 0)
192
+ end
193
+ alias :at_beginning_of_month :beginning_of_month
194
+
195
+ # Returns a new Time representing the end of the month (end of the last day of the month)
196
+ def end_of_month
197
+ #self - ((self.mday-1).days + self.seconds_since_midnight)
198
+ last_day = ::Time.days_in_month(month, year)
199
+ change(:day => last_day, :hour => 23, :min => 59, :sec => 59, :usec => 999999.999)
200
+ end
201
+ alias :at_end_of_month :end_of_month
202
+
203
+ # Returns a new Time representing the start of the quarter (1st of january, april, july, october, 0:00)
204
+ def beginning_of_quarter
205
+ beginning_of_month.change(:month => [10, 7, 4, 1].detect { |m| m <= month })
206
+ end
207
+ alias :at_beginning_of_quarter :beginning_of_quarter
208
+
209
+ # Returns a new Time representing the end of the quarter (end of the last day of march, june, september, december)
210
+ def end_of_quarter
211
+ beginning_of_month.change(:month => [3, 6, 9, 12].detect { |m| m >= month }).end_of_month
212
+ end
213
+ alias :at_end_of_quarter :end_of_quarter
214
+
215
+ # Returns a new Time representing the start of the year (1st of january, 0:00)
216
+ def beginning_of_year
217
+ change(:month => 1, :day => 1, :hour => 0, :min => 0, :sec => 0, :usec => 0)
218
+ end
219
+ alias :at_beginning_of_year :beginning_of_year
220
+
221
+ # Returns a new Time representing the end of the year (end of the 31st of december)
222
+ def end_of_year
223
+ change(:month => 12, :day => 31, :hour => 23, :min => 59, :sec => 59, :usec => 999999.999)
224
+ end
225
+ alias :at_end_of_year :end_of_year
226
+
227
+ # Convenience method which returns a new Time representing the time 1 day ago
228
+ def yesterday
229
+ advance(:days => -1)
230
+ end
231
+
232
+ # Convenience method which returns a new Time representing the time 1 day since the instance time
233
+ def tomorrow
234
+ advance(:days => 1)
235
+ end
236
+
237
+ def plus_with_duration(other) #:nodoc:
238
+ if ActiveSupport::Duration === other
239
+ other.since(self)
240
+ else
241
+ plus_without_duration(other)
242
+ end
243
+ end
244
+ alias_method :plus_without_duration, :+
245
+ alias_method :+, :plus_with_duration
246
+
247
+ def minus_with_duration(other) #:nodoc:
248
+ if ActiveSupport::Duration === other
249
+ other.until(self)
250
+ else
251
+ minus_without_duration(other)
252
+ end
253
+ end
254
+ alias_method :minus_without_duration, :-
255
+ alias_method :-, :minus_with_duration
256
+
257
+ # Time#- can also be used to determine the number of seconds between two Time instances.
258
+ # We're layering on additional behavior so that ActiveSupport::TimeWithZone instances
259
+ # are coerced into values that Time#- will recognize
260
+ def minus_with_coercion(other)
261
+ other = other.comparable_time if other.respond_to?(:comparable_time)
262
+ other.is_a?(DateTime) ? to_f - other.to_f : minus_without_coercion(other)
263
+ end
264
+ alias_method :minus_without_coercion, :-
265
+ alias_method :-, :minus_with_coercion
266
+
267
+ # Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
268
+ # can be chronologically compared with a Time
269
+ def compare_with_coercion(other)
270
+ # if other is an ActiveSupport::TimeWithZone, coerce a Time instance from it so we can do <=> comparison
271
+ other = other.comparable_time if other.respond_to?(:comparable_time)
272
+ if other.acts_like?(:date)
273
+ # other is a Date/DateTime, so coerce self #to_datetime and hand off to DateTime#<=>
274
+ to_datetime.compare_without_coercion(other)
275
+ else
276
+ compare_without_coercion(other)
311
277
  end
312
278
  end
279
+ alias_method :compare_without_coercion, :<=>
280
+ alias_method :<=>, :compare_with_coercion
313
281
  end