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
@@ -1,18 +1,4 @@
1
1
  class String
2
- unless '1.8.7 and up'.respond_to?(:start_with?)
3
- # Does the string start with the specified +prefix+?
4
- def start_with?(prefix)
5
- prefix = prefix.to_s
6
- self[0, prefix.length] == prefix
7
- end
8
-
9
- # Does the string end with the specified +suffix+?
10
- def end_with?(suffix)
11
- suffix = suffix.to_s
12
- self[-suffix.length, suffix.length] == suffix
13
- end
14
- end
15
-
16
2
  alias_method :starts_with?, :start_with?
17
3
  alias_method :ends_with?, :end_with?
18
4
  end
@@ -1,5 +1,5 @@
1
1
  begin
2
- # See http://bogomips.org/fast_xs/ by Eric Wong.
2
+ # See http://fast-xs.rubyforge.org/ by Eric Wong.
3
3
  # Also included with hpricot.
4
4
  require 'fast_xs'
5
5
  rescue LoadError
@@ -1,5 +1,7 @@
1
1
  require 'active_support/duration'
2
+ require 'active_support/core_ext/date/acts_like'
2
3
  require 'active_support/core_ext/date/calculations'
4
+ require 'active_support/core_ext/date_time/conversions'
3
5
 
4
6
  class Time
5
7
  COMMON_YEAR_DAYS_IN_MONTH = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
@@ -22,10 +24,11 @@ class Time
22
24
  # (i.e., if year is within either 1970..2038 or 1902..2038, depending on system architecture);
23
25
  # otherwise returns a DateTime
24
26
  def time_with_datetime_fallback(utc_or_local, year, month=1, day=1, hour=0, min=0, sec=0, usec=0)
25
- ::Time.send(utc_or_local, year, month, day, hour, min, sec, usec)
27
+ time = ::Time.send(utc_or_local, year, month, day, hour, min, sec, usec)
28
+ # This check is needed because Time.utc(y) returns a time object in the 2000s for 0 <= y <= 138.
29
+ time.year == year ? time : ::DateTime.civil_from_format(utc_or_local, year, month, day, hour, min, sec)
26
30
  rescue
27
- offset = utc_or_local.to_sym == :local ? ::DateTime.local_offset : 0
28
- ::DateTime.civil(year, month, day, hour, min, sec, offset)
31
+ ::DateTime.civil_from_format(utc_or_local, year, month, day, hour, min, sec)
29
32
  end
30
33
 
31
34
  # Wraps class method +time_with_datetime_fallback+ with +utc_or_local+ set to <tt>:utc</tt>.
@@ -37,6 +40,11 @@ class Time
37
40
  def local_time(*args)
38
41
  time_with_datetime_fallback(:local, *args)
39
42
  end
43
+
44
+ # Returns <tt>Time.zone.now</tt> when <tt>config.time_zone</tt> is set, otherwise just returns <tt>Time.now</tt>.
45
+ def current
46
+ ::Time.zone_default ? ::Time.zone.now : ::Time.now
47
+ end
40
48
  end
41
49
 
42
50
  # Tells whether the Time object's time lies in the past
@@ -130,7 +138,7 @@ class Time
130
138
  end
131
139
 
132
140
  # Short-hand for years_ago(1)
133
- def last_year
141
+ def prev_year
134
142
  years_ago(1)
135
143
  end
136
144
 
@@ -139,9 +147,8 @@ class Time
139
147
  years_since(1)
140
148
  end
141
149
 
142
-
143
150
  # Short-hand for months_ago(1)
144
- def last_month
151
+ def prev_month
145
152
  months_ago(1)
146
153
  end
147
154
 
@@ -258,7 +265,7 @@ class Time
258
265
  # are coerced into values that Time#- will recognize
259
266
  def minus_with_coercion(other)
260
267
  other = other.comparable_time if other.respond_to?(:comparable_time)
261
- minus_without_coercion(other)
268
+ other.is_a?(DateTime) ? to_f - other.to_f : minus_without_coercion(other)
262
269
  end
263
270
  alias_method :minus_without_coercion, :-
264
271
  alias_method :-, :minus_with_coercion
@@ -1,4 +1,5 @@
1
1
  require 'active_support/inflector'
2
+ require 'active_support/core_ext/time/publicize_conversion_methods'
2
3
  require 'active_support/values/time_zone'
3
4
 
4
5
  class Time
@@ -0,0 +1,56 @@
1
+ # Pre-1.9 versions of Ruby have a bug with marshaling Time instances, where utc instances are
2
+ # unmarshalled in the local zone, instead of utc. We're layering behavior on the _dump and _load
3
+ # methods so that utc instances can be flagged on dump, and coerced back to utc on load.
4
+ if !Marshal.load(Marshal.dump(Time.now.utc)).utc?
5
+ class Time
6
+ class << self
7
+ alias_method :_load_without_utc_flag, :_load
8
+ def _load(marshaled_time)
9
+ time = _load_without_utc_flag(marshaled_time)
10
+ time.instance_eval do
11
+ if defined?(@marshal_with_utc_coercion)
12
+ val = remove_instance_variable("@marshal_with_utc_coercion")
13
+ end
14
+ val ? utc : self
15
+ end
16
+ end
17
+ end
18
+
19
+ alias_method :_dump_without_utc_flag, :_dump
20
+ def _dump(*args)
21
+ obj = dup
22
+ obj.instance_variable_set('@marshal_with_utc_coercion', utc?)
23
+ obj._dump_without_utc_flag(*args)
24
+ end
25
+ end
26
+ end
27
+
28
+ # Ruby 1.9.2 adds utc_offset and zone to Time, but marshaling only
29
+ # preserves utc_offset. Preserve zone also, even though it may not
30
+ # work in some edge cases.
31
+ if Time.local(2010).zone != Marshal.load(Marshal.dump(Time.local(2010))).zone
32
+ class Time
33
+ class << self
34
+ alias_method :_load_without_zone, :_load
35
+ def _load(marshaled_time)
36
+ time = _load_without_zone(marshaled_time)
37
+ time.instance_eval do
38
+ if zone = defined?(@_zone) && remove_instance_variable('@_zone')
39
+ ary = to_a
40
+ ary[-1] = zone
41
+ utc? ? Time.utc(*ary) : Time.local(*ary)
42
+ else
43
+ self
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ alias_method :_dump_without_zone, :_dump
50
+ def _dump(*args)
51
+ obj = dup
52
+ obj.instance_variable_set('@_zone', zone)
53
+ obj._dump_without_zone(*args)
54
+ end
55
+ end
56
+ end
@@ -41,11 +41,6 @@ class Time
41
41
  ::Time.zone = old_zone
42
42
  end
43
43
 
44
- # Returns <tt>Time.zone.now</tt> when <tt>config.time_zone</tt> is set, otherwise just returns <tt>Time.now</tt>.
45
- def current
46
- ::Time.zone_default ? ::Time.zone.now : ::Time.now
47
- end
48
-
49
44
  private
50
45
  def get_zone(time_zone)
51
46
  return time_zone if time_zone.nil? || time_zone.is_a?(ActiveSupport::TimeZone)
@@ -73,6 +68,8 @@ class Time
73
68
  #
74
69
  # Time.utc(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
75
70
  def in_time_zone(zone = ::Time.zone)
71
+ return self unless zone
72
+
76
73
  ActiveSupport::TimeWithZone.new(utc? ? self : getutc, ::Time.__send__(:get_zone, zone))
77
74
  end
78
75
  end
@@ -1,14 +1,20 @@
1
+ # encoding: utf-8
2
+
1
3
  if RUBY_VERSION >= '1.9'
2
4
  require 'uri'
3
5
 
4
6
  str = "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E" # Ni-ho-nn-go in UTF-8, means Japanese.
5
- str.force_encoding(Encoding::UTF_8) if str.respond_to?(:force_encoding)
6
7
 
7
- unless str == URI.unescape(URI.escape(str))
8
+ parser = URI::Parser.new
9
+
10
+ unless str == parser.unescape(parser.escape(str))
8
11
  URI::Parser.class_eval do
9
12
  remove_method :unescape
10
- def unescape(str, escaped = @regexp[:ESCAPED])
11
- enc = (str.encoding == Encoding::US_ASCII) ? Encoding::UTF_8 : str.encoding
13
+ def unescape(str, escaped = /%[a-fA-F\d]{2}/)
14
+ # TODO: Are we actually sure that ASCII == UTF-8?
15
+ # YK: My initial experiments say yes, but let's be sure please
16
+ enc = str.encoding
17
+ enc = Encoding::UTF_8 if enc == Encoding::US_ASCII
12
18
  str.gsub(escaped) { [$&[1, 2].hex].pack('C') }.force_encoding(enc)
13
19
  end
14
20
  end
@@ -1,8 +1,10 @@
1
1
  require 'set'
2
2
  require 'thread'
3
+ require 'pathname'
3
4
  require 'active_support/core_ext/module/aliasing'
4
5
  require 'active_support/core_ext/module/attribute_accessors'
5
6
  require 'active_support/core_ext/module/introspection'
7
+ require 'active_support/core_ext/module/anonymous'
6
8
  require 'active_support/core_ext/object/blank'
7
9
  require 'active_support/core_ext/load_error'
8
10
  require 'active_support/core_ext/name_error'
@@ -31,20 +33,23 @@ module ActiveSupport #:nodoc:
31
33
 
32
34
  # The set of directories from which we may automatically load files. Files
33
35
  # under these directories will be reloaded on each request in development mode,
34
- # unless the directory also appears in load_once_paths.
35
- mattr_accessor :load_paths
36
- self.load_paths = []
36
+ # unless the directory also appears in autoload_once_paths.
37
+ mattr_accessor :autoload_paths
38
+ self.autoload_paths = []
37
39
 
38
40
  # The set of directories from which automatically loaded constants are loaded
39
- # only once. All directories in this set must also be present in +load_paths+.
40
- mattr_accessor :load_once_paths
41
- self.load_once_paths = []
41
+ # only once. All directories in this set must also be present in +autoload_paths+.
42
+ mattr_accessor :autoload_once_paths
43
+ self.autoload_once_paths = []
42
44
 
43
45
  # An array of qualified constant names that have been loaded. Adding a name to
44
46
  # this array will cause it to be unloaded the next time Dependencies are cleared.
45
47
  mattr_accessor :autoloaded_constants
46
48
  self.autoloaded_constants = []
47
49
 
50
+ mattr_accessor :references
51
+ self.references = {}
52
+
48
53
  # An array of constant names that need to be unloaded on every request. Used
49
54
  # to allow arbitrary constants to be marked for unloading.
50
55
  mattr_accessor :explicitly_unloadable_constants
@@ -58,85 +63,125 @@ module ActiveSupport #:nodoc:
58
63
  mattr_accessor :log_activity
59
64
  self.log_activity = false
60
65
 
66
+ class WatchStack < Array
67
+ def initialize
68
+ @mutex = Mutex.new
69
+ end
70
+
71
+ def self.locked(*methods)
72
+ methods.each { |m| class_eval "def #{m}(*) lock { super } end", __FILE__, __LINE__ }
73
+ end
74
+
75
+ locked :concat, :each, :delete_if, :<<
76
+
77
+ def new_constants_for(frames)
78
+ constants = []
79
+ frames.each do |mod_name, prior_constants|
80
+ mod = Inflector.constantize(mod_name) if Dependencies.qualified_const_defined?(mod_name)
81
+ next unless mod.is_a?(Module)
82
+
83
+ new_constants = mod.local_constant_names - prior_constants
84
+
85
+ # If we are checking for constants under, say, :Object, nested under something
86
+ # else that is checking for constants also under :Object, make sure the
87
+ # parent knows that we have found, and taken care of, the constant.
88
+ #
89
+ # In particular, this means that since Kernel.require discards the constants
90
+ # it finds, parents will be notified that about those constants, and not
91
+ # consider them "new". As a result, they will not be added to the
92
+ # autoloaded_constants list.
93
+ each do |key, value|
94
+ value.concat(new_constants) if key == mod_name
95
+ end
96
+
97
+ new_constants.each do |suffix|
98
+ constants << ([mod_name, suffix] - ["Object"]).join("::")
99
+ end
100
+ end
101
+ constants
102
+ end
103
+
104
+ # Add a set of modules to the watch stack, remembering the initial constants
105
+ def add_modules(modules)
106
+ list = modules.map do |desc|
107
+ name = Dependencies.to_constant_name(desc)
108
+ consts = Dependencies.qualified_const_defined?(name) ?
109
+ Inflector.constantize(name).local_constant_names : []
110
+ [name, consts]
111
+ end
112
+ concat(list)
113
+ list
114
+ end
115
+
116
+ def lock
117
+ @mutex.synchronize { yield self }
118
+ end
119
+ end
120
+
61
121
  # An internal stack used to record which constants are loaded by any block.
62
122
  mattr_accessor :constant_watch_stack
63
- self.constant_watch_stack = []
64
-
65
- mattr_accessor :constant_watch_stack_mutex
66
- self.constant_watch_stack_mutex = Mutex.new
123
+ self.constant_watch_stack = WatchStack.new
67
124
 
68
125
  # Module includes this module
69
126
  module ModuleConstMissing #:nodoc:
70
- def self.included(base) #:nodoc:
127
+ def self.append_features(base)
71
128
  base.class_eval do
72
- unless defined? const_missing_without_dependencies
73
- alias_method_chain :const_missing, :dependencies
74
- end
129
+ # Emulate #exclude via an ivar
130
+ return if defined?(@_const_missing) && @_const_missing
131
+ @_const_missing = instance_method(:const_missing)
132
+ remove_method(:const_missing)
75
133
  end
134
+ super
76
135
  end
77
136
 
78
- def self.excluded(base) #:nodoc:
137
+ def self.exclude_from(base)
79
138
  base.class_eval do
80
- if defined? const_missing_without_dependencies
81
- undef_method :const_missing
82
- alias_method :const_missing, :const_missing_without_dependencies
83
- undef_method :const_missing_without_dependencies
84
- end
139
+ define_method :const_missing, @_const_missing
140
+ @_const_missing = nil
85
141
  end
86
142
  end
87
143
 
88
144
  # Use const_missing to autoload associations so we don't have to
89
145
  # require_association when using single-table inheritance.
90
- def const_missing_with_dependencies(class_id)
91
- ActiveSupport::Dependencies.load_missing_constant self, class_id
92
- end
146
+ def const_missing(const_name, nesting = nil)
147
+ klass_name = name.presence || "Object"
148
+
149
+ if !nesting
150
+ # We'll assume that the nesting of Foo::Bar is ["Foo::Bar", "Foo"]
151
+ # even though it might not be, such as in the case of
152
+ # class Foo::Bar; Baz; end
153
+ nesting = []
154
+ klass_name.to_s.scan(/::|$/) { nesting.unshift $` }
155
+ end
93
156
 
94
- def unloadable(const_desc = self)
95
- super(const_desc)
96
- end
97
- end
157
+ # If there are multiple levels of nesting to search under, the top
158
+ # level is the one we want to report as the lookup fail.
159
+ error = nil
98
160
 
99
- # Class includes this module
100
- module ClassConstMissing #:nodoc:
101
- def const_missing(const_name)
102
- if [Object, Kernel].include?(self) || parent == self
103
- super
104
- else
161
+ nesting.each do |namespace|
105
162
  begin
106
- begin
107
- Dependencies.load_missing_constant self, const_name
108
- rescue NameError
109
- parent.send :const_missing, const_name
110
- end
163
+ return Dependencies.load_missing_constant Inflector.constantize(namespace), const_name
164
+ rescue NoMethodError then raise
111
165
  rescue NameError => e
112
- # Make sure that the name we are missing is the one that caused the error
113
- parent_qualified_name = Dependencies.qualified_name_for parent, const_name
114
- raise unless e.missing_name? parent_qualified_name
115
- qualified_name = Dependencies.qualified_name_for self, const_name
116
- raise NameError.new("uninitialized constant #{qualified_name}").copy_blame!(e)
166
+ error ||= e
117
167
  end
118
168
  end
169
+
170
+ # Raise the first error for this set. If this const_missing came from an
171
+ # earlier const_missing, this will result in the real error bubbling
172
+ # all the way up
173
+ raise error
174
+ end
175
+
176
+ def unloadable(const_desc = self)
177
+ super(const_desc)
119
178
  end
120
179
  end
121
180
 
122
181
  # Object includes this module
123
182
  module Loadable #:nodoc:
124
- def self.included(base) #:nodoc:
125
- base.class_eval do
126
- unless defined? load_without_new_constant_marking
127
- alias_method_chain :load, :new_constant_marking
128
- end
129
- end
130
- end
131
-
132
- def self.excluded(base) #:nodoc:
133
- base.class_eval do
134
- if defined? load_without_new_constant_marking
135
- undef_method :load
136
- alias_method :load, :load_without_new_constant_marking
137
- undef_method :load_without_new_constant_marking
138
- end
139
- end
183
+ def self.exclude_from(base)
184
+ base.class_eval { define_method(:load, Kernel.instance_method(:load)) }
140
185
  end
141
186
 
142
187
  def require_or_load(file_name)
@@ -144,6 +189,10 @@ module ActiveSupport #:nodoc:
144
189
  end
145
190
 
146
191
  def require_dependency(file_name, message = "No such file to load -- %s")
192
+ unless file_name.is_a?(String)
193
+ raise ArgumentError, "the file name must be a String -- you passed #{file_name.inspect}"
194
+ end
195
+
147
196
  Dependencies.depend_on(file_name, false, message)
148
197
  end
149
198
 
@@ -151,26 +200,23 @@ module ActiveSupport #:nodoc:
151
200
  Dependencies.associate_with(file_name)
152
201
  end
153
202
 
154
- def load_with_new_constant_marking(file, *extras) #:nodoc:
203
+ def load_dependency(file)
155
204
  if Dependencies.load?
156
- Dependencies.new_constants_in(Object) { load_without_new_constant_marking(file, *extras) }
205
+ Dependencies.new_constants_in(Object) { yield }.presence
157
206
  else
158
- load_without_new_constant_marking(file, *extras)
207
+ yield
159
208
  end
160
209
  rescue Exception => exception # errors from loading file
161
210
  exception.blame_file! file
162
211
  raise
163
212
  end
164
213
 
165
- def require(file, *extras) #:nodoc:
166
- if Dependencies.load?
167
- Dependencies.new_constants_in(Object) { super }
168
- else
169
- super
170
- end
171
- rescue Exception => exception # errors from required file
172
- exception.blame_file! file
173
- raise
214
+ def load(file, *)
215
+ load_dependency(file) { super }
216
+ end
217
+
218
+ def require(file, *)
219
+ load_dependency(file) { super }
174
220
  end
175
221
 
176
222
  # Mark the given constant as unloadable. Unloadable constants are removed each
@@ -213,16 +259,15 @@ module ActiveSupport #:nodoc:
213
259
  end
214
260
 
215
261
  def hook!
216
- Object.instance_eval { include Loadable }
217
- Module.instance_eval { include ModuleConstMissing }
218
- Class.instance_eval { include ClassConstMissing }
219
- Exception.instance_eval { include Blamable }
262
+ Object.class_eval { include Loadable }
263
+ Module.class_eval { include ModuleConstMissing }
264
+ Exception.class_eval { include Blamable }
220
265
  true
221
266
  end
222
267
 
223
268
  def unhook!
224
- ModuleConstMissing.excluded(Module)
225
- Loadable.excluded(Object)
269
+ ModuleConstMissing.exclude_from(Module)
270
+ Loadable.exclude_from(Object)
226
271
  true
227
272
  end
228
273
 
@@ -236,7 +281,7 @@ module ActiveSupport #:nodoc:
236
281
  rescue LoadError => load_error
237
282
  unless swallow_load_errors
238
283
  if file_name = load_error.message[/ -- (.*?)(\.rb)?$/, 1]
239
- raise MissingSourceFile.new(message % file_name, load_error.path).copy_blame!(load_error)
284
+ raise LoadError.new(message % file_name).copy_blame!(load_error)
240
285
  end
241
286
  raise
242
287
  end
@@ -292,60 +337,53 @@ module ActiveSupport #:nodoc:
292
337
 
293
338
  # Is the provided constant path defined?
294
339
  def qualified_const_defined?(path)
295
- raise NameError, "#{path.inspect} is not a valid constant name!" unless
296
- /^(::)?([A-Z]\w*)(::[A-Z]\w*)*$/ =~ path
340
+ names = path.sub(/^::/, '').to_s.split('::')
297
341
 
298
- names = path.to_s.split('::')
299
- names.shift if names.first.empty?
300
-
301
- # We can't use defined? because it will invoke const_missing for the parent
302
- # of the name we are checking.
303
342
  names.inject(Object) do |mod, name|
304
- return false unless uninherited_const_defined?(mod, name)
343
+ return false unless local_const_defined?(mod, name)
305
344
  mod.const_get name
306
345
  end
307
- return true
308
346
  end
309
347
 
310
348
  if Module.method(:const_defined?).arity == 1
311
349
  # Does this module define this constant?
312
- # Wrapper to accomodate changing Module#const_defined? in Ruby 1.9
313
- def uninherited_const_defined?(mod, const)
350
+ # Wrapper to accommodate changing Module#const_defined? in Ruby 1.9
351
+ def local_const_defined?(mod, const)
314
352
  mod.const_defined?(const)
315
353
  end
316
354
  else
317
- def uninherited_const_defined?(mod, const) #:nodoc:
355
+ def local_const_defined?(mod, const) #:nodoc:
318
356
  mod.const_defined?(const, false)
319
357
  end
320
358
  end
321
359
 
322
360
  # Given +path+, a filesystem path to a ruby file, return an array of constant
323
361
  # paths which would cause Dependencies to attempt to load this file.
324
- def loadable_constants_for_path(path, bases = load_paths)
362
+ def loadable_constants_for_path(path, bases = autoload_paths)
325
363
  path = $1 if path =~ /\A(.*)\.rb\Z/
326
364
  expanded_path = File.expand_path(path)
365
+ paths = []
327
366
 
328
- bases.collect do |root|
367
+ bases.each do |root|
329
368
  expanded_root = File.expand_path(root)
330
369
  next unless %r{\A#{Regexp.escape(expanded_root)}(/|\\)} =~ expanded_path
331
370
 
332
371
  nesting = expanded_path[(expanded_root.size)..-1]
333
372
  nesting = nesting[1..-1] if nesting && nesting[0] == ?/
334
373
  next if nesting.blank?
335
- nesting_camel = nesting.camelize
336
- begin
337
- qualified_const_defined?(nesting_camel)
338
- rescue NameError
339
- next
340
- end
341
- [ nesting_camel ]
342
- end.flatten.compact.uniq
374
+
375
+ paths << nesting.camelize
376
+ end
377
+
378
+ paths.uniq!
379
+ paths
343
380
  end
344
381
 
345
- # Search for a file in load_paths matching the provided suffix.
382
+ # Search for a file in autoload_paths matching the provided suffix.
346
383
  def search_for_file(path_suffix)
347
- path_suffix = "#{path_suffix}.rb" unless path_suffix =~ /\.rb\Z/
348
- load_paths.each do |root|
384
+ path_suffix = path_suffix.sub(/(\.rb)?$/, ".rb")
385
+
386
+ autoload_paths.each do |root|
349
387
  path = File.join(root, path_suffix)
350
388
  return path if File.file? path
351
389
  end
@@ -355,14 +393,14 @@ module ActiveSupport #:nodoc:
355
393
  # Does the provided path_suffix correspond to an autoloadable module?
356
394
  # Instead of returning a boolean, the autoload base for this module is returned.
357
395
  def autoloadable_module?(path_suffix)
358
- load_paths.each do |load_path|
396
+ autoload_paths.each do |load_path|
359
397
  return load_path if File.directory? File.join(load_path, path_suffix)
360
398
  end
361
399
  nil
362
400
  end
363
401
 
364
402
  def load_once_path?(path)
365
- load_once_paths.any? { |base| path.starts_with? base }
403
+ autoload_once_paths.any? { |base| path.starts_with? base }
366
404
  end
367
405
 
368
406
  # Attempt to autoload the provided module name by searching for a directory
@@ -374,7 +412,7 @@ module ActiveSupport #:nodoc:
374
412
  return nil unless base_path = autoloadable_module?(path_suffix)
375
413
  mod = Module.new
376
414
  into.const_set const_name, mod
377
- autoloaded_constants << qualified_name unless load_once_paths.include?(base_path)
415
+ autoloaded_constants << qualified_name unless autoload_once_paths.include?(base_path)
378
416
  return mod
379
417
  end
380
418
 
@@ -393,7 +431,7 @@ module ActiveSupport #:nodoc:
393
431
 
394
432
  result = nil
395
433
  newly_defined_paths = new_constants_in(*parent_paths) do
396
- result = load_without_new_constant_marking path
434
+ result = Kernel.load path
397
435
  end
398
436
 
399
437
  autoloaded_constants.concat newly_defined_paths unless load_once_path?(path)
@@ -405,7 +443,7 @@ module ActiveSupport #:nodoc:
405
443
  # Return the constant path for the provided parent and constant name.
406
444
  def qualified_name_for(mod, name)
407
445
  mod_name = to_constant_name mod
408
- (%w(Object Kernel).include? mod_name) ? name.to_s : "#{mod_name}::#{name}"
446
+ mod_name == "Object" ? name.to_s : "#{mod_name}::#{name}"
409
447
  end
410
448
 
411
449
  # Load the constant named +const_name+ which is missing from +from_mod+. If
@@ -413,38 +451,30 @@ module ActiveSupport #:nodoc:
413
451
  # using const_missing.
414
452
  def load_missing_constant(from_mod, const_name)
415
453
  log_call from_mod, const_name
416
- if from_mod == Kernel
417
- if ::Object.const_defined?(const_name)
418
- log "Returning Object::#{const_name} for Kernel::#{const_name}"
419
- return ::Object.const_get(const_name)
420
- else
421
- log "Substituting Object for Kernel"
422
- from_mod = Object
423
- end
424
- end
425
454
 
426
- # If we have an anonymous module, all we can do is attempt to load from Object.
427
- from_mod = Object if from_mod.name.blank?
428
-
429
- unless qualified_const_defined?(from_mod.name) && Inflector.constantize(from_mod.name).object_id == from_mod.object_id
455
+ unless qualified_const_defined?(from_mod.name) && Inflector.constantize(from_mod.name).equal?(from_mod)
430
456
  raise ArgumentError, "A copy of #{from_mod} has been removed from the module tree but is still active!"
431
457
  end
432
458
 
433
- raise ArgumentError, "#{from_mod} is not missing constant #{const_name}!" if uninherited_const_defined?(from_mod, const_name)
459
+ raise ArgumentError, "#{from_mod} is not missing constant #{const_name}!" if local_const_defined?(from_mod, const_name)
434
460
 
435
461
  qualified_name = qualified_name_for from_mod, const_name
436
462
  path_suffix = qualified_name.underscore
463
+
464
+ trace = caller.reject {|l| l =~ %r{#{Regexp.escape(__FILE__)}}}
437
465
  name_error = NameError.new("uninitialized constant #{qualified_name}")
466
+ name_error.set_backtrace(trace)
438
467
 
439
468
  file_path = search_for_file(path_suffix)
469
+
440
470
  if file_path && ! loaded.include?(File.expand_path(file_path)) # We found a matching file to load
441
471
  require_or_load file_path
442
- raise LoadError, "Expected #{file_path} to define #{qualified_name}" unless uninherited_const_defined?(from_mod, const_name)
472
+ raise LoadError, "Expected #{file_path} to define #{qualified_name}" unless local_const_defined?(from_mod, const_name)
443
473
  return from_mod.const_get(const_name)
444
474
  elsif mod = autoload_module!(from_mod, const_name, qualified_name, path_suffix)
445
475
  return mod
446
476
  elsif (parent = from_mod.parent) && parent != from_mod &&
447
- ! from_mod.parents.any? { |p| uninherited_const_defined?(p, const_name) }
477
+ ! from_mod.parents.any? { |p| local_const_defined?(p, const_name) }
448
478
  # If our parents do not have a constant named +const_name+ then we are free
449
479
  # to attempt to load upwards. If they do have such a constant, then this
450
480
  # const_missing must be due to from_mod::const_name, which should not
@@ -465,13 +495,41 @@ module ActiveSupport #:nodoc:
465
495
  def remove_unloadable_constants!
466
496
  autoloaded_constants.each { |const| remove_constant const }
467
497
  autoloaded_constants.clear
498
+ Reference.clear!
468
499
  explicitly_unloadable_constants.each { |const| remove_constant const }
469
500
  end
470
501
 
502
+ class Reference
503
+ @@constants = Hash.new { |h, k| h[k] = Inflector.constantize(k) }
504
+
505
+ attr_reader :name
506
+
507
+ def initialize(name)
508
+ @name = name.to_s
509
+ @@constants[@name] = name if name.respond_to?(:name)
510
+ end
511
+
512
+ def get
513
+ @@constants[@name]
514
+ end
515
+
516
+ def self.clear!
517
+ @@constants.clear
518
+ end
519
+ end
520
+
521
+ def ref(name)
522
+ references[name] ||= Reference.new(name)
523
+ end
524
+
525
+ def constantize(name)
526
+ ref(name).get
527
+ end
528
+
471
529
  # Determine if the given constant has been automatically loaded.
472
530
  def autoloaded?(desc)
473
531
  # No name => anonymous module.
474
- return false if desc.is_a?(Module) && desc.name.blank?
532
+ return false if desc.is_a?(Module) && desc.anonymous?
475
533
  name = to_constant_name desc
476
534
  return false unless qualified_const_defined? name
477
535
  return autoloaded_constants.include?(name)
@@ -505,79 +563,26 @@ module ActiveSupport #:nodoc:
505
563
  # and will be removed immediately.
506
564
  def new_constants_in(*descs)
507
565
  log_call(*descs)
508
-
509
- # Build the watch frames. Each frame is a tuple of
510
- # [module_name_as_string, constants_defined_elsewhere]
511
- watch_frames = descs.collect do |desc|
512
- if desc.is_a? Module
513
- mod_name = desc.name
514
- initial_constants = desc.local_constant_names
515
- elsif desc.is_a?(String) || desc.is_a?(Symbol)
516
- mod_name = desc.to_s
517
-
518
- # Handle the case where the module has yet to be defined.
519
- initial_constants = if qualified_const_defined?(mod_name)
520
- Inflector.constantize(mod_name).local_constant_names
521
- else
522
- []
523
- end
524
- else
525
- raise Argument, "#{desc.inspect} does not describe a module!"
526
- end
527
-
528
- [mod_name, initial_constants]
529
- end
530
-
531
- constant_watch_stack_mutex.synchronize do
532
- constant_watch_stack.concat watch_frames
533
- end
566
+ watch_frames = constant_watch_stack.add_modules(descs)
534
567
 
535
568
  aborting = true
536
569
  begin
537
570
  yield # Now yield to the code that is to define new constants.
538
571
  aborting = false
539
572
  ensure
540
- # Find the new constants.
541
- new_constants = watch_frames.collect do |mod_name, prior_constants|
542
- # Module still doesn't exist? Treat it as if it has no constants.
543
- next [] unless qualified_const_defined?(mod_name)
544
-
545
- mod = Inflector.constantize(mod_name)
546
- next [] unless mod.is_a? Module
547
- new_constants = mod.local_constant_names - prior_constants
548
-
549
- # Make sure no other frames takes credit for these constants.
550
- constant_watch_stack_mutex.synchronize do
551
- constant_watch_stack.each do |frame_name, constants|
552
- constants.concat new_constants if frame_name == mod_name
553
- end
554
- end
555
-
556
- new_constants.collect do |suffix|
557
- mod_name == "Object" ? suffix : "#{mod_name}::#{suffix}"
558
- end
559
- end.flatten
573
+ new_constants = constant_watch_stack.new_constants_for(watch_frames)
560
574
 
561
575
  log "New constants: #{new_constants * ', '}"
576
+ return new_constants unless aborting
562
577
 
563
- if aborting
564
- log "Error during loading, removing partially loaded constants "
565
- new_constants.each { |name| remove_constant name }
566
- new_constants.clear
567
- end
578
+ log "Error during loading, removing partially loaded constants "
579
+ new_constants.each {|c| remove_constant(c) }.clear
568
580
  end
569
581
 
570
- return new_constants
582
+ return []
571
583
  ensure
572
584
  # Remove the stack frames that we added.
573
- if defined?(watch_frames) && ! watch_frames.blank?
574
- frame_ids = watch_frames.collect { |frame| frame.object_id }
575
- constant_watch_stack_mutex.synchronize do
576
- constant_watch_stack.delete_if do |watch_frame|
577
- frame_ids.include? watch_frame.object_id
578
- end
579
- end
580
- end
585
+ watch_frames.each {|f| constant_watch_stack.delete(f) } if watch_frames.present?
581
586
  end
582
587
 
583
588
  class LoadingModule #:nodoc:
@@ -594,12 +599,12 @@ module ActiveSupport #:nodoc:
594
599
  # Convert the provided const desc to a qualified constant name (as a string).
595
600
  # A module, class, symbol, or string may be provided.
596
601
  def to_constant_name(desc) #:nodoc:
597
- name = case desc
598
- when String then desc.starts_with?('::') ? desc[2..-1] : desc
602
+ case desc
603
+ when String then desc.sub(/^::/, '')
599
604
  when Symbol then desc.to_s
600
605
  when Module
601
- raise ArgumentError, "Anonymous modules have no name to be referenced by" if desc.name.blank?
602
- desc.name
606
+ desc.name.presence ||
607
+ raise(ArgumentError, "Anonymous modules have no name to be referenced by")
603
608
  else raise TypeError, "Not a valid constant descriptor: #{desc.inspect}"
604
609
  end
605
610
  end
@@ -607,16 +612,14 @@ module ActiveSupport #:nodoc:
607
612
  def remove_constant(const) #:nodoc:
608
613
  return false unless qualified_const_defined? const
609
614
 
610
- const = $1 if /\A::(.*)\Z/ =~ const.to_s
611
- names = const.to_s.split('::')
612
- if names.size == 1 # It's under Object
613
- parent = Object
614
- else
615
- parent = Inflector.constantize(names[0..-2] * '::')
616
- end
615
+ # Normalize ::Foo, Foo, Object::Foo, and ::Object::Foo to Object::Foo
616
+ names = const.to_s.sub(/^::(Object)?/, 'Object::').split("::")
617
+ to_remove = names.pop
618
+ parent = Inflector.constantize(names * '::')
617
619
 
618
620
  log "removing constant #{const}"
619
- parent.instance_eval { remove_const names.last }
621
+ parent.instance_eval { remove_const to_remove }
622
+
620
623
  return true
621
624
  end
622
625