activesupport 2.0.5 → 2.1.0
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 +183 -5
- data/lib/active_support.rb +6 -2
- data/lib/active_support/base64.rb +5 -0
- data/lib/active_support/basic_object.rb +23 -4
- data/lib/active_support/buffered_logger.rb +17 -3
- data/lib/active_support/cache.rb +145 -0
- data/lib/active_support/cache/compressed_mem_cache_store.rb +15 -0
- data/lib/active_support/cache/drb_store.rb +15 -0
- data/lib/active_support/cache/file_store.rb +70 -0
- data/lib/active_support/cache/mem_cache_store.rb +100 -0
- data/lib/active_support/cache/memory_store.rb +38 -0
- data/lib/active_support/callbacks.rb +275 -0
- data/lib/active_support/core_ext/array/access.rb +2 -4
- data/lib/active_support/core_ext/array/conversions.rb +89 -5
- data/lib/active_support/core_ext/array/extract_options.rb +2 -1
- data/lib/active_support/core_ext/array/grouping.rb +3 -8
- data/lib/active_support/core_ext/array/random_access.rb +1 -1
- data/lib/active_support/core_ext/base64.rb +4 -0
- data/lib/active_support/core_ext/base64/encoding.rb +13 -0
- data/lib/active_support/core_ext/benchmark.rb +12 -0
- data/lib/active_support/core_ext/bigdecimal.rb +4 -0
- data/lib/active_support/core_ext/bigdecimal/conversions.rb +39 -4
- data/lib/active_support/core_ext/blank.rb +5 -2
- data/lib/active_support/core_ext/class/attribute_accessors.rb +7 -1
- data/lib/active_support/core_ext/class/delegating_attributes.rb +7 -1
- data/lib/active_support/core_ext/class/inheritable_attributes.rb +1 -1
- data/lib/active_support/core_ext/class/removal.rb +26 -0
- data/lib/active_support/core_ext/date/calculations.rb +28 -1
- data/lib/active_support/core_ext/date/conversions.rb +1 -0
- data/lib/active_support/core_ext/date_time.rb +2 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +37 -2
- data/lib/active_support/core_ext/date_time/conversions.rb +27 -14
- data/lib/active_support/core_ext/enumerable.rb +16 -9
- data/lib/active_support/core_ext/exception.rb +8 -0
- data/lib/active_support/core_ext/file.rb +6 -6
- data/lib/active_support/core_ext/hash/conversions.rb +26 -8
- data/lib/active_support/core_ext/hash/indifferent_access.rb +35 -0
- data/lib/active_support/core_ext/hash/reverse_merge.rb +4 -1
- data/lib/active_support/core_ext/integer/even_odd.rb +10 -5
- data/lib/active_support/core_ext/integer/inflections.rb +0 -1
- data/lib/active_support/core_ext/kernel/daemonizing.rb +2 -10
- data/lib/active_support/core_ext/kernel/reporting.rb +8 -0
- data/lib/active_support/core_ext/module/attr_internal.rb +4 -3
- data/lib/active_support/core_ext/module/attribute_accessors.rb +11 -1
- data/lib/active_support/core_ext/module/delegation.rb +5 -3
- data/lib/active_support/core_ext/module/inclusion.rb +19 -0
- data/lib/active_support/core_ext/module/introspection.rb +50 -16
- data/lib/active_support/core_ext/module/loading.rb +10 -0
- data/lib/active_support/core_ext/numeric.rb +3 -1
- data/lib/active_support/core_ext/numeric/conversions.rb +19 -0
- data/lib/active_support/core_ext/object/instance_variables.rb +52 -0
- data/lib/active_support/core_ext/object/misc.rb +1 -1
- data/lib/active_support/core_ext/process.rb +1 -0
- data/lib/active_support/core_ext/process/daemon.rb +25 -0
- data/lib/active_support/core_ext/range/conversions.rb +5 -1
- data/lib/active_support/core_ext/range/include_range.rb +8 -0
- data/lib/active_support/core_ext/range/overlaps.rb +3 -0
- data/lib/active_support/core_ext/string.rb +5 -10
- data/lib/active_support/core_ext/string/access.rb +72 -48
- data/lib/active_support/core_ext/string/conversions.rb +4 -4
- data/lib/active_support/core_ext/string/filters.rb +26 -0
- data/lib/active_support/core_ext/string/inflections.rb +56 -64
- data/lib/active_support/core_ext/string/iterators.rb +4 -0
- data/lib/active_support/core_ext/string/starts_ends_with.rb +12 -4
- data/lib/active_support/core_ext/string/unicode.rb +14 -7
- data/lib/active_support/core_ext/symbol.rb +1 -1
- data/lib/active_support/core_ext/time.rb +2 -0
- data/lib/active_support/core_ext/time/calculations.rb +75 -23
- data/lib/active_support/core_ext/time/conversions.rb +22 -35
- data/lib/active_support/core_ext/time/zones.rb +86 -0
- data/lib/active_support/dependencies.rb +92 -80
- data/lib/active_support/deprecation.rb +2 -16
- data/lib/active_support/duration.rb +4 -4
- data/lib/active_support/gzip.rb +25 -0
- data/lib/active_support/inflector.rb +92 -69
- data/lib/active_support/json.rb +17 -25
- data/lib/active_support/json/decoding.rb +1 -1
- data/lib/active_support/json/encoders/date.rb +11 -2
- data/lib/active_support/json/encoders/date_time.rb +11 -2
- data/lib/active_support/json/encoders/enumerable.rb +2 -2
- data/lib/active_support/json/encoders/hash.rb +3 -6
- data/lib/active_support/json/encoders/object.rb +1 -1
- data/lib/active_support/json/encoders/string.rb +8 -2
- data/lib/active_support/json/encoders/time.rb +11 -2
- data/lib/active_support/json/encoding.rb +0 -1
- data/lib/active_support/multibyte/chars.rb +8 -6
- data/lib/active_support/multibyte/handlers/utf8_handler.rb +11 -11
- data/lib/active_support/ordered_hash.rb +43 -0
- data/lib/active_support/ordered_options.rb +0 -38
- data/lib/active_support/test_case.rb +10 -2
- data/lib/active_support/testing/default.rb +3 -6
- data/lib/active_support/testing/setup_and_teardown.rb +93 -0
- data/lib/active_support/time_with_zone.rb +283 -0
- data/lib/active_support/values/time_zone.rb +336 -123
- data/lib/active_support/vendor.rb +12 -0
- data/lib/active_support/vendor/memcache-client-1.5.0/memcache.rb +849 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo.rb +33 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/data_timezone.rb +47 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/data_timezone_info.rb +226 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Algiers.rb +55 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Cairo.rb +219 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Casablanca.rb +38 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Harare.rb +18 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Johannesburg.rb +25 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Monrovia.rb +22 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Africa/Nairobi.rb +23 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Argentina/Buenos_Aires.rb +166 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Argentina/San_Juan.rb +170 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Bogota.rb +23 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Caracas.rb +23 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Chicago.rb +283 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Chihuahua.rb +136 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Denver.rb +204 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Godthab.rb +161 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Guatemala.rb +27 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Halifax.rb +274 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Indiana/Indianapolis.rb +149 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Juneau.rb +194 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/La_Paz.rb +22 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Lima.rb +35 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Los_Angeles.rb +232 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Mazatlan.rb +139 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Mexico_City.rb +144 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Monterrey.rb +131 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/New_York.rb +282 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Phoenix.rb +30 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Regina.rb +74 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Santiago.rb +205 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/St_Johns.rb +288 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/America/Tijuana.rb +196 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Almaty.rb +67 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Baghdad.rb +73 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Baku.rb +161 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Bangkok.rb +20 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Chongqing.rb +33 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Dhaka.rb +27 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Hong_Kong.rb +87 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Irkutsk.rb +165 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Jakarta.rb +30 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Jerusalem.rb +163 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Kabul.rb +20 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Kamchatka.rb +163 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Karachi.rb +28 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Katmandu.rb +20 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Kolkata.rb +25 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Krasnoyarsk.rb +163 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Kuala_Lumpur.rb +31 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Kuwait.rb +18 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Magadan.rb +163 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Muscat.rb +18 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Novosibirsk.rb +164 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Rangoon.rb +24 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Riyadh.rb +18 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Seoul.rb +34 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Shanghai.rb +35 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Singapore.rb +33 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Taipei.rb +59 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Tashkent.rb +47 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Tbilisi.rb +78 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Tehran.rb +121 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Tokyo.rb +30 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Ulaanbaatar.rb +65 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Urumqi.rb +33 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Vladivostok.rb +164 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Yakutsk.rb +163 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Yekaterinburg.rb +165 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Asia/Yerevan.rb +165 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Atlantic/Azores.rb +270 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Atlantic/Cape_Verde.rb +23 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Atlantic/South_Georgia.rb +18 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Adelaide.rb +187 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Brisbane.rb +35 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Darwin.rb +29 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Hobart.rb +193 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Melbourne.rb +185 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Perth.rb +37 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Australia/Sydney.rb +185 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Etc/UTC.rb +16 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Amsterdam.rb +228 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Athens.rb +185 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Belgrade.rb +163 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Berlin.rb +188 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Bratislava.rb +13 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Brussels.rb +232 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Bucharest.rb +181 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Budapest.rb +197 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Copenhagen.rb +179 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Dublin.rb +276 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Helsinki.rb +163 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Istanbul.rb +218 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Kiev.rb +168 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Lisbon.rb +268 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Ljubljana.rb +13 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/London.rb +288 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Madrid.rb +211 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Minsk.rb +170 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Moscow.rb +181 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Paris.rb +232 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Prague.rb +187 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Riga.rb +176 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Rome.rb +215 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Sarajevo.rb +13 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Skopje.rb +13 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Sofia.rb +173 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Stockholm.rb +165 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Tallinn.rb +172 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Vienna.rb +183 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Vilnius.rb +170 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Warsaw.rb +212 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Europe/Zagreb.rb +13 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Auckland.rb +202 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Fiji.rb +23 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Guam.rb +22 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Honolulu.rb +28 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Majuro.rb +20 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Midway.rb +25 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Noumea.rb +25 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Pago_Pago.rb +26 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Port_Moresby.rb +20 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/definitions/Pacific/Tongatapu.rb +27 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/info_timezone.rb +52 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/linked_timezone.rb +51 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/linked_timezone_info.rb +44 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/offset_rationals.rb +95 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/time_or_datetime.rb +292 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone.rb +508 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone_definition.rb +56 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone_info.rb +40 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone_offset_info.rb +94 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone_period.rb +198 -0
- data/lib/active_support/vendor/tzinfo-0.3.8/tzinfo/timezone_transition_info.rb +138 -0
- data/lib/active_support/version.rb +2 -2
- data/lib/active_support/whiny_nil.rb +30 -10
- metadata +175 -5
- data/lib/active_support/core_ext/rexml.rb +0 -38
- data/lib/active_support/testing.rb +0 -1
@@ -2,8 +2,8 @@ module Enumerable
|
|
2
2
|
# Returns a JSON string representing the enumerable. Any +options+
|
3
3
|
# given will be passed on to its elements. For example:
|
4
4
|
#
|
5
|
-
#
|
6
|
-
# users.to_json(:only => :name)
|
5
|
+
# users = User.find(:all)
|
6
|
+
# # => users.to_json(:only => :name)
|
7
7
|
#
|
8
8
|
# will pass the <tt>:only => :name</tt> option to each user.
|
9
9
|
def to_json(options = {}) #:nodoc:
|
@@ -5,8 +5,7 @@ class Hash
|
|
5
5
|
# the hash keys. For example:
|
6
6
|
#
|
7
7
|
# { :name => "Konata Izumi", 'age' => 16, 1 => 2 }.to_json
|
8
|
-
#
|
9
|
-
# {"name": "Konata Izumi", 1: 2, "age": 16}
|
8
|
+
# # => {"name": "Konata Izumi", 1: 2, "age": 16}
|
10
9
|
#
|
11
10
|
# The keys in the JSON string are unordered due to the nature of hashes.
|
12
11
|
#
|
@@ -14,12 +13,10 @@ class Hash
|
|
14
13
|
# attributes included, and will accept 1 or more hash keys to include/exclude.
|
15
14
|
#
|
16
15
|
# { :name => "Konata Izumi", 'age' => 16, 1 => 2 }.to_json(:only => [:name, 'age'])
|
17
|
-
#
|
18
|
-
# {"name": "Konata Izumi", "age": 16}
|
16
|
+
# # => {"name": "Konata Izumi", "age": 16}
|
19
17
|
#
|
20
18
|
# { :name => "Konata Izumi", 'age' => 16, 1 => 2 }.to_json(:except => 1)
|
21
|
-
#
|
22
|
-
# {"name": "Konata Izumi", "age": 16}
|
19
|
+
# # => {"name": "Konata Izumi", "age": 16}
|
23
20
|
#
|
24
21
|
# The +options+ also filter down to any hash values. This is particularly
|
25
22
|
# useful for converting hashes containing ActiveRecord objects or any object
|
@@ -1,5 +1,5 @@
|
|
1
1
|
class Object
|
2
|
-
# Dumps object in JSON (JavaScript Object Notation).
|
2
|
+
# Dumps object in JSON (JavaScript Object Notation). See www.json.org for more info.
|
3
3
|
def to_json(options = {})
|
4
4
|
ActiveSupport::JSON.encode(instance_values, options)
|
5
5
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module ActiveSupport
|
2
2
|
module JSON
|
3
3
|
module Encoding
|
4
|
+
mattr_accessor :escape_regex
|
5
|
+
|
4
6
|
ESCAPED_CHARS = {
|
5
7
|
"\010" => '\b',
|
6
8
|
"\f" => '\f',
|
@@ -17,11 +19,15 @@ module ActiveSupport
|
|
17
19
|
end
|
18
20
|
end
|
19
21
|
|
22
|
+
ActiveSupport.escape_html_entities_in_json = true
|
23
|
+
|
20
24
|
class String
|
21
25
|
def to_json(options = nil) #:nodoc:
|
22
|
-
'"' + gsub(
|
26
|
+
json = '"' + gsub(ActiveSupport::JSON::Encoding.escape_regex) { |s|
|
23
27
|
ActiveSupport::JSON::Encoding::ESCAPED_CHARS[s]
|
24
|
-
}
|
28
|
+
}
|
29
|
+
json.force_encoding('ascii-8bit') if respond_to?(:force_encoding)
|
30
|
+
json.gsub(/([\xC0-\xDF][\x80-\xBF]|
|
25
31
|
[\xE0-\xEF][\x80-\xBF]{2}|
|
26
32
|
[\xF0-\xF7][\x80-\xBF]{3})+/nx) { |s|
|
27
33
|
s.unpack("U*").pack("n*").unpack("H*")[0].gsub(/.{4}/, '\\\\u\&')
|
@@ -1,5 +1,14 @@
|
|
1
1
|
class Time
|
2
|
-
|
3
|
-
|
2
|
+
# Returns a JSON string representing the time.
|
3
|
+
#
|
4
|
+
# ==== Example:
|
5
|
+
# Time.utc(2005,2,1,15,15,10).to_json
|
6
|
+
# # => 2005/02/01 15:15:10 +0000"
|
7
|
+
def to_json(options = nil)
|
8
|
+
if ActiveSupport.use_standard_json_time_format
|
9
|
+
xmlschema.inspect
|
10
|
+
else
|
11
|
+
%("#{strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)}")
|
12
|
+
end
|
4
13
|
end
|
5
14
|
end
|
@@ -10,7 +10,7 @@ module ActiveSupport::Multibyte #:nodoc:
|
|
10
10
|
# String methods are proxied through the Chars object, and can be accessed through the +chars+ method. Methods
|
11
11
|
# which would normally return a String object now return a Chars object so methods can be chained.
|
12
12
|
#
|
13
|
-
# "The Perfect String ".chars.downcase.strip.normalize
|
13
|
+
# "The Perfect String ".chars.downcase.strip.normalize # => "the perfect string"
|
14
14
|
#
|
15
15
|
# Chars objects are perfectly interchangeable with String objects as long as no explicit class checks are made.
|
16
16
|
# If certain methods do explicitly check the class, call +to_s+ before you pass chars objects to them.
|
@@ -40,13 +40,15 @@ module ActiveSupport::Multibyte #:nodoc:
|
|
40
40
|
# core dumps. Don't go there.
|
41
41
|
@string
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
# Make duck-typing with String possible
|
45
|
-
def respond_to?(method)
|
46
|
-
super || @string.respond_to?(method
|
47
|
-
|
45
|
+
def respond_to?(method, include_priv = false)
|
46
|
+
super || @string.respond_to?(method, include_priv) ||
|
47
|
+
handler.respond_to?(method, include_priv) ||
|
48
|
+
(method.to_s =~ /(.*)!/ && handler.respond_to?($1, include_priv)) ||
|
49
|
+
false
|
48
50
|
end
|
49
|
-
|
51
|
+
|
50
52
|
# Create a new Chars instance.
|
51
53
|
def initialize(str)
|
52
54
|
@string = str.respond_to?(:string) ? str.string : str
|
@@ -147,13 +147,11 @@ module ActiveSupport::Multibyte::Handlers #:nodoc:
|
|
147
147
|
#
|
148
148
|
# s = "Müller"
|
149
149
|
# s.chars[2] = "e" # Replace character with offset 2
|
150
|
-
# s
|
151
|
-
# #=> "Müeler"
|
150
|
+
# s # => "Müeler"
|
152
151
|
#
|
153
152
|
# s = "Müller"
|
154
153
|
# s.chars[1, 2] = "ö" # Replace 2 characters at character offset 1
|
155
|
-
# s
|
156
|
-
# #=> "Möler"
|
154
|
+
# s # => "Möler"
|
157
155
|
def []=(str, *args)
|
158
156
|
replace_by = args.pop
|
159
157
|
# Indexed replace with regular expressions already works
|
@@ -183,10 +181,10 @@ module ActiveSupport::Multibyte::Handlers #:nodoc:
|
|
183
181
|
# Example:
|
184
182
|
#
|
185
183
|
# "¾ cup".chars.rjust(8).to_s
|
186
|
-
#
|
184
|
+
# # => " ¾ cup"
|
187
185
|
#
|
188
186
|
# "¾ cup".chars.rjust(8, " ").to_s # Use non-breaking whitespace
|
189
|
-
#
|
187
|
+
# # => " ¾ cup"
|
190
188
|
def rjust(str, integer, padstr=' ')
|
191
189
|
justify(str, integer, :right, padstr)
|
192
190
|
end
|
@@ -196,10 +194,10 @@ module ActiveSupport::Multibyte::Handlers #:nodoc:
|
|
196
194
|
# Example:
|
197
195
|
#
|
198
196
|
# "¾ cup".chars.rjust(8).to_s
|
199
|
-
#
|
197
|
+
# # => "¾ cup "
|
200
198
|
#
|
201
199
|
# "¾ cup".chars.rjust(8, " ").to_s # Use non-breaking whitespace
|
202
|
-
#
|
200
|
+
# # => "¾ cup "
|
203
201
|
def ljust(str, integer, padstr=' ')
|
204
202
|
justify(str, integer, :left, padstr)
|
205
203
|
end
|
@@ -209,10 +207,10 @@ module ActiveSupport::Multibyte::Handlers #:nodoc:
|
|
209
207
|
# Example:
|
210
208
|
#
|
211
209
|
# "¾ cup".chars.center(8).to_s
|
212
|
-
#
|
210
|
+
# # => " ¾ cup "
|
213
211
|
#
|
214
212
|
# "¾ cup".chars.center(8, " ").to_s # Use non-breaking whitespace
|
215
|
-
#
|
213
|
+
# # => " ¾ cup "
|
216
214
|
def center(str, integer, padstr=' ')
|
217
215
|
justify(str, integer, :center, padstr)
|
218
216
|
end
|
@@ -284,7 +282,9 @@ module ActiveSupport::Multibyte::Handlers #:nodoc:
|
|
284
282
|
# passing strings to databases and validations.
|
285
283
|
#
|
286
284
|
# * <tt>str</tt> - The string to perform normalization on.
|
287
|
-
# * <tt>form</tt> - The form you want to normalize in. Should be one of the following:
|
285
|
+
# * <tt>form</tt> - The form you want to normalize in. Should be one of the following:
|
286
|
+
# <tt>:c</tt>, <tt>:kc</tt>, <tt>:d</tt>, or <tt>:kd</tt>. Default is
|
287
|
+
# ActiveSupport::Multibyte::DEFAULT_NORMALIZATION_FORM.
|
288
288
|
def normalize(str, form=ActiveSupport::Multibyte::DEFAULT_NORMALIZATION_FORM)
|
289
289
|
# See http://www.unicode.org/reports/tr15, Table 1
|
290
290
|
codepoints = u_unpack(str)
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# OrderedHash is namespaced to prevent conflicts with other implementations
|
2
|
+
module ActiveSupport
|
3
|
+
# Hash is ordered in Ruby 1.9!
|
4
|
+
if RUBY_VERSION >= '1.9'
|
5
|
+
OrderedHash = ::Hash
|
6
|
+
else
|
7
|
+
class OrderedHash < Array #:nodoc:
|
8
|
+
def []=(key, value)
|
9
|
+
if pair = assoc(key)
|
10
|
+
pair.pop
|
11
|
+
pair << value
|
12
|
+
else
|
13
|
+
self << [key, value]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def [](key)
|
18
|
+
pair = assoc(key)
|
19
|
+
pair ? pair.last : nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def delete(key)
|
23
|
+
pair = assoc(key)
|
24
|
+
pair ? array_index = index(pair) : nil
|
25
|
+
array_index ? delete_at(array_index).last : nil
|
26
|
+
end
|
27
|
+
|
28
|
+
def keys
|
29
|
+
collect { |key, value| key }
|
30
|
+
end
|
31
|
+
|
32
|
+
def values
|
33
|
+
collect { |key, value| value }
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_hash
|
37
|
+
returning({}) do |hash|
|
38
|
+
each { |array| hash[array[0]] = array[1] }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -1,41 +1,3 @@
|
|
1
|
-
# OrderedHash is namespaced to prevent conflicts with other implementations
|
2
|
-
module ActiveSupport
|
3
|
-
# Hash is ordered in Ruby 1.9!
|
4
|
-
if RUBY_VERSION >= '1.9'
|
5
|
-
OrderedHash = ::Hash
|
6
|
-
else
|
7
|
-
class OrderedHash < Array #:nodoc:
|
8
|
-
def []=(key, value)
|
9
|
-
if pair = assoc(key)
|
10
|
-
pair.pop
|
11
|
-
pair << value
|
12
|
-
else
|
13
|
-
self << [key, value]
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def [](key)
|
18
|
-
pair = assoc(key)
|
19
|
-
pair ? pair.last : nil
|
20
|
-
end
|
21
|
-
|
22
|
-
def keys
|
23
|
-
collect { |key, value| key }
|
24
|
-
end
|
25
|
-
|
26
|
-
def values
|
27
|
-
collect { |key, value| value }
|
28
|
-
end
|
29
|
-
|
30
|
-
def to_hash
|
31
|
-
returning({}) do |hash|
|
32
|
-
each { |array| hash[array[0]] = array[1] }
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
1
|
class OrderedOptions < ActiveSupport::OrderedHash #:nodoc:
|
40
2
|
def []=(key, value)
|
41
3
|
super(key.to_sym, value)
|
@@ -1,5 +1,13 @@
|
|
1
|
+
require 'test/unit/testcase'
|
2
|
+
require 'active_support/testing/setup_and_teardown'
|
3
|
+
require 'active_support/testing/default'
|
4
|
+
|
5
|
+
# TODO: move to core_ext
|
6
|
+
class Test::Unit::TestCase #:nodoc:
|
7
|
+
include ActiveSupport::Testing::SetupAndTeardown
|
8
|
+
end
|
9
|
+
|
1
10
|
module ActiveSupport
|
2
11
|
class TestCase < Test::Unit::TestCase
|
3
|
-
include ActiveSupport::Testing::Default
|
4
12
|
end
|
5
|
-
end
|
13
|
+
end
|
@@ -1,12 +1,9 @@
|
|
1
1
|
module ActiveSupport
|
2
2
|
module Testing
|
3
|
-
module Default
|
4
|
-
|
5
|
-
|
6
|
-
return if @method_name.to_s == "default_test"
|
7
|
-
super
|
3
|
+
module Default #:nodoc:
|
4
|
+
# Placeholder so test/unit ignores test cases without any tests.
|
5
|
+
def default_test
|
8
6
|
end
|
9
7
|
end
|
10
8
|
end
|
11
9
|
end
|
12
|
-
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module ActiveSupport
|
2
|
+
module Testing
|
3
|
+
module SetupAndTeardown
|
4
|
+
# For compatibility with Ruby < 1.8.6
|
5
|
+
PASSTHROUGH_EXCEPTIONS =
|
6
|
+
if defined?(Test::Unit::TestCase::PASSTHROUGH_EXCEPTIONS)
|
7
|
+
Test::Unit::TestCase::PASSTHROUGH_EXCEPTIONS
|
8
|
+
else
|
9
|
+
[NoMemoryError, SignalException, Interrupt, SystemExit]
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.included(base)
|
13
|
+
base.send :include, ActiveSupport::Callbacks
|
14
|
+
base.define_callbacks :setup, :teardown
|
15
|
+
|
16
|
+
begin
|
17
|
+
require 'mocha'
|
18
|
+
base.alias_method_chain :run, :callbacks_and_mocha
|
19
|
+
rescue LoadError
|
20
|
+
base.alias_method_chain :run, :callbacks
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# This redefinition is unfortunate but test/unit shows us no alternative.
|
25
|
+
def run_with_callbacks(result) #:nodoc:
|
26
|
+
return if @method_name.to_s == "default_test"
|
27
|
+
|
28
|
+
yield(Test::Unit::TestCase::STARTED, name)
|
29
|
+
@_result = result
|
30
|
+
begin
|
31
|
+
run_callbacks :setup
|
32
|
+
setup
|
33
|
+
__send__(@method_name)
|
34
|
+
rescue Test::Unit::AssertionFailedError => e
|
35
|
+
add_failure(e.message, e.backtrace)
|
36
|
+
rescue *PASSTHROUGH_EXCEPTIONS
|
37
|
+
raise
|
38
|
+
rescue Exception
|
39
|
+
add_error($!)
|
40
|
+
ensure
|
41
|
+
begin
|
42
|
+
teardown
|
43
|
+
run_callbacks :teardown, :enumerator => :reverse_each
|
44
|
+
rescue Test::Unit::AssertionFailedError => e
|
45
|
+
add_failure(e.message, e.backtrace)
|
46
|
+
rescue *PASSTHROUGH_EXCEPTIONS
|
47
|
+
raise
|
48
|
+
rescue Exception
|
49
|
+
add_error($!)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
result.add_run
|
53
|
+
yield(Test::Unit::TestCase::FINISHED, name)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Doubly unfortunate: mocha does the same so we have to hax their hax.
|
57
|
+
def run_with_callbacks_and_mocha(result)
|
58
|
+
return if @method_name.to_s == "default_test"
|
59
|
+
|
60
|
+
yield(Test::Unit::TestCase::STARTED, name)
|
61
|
+
@_result = result
|
62
|
+
begin
|
63
|
+
mocha_setup
|
64
|
+
begin
|
65
|
+
run_callbacks :setup
|
66
|
+
setup
|
67
|
+
__send__(@method_name)
|
68
|
+
mocha_verify { add_assertion }
|
69
|
+
rescue Mocha::ExpectationError => e
|
70
|
+
add_failure(e.message, e.backtrace)
|
71
|
+
rescue Test::Unit::AssertionFailedError => e
|
72
|
+
add_failure(e.message, e.backtrace)
|
73
|
+
rescue StandardError, ScriptError
|
74
|
+
add_error($!)
|
75
|
+
ensure
|
76
|
+
begin
|
77
|
+
teardown
|
78
|
+
run_callbacks :teardown, :enumerator => :reverse_each
|
79
|
+
rescue Test::Unit::AssertionFailedError => e
|
80
|
+
add_failure(e.message, e.backtrace)
|
81
|
+
rescue StandardError, ScriptError
|
82
|
+
add_error($!)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
ensure
|
86
|
+
mocha_teardown
|
87
|
+
end
|
88
|
+
result.add_run
|
89
|
+
yield(Test::Unit::TestCase::FINISHED, name)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,283 @@
|
|
1
|
+
require 'tzinfo'
|
2
|
+
module ActiveSupport
|
3
|
+
# A Time-like class that can represent a time in any time zone. Necessary because standard Ruby Time instances are
|
4
|
+
# limited to UTC and the system's <tt>ENV['TZ']</tt> zone.
|
5
|
+
#
|
6
|
+
# You shouldn't ever need to create a TimeWithZone instance directly via <tt>new</tt> -- instead, Rails provides the methods
|
7
|
+
# +local+, +parse+, +at+ and +now+ on TimeZone instances, and +in_time_zone+ on Time and DateTime instances, for a more
|
8
|
+
# user-friendly syntax. Examples:
|
9
|
+
#
|
10
|
+
# Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
|
11
|
+
# Time.zone.local(2007, 2, 10, 15, 30, 45) # => Sat, 10 Feb 2007 15:30:45 EST -05:00
|
12
|
+
# Time.zone.parse('2007-02-01 15:30:45') # => Sat, 10 Feb 2007 15:30:45 EST -05:00
|
13
|
+
# Time.zone.at(1170361845) # => Sat, 10 Feb 2007 15:30:45 EST -05:00
|
14
|
+
# Time.zone.now # => Sun, 18 May 2008 13:07:55 EDT -04:00
|
15
|
+
# Time.utc(2007, 2, 10, 20, 30, 45).in_time_zone # => Sat, 10 Feb 2007 15:30:45 EST -05:00
|
16
|
+
#
|
17
|
+
# See TimeZone and ActiveSupport::CoreExtensions::Time::Zones for further documentation for these methods.
|
18
|
+
#
|
19
|
+
# TimeWithZone instances implement the same API as Ruby Time instances, so that Time and TimeWithZone instances are interchangable. Examples:
|
20
|
+
#
|
21
|
+
# t = Time.zone.now # => Sun, 18 May 2008 13:27:25 EDT -04:00
|
22
|
+
# t.hour # => 13
|
23
|
+
# t.dst? # => true
|
24
|
+
# t.utc_offset # => -14400
|
25
|
+
# t.zone # => "EDT"
|
26
|
+
# t.to_s(:rfc822) # => "Sun, 18 May 2008 13:27:25 -0400"
|
27
|
+
# t + 1.day # => Mon, 19 May 2008 13:27:25 EDT -04:00
|
28
|
+
# t.beginning_of_year # => Tue, 01 Jan 2008 00:00:00 EST -05:00
|
29
|
+
# t > Time.utc(1999) # => true
|
30
|
+
# t.is_a?(Time) # => true
|
31
|
+
# t.is_a?(ActiveSupport::TimeWithZone) # => true
|
32
|
+
class TimeWithZone
|
33
|
+
include Comparable
|
34
|
+
attr_reader :time_zone
|
35
|
+
|
36
|
+
def initialize(utc_time, time_zone, local_time = nil, period = nil)
|
37
|
+
@utc, @time_zone, @time = utc_time, time_zone, local_time
|
38
|
+
@period = @utc ? period : get_period_and_ensure_valid_local_time
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns a Time or DateTime instance that represents the time in +time_zone+.
|
42
|
+
def time
|
43
|
+
@time ||= period.to_local(@utc)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns a Time or DateTime instance that represents the time in UTC.
|
47
|
+
def utc
|
48
|
+
@utc ||= period.to_utc(@time)
|
49
|
+
end
|
50
|
+
alias_method :comparable_time, :utc
|
51
|
+
alias_method :getgm, :utc
|
52
|
+
alias_method :getutc, :utc
|
53
|
+
alias_method :gmtime, :utc
|
54
|
+
|
55
|
+
# Returns the underlying TZInfo::TimezonePeriod.
|
56
|
+
def period
|
57
|
+
@period ||= time_zone.period_for_utc(@utc)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Returns the simultaneous time in <tt>Time.zone</tt>, or the specified zone.
|
61
|
+
def in_time_zone(new_zone = ::Time.zone)
|
62
|
+
return self if time_zone == new_zone
|
63
|
+
utc.in_time_zone(new_zone)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Returns a <tt>Time.local()</tt> instance of the simultaneous time in your system's <tt>ENV['TZ']</tt> zone
|
67
|
+
def localtime
|
68
|
+
utc.getlocal
|
69
|
+
end
|
70
|
+
alias_method :getlocal, :localtime
|
71
|
+
|
72
|
+
def dst?
|
73
|
+
period.dst?
|
74
|
+
end
|
75
|
+
alias_method :isdst, :dst?
|
76
|
+
|
77
|
+
def utc?
|
78
|
+
time_zone.name == 'UTC'
|
79
|
+
end
|
80
|
+
alias_method :gmt?, :utc?
|
81
|
+
|
82
|
+
def utc_offset
|
83
|
+
period.utc_total_offset
|
84
|
+
end
|
85
|
+
alias_method :gmt_offset, :utc_offset
|
86
|
+
alias_method :gmtoff, :utc_offset
|
87
|
+
|
88
|
+
def formatted_offset(colon = true, alternate_utc_string = nil)
|
89
|
+
utc? && alternate_utc_string || utc_offset.to_utc_offset_s(colon)
|
90
|
+
end
|
91
|
+
|
92
|
+
# Time uses +zone+ to display the time zone abbreviation, so we're duck-typing it.
|
93
|
+
def zone
|
94
|
+
period.zone_identifier.to_s
|
95
|
+
end
|
96
|
+
|
97
|
+
def inspect
|
98
|
+
"#{time.strftime('%a, %d %b %Y %H:%M:%S')} #{zone} #{formatted_offset}"
|
99
|
+
end
|
100
|
+
|
101
|
+
def xmlschema
|
102
|
+
"#{time.strftime("%Y-%m-%dT%H:%M:%S")}#{formatted_offset(true, 'Z')}"
|
103
|
+
end
|
104
|
+
alias_method :iso8601, :xmlschema
|
105
|
+
|
106
|
+
def to_json(options = nil)
|
107
|
+
if ActiveSupport.use_standard_json_time_format
|
108
|
+
xmlschema.inspect
|
109
|
+
else
|
110
|
+
%("#{time.strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)}")
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def to_yaml(options = {})
|
115
|
+
if options.kind_of?(YAML::Emitter)
|
116
|
+
utc.to_yaml(options)
|
117
|
+
else
|
118
|
+
time.to_yaml(options).gsub('Z', formatted_offset(true, 'Z'))
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def httpdate
|
123
|
+
utc.httpdate
|
124
|
+
end
|
125
|
+
|
126
|
+
def rfc2822
|
127
|
+
to_s(:rfc822)
|
128
|
+
end
|
129
|
+
alias_method :rfc822, :rfc2822
|
130
|
+
|
131
|
+
# <tt>:db</tt> format outputs time in UTC; all others output time in local.
|
132
|
+
# Uses TimeWithZone's +strftime+, so <tt>%Z</tt> and <tt>%z</tt> work correctly.
|
133
|
+
def to_s(format = :default)
|
134
|
+
return utc.to_s(format) if format == :db
|
135
|
+
if formatter = ::Time::DATE_FORMATS[format]
|
136
|
+
formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
|
137
|
+
else
|
138
|
+
"#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}" # mimicking Ruby 1.9 Time#to_s format
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# Replaces <tt>%Z</tt> and <tt>%z</tt> directives with +zone+ and +formatted_offset+, respectively, before passing to
|
143
|
+
# Time#strftime, so that zone information is correct
|
144
|
+
def strftime(format)
|
145
|
+
format = format.gsub('%Z', zone).gsub('%z', formatted_offset(false))
|
146
|
+
time.strftime(format)
|
147
|
+
end
|
148
|
+
|
149
|
+
# Use the time in UTC for comparisons.
|
150
|
+
def <=>(other)
|
151
|
+
utc <=> other
|
152
|
+
end
|
153
|
+
|
154
|
+
def between?(min, max)
|
155
|
+
utc.between?(min, max)
|
156
|
+
end
|
157
|
+
|
158
|
+
def eql?(other)
|
159
|
+
utc == other
|
160
|
+
end
|
161
|
+
|
162
|
+
# If wrapped +time+ is a DateTime, use DateTime#since instead of <tt>+</tt>.
|
163
|
+
# Otherwise, just pass on to +method_missing+.
|
164
|
+
def +(other)
|
165
|
+
result = utc.acts_like?(:date) ? utc.since(other) : utc + other rescue utc.since(other)
|
166
|
+
result.in_time_zone(time_zone)
|
167
|
+
end
|
168
|
+
|
169
|
+
# If a time-like object is passed in, compare it with +utc+.
|
170
|
+
# Else if wrapped +time+ is a DateTime, use DateTime#ago instead of DateTime#-.
|
171
|
+
# Otherwise, just pass on to +method_missing+.
|
172
|
+
def -(other)
|
173
|
+
if other.acts_like?(:time)
|
174
|
+
utc - other
|
175
|
+
else
|
176
|
+
result = utc.acts_like?(:date) ? utc.ago(other) : utc - other rescue utc.ago(other)
|
177
|
+
result.in_time_zone(time_zone)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def since(other)
|
182
|
+
utc.since(other).in_time_zone(time_zone)
|
183
|
+
end
|
184
|
+
|
185
|
+
def ago(other)
|
186
|
+
utc.ago(other).in_time_zone(time_zone)
|
187
|
+
end
|
188
|
+
|
189
|
+
def advance(options)
|
190
|
+
utc.advance(options).in_time_zone(time_zone)
|
191
|
+
end
|
192
|
+
|
193
|
+
%w(year mon month day mday hour min sec).each do |method_name|
|
194
|
+
class_eval <<-EOV
|
195
|
+
def #{method_name}
|
196
|
+
time.#{method_name}
|
197
|
+
end
|
198
|
+
EOV
|
199
|
+
end
|
200
|
+
|
201
|
+
def usec
|
202
|
+
time.respond_to?(:usec) ? time.usec : 0
|
203
|
+
end
|
204
|
+
|
205
|
+
def to_a
|
206
|
+
[time.sec, time.min, time.hour, time.day, time.mon, time.year, time.wday, time.yday, dst?, zone]
|
207
|
+
end
|
208
|
+
|
209
|
+
def to_f
|
210
|
+
utc.to_f
|
211
|
+
end
|
212
|
+
|
213
|
+
def to_i
|
214
|
+
utc.to_i
|
215
|
+
end
|
216
|
+
alias_method :hash, :to_i
|
217
|
+
alias_method :tv_sec, :to_i
|
218
|
+
|
219
|
+
# A TimeWithZone acts like a Time, so just return +self+.
|
220
|
+
def to_time
|
221
|
+
self
|
222
|
+
end
|
223
|
+
|
224
|
+
def to_datetime
|
225
|
+
utc.to_datetime.new_offset(Rational(utc_offset, 86_400))
|
226
|
+
end
|
227
|
+
|
228
|
+
# So that +self+ <tt>acts_like?(:time)</tt>.
|
229
|
+
def acts_like_time?
|
230
|
+
true
|
231
|
+
end
|
232
|
+
|
233
|
+
# Say we're a Time to thwart type checking.
|
234
|
+
def is_a?(klass)
|
235
|
+
klass == ::Time || super
|
236
|
+
end
|
237
|
+
alias_method :kind_of?, :is_a?
|
238
|
+
|
239
|
+
# Neuter freeze because freezing can cause problems with lazy loading of attributes.
|
240
|
+
def freeze
|
241
|
+
self
|
242
|
+
end
|
243
|
+
|
244
|
+
def marshal_dump
|
245
|
+
[utc, time_zone.name, time]
|
246
|
+
end
|
247
|
+
|
248
|
+
def marshal_load(variables)
|
249
|
+
initialize(variables[0], ::Time.send!(:get_zone, variables[1]), variables[2])
|
250
|
+
end
|
251
|
+
|
252
|
+
# Ensure proxy class responds to all methods that underlying time instance responds to.
|
253
|
+
def respond_to?(sym, include_priv = false)
|
254
|
+
# consistently respond false to acts_like?(:date), regardless of whether #time is a Time or DateTime
|
255
|
+
return false if sym.to_s == 'acts_like_date?'
|
256
|
+
super || time.respond_to?(sym, include_priv)
|
257
|
+
end
|
258
|
+
|
259
|
+
# Send the missing method to +time+ instance, and wrap result in a new TimeWithZone with the existing +time_zone+.
|
260
|
+
def method_missing(sym, *args, &block)
|
261
|
+
result = time.__send__(sym, *args, &block)
|
262
|
+
result.acts_like?(:time) ? self.class.new(nil, time_zone, result) : result
|
263
|
+
end
|
264
|
+
|
265
|
+
private
|
266
|
+
def get_period_and_ensure_valid_local_time
|
267
|
+
# we don't want a Time.local instance enforcing its own DST rules as well,
|
268
|
+
# so transfer time values to a utc constructor if necessary
|
269
|
+
@time = transfer_time_values_to_utc_constructor(@time) unless @time.utc?
|
270
|
+
begin
|
271
|
+
@time_zone.period_for_local(@time)
|
272
|
+
rescue ::TZInfo::PeriodNotFound
|
273
|
+
# time is in the "spring forward" hour gap, so we're moving the time forward one hour and trying again
|
274
|
+
@time += 1.hour
|
275
|
+
retry
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
def transfer_time_values_to_utc_constructor(time)
|
280
|
+
::Time.utc_time(time.year, time.month, time.day, time.hour, time.min, time.sec, time.respond_to?(:usec) ? time.usec : 0)
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|