activesupport 2.1.0 → 2.1.1
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.
- data/CHANGELOG +13 -1
- data/lib/active_support.rb +6 -0
- data/lib/active_support/cache.rb +3 -1
- data/lib/active_support/cache/compressed_mem_cache_store.rb +4 -4
- data/lib/active_support/core_ext/date/behavior.rb +26 -0
- data/lib/active_support/core_ext/date/calculations.rb +1 -1
- data/lib/active_support/core_ext/hash/except.rb +4 -3
- data/lib/active_support/core_ext/hash/slice.rb +3 -1
- data/lib/active_support/core_ext/module.rb +5 -0
- data/lib/active_support/core_ext/module/model_naming.rb +22 -0
- data/lib/active_support/core_ext/object/extending.rb +9 -8
- data/lib/active_support/core_ext/range/blockless_step.rb +2 -2
- data/lib/active_support/core_ext/rexml.rb +35 -0
- data/lib/active_support/core_ext/string/unicode.rb +11 -13
- data/lib/active_support/core_ext/time.rb +22 -1
- data/lib/active_support/dependencies.rb +393 -392
- data/lib/active_support/deprecation.rb +27 -9
- data/lib/active_support/inflections.rb +51 -49
- data/lib/active_support/inflector.rb +267 -262
- data/lib/active_support/json/encoders/date_time.rb +1 -1
- data/lib/active_support/ordered_options.rb +14 -12
- data/lib/active_support/string_inquirer.rb +11 -0
- data/lib/active_support/time_with_zone.rb +34 -13
- data/lib/active_support/values/time_zone.rb +348 -346
- data/lib/active_support/vendor.rb +2 -2
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/data_timezone.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/data_timezone_info.rb +2 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Africa/Algiers.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Africa/Cairo.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Africa/Casablanca.rb +2 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Africa/Harare.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Africa/Johannesburg.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Africa/Monrovia.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Africa/Nairobi.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/America/Argentina/Buenos_Aires.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/America/Argentina/San_Juan.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/America/Bogota.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/America/Caracas.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/America/Chicago.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/America/Chihuahua.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/America/Denver.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/America/Godthab.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/America/Guatemala.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/America/Halifax.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/America/Indiana/Indianapolis.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/America/Juneau.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/America/La_Paz.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/America/Lima.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/America/Los_Angeles.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/America/Mazatlan.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/America/Mexico_City.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/America/Monterrey.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/America/New_York.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/America/Phoenix.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/America/Regina.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/America/Santiago.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/America/St_Johns.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/America/Tijuana.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Almaty.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Baghdad.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Baku.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Bangkok.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Chongqing.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Dhaka.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Hong_Kong.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Irkutsk.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Jakarta.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Jerusalem.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Kabul.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Kamchatka.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Karachi.rb +2 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Katmandu.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Kolkata.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Krasnoyarsk.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Kuala_Lumpur.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Kuwait.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Magadan.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Muscat.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Novosibirsk.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Rangoon.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Riyadh.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Seoul.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Shanghai.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Singapore.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Taipei.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Tashkent.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Tbilisi.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Tehran.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Tokyo.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Ulaanbaatar.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Urumqi.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Vladivostok.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Yakutsk.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Yekaterinburg.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Asia/Yerevan.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Atlantic/Azores.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Atlantic/Cape_Verde.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Atlantic/South_Georgia.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Australia/Adelaide.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Australia/Brisbane.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Australia/Darwin.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Australia/Hobart.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Australia/Melbourne.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Australia/Perth.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Australia/Sydney.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Etc/UTC.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Amsterdam.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Athens.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Belgrade.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Berlin.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Bratislava.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Brussels.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Bucharest.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Budapest.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Copenhagen.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Dublin.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Helsinki.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Istanbul.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Kiev.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Lisbon.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Ljubljana.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/London.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Madrid.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Minsk.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Moscow.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Paris.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Prague.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Riga.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Rome.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Sarajevo.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Skopje.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Sofia.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Stockholm.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Tallinn.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Vienna.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Vilnius.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Warsaw.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Europe/Zagreb.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Pacific/Auckland.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Pacific/Fiji.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Pacific/Guam.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Pacific/Honolulu.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Pacific/Majuro.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Pacific/Midway.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Pacific/Noumea.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Pacific/Pago_Pago.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Pacific/Port_Moresby.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/definitions/Pacific/Tongatapu.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/info_timezone.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/linked_timezone.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/linked_timezone_info.rb +0 -0
- data/lib/active_support/vendor/tzinfo-0.3.9/tzinfo/offset_rationals.rb +95 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/time_or_datetime.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/timezone.rb +6 -6
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/timezone_definition.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/timezone_info.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/timezone_offset_info.rb +4 -4
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/timezone_period.rb +0 -0
- data/lib/active_support/vendor/{tzinfo-0.3.8 → tzinfo-0.3.9}/tzinfo/timezone_transition_info.rb +2 -2
- data/lib/active_support/version.rb +1 -1
- metadata +154 -151
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/offset_rationals.rb +0 -95
data/CHANGELOG
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
*2.1.1 (September 4th, 2008)*
|
2
|
+
|
3
|
+
* Fix Ruby's Time marshaling bug in pre-1.9 versions of Ruby: utc instances are now correctly unmarshaled with a utc zone instead of the system local zone [#900 state:resolved]:activesupport/CHANGELOG
|
4
|
+
|
5
|
+
* TimeWithZone: when crossing DST boundary, treat Durations of days, months or years as variable-length, and all other values as absolute length. A time + 24.hours will advance exactly 24 hours, but a time + 1.day will advance 23-25 hours, depending on the day. Ensure consistent behavior across all advancing methods [Geoff Buesing]
|
6
|
+
|
7
|
+
* Fix TimeWithZone unmarshaling: coerce unmarshaled Time instances to utc, because Ruby's marshaling of Time instances doesn't respect the zone [Geoff Buesing]
|
8
|
+
|
9
|
+
* Added StringQuestioneer for doing things like StringQuestioneer.new("production").production? # => true and StringQuestioneer.new("production").development? # => false [DHH]
|
10
|
+
|
11
|
+
* Fixed Date#end_of_quarter to not blow up on May 31st [#289 state:resolved] (Danger)
|
12
|
+
|
13
|
+
|
1
14
|
*2.1.0 (May 31st, 2008)*
|
2
15
|
|
3
16
|
* TimeZone#to_s shows offset as GMT instead of UTC, because GMT will be more familiar to end users (see time zone selects used by Windows OS, google.com and yahoo.com.) Reverts [8370] [Geoff Buesing]
|
@@ -166,7 +179,6 @@
|
|
166
179
|
|
167
180
|
* Introduce ActiveSupport::TimeWithZone, for wrapping Time instances with a TimeZone. Introduce instance methods to Time for creating TimeWithZone instances, and class methods for managing a global time zone. [Geoff Buesing]
|
168
181
|
|
169
|
-
>>>>>>> .r8815
|
170
182
|
* Replace non-dst-aware TimeZone class with dst-aware class from tzinfo_timezone plugin. TimeZone#adjust and #unadjust are no longer available; tzinfo gem must now be present in order to perform time zone calculations, via #local_to_utc and #utc_to_local methods. [Geoff Buesing]
|
171
183
|
|
172
184
|
* Extract ActiveSupport::Callbacks from Active Record, test case setup and teardown, and ActionController::Dispatcher. #10727 [Josh Peek]
|
data/lib/active_support.rb
CHANGED
@@ -43,6 +43,8 @@ require 'active_support/ordered_hash'
|
|
43
43
|
require 'active_support/ordered_options'
|
44
44
|
require 'active_support/option_merger'
|
45
45
|
|
46
|
+
require 'active_support/string_inquirer'
|
47
|
+
|
46
48
|
require 'active_support/values/time_zone'
|
47
49
|
require 'active_support/duration'
|
48
50
|
|
@@ -53,3 +55,7 @@ require 'active_support/multibyte'
|
|
53
55
|
require 'active_support/base64'
|
54
56
|
|
55
57
|
require 'active_support/time_with_zone'
|
58
|
+
|
59
|
+
Inflector = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('Inflector', 'ActiveSupport::Inflector')
|
60
|
+
Dependencies = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('Dependencies', 'ActiveSupport::Dependencies')
|
61
|
+
TimeZone = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('TimeZone', 'ActiveSupport::TimeZone')
|
data/lib/active_support/cache.rb
CHANGED
@@ -19,7 +19,7 @@ module ActiveSupport
|
|
19
19
|
|
20
20
|
def self.expand_cache_key(key, namespace = nil)
|
21
21
|
expanded_cache_key = namespace ? "#{namespace}/" : ""
|
22
|
-
|
22
|
+
|
23
23
|
if ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"]
|
24
24
|
expanded_cache_key << "#{ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"]}/"
|
25
25
|
end
|
@@ -31,6 +31,8 @@ module ActiveSupport
|
|
31
31
|
key.collect { |element| expand_cache_key(element) }.to_param
|
32
32
|
when key.respond_to?(:to_param)
|
33
33
|
key.to_param
|
34
|
+
else
|
35
|
+
key.to_s
|
34
36
|
end
|
35
37
|
|
36
38
|
expanded_cache_key
|
@@ -1,14 +1,14 @@
|
|
1
1
|
module ActiveSupport
|
2
2
|
module Cache
|
3
3
|
class CompressedMemCacheStore < MemCacheStore
|
4
|
-
def read(name, options =
|
5
|
-
if value = super(name, options.merge(:raw => true))
|
4
|
+
def read(name, options = nil)
|
5
|
+
if value = super(name, (options || {}).merge(:raw => true))
|
6
6
|
Marshal.load(ActiveSupport::Gzip.decompress(value))
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
|
-
def write(name, value, options =
|
11
|
-
super(name, ActiveSupport::Gzip.compress(Marshal.dump(value)), options.merge(:raw => true))
|
10
|
+
def write(name, value, options = nil)
|
11
|
+
super(name, ActiveSupport::Gzip.compress(Marshal.dump(value)), (options || {}).merge(:raw => true))
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
@@ -7,6 +7,32 @@ module ActiveSupport #:nodoc:
|
|
7
7
|
def acts_like_date?
|
8
8
|
true
|
9
9
|
end
|
10
|
+
|
11
|
+
# Date memoizes some instance methods using metaprogramming to wrap
|
12
|
+
# the methods with one that caches the result in an instance variable.
|
13
|
+
# If a Date is frozen but the memoized method hasn't been called, the
|
14
|
+
# first call will result in a frozen object error since the memo
|
15
|
+
# instance variable is uninitialized.
|
16
|
+
#
|
17
|
+
# Work around by eagerly memoizing before freezing.
|
18
|
+
#
|
19
|
+
# Ruby 1.9 uses a preinitialized instance variable so it's unaffected.
|
20
|
+
# This hack is as close as we can get to feature detection:
|
21
|
+
begin
|
22
|
+
::Date.today.freeze.jd
|
23
|
+
rescue => frozen_object_error
|
24
|
+
if frozen_object_error.message =~ /frozen/
|
25
|
+
def freeze #:nodoc:
|
26
|
+
self.class.private_instance_methods(false).each do |m|
|
27
|
+
if m.to_s =~ /\A__\d+__\Z/
|
28
|
+
instance_variable_set(:"@#{m}", [send(m)])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
super
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
10
36
|
end
|
11
37
|
end
|
12
38
|
end
|
@@ -184,7 +184,7 @@ module ActiveSupport #:nodoc:
|
|
184
184
|
|
185
185
|
# Returns a new Date/DateTime representing the end of the quarter (last day of march, june, september, december; DateTime objects will have time set to 23:59:59)
|
186
186
|
def end_of_quarter
|
187
|
-
change(:month => [3, 6, 9, 12].detect { |m| m >= self.month }).end_of_month
|
187
|
+
beginning_of_month.change(:month => [3, 6, 9, 12].detect { |m| m >= self.month }).end_of_month
|
188
188
|
end
|
189
189
|
alias :at_end_of_quarter :end_of_quarter
|
190
190
|
|
@@ -10,13 +10,14 @@ module ActiveSupport #:nodoc:
|
|
10
10
|
module Except
|
11
11
|
# Returns a new hash without the given keys.
|
12
12
|
def except(*keys)
|
13
|
-
|
14
|
-
reject { |key,| rejected.include?(key) }
|
13
|
+
clone.except!(*keys)
|
15
14
|
end
|
16
15
|
|
17
16
|
# Replaces the hash without only the given keys.
|
18
17
|
def except!(*keys)
|
19
|
-
|
18
|
+
keys.map! { |key| convert_key(key) } if respond_to?(:convert_key)
|
19
|
+
keys.each { |key| delete(key) }
|
20
|
+
self
|
20
21
|
end
|
21
22
|
end
|
22
23
|
end
|
@@ -15,7 +15,9 @@ module ActiveSupport #:nodoc:
|
|
15
15
|
# Returns a new hash with only the given keys.
|
16
16
|
def slice(*keys)
|
17
17
|
allowed = Set.new(respond_to?(:convert_key) ? keys.map { |key| convert_key(key) } : keys)
|
18
|
-
|
18
|
+
hash = {}
|
19
|
+
allowed.each { |k| hash[k] = self[k] if has_key?(k) }
|
20
|
+
hash
|
19
21
|
end
|
20
22
|
|
21
23
|
# Replaces the hash with only the given keys.
|
@@ -6,3 +6,8 @@ require 'active_support/core_ext/module/delegation'
|
|
6
6
|
require 'active_support/core_ext/module/introspection'
|
7
7
|
require 'active_support/core_ext/module/loading'
|
8
8
|
require 'active_support/core_ext/module/aliasing'
|
9
|
+
require 'active_support/core_ext/module/model_naming'
|
10
|
+
|
11
|
+
class Module
|
12
|
+
include ActiveSupport::CoreExt::Module::ModelNaming
|
13
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module ActiveSupport
|
2
|
+
class ModelName < String
|
3
|
+
attr_reader :singular, :plural, :partial_path
|
4
|
+
|
5
|
+
def initialize(name)
|
6
|
+
super
|
7
|
+
@singular = underscore.tr('/', '_').freeze
|
8
|
+
@plural = @singular.pluralize.freeze
|
9
|
+
@partial_path = "#{tableize}/#{demodulize.underscore}".freeze
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module CoreExt
|
14
|
+
module Module
|
15
|
+
module ModelNaming
|
16
|
+
def model_name
|
17
|
+
@model_name ||= ModelName.new(name)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -3,17 +3,18 @@ class Object
|
|
3
3
|
Class.remove_class(*subclasses_of(*superclasses))
|
4
4
|
end
|
5
5
|
|
6
|
+
# Exclude this class unless it's a subclass of our supers and is defined.
|
7
|
+
# We check defined? in case we find a removed class that has yet to be
|
8
|
+
# garbage collected. This also fails for anonymous classes -- please
|
9
|
+
# submit a patch if you have a workaround.
|
6
10
|
def subclasses_of(*superclasses) #:nodoc:
|
7
11
|
subclasses = []
|
8
12
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
if superclasses.any? { |superclass| k < superclass } &&
|
15
|
-
(k.name.blank? || eval("defined?(::#{k}) && ::#{k}.object_id == k.object_id"))
|
16
|
-
subclasses << k
|
13
|
+
superclasses.each do |sup|
|
14
|
+
ObjectSpace.each_object(class << sup; self; end) do |k|
|
15
|
+
if k != sup && (k.name.blank? || eval("defined?(::#{k}) && ::#{k}.object_id == k.object_id"))
|
16
|
+
subclasses << k
|
17
|
+
end
|
17
18
|
end
|
18
19
|
end
|
19
20
|
|
@@ -8,7 +8,7 @@ module ActiveSupport #:nodoc:
|
|
8
8
|
end
|
9
9
|
|
10
10
|
if RUBY_VERSION < '1.9'
|
11
|
-
def step_with_blockless(value, &block)
|
11
|
+
def step_with_blockless(value = 1, &block)
|
12
12
|
if block_given?
|
13
13
|
step_without_blockless(value, &block)
|
14
14
|
else
|
@@ -18,7 +18,7 @@ module ActiveSupport #:nodoc:
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
else
|
21
|
-
def step_with_blockless(value, &block)
|
21
|
+
def step_with_blockless(value = 1, &block)
|
22
22
|
if block_given?
|
23
23
|
step_without_blockless(value, &block)
|
24
24
|
else
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
require 'rexml/entity'
|
3
|
+
|
4
|
+
# Fixes the rexml vulnerability disclosed at:
|
5
|
+
# http://www.ruby-lang.org/en/news/2008/08/23/dos-vulnerability-in-rexml/
|
6
|
+
# This fix is identical to rexml-expansion-fix version 1.0.1
|
7
|
+
|
8
|
+
unless REXML::VERSION > "3.1.7.2"
|
9
|
+
module REXML
|
10
|
+
class Entity < Child
|
11
|
+
undef_method :unnormalized
|
12
|
+
def unnormalized
|
13
|
+
document.record_entity_expansion! if document
|
14
|
+
v = value()
|
15
|
+
return nil if v.nil?
|
16
|
+
@unnormalized = Text::unnormalize(v, parent)
|
17
|
+
@unnormalized
|
18
|
+
end
|
19
|
+
end
|
20
|
+
class Document < Element
|
21
|
+
@@entity_expansion_limit = 10_000
|
22
|
+
def self.entity_expansion_limit= val
|
23
|
+
@@entity_expansion_limit = val
|
24
|
+
end
|
25
|
+
|
26
|
+
def record_entity_expansion!
|
27
|
+
@number_of_expansions ||= 0
|
28
|
+
@number_of_expansions += 1
|
29
|
+
if @number_of_expansions > @@entity_expansion_limit
|
30
|
+
raise "Number of entity expansions exceeded, processing aborted."
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -1,16 +1,16 @@
|
|
1
1
|
module ActiveSupport #:nodoc:
|
2
2
|
module CoreExtensions #:nodoc:
|
3
3
|
module String #:nodoc:
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
base.class_eval { remove_method :chars }
|
10
|
-
end
|
11
|
-
super
|
4
|
+
# Define methods for handling unicode data.
|
5
|
+
module Unicode
|
6
|
+
def self.append_features(base)
|
7
|
+
if '1.8.7 and later'.respond_to?(:chars)
|
8
|
+
base.class_eval { remove_method :chars }
|
12
9
|
end
|
10
|
+
super
|
11
|
+
end
|
13
12
|
|
13
|
+
unless '1.9'.respond_to?(:force_encoding)
|
14
14
|
# +chars+ is a Unicode safe proxy for string methods. It creates and returns an instance of the
|
15
15
|
# ActiveSupport::Multibyte::Chars class which encapsulates the original string. A Unicode safe version of all
|
16
16
|
# the String methods are defined on this proxy class. Undefined methods are forwarded to String, so all of the
|
@@ -44,14 +44,12 @@ module ActiveSupport #:nodoc:
|
|
44
44
|
def is_utf8?
|
45
45
|
ActiveSupport::Multibyte::Handlers::UTF8Handler.consumes?(self)
|
46
46
|
end
|
47
|
-
|
48
|
-
|
49
|
-
module Unicode #:nodoc:
|
50
|
-
def chars
|
47
|
+
else
|
48
|
+
def chars #:nodoc:
|
51
49
|
self
|
52
50
|
end
|
53
51
|
|
54
|
-
def is_utf8?
|
52
|
+
def is_utf8? #:nodoc:
|
55
53
|
case encoding
|
56
54
|
when Encoding::UTF_8
|
57
55
|
valid_encoding?
|
@@ -1,11 +1,32 @@
|
|
1
1
|
require 'date'
|
2
2
|
require 'time'
|
3
3
|
|
4
|
-
# Ruby 1.8-cvs and 1.9 define private Time#to_date
|
5
4
|
class Time
|
5
|
+
# Ruby 1.8-cvs and 1.9 define private Time#to_date
|
6
6
|
%w(to_date to_datetime).each do |method|
|
7
7
|
public method if private_instance_methods.include?(method)
|
8
8
|
end
|
9
|
+
|
10
|
+
# Pre-1.9 versions of Ruby have a bug with marshaling Time instances, where utc instances are
|
11
|
+
# unmarshaled in the local zone, instead of utc. We're layering behavior on the _dump and _load
|
12
|
+
# methods so that utc instances can be flagged on dump, and coerced back to utc on load.
|
13
|
+
if RUBY_VERSION < '1.9'
|
14
|
+
class << self
|
15
|
+
alias_method :_original_load, :_load
|
16
|
+
def _load(marshaled_time)
|
17
|
+
time = _original_load(marshaled_time)
|
18
|
+
utc = time.instance_variable_get('@marshal_with_utc_coercion')
|
19
|
+
utc ? time.utc : time
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
alias_method :_original_dump, :_dump
|
24
|
+
def _dump(*args)
|
25
|
+
obj = self.frozen? ? self.dup : self
|
26
|
+
obj.instance_variable_set('@marshal_with_utc_coercion', utc?)
|
27
|
+
obj._original_dump(*args)
|
28
|
+
end
|
29
|
+
end
|
9
30
|
end
|
10
31
|
|
11
32
|
require 'active_support/core_ext/time/behavior'
|
@@ -3,458 +3,459 @@ require 'active_support/core_ext/module/attribute_accessors'
|
|
3
3
|
require 'active_support/core_ext/load_error'
|
4
4
|
require 'active_support/core_ext/kernel'
|
5
5
|
|
6
|
-
module
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
def depend_on(file_name, swallow_load_errors = false)
|
59
|
-
path = search_for_file(file_name)
|
60
|
-
require_or_load(path || file_name)
|
61
|
-
rescue LoadError
|
62
|
-
raise unless swallow_load_errors
|
63
|
-
end
|
64
|
-
|
65
|
-
def associate_with(file_name)
|
66
|
-
depend_on(file_name, true)
|
67
|
-
end
|
6
|
+
module ActiveSupport #:nodoc:
|
7
|
+
module Dependencies #:nodoc:
|
8
|
+
extend self
|
9
|
+
|
10
|
+
# Should we turn on Ruby warnings on the first load of dependent files?
|
11
|
+
mattr_accessor :warnings_on_first_load
|
12
|
+
self.warnings_on_first_load = false
|
13
|
+
|
14
|
+
# All files ever loaded.
|
15
|
+
mattr_accessor :history
|
16
|
+
self.history = Set.new
|
17
|
+
|
18
|
+
# All files currently loaded.
|
19
|
+
mattr_accessor :loaded
|
20
|
+
self.loaded = Set.new
|
21
|
+
|
22
|
+
# Should we load files or require them?
|
23
|
+
mattr_accessor :mechanism
|
24
|
+
self.mechanism = :load
|
25
|
+
|
26
|
+
# The set of directories from which we may automatically load files. Files
|
27
|
+
# under these directories will be reloaded on each request in development mode,
|
28
|
+
# unless the directory also appears in load_once_paths.
|
29
|
+
mattr_accessor :load_paths
|
30
|
+
self.load_paths = []
|
31
|
+
|
32
|
+
# The set of directories from which automatically loaded constants are loaded
|
33
|
+
# only once. All directories in this set must also be present in +load_paths+.
|
34
|
+
mattr_accessor :load_once_paths
|
35
|
+
self.load_once_paths = []
|
36
|
+
|
37
|
+
# An array of qualified constant names that have been loaded. Adding a name to
|
38
|
+
# this array will cause it to be unloaded the next time Dependencies are cleared.
|
39
|
+
mattr_accessor :autoloaded_constants
|
40
|
+
self.autoloaded_constants = []
|
41
|
+
|
42
|
+
# An array of constant names that need to be unloaded on every request. Used
|
43
|
+
# to allow arbitrary constants to be marked for unloading.
|
44
|
+
mattr_accessor :explicitly_unloadable_constants
|
45
|
+
self.explicitly_unloadable_constants = []
|
46
|
+
|
47
|
+
# Set to true to enable logging of const_missing and file loads
|
48
|
+
mattr_accessor :log_activity
|
49
|
+
self.log_activity = false
|
50
|
+
|
51
|
+
# An internal stack used to record which constants are loaded by any block.
|
52
|
+
mattr_accessor :constant_watch_stack
|
53
|
+
self.constant_watch_stack = []
|
54
|
+
|
55
|
+
def load?
|
56
|
+
mechanism == :load
|
57
|
+
end
|
68
58
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
59
|
+
def depend_on(file_name, swallow_load_errors = false)
|
60
|
+
path = search_for_file(file_name)
|
61
|
+
require_or_load(path || file_name)
|
62
|
+
rescue LoadError
|
63
|
+
raise unless swallow_load_errors
|
64
|
+
end
|
74
65
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
expanded = File.expand_path(file_name)
|
79
|
-
return if loaded.include?(expanded)
|
66
|
+
def associate_with(file_name)
|
67
|
+
depend_on(file_name, true)
|
68
|
+
end
|
80
69
|
|
81
|
-
|
82
|
-
|
83
|
-
|
70
|
+
def clear
|
71
|
+
log_call
|
72
|
+
loaded.clear
|
73
|
+
remove_unloadable_constants!
|
74
|
+
end
|
84
75
|
|
85
|
-
|
86
|
-
|
87
|
-
|
76
|
+
def require_or_load(file_name, const_path = nil)
|
77
|
+
log_call file_name, const_path
|
78
|
+
file_name = $1 if file_name =~ /^(.*)\.rb$/
|
79
|
+
expanded = File.expand_path(file_name)
|
80
|
+
return if loaded.include?(expanded)
|
88
81
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
load_args << const_path unless const_path.nil?
|
82
|
+
# Record that we've seen this file *before* loading it to avoid an
|
83
|
+
# infinite loop with mutual dependencies.
|
84
|
+
loaded << expanded
|
93
85
|
|
94
|
-
|
95
|
-
|
86
|
+
begin
|
87
|
+
if load?
|
88
|
+
log "loading #{file_name}"
|
89
|
+
|
90
|
+
# Enable warnings iff this file has not been loaded before and
|
91
|
+
# warnings_on_first_load is set.
|
92
|
+
load_args = ["#{file_name}.rb"]
|
93
|
+
load_args << const_path unless const_path.nil?
|
94
|
+
|
95
|
+
if !warnings_on_first_load or history.include?(expanded)
|
96
|
+
result = load_file(*load_args)
|
97
|
+
else
|
98
|
+
enable_warnings { result = load_file(*load_args) }
|
99
|
+
end
|
96
100
|
else
|
97
|
-
|
101
|
+
log "requiring #{file_name}"
|
102
|
+
result = require file_name
|
98
103
|
end
|
99
|
-
|
100
|
-
|
101
|
-
|
104
|
+
rescue Exception
|
105
|
+
loaded.delete expanded
|
106
|
+
raise
|
102
107
|
end
|
103
|
-
rescue Exception
|
104
|
-
loaded.delete expanded
|
105
|
-
raise
|
106
|
-
end
|
107
108
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
109
|
+
# Record history *after* loading so first load gets warnings.
|
110
|
+
history << expanded
|
111
|
+
return result
|
112
|
+
end
|
112
113
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
114
|
+
# Is the provided constant path defined?
|
115
|
+
def qualified_const_defined?(path)
|
116
|
+
raise NameError, "#{path.inspect} is not a valid constant name!" unless
|
117
|
+
/^(::)?([A-Z]\w*)(::[A-Z]\w*)*$/ =~ path
|
117
118
|
|
118
|
-
|
119
|
-
|
119
|
+
names = path.to_s.split('::')
|
120
|
+
names.shift if names.first.empty?
|
120
121
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
122
|
+
# We can't use defined? because it will invoke const_missing for the parent
|
123
|
+
# of the name we are checking.
|
124
|
+
names.inject(Object) do |mod, name|
|
125
|
+
return false unless uninherited_const_defined?(mod, name)
|
126
|
+
mod.const_get name
|
127
|
+
end
|
128
|
+
return true
|
126
129
|
end
|
127
|
-
return true
|
128
|
-
end
|
129
130
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
131
|
+
if Module.method(:const_defined?).arity == 1
|
132
|
+
# Does this module define this constant?
|
133
|
+
# Wrapper to accomodate changing Module#const_defined? in Ruby 1.9
|
134
|
+
def uninherited_const_defined?(mod, const)
|
135
|
+
mod.const_defined?(const)
|
136
|
+
end
|
137
|
+
else
|
138
|
+
def uninherited_const_defined?(mod, const) #:nodoc:
|
139
|
+
mod.const_defined?(const, false)
|
140
|
+
end
|
139
141
|
end
|
140
|
-
end
|
141
|
-
|
142
|
-
# Given +path+, a filesystem path to a ruby file, return an array of constant
|
143
|
-
# paths which would cause Dependencies to attempt to load this file.
|
144
|
-
def loadable_constants_for_path(path, bases = load_paths)
|
145
|
-
path = $1 if path =~ /\A(.*)\.rb\Z/
|
146
|
-
expanded_path = File.expand_path(path)
|
147
|
-
|
148
|
-
bases.collect do |root|
|
149
|
-
expanded_root = File.expand_path(root)
|
150
|
-
next unless %r{\A#{Regexp.escape(expanded_root)}(/|\\)} =~ expanded_path
|
151
|
-
|
152
|
-
nesting = expanded_path[(expanded_root.size)..-1]
|
153
|
-
nesting = nesting[1..-1] if nesting && nesting[0] == ?/
|
154
|
-
next if nesting.blank?
|
155
|
-
|
156
|
-
[
|
157
|
-
nesting.camelize,
|
158
|
-
# Special case: application.rb might define ApplicationControlller.
|
159
|
-
('ApplicationController' if nesting == 'application')
|
160
|
-
]
|
161
|
-
end.flatten.compact.uniq
|
162
|
-
end
|
163
142
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
143
|
+
# Given +path+, a filesystem path to a ruby file, return an array of constant
|
144
|
+
# paths which would cause Dependencies to attempt to load this file.
|
145
|
+
def loadable_constants_for_path(path, bases = load_paths)
|
146
|
+
path = $1 if path =~ /\A(.*)\.rb\Z/
|
147
|
+
expanded_path = File.expand_path(path)
|
148
|
+
|
149
|
+
bases.collect do |root|
|
150
|
+
expanded_root = File.expand_path(root)
|
151
|
+
next unless %r{\A#{Regexp.escape(expanded_root)}(/|\\)} =~ expanded_path
|
152
|
+
|
153
|
+
nesting = expanded_path[(expanded_root.size)..-1]
|
154
|
+
nesting = nesting[1..-1] if nesting && nesting[0] == ?/
|
155
|
+
next if nesting.blank?
|
156
|
+
|
157
|
+
[
|
158
|
+
nesting.camelize,
|
159
|
+
# Special case: application.rb might define ApplicationControlller.
|
160
|
+
('ApplicationController' if nesting == 'application')
|
161
|
+
]
|
162
|
+
end.flatten.compact.uniq
|
170
163
|
end
|
171
|
-
nil # Gee, I sure wish we had first_match ;-)
|
172
|
-
end
|
173
164
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
165
|
+
# Search for a file in load_paths matching the provided suffix.
|
166
|
+
def search_for_file(path_suffix)
|
167
|
+
path_suffix = path_suffix + '.rb' unless path_suffix.ends_with? '.rb'
|
168
|
+
load_paths.each do |root|
|
169
|
+
path = File.join(root, path_suffix)
|
170
|
+
return path if File.file? path
|
171
|
+
end
|
172
|
+
nil # Gee, I sure wish we had first_match ;-)
|
179
173
|
end
|
180
|
-
nil
|
181
|
-
end
|
182
|
-
|
183
|
-
def load_once_path?(path)
|
184
|
-
load_once_paths.any? { |base| path.starts_with? base }
|
185
|
-
end
|
186
174
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
mod = Module.new
|
195
|
-
into.const_set const_name, mod
|
196
|
-
autoloaded_constants << qualified_name unless load_once_paths.include?(base_path)
|
197
|
-
return mod
|
198
|
-
end
|
199
|
-
|
200
|
-
# Load the file at the provided path. +const_paths+ is a set of qualified
|
201
|
-
# constant names. When loading the file, Dependencies will watch for the
|
202
|
-
# addition of these constants. Each that is defined will be marked as
|
203
|
-
# autoloaded, and will be removed when Dependencies.clear is next called.
|
204
|
-
#
|
205
|
-
# If the second parameter is left off, then Dependencies will construct a set
|
206
|
-
# of names that the file at +path+ may define. See
|
207
|
-
# +loadable_constants_for_path+ for more details.
|
208
|
-
def load_file(path, const_paths = loadable_constants_for_path(path))
|
209
|
-
log_call path, const_paths
|
210
|
-
const_paths = [const_paths].compact unless const_paths.is_a? Array
|
211
|
-
parent_paths = const_paths.collect { |const_path| /(.*)::[^:]+\Z/ =~ const_path ? $1 : :Object }
|
212
|
-
|
213
|
-
result = nil
|
214
|
-
newly_defined_paths = new_constants_in(*parent_paths) do
|
215
|
-
result = load_without_new_constant_marking path
|
175
|
+
# Does the provided path_suffix correspond to an autoloadable module?
|
176
|
+
# Instead of returning a boolean, the autoload base for this module is returned.
|
177
|
+
def autoloadable_module?(path_suffix)
|
178
|
+
load_paths.each do |load_path|
|
179
|
+
return load_path if File.directory? File.join(load_path, path_suffix)
|
180
|
+
end
|
181
|
+
nil
|
216
182
|
end
|
217
183
|
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
return result
|
222
|
-
end
|
184
|
+
def load_once_path?(path)
|
185
|
+
load_once_paths.any? { |base| path.starts_with? base }
|
186
|
+
end
|
223
187
|
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
188
|
+
# Attempt to autoload the provided module name by searching for a directory
|
189
|
+
# matching the expect path suffix. If found, the module is created and assigned
|
190
|
+
# to +into+'s constants with the name +const_name+. Provided that the directory
|
191
|
+
# was loaded from a reloadable base path, it is added to the set of constants
|
192
|
+
# that are to be unloaded.
|
193
|
+
def autoload_module!(into, const_name, qualified_name, path_suffix)
|
194
|
+
return nil unless base_path = autoloadable_module?(path_suffix)
|
195
|
+
mod = Module.new
|
196
|
+
into.const_set const_name, mod
|
197
|
+
autoloaded_constants << qualified_name unless load_once_paths.include?(base_path)
|
198
|
+
return mod
|
199
|
+
end
|
229
200
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
201
|
+
# Load the file at the provided path. +const_paths+ is a set of qualified
|
202
|
+
# constant names. When loading the file, Dependencies will watch for the
|
203
|
+
# addition of these constants. Each that is defined will be marked as
|
204
|
+
# autoloaded, and will be removed when Dependencies.clear is next called.
|
205
|
+
#
|
206
|
+
# If the second parameter is left off, then Dependencies will construct a set
|
207
|
+
# of names that the file at +path+ may define. See
|
208
|
+
# +loadable_constants_for_path+ for more details.
|
209
|
+
def load_file(path, const_paths = loadable_constants_for_path(path))
|
210
|
+
log_call path, const_paths
|
211
|
+
const_paths = [const_paths].compact unless const_paths.is_a? Array
|
212
|
+
parent_paths = const_paths.collect { |const_path| /(.*)::[^:]+\Z/ =~ const_path ? $1 : :Object }
|
213
|
+
|
214
|
+
result = nil
|
215
|
+
newly_defined_paths = new_constants_in(*parent_paths) do
|
216
|
+
result = load_without_new_constant_marking path
|
242
217
|
end
|
243
|
-
end
|
244
218
|
|
245
|
-
|
246
|
-
|
219
|
+
autoloaded_constants.concat newly_defined_paths unless load_once_path?(path)
|
220
|
+
autoloaded_constants.uniq!
|
221
|
+
log "loading #{path} defined #{newly_defined_paths * ', '}" unless newly_defined_paths.empty?
|
222
|
+
return result
|
223
|
+
end
|
247
224
|
|
248
|
-
|
249
|
-
|
225
|
+
# Return the constant path for the provided parent and constant name.
|
226
|
+
def qualified_name_for(mod, name)
|
227
|
+
mod_name = to_constant_name mod
|
228
|
+
(%w(Object Kernel).include? mod_name) ? name.to_s : "#{mod_name}::#{name}"
|
250
229
|
end
|
251
230
|
|
252
|
-
|
231
|
+
# Load the constant named +const_name+ which is missing from +from_mod+. If
|
232
|
+
# it is not possible to load the constant into from_mod, try its parent module
|
233
|
+
# using const_missing.
|
234
|
+
def load_missing_constant(from_mod, const_name)
|
235
|
+
log_call from_mod, const_name
|
236
|
+
if from_mod == Kernel
|
237
|
+
if ::Object.const_defined?(const_name)
|
238
|
+
log "Returning Object::#{const_name} for Kernel::#{const_name}"
|
239
|
+
return ::Object.const_get(const_name)
|
240
|
+
else
|
241
|
+
log "Substituting Object for Kernel"
|
242
|
+
from_mod = Object
|
243
|
+
end
|
244
|
+
end
|
253
245
|
|
254
|
-
|
255
|
-
|
256
|
-
name_error = NameError.new("uninitialized constant #{qualified_name}")
|
246
|
+
# If we have an anonymous module, all we can do is attempt to load from Object.
|
247
|
+
from_mod = Object if from_mod.name.blank?
|
257
248
|
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
return
|
273
|
-
|
274
|
-
|
249
|
+
unless qualified_const_defined?(from_mod.name) && from_mod.name.constantize.object_id == from_mod.object_id
|
250
|
+
raise ArgumentError, "A copy of #{from_mod} has been removed from the module tree but is still active!"
|
251
|
+
end
|
252
|
+
|
253
|
+
raise ArgumentError, "#{from_mod} is not missing constant #{const_name}!" if uninherited_const_defined?(from_mod, const_name)
|
254
|
+
|
255
|
+
qualified_name = qualified_name_for from_mod, const_name
|
256
|
+
path_suffix = qualified_name.underscore
|
257
|
+
name_error = NameError.new("uninitialized constant #{qualified_name}")
|
258
|
+
|
259
|
+
file_path = search_for_file(path_suffix)
|
260
|
+
if file_path && ! loaded.include?(File.expand_path(file_path)) # We found a matching file to load
|
261
|
+
require_or_load file_path
|
262
|
+
raise LoadError, "Expected #{file_path} to define #{qualified_name}" unless uninherited_const_defined?(from_mod, const_name)
|
263
|
+
return from_mod.const_get(const_name)
|
264
|
+
elsif mod = autoload_module!(from_mod, const_name, qualified_name, path_suffix)
|
265
|
+
return mod
|
266
|
+
elsif (parent = from_mod.parent) && parent != from_mod &&
|
267
|
+
! from_mod.parents.any? { |p| uninherited_const_defined?(p, const_name) }
|
268
|
+
# If our parents do not have a constant named +const_name+ then we are free
|
269
|
+
# to attempt to load upwards. If they do have such a constant, then this
|
270
|
+
# const_missing must be due to from_mod::const_name, which should not
|
271
|
+
# return constants from from_mod's parents.
|
272
|
+
begin
|
273
|
+
return parent.const_missing(const_name)
|
274
|
+
rescue NameError => e
|
275
|
+
raise unless e.missing_name? qualified_name_for(parent, const_name)
|
276
|
+
raise name_error
|
277
|
+
end
|
278
|
+
else
|
275
279
|
raise name_error
|
276
280
|
end
|
277
|
-
else
|
278
|
-
raise name_error
|
279
281
|
end
|
280
|
-
end
|
281
282
|
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
283
|
+
# Remove the constants that have been autoloaded, and those that have been
|
284
|
+
# marked for unloading.
|
285
|
+
def remove_unloadable_constants!
|
286
|
+
autoloaded_constants.each { |const| remove_constant const }
|
287
|
+
autoloaded_constants.clear
|
288
|
+
explicitly_unloadable_constants.each { |const| remove_constant const }
|
289
|
+
end
|
289
290
|
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
291
|
+
# Determine if the given constant has been automatically loaded.
|
292
|
+
def autoloaded?(desc)
|
293
|
+
# No name => anonymous module.
|
294
|
+
return false if desc.is_a?(Module) && desc.name.blank?
|
295
|
+
name = to_constant_name desc
|
296
|
+
return false unless qualified_const_defined? name
|
297
|
+
return autoloaded_constants.include?(name)
|
298
|
+
end
|
298
299
|
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
300
|
+
# Will the provided constant descriptor be unloaded?
|
301
|
+
def will_unload?(const_desc)
|
302
|
+
autoloaded?(const_desc) ||
|
303
|
+
explicitly_unloadable_constants.include?(to_constant_name(const_desc))
|
304
|
+
end
|
304
305
|
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
306
|
+
# Mark the provided constant name for unloading. This constant will be
|
307
|
+
# unloaded on each request, not just the next one.
|
308
|
+
def mark_for_unload(const_desc)
|
309
|
+
name = to_constant_name const_desc
|
310
|
+
if explicitly_unloadable_constants.include? name
|
311
|
+
return false
|
312
|
+
else
|
313
|
+
explicitly_unloadable_constants << name
|
314
|
+
return true
|
315
|
+
end
|
314
316
|
end
|
315
|
-
end
|
316
317
|
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
318
|
+
# Run the provided block and detect the new constants that were loaded during
|
319
|
+
# its execution. Constants may only be regarded as 'new' once -- so if the
|
320
|
+
# block calls +new_constants_in+ again, then the constants defined within the
|
321
|
+
# inner call will not be reported in this one.
|
322
|
+
#
|
323
|
+
# If the provided block does not run to completion, and instead raises an
|
324
|
+
# exception, any new constants are regarded as being only partially defined
|
325
|
+
# and will be removed immediately.
|
326
|
+
def new_constants_in(*descs)
|
327
|
+
log_call(*descs)
|
328
|
+
|
329
|
+
# Build the watch frames. Each frame is a tuple of
|
330
|
+
# [module_name_as_string, constants_defined_elsewhere]
|
331
|
+
watch_frames = descs.collect do |desc|
|
332
|
+
if desc.is_a? Module
|
333
|
+
mod_name = desc.name
|
334
|
+
initial_constants = desc.local_constant_names
|
335
|
+
elsif desc.is_a?(String) || desc.is_a?(Symbol)
|
336
|
+
mod_name = desc.to_s
|
337
|
+
|
338
|
+
# Handle the case where the module has yet to be defined.
|
339
|
+
initial_constants = if qualified_const_defined?(mod_name)
|
340
|
+
mod_name.constantize.local_constant_names
|
341
|
+
else
|
342
|
+
[]
|
343
|
+
end
|
340
344
|
else
|
341
|
-
|
345
|
+
raise Argument, "#{desc.inspect} does not describe a module!"
|
342
346
|
end
|
343
|
-
else
|
344
|
-
raise Argument, "#{desc.inspect} does not describe a module!"
|
345
|
-
end
|
346
347
|
|
347
|
-
|
348
|
-
|
348
|
+
[mod_name, initial_constants]
|
349
|
+
end
|
349
350
|
|
350
|
-
|
351
|
+
constant_watch_stack.concat watch_frames
|
351
352
|
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
353
|
+
aborting = true
|
354
|
+
begin
|
355
|
+
yield # Now yield to the code that is to define new constants.
|
356
|
+
aborting = false
|
357
|
+
ensure
|
358
|
+
# Find the new constants.
|
359
|
+
new_constants = watch_frames.collect do |mod_name, prior_constants|
|
360
|
+
# Module still doesn't exist? Treat it as if it has no constants.
|
361
|
+
next [] unless qualified_const_defined?(mod_name)
|
362
|
+
|
363
|
+
mod = mod_name.constantize
|
364
|
+
next [] unless mod.is_a? Module
|
365
|
+
new_constants = mod.local_constant_names - prior_constants
|
366
|
+
|
367
|
+
# Make sure no other frames takes credit for these constants.
|
368
|
+
constant_watch_stack.each do |frame_name, constants|
|
369
|
+
constants.concat new_constants if frame_name == mod_name
|
370
|
+
end
|
371
|
+
|
372
|
+
new_constants.collect do |suffix|
|
373
|
+
mod_name == "Object" ? suffix : "#{mod_name}::#{suffix}"
|
374
|
+
end
|
375
|
+
end.flatten
|
376
|
+
|
377
|
+
log "New constants: #{new_constants * ', '}"
|
378
|
+
|
379
|
+
if aborting
|
380
|
+
log "Error during loading, removing partially loaded constants "
|
381
|
+
new_constants.each { |name| remove_constant name }
|
382
|
+
new_constants.clear
|
369
383
|
end
|
384
|
+
end
|
370
385
|
|
371
|
-
|
372
|
-
|
386
|
+
return new_constants
|
387
|
+
ensure
|
388
|
+
# Remove the stack frames that we added.
|
389
|
+
if defined?(watch_frames) && ! watch_frames.blank?
|
390
|
+
frame_ids = watch_frames.collect(&:object_id)
|
391
|
+
constant_watch_stack.delete_if do |watch_frame|
|
392
|
+
frame_ids.include? watch_frame.object_id
|
373
393
|
end
|
374
|
-
end.flatten
|
375
|
-
|
376
|
-
log "New constants: #{new_constants * ', '}"
|
377
|
-
|
378
|
-
if aborting
|
379
|
-
log "Error during loading, removing partially loaded constants "
|
380
|
-
new_constants.each { |name| remove_constant name }
|
381
|
-
new_constants.clear
|
382
394
|
end
|
383
395
|
end
|
384
396
|
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
397
|
+
class LoadingModule #:nodoc:
|
398
|
+
# Old style environment.rb referenced this method directly. Please note, it doesn't
|
399
|
+
# actually *do* anything any more.
|
400
|
+
def self.root(*args)
|
401
|
+
if defined?(RAILS_DEFAULT_LOGGER)
|
402
|
+
RAILS_DEFAULT_LOGGER.warn "Your environment.rb uses the old syntax, it may not continue to work in future releases."
|
403
|
+
RAILS_DEFAULT_LOGGER.warn "For upgrade instructions please see: http://manuals.rubyonrails.com/read/book/19"
|
404
|
+
end
|
392
405
|
end
|
393
406
|
end
|
394
|
-
end
|
395
407
|
|
396
|
-
|
397
|
-
#
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
408
|
+
# Convert the provided const desc to a qualified constant name (as a string).
|
409
|
+
# A module, class, symbol, or string may be provided.
|
410
|
+
def to_constant_name(desc) #:nodoc:
|
411
|
+
name = case desc
|
412
|
+
when String then desc.starts_with?('::') ? desc[2..-1] : desc
|
413
|
+
when Symbol then desc.to_s
|
414
|
+
when Module
|
415
|
+
raise ArgumentError, "Anonymous modules have no name to be referenced by" if desc.name.blank?
|
416
|
+
desc.name
|
417
|
+
else raise TypeError, "Not a valid constant descriptor: #{desc.inspect}"
|
403
418
|
end
|
404
419
|
end
|
405
|
-
end
|
406
420
|
|
407
|
-
|
408
|
-
|
409
|
-
def to_constant_name(desc) #:nodoc:
|
410
|
-
name = case desc
|
411
|
-
when String then desc.starts_with?('::') ? desc[2..-1] : desc
|
412
|
-
when Symbol then desc.to_s
|
413
|
-
when Module
|
414
|
-
raise ArgumentError, "Anonymous modules have no name to be referenced by" if desc.name.blank?
|
415
|
-
desc.name
|
416
|
-
else raise TypeError, "Not a valid constant descriptor: #{desc.inspect}"
|
417
|
-
end
|
418
|
-
end
|
421
|
+
def remove_constant(const) #:nodoc:
|
422
|
+
return false unless qualified_const_defined? const
|
419
423
|
|
420
|
-
|
421
|
-
|
424
|
+
const = $1 if /\A::(.*)\Z/ =~ const.to_s
|
425
|
+
names = const.to_s.split('::')
|
426
|
+
if names.size == 1 # It's under Object
|
427
|
+
parent = Object
|
428
|
+
else
|
429
|
+
parent = (names[0..-2] * '::').constantize
|
430
|
+
end
|
422
431
|
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
parent = Object
|
427
|
-
else
|
428
|
-
parent = (names[0..-2] * '::').constantize
|
432
|
+
log "removing constant #{const}"
|
433
|
+
parent.instance_eval { remove_const names.last }
|
434
|
+
return true
|
429
435
|
end
|
430
436
|
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
/in `([a-z_\?\!]+)'/ =~ caller(1).first
|
441
|
-
selector = $1 || '<unknown>'
|
442
|
-
log "called #{selector}(#{arg_str})"
|
443
|
-
end
|
444
|
-
end
|
437
|
+
protected
|
438
|
+
def log_call(*args)
|
439
|
+
if defined?(RAILS_DEFAULT_LOGGER) && RAILS_DEFAULT_LOGGER && log_activity
|
440
|
+
arg_str = args.collect(&:inspect) * ', '
|
441
|
+
/in `([a-z_\?\!]+)'/ =~ caller(1).first
|
442
|
+
selector = $1 || '<unknown>'
|
443
|
+
log "called #{selector}(#{arg_str})"
|
444
|
+
end
|
445
|
+
end
|
445
446
|
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
447
|
+
def log(msg)
|
448
|
+
if defined?(RAILS_DEFAULT_LOGGER) && RAILS_DEFAULT_LOGGER && log_activity
|
449
|
+
RAILS_DEFAULT_LOGGER.debug "Dependencies: #{msg}"
|
450
|
+
end
|
451
|
+
end
|
450
452
|
end
|
451
|
-
|
452
453
|
end
|
453
454
|
|
454
455
|
Object.instance_eval do
|
455
|
-
define_method(:require_or_load) { |file_name| Dependencies.require_or_load(file_name) } unless Object.respond_to?(:require_or_load)
|
456
|
-
define_method(:require_dependency) { |file_name| Dependencies.depend_on(file_name) } unless Object.respond_to?(:require_dependency)
|
457
|
-
define_method(:require_association) { |file_name| Dependencies.associate_with(file_name) } unless Object.respond_to?(:require_association)
|
456
|
+
define_method(:require_or_load) { |file_name| ActiveSupport::Dependencies.require_or_load(file_name) } unless Object.respond_to?(:require_or_load)
|
457
|
+
define_method(:require_dependency) { |file_name| ActiveSupport::Dependencies.depend_on(file_name) } unless Object.respond_to?(:require_dependency)
|
458
|
+
define_method(:require_association) { |file_name| ActiveSupport::Dependencies.associate_with(file_name) } unless Object.respond_to?(:require_association)
|
458
459
|
end
|
459
460
|
|
460
461
|
class Module #:nodoc:
|
@@ -464,7 +465,7 @@ class Module #:nodoc:
|
|
464
465
|
# Use const_missing to autoload associations so we don't have to
|
465
466
|
# require_association when using single-table inheritance.
|
466
467
|
def const_missing(class_id)
|
467
|
-
Dependencies.load_missing_constant self, class_id
|
468
|
+
ActiveSupport::Dependencies.load_missing_constant self, class_id
|
468
469
|
end
|
469
470
|
|
470
471
|
def unloadable(const_desc = self)
|
@@ -480,15 +481,15 @@ class Class
|
|
480
481
|
else
|
481
482
|
begin
|
482
483
|
begin
|
483
|
-
Dependencies.load_missing_constant self, const_name
|
484
|
+
ActiveSupport::Dependencies.load_missing_constant self, const_name
|
484
485
|
rescue NameError
|
485
486
|
parent.send :const_missing, const_name
|
486
487
|
end
|
487
488
|
rescue NameError => e
|
488
489
|
# Make sure that the name we are missing is the one that caused the error
|
489
|
-
parent_qualified_name = Dependencies.qualified_name_for parent, const_name
|
490
|
+
parent_qualified_name = ActiveSupport::Dependencies.qualified_name_for parent, const_name
|
490
491
|
raise unless e.missing_name? parent_qualified_name
|
491
|
-
qualified_name = Dependencies.qualified_name_for self, const_name
|
492
|
+
qualified_name = ActiveSupport::Dependencies.qualified_name_for self, const_name
|
492
493
|
raise NameError.new("uninitialized constant #{qualified_name}").copy_blame!(e)
|
493
494
|
end
|
494
495
|
end
|
@@ -499,14 +500,14 @@ class Object
|
|
499
500
|
alias_method :load_without_new_constant_marking, :load
|
500
501
|
|
501
502
|
def load(file, *extras) #:nodoc:
|
502
|
-
Dependencies.new_constants_in(Object) { super }
|
503
|
+
ActiveSupport::Dependencies.new_constants_in(Object) { super }
|
503
504
|
rescue Exception => exception # errors from loading file
|
504
505
|
exception.blame_file! file
|
505
506
|
raise
|
506
507
|
end
|
507
508
|
|
508
509
|
def require(file, *extras) #:nodoc:
|
509
|
-
Dependencies.new_constants_in(Object) { super }
|
510
|
+
ActiveSupport::Dependencies.new_constants_in(Object) { super }
|
510
511
|
rescue Exception => exception # errors from required file
|
511
512
|
exception.blame_file! file
|
512
513
|
raise
|
@@ -526,7 +527,7 @@ class Object
|
|
526
527
|
# Returns true if the constant was not previously marked for unloading, false
|
527
528
|
# otherwise.
|
528
529
|
def unloadable(const_desc)
|
529
|
-
Dependencies.mark_for_unload const_desc
|
530
|
+
ActiveSupport::Dependencies.mark_for_unload const_desc
|
530
531
|
end
|
531
532
|
end
|
532
533
|
|