activesupport 3.0.pre → 3.0.0.rc

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 (351) hide show
  1. data/CHANGELOG +121 -1
  2. data/README.rdoc +33 -0
  3. data/lib/active_support.rb +42 -4
  4. data/lib/active_support/backtrace_cleaner.rb +31 -9
  5. data/lib/active_support/benchmarkable.rb +1 -0
  6. data/lib/active_support/buffered_logger.rb +5 -2
  7. data/lib/active_support/builder.rb +6 -0
  8. data/lib/active_support/cache.rb +454 -84
  9. data/lib/active_support/cache/compressed_mem_cache_store.rb +6 -13
  10. data/lib/active_support/cache/file_store.rb +140 -41
  11. data/lib/active_support/cache/mem_cache_store.rb +121 -76
  12. data/lib/active_support/cache/memory_store.rb +127 -27
  13. data/lib/active_support/cache/strategy/local_cache.rb +111 -58
  14. data/lib/active_support/cache/synchronized_memory_store.rb +2 -38
  15. data/lib/active_support/callbacks.rb +105 -76
  16. data/lib/active_support/configurable.rb +19 -18
  17. data/lib/active_support/core_ext/array.rb +1 -0
  18. data/lib/active_support/core_ext/array/access.rb +1 -1
  19. data/lib/active_support/core_ext/array/conversions.rb +29 -54
  20. data/lib/active_support/core_ext/array/extract_options.rb +16 -1
  21. data/lib/active_support/core_ext/array/grouping.rb +1 -1
  22. data/lib/active_support/core_ext/array/random_access.rb +26 -5
  23. data/lib/active_support/core_ext/array/uniq_by.rb +17 -0
  24. data/lib/active_support/core_ext/array/wrap.rb +13 -9
  25. data/lib/active_support/core_ext/benchmark.rb +0 -12
  26. data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +2 -0
  27. data/lib/active_support/core_ext/class.rb +2 -1
  28. data/lib/active_support/core_ext/class/attribute.rb +67 -0
  29. data/lib/active_support/core_ext/class/attribute_accessors.rb +33 -27
  30. data/lib/active_support/core_ext/class/delegating_attributes.rb +35 -41
  31. data/lib/active_support/core_ext/class/inheritable_attributes.rb +23 -14
  32. data/lib/active_support/core_ext/class/subclasses.rb +50 -0
  33. data/lib/active_support/core_ext/date/calculations.rb +35 -12
  34. data/lib/active_support/core_ext/date/conversions.rb +5 -5
  35. data/lib/active_support/core_ext/date/zones.rb +14 -0
  36. data/lib/active_support/core_ext/date_time/calculations.rb +3 -1
  37. data/lib/active_support/core_ext/date_time/conversions.rb +24 -5
  38. data/lib/active_support/core_ext/date_time/zones.rb +4 -0
  39. data/lib/active_support/core_ext/enumerable.rb +5 -9
  40. data/lib/active_support/core_ext/exception.rb +0 -47
  41. data/lib/active_support/core_ext/file.rb +1 -0
  42. data/lib/active_support/core_ext/file/atomic.rb +3 -2
  43. data/lib/active_support/core_ext/file/path.rb +5 -0
  44. data/lib/active_support/core_ext/float/rounding.rb +3 -2
  45. data/lib/active_support/core_ext/hash/conversions.rb +65 -145
  46. data/lib/active_support/core_ext/hash/deep_merge.rb +6 -7
  47. data/lib/active_support/core_ext/hash/except.rb +8 -1
  48. data/lib/active_support/core_ext/hash/indifferent_access.rb +5 -0
  49. data/lib/active_support/core_ext/hash/keys.rb +10 -11
  50. data/lib/active_support/core_ext/hash/slice.rb +6 -0
  51. data/lib/active_support/core_ext/integer.rb +1 -1
  52. data/lib/active_support/core_ext/integer/multiple.rb +6 -0
  53. data/lib/active_support/core_ext/kernel.rb +1 -1
  54. data/lib/active_support/core_ext/kernel/debugger.rb +3 -2
  55. data/lib/active_support/core_ext/kernel/reporting.rb +2 -1
  56. data/lib/active_support/core_ext/kernel/requires.rb +2 -2
  57. data/lib/active_support/core_ext/kernel/singleton_class.rb +13 -0
  58. data/lib/active_support/core_ext/load_error.rb +17 -30
  59. data/lib/active_support/core_ext/logger.rb +2 -40
  60. data/lib/active_support/core_ext/module.rb +5 -3
  61. data/lib/active_support/core_ext/module/aliasing.rb +1 -1
  62. data/lib/active_support/core_ext/module/anonymous.rb +24 -0
  63. data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +1 -1
  64. data/lib/active_support/core_ext/module/attr_internal.rb +2 -2
  65. data/lib/active_support/core_ext/module/attribute_accessors.rb +20 -22
  66. data/lib/active_support/core_ext/module/delegation.rb +21 -10
  67. data/lib/active_support/core_ext/module/introspection.rb +8 -8
  68. data/lib/active_support/core_ext/module/method_names.rb +14 -0
  69. data/lib/active_support/core_ext/module/reachable.rb +10 -0
  70. data/lib/active_support/core_ext/module/remove_method.rb +11 -0
  71. data/lib/active_support/core_ext/module/synchronization.rb +2 -1
  72. data/lib/active_support/core_ext/name_error.rb +3 -1
  73. data/lib/active_support/core_ext/object.rb +5 -3
  74. data/lib/active_support/core_ext/object/blank.rb +20 -2
  75. data/lib/active_support/core_ext/object/conversions.rb +2 -16
  76. data/lib/active_support/core_ext/object/duplicable.rb +23 -1
  77. data/lib/active_support/core_ext/object/instance_variables.rb +0 -7
  78. data/lib/active_support/core_ext/object/to_json.rb +19 -0
  79. data/lib/active_support/core_ext/object/to_param.rb +49 -0
  80. data/lib/active_support/core_ext/object/to_query.rb +27 -0
  81. data/lib/active_support/core_ext/object/with_options.rb +2 -0
  82. data/lib/active_support/core_ext/proc.rb +4 -4
  83. data/lib/active_support/core_ext/range/overlaps.rb +1 -1
  84. data/lib/active_support/core_ext/regexp.rb +0 -22
  85. data/lib/active_support/core_ext/rexml.rb +4 -1
  86. data/lib/active_support/core_ext/string.rb +3 -2
  87. data/lib/active_support/core_ext/string/access.rb +4 -2
  88. data/lib/active_support/core_ext/string/conversions.rb +28 -1
  89. data/lib/active_support/core_ext/string/encoding.rb +11 -0
  90. data/lib/active_support/core_ext/string/exclude.rb +6 -0
  91. data/lib/active_support/core_ext/string/filters.rb +29 -0
  92. data/lib/active_support/core_ext/string/inflections.rb +12 -12
  93. data/lib/active_support/core_ext/string/interpolation.rb +2 -92
  94. data/lib/active_support/core_ext/string/multibyte.rb +16 -19
  95. data/lib/active_support/core_ext/string/output_safety.rb +101 -35
  96. data/lib/active_support/core_ext/string/starts_ends_with.rb +0 -14
  97. data/lib/active_support/core_ext/string/xchar.rb +1 -1
  98. data/lib/active_support/core_ext/time/calculations.rb +14 -7
  99. data/lib/active_support/core_ext/time/conversions.rb +1 -0
  100. data/lib/active_support/core_ext/time/marshal.rb +56 -0
  101. data/lib/active_support/core_ext/time/zones.rb +2 -5
  102. data/lib/active_support/core_ext/uri.rb +10 -4
  103. data/lib/active_support/dependencies.rb +200 -197
  104. data/lib/active_support/dependencies/autoload.rb +50 -0
  105. data/lib/active_support/deprecation/behaviors.rb +13 -9
  106. data/lib/active_support/deprecation/method_wrappers.rb +10 -9
  107. data/lib/active_support/deprecation/proxy_wrappers.rb +7 -0
  108. data/lib/active_support/deprecation/reporting.rb +5 -3
  109. data/lib/active_support/descendants_tracker.rb +43 -0
  110. data/lib/active_support/duration.rb +8 -4
  111. data/lib/active_support/file_update_checker.rb +36 -0
  112. data/lib/active_support/hash_with_indifferent_access.rb +9 -1
  113. data/lib/active_support/i18n.rb +9 -0
  114. data/lib/active_support/i18n_railtie.rb +81 -0
  115. data/lib/active_support/inflections.rb +1 -1
  116. data/lib/active_support/inflector.rb +4 -407
  117. data/lib/active_support/inflector/inflections.rb +211 -0
  118. data/lib/active_support/inflector/methods.rb +151 -0
  119. data/lib/active_support/inflector/transliterate.rb +97 -0
  120. data/lib/active_support/json/backends/jsongem.rb +12 -9
  121. data/lib/active_support/json/backends/yajl.rb +40 -0
  122. data/lib/active_support/json/backends/yaml.rb +1 -1
  123. data/lib/active_support/json/decoding.rb +17 -2
  124. data/lib/active_support/json/encoding.rb +48 -31
  125. data/lib/active_support/json/variable.rb +2 -4
  126. data/lib/active_support/lazy_load_hooks.rb +27 -0
  127. data/lib/active_support/locale/en.yml +5 -2
  128. data/lib/active_support/log_subscriber.rb +123 -0
  129. data/lib/active_support/log_subscriber/test_helper.rb +99 -0
  130. data/lib/active_support/memoizable.rb +1 -1
  131. data/lib/active_support/message_encryptor.rb +1 -0
  132. data/lib/active_support/message_verifier.rb +2 -1
  133. data/lib/active_support/multibyte.rb +8 -23
  134. data/lib/active_support/multibyte/chars.rb +213 -446
  135. data/lib/active_support/multibyte/unicode.rb +392 -0
  136. data/lib/active_support/multibyte/utils.rb +6 -7
  137. data/lib/active_support/notifications.rb +29 -122
  138. data/lib/active_support/notifications/fanout.rb +61 -0
  139. data/lib/active_support/notifications/instrumenter.rb +54 -0
  140. data/lib/active_support/ordered_hash.rb +59 -14
  141. data/lib/active_support/ordered_options.rb +6 -0
  142. data/lib/active_support/railtie.rb +60 -0
  143. data/lib/active_support/rescuable.rb +7 -4
  144. data/lib/active_support/ruby/shim.rb +4 -6
  145. data/lib/active_support/test_case.rb +2 -7
  146. data/lib/active_support/testing/assertions.rb +15 -0
  147. data/lib/active_support/testing/declarative.rb +1 -1
  148. data/lib/active_support/testing/isolation.rb +64 -17
  149. data/lib/active_support/testing/performance.rb +306 -335
  150. data/lib/active_support/testing/setup_and_teardown.rb +51 -29
  151. data/lib/active_support/time.rb +24 -3
  152. data/lib/active_support/time_with_zone.rb +10 -14
  153. data/lib/active_support/values/time_zone.rb +192 -234
  154. data/lib/active_support/values/unicode_tables.dat +0 -0
  155. data/lib/active_support/version.rb +3 -2
  156. data/lib/active_support/whiny_nil.rb +9 -7
  157. data/lib/active_support/xml_mini.rb +130 -1
  158. data/lib/active_support/xml_mini/jdom.rb +2 -0
  159. data/lib/active_support/xml_mini/libxml.rb +23 -86
  160. data/lib/active_support/xml_mini/libxmlsax.rb +85 -0
  161. data/lib/active_support/xml_mini/nokogiri.rb +27 -24
  162. data/lib/active_support/xml_mini/nokogirisax.rb +83 -0
  163. data/lib/active_support/xml_mini/rexml.rb +8 -2
  164. metadata +62 -195
  165. data/README +0 -43
  166. data/lib/active_support/autoload.rb +0 -28
  167. data/lib/active_support/core_ext/boolean.rb +0 -1
  168. data/lib/active_support/core_ext/boolean/conversions.rb +0 -11
  169. data/lib/active_support/core_ext/class/removal.rb +0 -53
  170. data/lib/active_support/core_ext/date.rb +0 -7
  171. data/lib/active_support/core_ext/date_time.rb +0 -5
  172. data/lib/active_support/core_ext/integer/even_odd.rb +0 -16
  173. data/lib/active_support/core_ext/kernel/daemonizing.rb +0 -7
  174. data/lib/active_support/core_ext/module/inclusion.rb +0 -30
  175. data/lib/active_support/core_ext/module/loading.rb +0 -23
  176. data/lib/active_support/core_ext/nil.rb +0 -1
  177. data/lib/active_support/core_ext/nil/conversions.rb +0 -5
  178. data/lib/active_support/core_ext/object/extending.rb +0 -80
  179. data/lib/active_support/core_ext/object/metaclass.rb +0 -13
  180. data/lib/active_support/core_ext/object/misc.rb +0 -3
  181. data/lib/active_support/core_ext/object/returning.rb +0 -42
  182. data/lib/active_support/core_ext/object/tap.rb +0 -16
  183. data/lib/active_support/core_ext/string/bytesize.rb +0 -5
  184. data/lib/active_support/core_ext/string/iterators.rb +0 -13
  185. data/lib/active_support/core_ext/symbol.rb +0 -1
  186. data/lib/active_support/core_ext/symbol/to_proc.rb +0 -14
  187. data/lib/active_support/core_ext/time.rb +0 -10
  188. data/lib/active_support/core_ext/time/marshal_with_utc_flag.rb +0 -22
  189. data/lib/active_support/deprecated_callbacks.rb +0 -283
  190. data/lib/active_support/multibyte/unicode_database.rb +0 -71
  191. data/lib/active_support/vendor.rb +0 -16
  192. data/lib/active_support/vendor/builder-2.1.2/lib/blankslate.rb +0 -113
  193. data/lib/active_support/vendor/builder-2.1.2/lib/builder.rb +0 -13
  194. data/lib/active_support/vendor/builder-2.1.2/lib/builder/blankslate.rb +0 -20
  195. data/lib/active_support/vendor/builder-2.1.2/lib/builder/css.rb +0 -250
  196. data/lib/active_support/vendor/builder-2.1.2/lib/builder/xchar.rb +0 -115
  197. data/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlbase.rb +0 -139
  198. data/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlevents.rb +0 -63
  199. data/lib/active_support/vendor/builder-2.1.2/lib/builder/xmlmarkup.rb +0 -328
  200. data/lib/active_support/vendor/i18n-0.1.3/MIT-LICENSE +0 -20
  201. data/lib/active_support/vendor/i18n-0.1.3/README.textile +0 -20
  202. data/lib/active_support/vendor/i18n-0.1.3/Rakefile +0 -5
  203. data/lib/active_support/vendor/i18n-0.1.3/i18n.gemspec +0 -27
  204. data/lib/active_support/vendor/i18n-0.1.3/lib/i18n.rb +0 -204
  205. data/lib/active_support/vendor/i18n-0.1.3/lib/i18n/backend/simple.rb +0 -215
  206. data/lib/active_support/vendor/i18n-0.1.3/lib/i18n/exceptions.rb +0 -53
  207. data/lib/active_support/vendor/i18n-0.1.3/test/all.rb +0 -5
  208. data/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb +0 -99
  209. data/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb +0 -124
  210. data/lib/active_support/vendor/i18n-0.1.3/test/locale/en.rb +0 -1
  211. data/lib/active_support/vendor/i18n-0.1.3/test/locale/en.yml +0 -3
  212. data/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb +0 -567
  213. data/lib/active_support/vendor/memcache-client-1.7.5/lib/memcache.rb +0 -1133
  214. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo.rb +0 -33
  215. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/data_timezone.rb +0 -47
  216. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/data_timezone_info.rb +0 -228
  217. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Algiers.rb +0 -55
  218. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Cairo.rb +0 -219
  219. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Casablanca.rb +0 -42
  220. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Harare.rb +0 -18
  221. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Johannesburg.rb +0 -25
  222. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Monrovia.rb +0 -22
  223. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Africa/Nairobi.rb +0 -23
  224. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Argentina/Buenos_Aires.rb +0 -166
  225. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Argentina/San_Juan.rb +0 -86
  226. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Bogota.rb +0 -23
  227. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Caracas.rb +0 -23
  228. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Chicago.rb +0 -283
  229. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Chihuahua.rb +0 -136
  230. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Denver.rb +0 -204
  231. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Godthab.rb +0 -161
  232. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Guatemala.rb +0 -27
  233. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Halifax.rb +0 -274
  234. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Indiana/Indianapolis.rb +0 -149
  235. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Juneau.rb +0 -194
  236. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/La_Paz.rb +0 -22
  237. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Lima.rb +0 -35
  238. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Los_Angeles.rb +0 -232
  239. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Mazatlan.rb +0 -139
  240. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Mexico_City.rb +0 -144
  241. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Monterrey.rb +0 -131
  242. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/New_York.rb +0 -282
  243. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Phoenix.rb +0 -30
  244. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Regina.rb +0 -74
  245. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Santiago.rb +0 -205
  246. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Sao_Paulo.rb +0 -171
  247. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/St_Johns.rb +0 -288
  248. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/America/Tijuana.rb +0 -196
  249. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Almaty.rb +0 -67
  250. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Baghdad.rb +0 -73
  251. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Baku.rb +0 -161
  252. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Bangkok.rb +0 -20
  253. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Chongqing.rb +0 -33
  254. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Colombo.rb +0 -30
  255. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Dhaka.rb +0 -27
  256. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Hong_Kong.rb +0 -87
  257. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Irkutsk.rb +0 -165
  258. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Jakarta.rb +0 -30
  259. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Jerusalem.rb +0 -163
  260. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kabul.rb +0 -20
  261. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kamchatka.rb +0 -163
  262. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Karachi.rb +0 -32
  263. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kathmandu.rb +0 -20
  264. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kolkata.rb +0 -25
  265. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Krasnoyarsk.rb +0 -163
  266. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kuala_Lumpur.rb +0 -31
  267. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Kuwait.rb +0 -18
  268. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Magadan.rb +0 -163
  269. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Muscat.rb +0 -18
  270. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Novosibirsk.rb +0 -164
  271. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Rangoon.rb +0 -24
  272. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Riyadh.rb +0 -18
  273. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Seoul.rb +0 -34
  274. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Shanghai.rb +0 -35
  275. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Singapore.rb +0 -33
  276. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Taipei.rb +0 -59
  277. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Tashkent.rb +0 -47
  278. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Tbilisi.rb +0 -78
  279. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Tehran.rb +0 -121
  280. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Tokyo.rb +0 -30
  281. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Ulaanbaatar.rb +0 -65
  282. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Urumqi.rb +0 -33
  283. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Vladivostok.rb +0 -164
  284. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Yakutsk.rb +0 -163
  285. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Yekaterinburg.rb +0 -165
  286. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Asia/Yerevan.rb +0 -165
  287. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Atlantic/Azores.rb +0 -270
  288. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Atlantic/Cape_Verde.rb +0 -23
  289. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Atlantic/South_Georgia.rb +0 -18
  290. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Adelaide.rb +0 -187
  291. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Brisbane.rb +0 -35
  292. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Darwin.rb +0 -29
  293. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Hobart.rb +0 -193
  294. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Melbourne.rb +0 -185
  295. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Perth.rb +0 -37
  296. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Australia/Sydney.rb +0 -185
  297. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Etc/UTC.rb +0 -16
  298. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Amsterdam.rb +0 -228
  299. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Athens.rb +0 -185
  300. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Belgrade.rb +0 -163
  301. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Berlin.rb +0 -188
  302. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Bratislava.rb +0 -13
  303. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Brussels.rb +0 -232
  304. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Bucharest.rb +0 -181
  305. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Budapest.rb +0 -197
  306. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Copenhagen.rb +0 -179
  307. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Dublin.rb +0 -276
  308. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Helsinki.rb +0 -163
  309. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Istanbul.rb +0 -218
  310. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Kiev.rb +0 -168
  311. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Lisbon.rb +0 -268
  312. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Ljubljana.rb +0 -13
  313. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/London.rb +0 -288
  314. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Madrid.rb +0 -211
  315. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Minsk.rb +0 -170
  316. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Moscow.rb +0 -181
  317. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Paris.rb +0 -232
  318. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Prague.rb +0 -187
  319. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Riga.rb +0 -176
  320. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Rome.rb +0 -215
  321. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Sarajevo.rb +0 -13
  322. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Skopje.rb +0 -13
  323. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Sofia.rb +0 -173
  324. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Stockholm.rb +0 -165
  325. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Tallinn.rb +0 -172
  326. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Vienna.rb +0 -183
  327. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Vilnius.rb +0 -170
  328. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Warsaw.rb +0 -212
  329. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Europe/Zagreb.rb +0 -13
  330. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Auckland.rb +0 -202
  331. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Fiji.rb +0 -23
  332. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Guam.rb +0 -22
  333. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Honolulu.rb +0 -28
  334. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Majuro.rb +0 -20
  335. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Midway.rb +0 -25
  336. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Noumea.rb +0 -25
  337. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Pago_Pago.rb +0 -26
  338. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Port_Moresby.rb +0 -20
  339. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/definitions/Pacific/Tongatapu.rb +0 -27
  340. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/info_timezone.rb +0 -52
  341. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/linked_timezone.rb +0 -51
  342. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/linked_timezone_info.rb +0 -44
  343. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/offset_rationals.rb +0 -98
  344. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/ruby_core_support.rb +0 -56
  345. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/time_or_datetime.rb +0 -292
  346. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone.rb +0 -508
  347. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone_definition.rb +0 -56
  348. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone_info.rb +0 -40
  349. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone_offset_info.rb +0 -94
  350. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone_period.rb +0 -198
  351. data/lib/active_support/vendor/tzinfo-0.3.13/lib/tzinfo/timezone_transition_info.rb +0 -129
data/CHANGELOG CHANGED
@@ -1,4 +1,124 @@
1
- *Edge*
1
+ *Rails 3.0.0 [release candidate] (July 26th, 2010)*
2
+
3
+ * Removed Object#returning, Object#tap should be used instead. [Santiago Pastorino]
4
+
5
+ * Deprecation behavior is no longer hardcoded to the name of the environment.
6
+ Instead, it is set via config.active_support.deprecation and can be one
7
+ of :log, :stderr or :notify. :notify is a new style that sends the warning
8
+ via ActiveSupport::Notifications, and is the new default for production
9
+ [Yehuda Katz]
10
+
11
+ * Renamed ActiveSupport::Dependecies.load_(once_)paths to autoload_(once_)paths. [fxn]
12
+
13
+ * Added ActiveSupport::FileUpdateChecker to execute a block only if a set of files changed, used by Router and I18n locale files. [José Valim]
14
+
15
+ * Added ActiveSupport::DescendantsTracker to track descendants with support to constants reloading. [José Valim]
16
+
17
+ * ActiveSupport::OrderedHash#merge and #merge! accept a block. #4838 [Paul Mucur, fxn]
18
+
19
+ * Date#since, #ago, #beginning_of_day, #end_of_day, and #xmlschema honor now the user time zone if set. [Geoff Buesing]
20
+
21
+
22
+ *Rails 3.0.0 [beta 4] (June 8th, 2010)*
23
+
24
+ * Extracted String#truncate from TextHelper#truncate [DHH]
25
+
26
+ * Ruby 1.9: support UTF-8 case folding. #4595 [Norman Clarke]
27
+
28
+ * Removes Array#rand and backports Array#sample from Ruby 1.9, thanks to Marc-Andre Lafortune. [fxn]
29
+
30
+ * Ruby 1.9: Renames last_(month|year) to prev_(month|year) in Date and Time. [fxn]
31
+
32
+ * Aliases Date#sunday to Date#end_of_week. [fxn]
33
+
34
+ * Backports Date#>> from 1.9 so that calculations do the right thing around the calendar reform. [fxn]
35
+
36
+ * Date#to_time handles properly years in the range 0..138. [fxn]
37
+
38
+ * Deprecate {{}} as interpolation syntax for I18n in favor of %{} [José Valim]
39
+
40
+ * Array#to_xml is more powerful and able to handle the same types as Hash#to_xml #4490 [Neeraj Singh]
41
+
42
+ * Harmonize the caching API and refactor the backends. #4452 [Brian Durand]
43
+ All caches:
44
+ * Add default options to initializer that will be sent to all read, write, fetch, exist?, increment, and decrement
45
+ * Add support for the :expires_in option to fetch and write for all caches. Cache entries are stored with the create timestamp and a ttl so that expiration can be handled independently of the implementation.
46
+ * Add support for a :namespace option. This can be used to set a global prefix for cache entries.
47
+ * Deprecate expand_cache_key on ActiveSupport::Cache and move it to ActionController::Caching and ActionDispatch::Http::Cache since the logic in the method used some Rails specific environment variables and was only used by ActionPack classes. Not very DRY but there didn't seem to be a good shared spot and ActiveSupport really shouldn't be Rails specific.
48
+ * Add support for :race_condition_ttl to fetch. This setting can prevent race conditions on fetch calls where several processes try to regenerate a recently expired entry at once.
49
+ * Add support for :compress option to fetch and write which will compress any data over a configurable threshold.
50
+ * Nil values can now be stored in the cache and are distinct from cache misses for fetch.
51
+ * Easier API to create new implementations. Just need to implement the methods read_entry, write_entry, and delete_entry instead of overwriting existing methods.
52
+ * Since all cache implementations support storing objects, update the docs to state that ActiveCache::Cache::Store implementations should store objects. Keys, however, must be strings since some implementations require that.
53
+ * Increase test coverage.
54
+ * Document methods which are provided as convenience but which may not be universally available.
55
+
56
+ MemoryStore:
57
+ * MemoryStore can now safely be used as the cache for single server sites.
58
+ * Make thread safe so that the default cache implementation used by Rails is thread safe. The overhead is minimal and it is still the fastest store available.
59
+ * Provide :size initialization option indicating the maximum size of the cache in memory (defaults to 32Mb).
60
+ * Add prune logic that removes the least recently used cache entries to keep the cache size from exceeding the max.
61
+ * Deprecated SynchronizedMemoryStore since it isn't needed anymore.
62
+
63
+ FileStore:
64
+ * Escape key values so they will work as file names on all file systems, be consistent, and case sensitive
65
+ * Use a hash algorithm to segment the cache into sub directories so that a large cache doesn't exceed file system limits.
66
+ * FileStore can be slow so implement the LocalCache strategy to cache reads for the duration of a request.
67
+ * Add cleanup method to keep the disk from filling up with expired entries.
68
+ * Fix increment and decrement to use file system locks so they are consistent between processes.
69
+
70
+ MemCacheStore:
71
+ * Support all keys. Previously keys with spaces in them would fail
72
+ * Deprecate CompressedMemCacheStore since it isn't needed anymore (use :compress => true)
73
+
74
+ * JSON: encode objects that don't have a native JSON representation using to_hash, if available, instead of instance_values (the old fallback) or to_s (other encoders' default). Encode BigDecimal and Regexp encode as strings to conform with other encoders. Try to transcode non-UTF-8 strings. [Jeremy Kemper]
75
+
76
+
77
+ *Rails 3.0.0 [beta 3] (April 13th, 2010)*
78
+
79
+ * HashWithIndifferentAccess: remove inherited symbolize_keys! since its keys are always strings. [Santiago Pastorino]
80
+
81
+ * Improve transliteration quality. #4374 [Norman Clarke]
82
+
83
+ * Speed up and add Ruby 1.9 support for ActiveSupport::Multibyte::Chars#tidy_bytes. #4350 [Norman Clarke]
84
+
85
+
86
+ *Rails 3.0.0 [beta 2] (April 1st, 2010)*
87
+
88
+ * Reduced load time by deferring configuration of classes using
89
+ ActiveSupport::on_load(:component_name) [YK]
90
+
91
+ * Rename #metaclass to #singleton_class now that ruby-core has decided [JK]
92
+
93
+ * New assertions assert_blank and assert_present. #4299 [Juanjo Bazan]
94
+
95
+ * Use Object#singleton_class instead of #metaclass. Prefer Ruby's choice. [Jeremy Kemper]
96
+
97
+ * JSON backend for YAJL. Preferred if available. #2666 [Brian Lopez]
98
+
99
+
100
+ *Rails 3.0.0 [beta 1] (February 4, 2010)*
101
+
102
+ * Introduce class_attribute to declare inheritable class attributes. Writing an attribute on a subclass behaves just like overriding the superclass reader method. Unifies and replaces most usage of cattr_accessor, class_inheritable_attribute, superclass_delegating_attribute, and extlib_inheritable_attribute. [Jeremy Kemper, Yehuda Katz]
103
+
104
+ * Time#- with a DateTime argument behaves the same as with a Time argument, i.e. returns the difference between self and arg as a Float #3476 [Geoff Buesing]
105
+
106
+ * YAML serialization for OrderedHash. #3608 [Gregor Schmidt]
107
+
108
+ * Update bundled TZInfo to v0.3.16 [Geoff Buesing]
109
+
110
+ * Georgetown TimeZone is now mapped to "America/Guyana" instead of "America/Argentina/San_Juan" #1821 [Geoff Buesing, Reuben Sivan]
111
+
112
+ * Changed the default ActiveSupport.use_standard_json_time_format from false to true and
113
+ ActiveSupport.escape_html_entities_in_json from true to false to match previously announced Rails 3 defaults [DHH]
114
+
115
+ * Added Object#presence that returns the object if it's #present? otherwise returns nil [DHH/Colin Kelley]
116
+
117
+ * Add Enumerable#exclude? to bring parity to Enumerable#include? and avoid if !x.include?/else calls [DHH]
118
+
119
+ * Update Edinburgh TimeZone to use "Europe/London" instead of "Europe/Dublin" #3310 [Phil Ross]
120
+
121
+ * Update bundled TZInfo to v0.3.15 [Geoff Buesing]
2
122
 
3
123
  * JSON: +Object#to_json+ calls +as_json+ to coerce itself into something natively encodable like +Hash+, +Integer+, or +String+. Override +as_json+ instead of +to_json+ so you're JSON library agnostic. [Jeremy Kemper]
4
124
 
@@ -0,0 +1,33 @@
1
+ = Active Support -- Utility classes and Ruby extensions from Rails
2
+
3
+ Active Support is a collection of utility classes and standard library
4
+ extensions that were found useful for the Rails framework. These additions
5
+ reside in this package so they can be loaded as needed in Ruby projects
6
+ outside of Rails.
7
+
8
+
9
+ == Download and installation
10
+
11
+ The latest version of Active Support can be installed with Rubygems:
12
+
13
+ % [sudo] gem install activesupport
14
+
15
+ Source code can be downloaded as part of the Rails project on GitHub
16
+
17
+ * http://github.com/rails/rails/tree/master/activesupport/
18
+
19
+
20
+ == License
21
+
22
+ Active Support is released under the MIT license.
23
+
24
+
25
+ == Support
26
+
27
+ API documentation is at
28
+
29
+ * http://api.rubyonrails.com
30
+
31
+ Bug reports and feature requests can be filed with the rest for the Ruby on Rails project here:
32
+
33
+ * https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets
@@ -34,8 +34,46 @@ module ActiveSupport
34
34
  end
35
35
  end
36
36
 
37
- require 'active_support/autoload'
38
- require 'active_support/vendor'
37
+ require "active_support/dependencies/autoload"
39
38
 
40
- require 'i18n'
41
- I18n.load_path << "#{File.dirname(__FILE__)}/active_support/locale/en.yml"
39
+ module ActiveSupport
40
+ extend ActiveSupport::Autoload
41
+
42
+ autoload :DescendantsTracker
43
+ autoload :FileUpdateChecker
44
+ autoload :LogSubscriber
45
+ autoload :Notifications
46
+
47
+ # TODO: Narrow this list down
48
+ eager_autoload do
49
+ autoload :BacktraceCleaner
50
+ autoload :Base64
51
+ autoload :BasicObject
52
+ autoload :Benchmarkable
53
+ autoload :BufferedLogger
54
+ autoload :Cache
55
+ autoload :Callbacks
56
+ autoload :Concern
57
+ autoload :Configurable
58
+ autoload :Deprecation
59
+ autoload :Gzip
60
+ autoload :Inflector
61
+ autoload :JSON
62
+ autoload :Memoizable
63
+ autoload :MessageEncryptor
64
+ autoload :MessageVerifier
65
+ autoload :Multibyte
66
+ autoload :OptionMerger
67
+ autoload :OrderedHash
68
+ autoload :OrderedOptions
69
+ autoload :Rescuable
70
+ autoload :SecureRandom
71
+ autoload :StringInquirer
72
+ autoload :XmlMini
73
+ end
74
+
75
+ autoload :SafeBuffer, "active_support/core_ext/string/output_safety"
76
+ autoload :TestCase
77
+ end
78
+
79
+ autoload :I18n, "active_support/i18n"
@@ -4,12 +4,14 @@ module ActiveSupport
4
4
  # context, so only the relevant lines are included.
5
5
  #
6
6
  # If you need to reconfigure an existing BacktraceCleaner, like the one in Rails, to show as much as possible, you can always
7
- # call BacktraceCleaner#remove_silencers!
7
+ # call BacktraceCleaner#remove_silencers! Also, if you need to reconfigure an existing BacktraceCleaner so that it does not
8
+ # filter or modify the paths of any lines of the backtrace, you can call BacktraceCleaner#remove_filters! These two methods
9
+ # will give you a completely untouched backtrace.
8
10
  #
9
11
  # Example:
10
12
  #
11
13
  # bc = BacktraceCleaner.new
12
- # bc.add_filter { |line| line.gsub(Rails.root, '') }
14
+ # bc.add_filter { |line| line.gsub(Rails.root, '') }
13
15
  # bc.add_silencer { |line| line =~ /mongrel|rubygems/ }
14
16
  # bc.clean(exception.backtrace) # will strip the Rails.root prefix and skip any lines from mongrel or rubygems
15
17
  #
@@ -18,10 +20,19 @@ module ActiveSupport
18
20
  def initialize
19
21
  @filters, @silencers = [], []
20
22
  end
21
-
23
+
22
24
  # Returns the backtrace after all filters and silencers has been run against it. Filters run first, then silencers.
23
- def clean(backtrace)
24
- silence(filter(backtrace))
25
+ def clean(backtrace, kind = :silent)
26
+ filtered = filter(backtrace)
27
+
28
+ case kind
29
+ when :silent
30
+ silence(filtered)
31
+ when :noise
32
+ noise(filtered)
33
+ else
34
+ filtered
35
+ end
25
36
  end
26
37
 
27
38
  # Adds a filter from the block provided. Each line in the backtrace will be mapped against this filter.
@@ -51,21 +62,32 @@ module ActiveSupport
51
62
  @silencers = []
52
63
  end
53
64
 
54
-
65
+ def remove_filters!
66
+ @filters = []
67
+ end
68
+
55
69
  private
56
70
  def filter(backtrace)
57
71
  @filters.each do |f|
58
72
  backtrace = backtrace.map { |line| f.call(line) }
59
73
  end
60
-
74
+
61
75
  backtrace
62
76
  end
63
-
77
+
64
78
  def silence(backtrace)
65
79
  @silencers.each do |s|
66
80
  backtrace = backtrace.reject { |line| s.call(line) }
67
81
  end
68
-
82
+
83
+ backtrace
84
+ end
85
+
86
+ def noise(backtrace)
87
+ @silencers.each do |s|
88
+ backtrace = backtrace.select { |line| s.call(line) }
89
+ end
90
+
69
91
  backtrace
70
92
  end
71
93
  end
@@ -1,4 +1,5 @@
1
1
  require 'active_support/core_ext/benchmark'
2
+ require 'active_support/core_ext/hash/keys'
2
3
 
3
4
  module ActiveSupport
4
5
  module Benchmarkable
@@ -53,7 +53,6 @@ module ActiveSupport
53
53
  FileUtils.mkdir_p(File.dirname(log))
54
54
  @log = open(log, (File::WRONLY | File::APPEND | File::CREAT))
55
55
  @log.sync = true
56
- @log.write("# Logfile created on %s" % [Time.now.to_s])
57
56
  end
58
57
  end
59
58
 
@@ -102,7 +101,11 @@ module ActiveSupport
102
101
  @guard.synchronize do
103
102
  unless buffer.empty?
104
103
  old_buffer = buffer
105
- @log.write(old_buffer.join)
104
+ all_content = StringIO.new
105
+ old_buffer.each do |content|
106
+ all_content << content
107
+ end
108
+ @log.write(all_content.string)
106
109
  end
107
110
 
108
111
  # Important to do this even if buffer was empty or else @buffer will
@@ -0,0 +1,6 @@
1
+ begin
2
+ require 'builder'
3
+ rescue LoadError => e
4
+ $stderr.puts "You don't have builder installed in your application. Please add it to your Gemfile and run bundle install"
5
+ raise e
6
+ end
@@ -1,23 +1,30 @@
1
1
  require 'benchmark'
2
+ require 'zlib'
3
+ require 'active_support/core_ext/array/extract_options'
4
+ require 'active_support/core_ext/array/wrap'
2
5
  require 'active_support/core_ext/benchmark'
3
6
  require 'active_support/core_ext/exception'
4
7
  require 'active_support/core_ext/class/attribute_accessors'
5
-
6
- %w(hash nil string time date date_time array big_decimal range object boolean).each do |library|
7
- require "active_support/core_ext/#{library}/conversions"
8
- end
9
-
10
- # require 'active_support/core_ext' # FIXME: pulling in all to_param extensions
8
+ require 'active_support/core_ext/numeric/bytes'
9
+ require 'active_support/core_ext/numeric/time'
10
+ require 'active_support/core_ext/object/to_param'
11
+ require 'active_support/core_ext/string/inflections'
11
12
 
12
13
  module ActiveSupport
13
14
  # See ActiveSupport::Cache::Store for documentation.
14
15
  module Cache
15
16
  autoload :FileStore, 'active_support/cache/file_store'
16
17
  autoload :MemoryStore, 'active_support/cache/memory_store'
17
- autoload :SynchronizedMemoryStore, 'active_support/cache/synchronized_memory_store'
18
18
  autoload :MemCacheStore, 'active_support/cache/mem_cache_store'
19
+ autoload :SynchronizedMemoryStore, 'active_support/cache/synchronized_memory_store'
19
20
  autoload :CompressedMemCacheStore, 'active_support/cache/compressed_mem_cache_store'
20
21
 
22
+ EMPTY_OPTIONS = {}.freeze
23
+
24
+ # These options mean something to all cache implementations. Individual cache
25
+ # implementations may support additional options.
26
+ UNIVERSAL_OPTIONS = [:namespace, :compress, :compress_threshold, :expires_in, :race_condition_ttl]
27
+
21
28
  module Strategy
22
29
  autoload :LocalCache, 'active_support/cache/strategy/local_cache'
23
30
  end
@@ -33,7 +40,7 @@ module ActiveSupport
33
40
  #
34
41
  # ActiveSupport::Cache.lookup_store(:memory_store)
35
42
  # # => returns a new ActiveSupport::Cache::MemoryStore object
36
- #
43
+ #
37
44
  # ActiveSupport::Cache.lookup_store(:mem_cache_store)
38
45
  # # => returns a new ActiveSupport::Cache::MemCacheStore object
39
46
  #
@@ -48,7 +55,7 @@ module ActiveSupport
48
55
  # ActiveSupport::Cache.lookup_store(MyOwnCacheStore.new)
49
56
  # # => returns MyOwnCacheStore.new
50
57
  def self.lookup_store(*store_option)
51
- store, *parameters = *([ store_option ].flatten)
58
+ store, *parameters = *Array.wrap(store_option).flatten
52
59
 
53
60
  case store
54
61
  when Symbol
@@ -62,15 +69,12 @@ module ActiveSupport
62
69
  end
63
70
  end
64
71
 
65
- RAILS_CACHE_ID = ENV["RAILS_CACHE_ID"]
66
- RAILS_APP_VERION = ENV["RAILS_APP_VERION"]
67
- EXPANDED_CACHE = RAILS_CACHE_ID || RAILS_APP_VERION
68
-
69
72
  def self.expand_cache_key(key, namespace = nil)
70
73
  expanded_cache_key = namespace ? "#{namespace}/" : ""
71
74
 
72
- if EXPANDED_CACHE
73
- expanded_cache_key << "#{RAILS_CACHE_ID || RAILS_APP_VERION}/"
75
+ prefix = ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"]
76
+ if prefix
77
+ expanded_cache_key << "#{prefix}/"
74
78
  end
75
79
 
76
80
  expanded_cache_key <<
@@ -95,26 +99,75 @@ module ActiveSupport
95
99
  # ActiveSupport::Cache::MemCacheStore. MemCacheStore is currently the most
96
100
  # popular cache store for large production websites.
97
101
  #
98
- # ActiveSupport::Cache::Store is meant for caching strings. Some cache
99
- # store implementations, like MemoryStore, are able to cache arbitrary
100
- # Ruby objects, but don't count on every cache store to be able to do that.
102
+ # Some implementations may not support all methods beyond the basic cache
103
+ # methods of +fetch+, +write+, +read+, +exist?+, and +delete+.
104
+ #
105
+ # ActiveSupport::Cache::Store can store any serializable Ruby object.
101
106
  #
102
107
  # cache = ActiveSupport::Cache::MemoryStore.new
103
- #
108
+ #
104
109
  # cache.read("city") # => nil
105
110
  # cache.write("city", "Duckburgh")
106
111
  # cache.read("city") # => "Duckburgh"
112
+ #
113
+ # Keys are always translated into Strings and are case sensitive. When an
114
+ # object is specified as a key, its +cache_key+ method will be called if it
115
+ # is defined. Otherwise, the +to_param+ method will be called. Hashes and
116
+ # Arrays can be used as keys. The elements will be delimited by slashes
117
+ # and Hashes elements will be sorted by key so they are consistent.
118
+ #
119
+ # cache.read("city") == cache.read(:city) # => true
120
+ #
121
+ # Nil values can be cached.
122
+ #
123
+ # If your cache is on a shared infrastructure, you can define a namespace for
124
+ # your cache entries. If a namespace is defined, it will be prefixed on to every
125
+ # key. The namespace can be either a static value or a Proc. If it is a Proc, it
126
+ # will be invoked when each key is evaluated so that you can use application logic
127
+ # to invalidate keys.
128
+ #
129
+ # cache.namespace = lambda { @last_mod_time } # Set the namespace to a variable
130
+ # @last_mod_time = Time.now # Invalidate the entire cache by changing namespace
131
+ #
132
+ # All caches support auto expiring content after a specified number of seconds.
133
+ # To set the cache entry time to live, you can either specify +:expires_in+ as
134
+ # an option to the constructor to have it affect all entries or to the +fetch+
135
+ # or +write+ methods for just one entry.
136
+ #
137
+ # cache = ActiveSupport::Cache::MemoryStore.new(:expire_in => 5.minutes)
138
+ # cache.write(key, value, :expire_in => 1.minute) # Set a lower value for one entry
139
+ #
140
+ # Caches can also store values in a compressed format to save space and reduce
141
+ # time spent sending data. Since there is some overhead, values must be large
142
+ # enough to warrant compression. To turn on compression either pass
143
+ # <tt>:compress => true</tt> in the initializer or to +fetch+ or +write+.
144
+ # To specify the threshold at which to compress values, set
145
+ # <tt>:compress_threshold</tt>. The default threshold is 32K.
107
146
  class Store
108
- cattr_accessor :logger, :instance_writter => false
147
+
148
+ cattr_accessor :logger, :instance_writer => true
109
149
 
110
150
  attr_reader :silence
111
151
  alias :silence? :silence
112
152
 
153
+ # Create a new cache. The options will be passed to any write method calls except
154
+ # for :namespace which can be used to set the global namespace for the cache.
155
+ def initialize (options = nil)
156
+ @options = options ? options.dup : {}
157
+ end
158
+
159
+ # Get the default options set when the cache was created.
160
+ def options
161
+ @options ||= {}
162
+ end
163
+
164
+ # Silence the logger.
113
165
  def silence!
114
166
  @silence = true
115
167
  self
116
168
  end
117
169
 
170
+ # Silence the logger within a block.
118
171
  def mute
119
172
  previous_silence, @silence = defined?(@silence) && @silence, true
120
173
  yield
@@ -142,7 +195,7 @@ module ActiveSupport
142
195
  #
143
196
  # cache.write("today", "Monday")
144
197
  # cache.fetch("today") # => "Monday"
145
- #
198
+ #
146
199
  # cache.fetch("city") # => nil
147
200
  # cache.fetch("city") do
148
201
  # "Duckburgh"
@@ -155,29 +208,98 @@ module ActiveSupport
155
208
  # cache.write("today", "Monday")
156
209
  # cache.fetch("today", :force => true) # => nil
157
210
  #
211
+ # Setting <tt>:compress</tt> will store a large cache entry set by the call
212
+ # in a compressed format.
213
+ #
214
+ # Setting <tt>:expires_in</tt> will set an expiration time on the cache
215
+ # entry if it is set by call.
216
+ #
217
+ # Setting <tt>:race_condition_ttl</tt> will invoke logic on entries set with
218
+ # an <tt>:expires_in</tt> option. If an entry is found in the cache that is
219
+ # expired and it has been expired for less than the number of seconds specified
220
+ # by this option and a block was passed to the method call, then the expiration
221
+ # future time of the entry in the cache will be updated to that many seconds
222
+ # in the and the block will be evaluated and written to the cache.
223
+ #
224
+ # This is very useful in situations where a cache entry is used very frequently
225
+ # under heavy load. The first process to find an expired cache entry will then
226
+ # become responsible for regenerating that entry while other processes continue
227
+ # to use the slightly out of date entry. This can prevent race conditions where
228
+ # too many processes are trying to regenerate the entry all at once. If the
229
+ # process regenerating the entry errors out, the entry will be regenerated
230
+ # after the specified number of seconds.
231
+ #
232
+ # # Set all values to expire after one minute.
233
+ # cache = ActiveSupport::Cache::MemoryCache.new(:expires_in => 1.minute)
234
+ #
235
+ # cache.write("foo", "original value")
236
+ # val_1 = nil
237
+ # val_2 = nil
238
+ # sleep 60
239
+ #
240
+ # Thread.new do
241
+ # val_1 = cache.fetch("foo", :race_condition_ttl => 10) do
242
+ # sleep 1
243
+ # "new value 1"
244
+ # end
245
+ # end
246
+ #
247
+ # Thread.new do
248
+ # val_2 = cache.fetch("foo", :race_condition_ttl => 10) do
249
+ # "new value 2"
250
+ # end
251
+ # end
252
+ #
253
+ # # val_1 => "new value 1"
254
+ # # val_2 => "original value"
255
+ # # cache.fetch("foo") => "new value 1"
256
+ #
158
257
  # Other options will be handled by the specific cache store implementation.
159
- # Internally, #fetch calls #read, and calls #write on a cache miss.
258
+ # Internally, #fetch calls #read_entry, and calls #write_entry on a cache miss.
160
259
  # +options+ will be passed to the #read and #write calls.
161
260
  #
162
- # For example, MemCacheStore's #write method supports the +:expires_in+
163
- # option, which tells the memcached server to automatically expire the
164
- # cache item after a certain period. This options is also supported by
165
- # FileStore's #read method. We can use this option with #fetch too:
261
+ # For example, MemCacheStore's #write method supports the +:raw+
262
+ # option, which tells the memcached server to store all values as strings.
263
+ # We can use this option with #fetch too:
166
264
  #
167
265
  # cache = ActiveSupport::Cache::MemCacheStore.new
168
- # cache.fetch("foo", :force => true, :expires_in => 5.seconds) do
169
- # "bar"
266
+ # cache.fetch("foo", :force => true, :raw => true) do
267
+ # :bar
170
268
  # end
171
269
  # cache.fetch("foo") # => "bar"
172
- # sleep(6)
173
- # cache.fetch("foo") # => nil
174
- def fetch(key, options = {}, &block)
175
- if !options[:force] && value = read(key, options)
176
- value
177
- elsif block_given?
178
- result = instrument(:generate, key, options, &block)
179
- write(key, result, options)
180
- result
270
+ def fetch(name, options = nil)
271
+ if block_given?
272
+ options = merged_options(options)
273
+ key = namespaced_key(name, options)
274
+ unless options[:force]
275
+ entry = instrument(:read, name, options) do |payload|
276
+ payload[:super_operation] = :fetch if payload
277
+ read_entry(key, options)
278
+ end
279
+ end
280
+ if entry && entry.expired?
281
+ race_ttl = options[:race_condition_ttl].to_f
282
+ if race_ttl and Time.now.to_f - entry.expires_at <= race_ttl
283
+ entry.expires_at = Time.now + race_ttl
284
+ write_entry(key, entry, :expires_in => race_ttl * 2)
285
+ else
286
+ delete_entry(key, options)
287
+ end
288
+ entry = nil
289
+ end
290
+
291
+ if entry
292
+ instrument(:fetch_hit, name, options) { |payload| }
293
+ entry.value
294
+ else
295
+ result = instrument(:generate, name, options) do |payload|
296
+ yield
297
+ end
298
+ write(name, result, options)
299
+ result
300
+ end
301
+ else
302
+ read(name, options)
181
303
  end
182
304
  end
183
305
 
@@ -185,15 +307,50 @@ module ActiveSupport
185
307
  # the cache with the given key, then that data is returned. Otherwise,
186
308
  # nil is returned.
187
309
  #
188
- # You may also specify additional options via the +options+ argument.
189
- # The specific cache store implementation will decide what to do with
190
- # +options+.
310
+ # Options are passed to the underlying cache implementation.
311
+ def read(name, options = nil)
312
+ options = merged_options(options)
313
+ key = namespaced_key(name, options)
314
+ instrument(:read, name, options) do |payload|
315
+ entry = read_entry(key, options)
316
+ if entry
317
+ if entry.expired?
318
+ delete_entry(key, options)
319
+ payload[:hit] = false if payload
320
+ nil
321
+ else
322
+ payload[:hit] = true if payload
323
+ entry.value
324
+ end
325
+ else
326
+ payload[:hit] = false if payload
327
+ nil
328
+ end
329
+ end
330
+ end
331
+
332
+ # Read multiple values at once from the cache. Options can be passed
333
+ # in the last argument.
334
+ #
335
+ # Some cache implementation may optimize this method.
191
336
  #
192
- # For example, FileStore supports the +:expires_in+ option, which
193
- # makes the method return nil for cache items older than the specified
194
- # period.
195
- def read(key, options = nil, &block)
196
- instrument(:read, key, options, &block)
337
+ # Returns a hash mapping the names provided to the values found.
338
+ def read_multi(*names)
339
+ options = names.extract_options!
340
+ options = merged_options(options)
341
+ results = {}
342
+ names.each do |name|
343
+ key = namespaced_key(name, options)
344
+ entry = read_entry(key, options)
345
+ if entry
346
+ if entry.expired?
347
+ delete_entry(key)
348
+ else
349
+ results[name] = entry.value
350
+ end
351
+ end
352
+ end
353
+ results
197
354
  end
198
355
 
199
356
  # Writes the given value to the cache, with the given key.
@@ -201,70 +358,283 @@ module ActiveSupport
201
358
  # You may also specify additional options via the +options+ argument.
202
359
  # The specific cache store implementation will decide what to do with
203
360
  # +options+.
204
- #
205
- # For example, MemCacheStore supports the +:expires_in+ option, which
206
- # tells the memcached server to automatically expire the cache item after
207
- # a certain period:
361
+ def write(name, value, options = nil)
362
+ options = merged_options(options)
363
+ instrument(:write, name, options) do |payload|
364
+ entry = Entry.new(value, options)
365
+ write_entry(namespaced_key(name, options), entry, options)
366
+ end
367
+ end
368
+
369
+ # Delete an entry in the cache. Returns +true+ if there was an entry to delete.
208
370
  #
209
- # cache = ActiveSupport::Cache::MemCacheStore.new
210
- # cache.write("foo", "bar", :expires_in => 5.seconds)
211
- # cache.read("foo") # => "bar"
212
- # sleep(6)
213
- # cache.read("foo") # => nil
214
- def write(key, value, options = nil, &block)
215
- instrument(:write, key, options, &block)
371
+ # Options are passed to the underlying cache implementation.
372
+ def delete(name, options = nil)
373
+ options = merged_options(options)
374
+ instrument(:delete, name) do |payload|
375
+ delete_entry(namespaced_key(name, options), options)
376
+ end
216
377
  end
217
378
 
218
- def delete(key, options = nil, &block)
219
- instrument(:delete, key, options, &block)
379
+ # Return true if the cache contains an entry with this name.
380
+ #
381
+ # Options are passed to the underlying cache implementation.
382
+ def exist?(name, options = nil)
383
+ options = merged_options(options)
384
+ instrument(:exist?, name) do |payload|
385
+ entry = read_entry(namespaced_key(name, options), options)
386
+ if entry && !entry.expired?
387
+ true
388
+ else
389
+ false
390
+ end
391
+ end
220
392
  end
221
393
 
222
- def delete_matched(matcher, options = nil, &block)
223
- instrument(:delete_matched, matcher.inspect, options, &block)
394
+ # Delete all entries whose keys match a pattern.
395
+ #
396
+ # Options are passed to the underlying cache implementation.
397
+ #
398
+ # Not all implementations may support +delete_matched+.
399
+ def delete_matched(matcher, options = nil)
400
+ raise NotImplementedError.new("#{self.class.name} does not support delete_matched")
224
401
  end
225
402
 
226
- def exist?(key, options = nil, &block)
227
- instrument(:exist?, key, options, &block)
403
+ # Increment an integer value in the cache.
404
+ #
405
+ # Options are passed to the underlying cache implementation.
406
+ #
407
+ # Not all implementations may support +delete_matched+.
408
+ def increment(name, amount = 1, options = nil)
409
+ raise NotImplementedError.new("#{self.class.name} does not support increment")
228
410
  end
229
411
 
230
- def increment(key, amount = 1)
231
- if num = read(key)
232
- write(key, num + amount)
233
- else
234
- nil
235
- end
412
+ # Increment an integer value in the cache.
413
+ #
414
+ # Options are passed to the underlying cache implementation.
415
+ #
416
+ # Not all implementations may support +delete_matched+.
417
+ def decrement(name, amount = 1, options = nil)
418
+ raise NotImplementedError.new("#{self.class.name} does not support decrement")
236
419
  end
237
420
 
238
- def decrement(key, amount = 1)
239
- if num = read(key)
240
- write(key, num - amount)
241
- else
242
- nil
243
- end
421
+ # Cleanup the cache by removing expired entries. Not all cache implementations may
422
+ # support this method.
423
+ #
424
+ # Options are passed to the underlying cache implementation.
425
+ #
426
+ # Not all implementations may support +delete_matched+.
427
+ def cleanup(options = nil)
428
+ raise NotImplementedError.new("#{self.class.name} does not support cleanup")
244
429
  end
245
430
 
431
+ # Clear the entire cache. Not all cache implementations may support this method.
432
+ # You should be careful with this method since it could affect other processes
433
+ # if you are using a shared cache.
434
+ #
435
+ # Options are passed to the underlying cache implementation.
436
+ #
437
+ # Not all implementations may support +delete_matched+.
438
+ def clear(options = nil)
439
+ raise NotImplementedError.new("#{self.class.name} does not support clear")
440
+ end
441
+
442
+ protected
443
+ # Add the namespace defined in the options to a pattern designed to match keys.
444
+ # Implementations that support delete_matched should call this method to translate
445
+ # a pattern that matches names into one that matches namespaced keys.
446
+ def key_matcher(pattern, options)
447
+ prefix = options[:namespace].is_a?(Proc) ? options[:namespace].call : options[:namespace]
448
+ if prefix
449
+ source = pattern.source
450
+ if source.start_with?('^')
451
+ source = source[1, source.length]
452
+ else
453
+ source = ".*#{source[0, source.length]}"
454
+ end
455
+ Regexp.new("^#{Regexp.escape(prefix)}:#{source}", pattern.options)
456
+ else
457
+ pattern
458
+ end
459
+ end
460
+
461
+ # Read an entry from the cache implementation. Subclasses must implement this method.
462
+ def read_entry(key, options) # :nodoc:
463
+ raise NotImplementedError.new
464
+ end
465
+
466
+ # Write an entry to the cache implementation. Subclasses must implement this method.
467
+ def write_entry(key, entry, options) # :nodoc:
468
+ raise NotImplementedError.new
469
+ end
470
+
471
+ # Delete an entry from the cache implementation. Subclasses must implement this method.
472
+ def delete_entry(key, options) # :nodoc:
473
+ raise NotImplementedError.new
474
+ end
475
+
246
476
  private
247
- def expires_in(options)
248
- expires_in = options && options[:expires_in]
249
- raise ":expires_in must be a number" if expires_in && !expires_in.is_a?(Numeric)
250
- expires_in || 0
477
+ # Merge the default options with ones specific to a method call.
478
+ def merged_options(call_options) # :nodoc:
479
+ if call_options
480
+ options.merge(call_options)
481
+ else
482
+ options.dup
483
+ end
251
484
  end
252
485
 
253
- def instrument(operation, key, options, &block)
486
+ # Expand a key to be a consistent string value. If the object responds to +cache_key+,
487
+ # it will be called. Otherwise, the to_param method will be called. If the key is a
488
+ # Hash, the keys will be sorted alphabetically.
489
+ def expanded_key(key) # :nodoc:
490
+ if key.respond_to?(:cache_key)
491
+ key = key.cache_key.to_s
492
+ elsif key.is_a?(Array)
493
+ if key.size > 1
494
+ key.collect{|element| expanded_key(element)}.to_param
495
+ else
496
+ key.first.to_param
497
+ end
498
+ elsif key.is_a?(Hash)
499
+ key = key.to_a.sort{|a,b| a.first.to_s <=> b.first.to_s}.collect{|k,v| "#{k}=#{v}"}.to_param
500
+ else
501
+ key = key.to_param
502
+ end
503
+ end
504
+
505
+ # Prefix a key with the namespace. The two values will be delimited with a colon.
506
+ def namespaced_key(key, options)
507
+ key = expanded_key(key)
508
+ namespace = options[:namespace] if options
509
+ prefix = namespace.is_a?(Proc) ? namespace.call : namespace
510
+ key = "#{prefix}:#{key}" if prefix
511
+ key
512
+ end
513
+
514
+ def instrument(operation, key, options = nil)
254
515
  log(operation, key, options)
255
516
 
256
517
  if self.class.instrument
257
518
  payload = { :key => key }
258
519
  payload.merge!(options) if options.is_a?(Hash)
259
- ActiveSupport::Notifications.instrument(:"cache_#{operation}", payload, &block)
520
+ ActiveSupport::Notifications.instrument("cache_#{operation}.active_support", payload){ yield(payload) }
260
521
  else
261
- yield
522
+ yield(nil)
262
523
  end
263
524
  end
264
525
 
265
- def log(operation, key, options)
266
- return unless logger && !silence?
267
- logger.debug("Cache #{operation}: #{key}#{options ? " (#{options.inspect})" : ""}")
526
+ def log(operation, key, options = nil)
527
+ return unless logger && logger.debug? && !silence?
528
+ logger.debug("Cache #{operation}: #{key}#{options.blank? ? "" : " (#{options.inspect})"}")
529
+ end
530
+ end
531
+
532
+ # Entry that is put into caches. It supports expiration time on entries and can compress values
533
+ # to save space in the cache.
534
+ class Entry
535
+ attr_reader :created_at, :expires_in
536
+
537
+ DEFAULT_COMPRESS_LIMIT = 16.kilobytes
538
+
539
+ class << self
540
+ # Create an entry with internal attributes set. This method is intended to be
541
+ # used by implementations that store cache entries in a native format instead
542
+ # of as serialized Ruby objects.
543
+ def create (raw_value, created_at, options = {})
544
+ entry = new(nil)
545
+ entry.instance_variable_set(:@value, raw_value)
546
+ entry.instance_variable_set(:@created_at, created_at.to_f)
547
+ entry.instance_variable_set(:@compressed, !!options[:compressed])
548
+ entry.instance_variable_set(:@expires_in, options[:expires_in])
549
+ entry
550
+ end
551
+ end
552
+
553
+ # Create a new cache entry for the specified value. Options supported are
554
+ # +:compress+, +:compress_threshold+, and +:expires_in+.
555
+ def initialize(value, options = {})
556
+ @compressed = false
557
+ @expires_in = options[:expires_in]
558
+ @expires_in = @expires_in.to_f if @expires_in
559
+ @created_at = Time.now.to_f
560
+ if value
561
+ if should_compress?(value, options)
562
+ @value = Zlib::Deflate.deflate(Marshal.dump(value))
563
+ @compressed = true
564
+ else
565
+ @value = value
566
+ end
567
+ else
568
+ @value = nil
569
+ end
570
+ end
571
+
572
+ # Get the raw value. This value may be serialized and compressed.
573
+ def raw_value
574
+ @value
575
+ end
576
+
577
+ # Get the value stored in the cache.
578
+ def value
579
+ if @value
580
+ val = compressed? ? Marshal.load(Zlib::Inflate.inflate(@value)) : @value
581
+ unless val.frozen?
582
+ val.freeze rescue nil
583
+ end
584
+ val
585
+ end
586
+ end
587
+
588
+ def compressed?
589
+ @compressed
590
+ end
591
+
592
+ # Check if the entry is expired. The +expires_in+ parameter can override the
593
+ # value set when the entry was created.
594
+ def expired?
595
+ if @expires_in && @created_at + @expires_in <= Time.now.to_f
596
+ true
597
+ else
598
+ false
599
+ end
600
+ end
601
+
602
+ # Set a new time to live on the entry so it expires at the given time.
603
+ def expires_at=(time)
604
+ if time
605
+ @expires_in = time.to_f - @created_at
606
+ else
607
+ @expires_in = nil
608
+ end
609
+ end
610
+
611
+ # Seconds since the epoch when the cache entry will expire.
612
+ def expires_at
613
+ @expires_in ? @created_at + @expires_in : nil
614
+ end
615
+
616
+ # Get the size of the cached value. This could be less than value.size
617
+ # if the data is compressed.
618
+ def size
619
+ if @value.nil?
620
+ 0
621
+ elsif @value.respond_to?(:bytesize)
622
+ @value.bytesize
623
+ else
624
+ Marshal.dump(@value).bytesize
625
+ end
626
+ end
627
+
628
+ private
629
+ def should_compress?(value, options)
630
+ if options[:compress] && value
631
+ unless value.is_a?(Numeric)
632
+ compress_threshold = options[:compress_threshold] || DEFAULT_COMPRESS_LIMIT
633
+ serialized_value = value.is_a?(String) ? value : Marshal.dump(value)
634
+ return true if serialized_value.size >= compress_threshold
635
+ end
636
+ end
637
+ false
268
638
  end
269
639
  end
270
640
  end