activesupport 3.0.20 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +24 -28
- data/README.rdoc +2 -2
- data/lib/active_support/backtrace_cleaner.rb +17 -12
- data/lib/active_support/buffered_logger.rb +7 -9
- data/lib/active_support/cache/file_store.rb +4 -3
- data/lib/active_support/cache/mem_cache_store.rb +10 -2
- data/lib/active_support/cache/strategy/local_cache.rb +28 -23
- data/lib/active_support/cache.rb +11 -14
- data/lib/active_support/callbacks.rb +195 -175
- data/lib/active_support/concern.rb +105 -35
- data/lib/active_support/configurable.rb +50 -8
- data/lib/active_support/core_ext/array/access.rb +2 -2
- data/lib/active_support/core_ext/array/conversions.rb +2 -2
- data/lib/active_support/core_ext/array/random_access.rb +10 -7
- data/lib/active_support/core_ext/array/uniq_by.rb +2 -3
- data/lib/active_support/core_ext/array/wrap.rb +1 -1
- data/lib/active_support/core_ext/big_decimal/conversions.rb +0 -2
- data/lib/active_support/core_ext/class/attribute.rb +15 -1
- data/lib/active_support/core_ext/class/inheritable_attributes.rb +10 -86
- data/lib/active_support/core_ext/class/subclasses.rb +20 -34
- data/lib/active_support/core_ext/date/calculations.rb +17 -5
- data/lib/active_support/core_ext/date/conversions.rb +9 -2
- data/lib/active_support/core_ext/date_time/calculations.rb +26 -9
- data/lib/active_support/core_ext/date_time/conversions.rb +9 -9
- data/lib/active_support/core_ext/date_time/zones.rb +1 -1
- data/lib/active_support/core_ext/enumerable.rb +3 -6
- data/lib/active_support/core_ext/float/rounding.rb +1 -1
- data/lib/active_support/core_ext/hash/conversions.rb +22 -34
- data/lib/active_support/core_ext/hash/deep_dup.rb +11 -0
- data/lib/active_support/core_ext/hash/indifferent_access.rb +12 -0
- data/lib/active_support/core_ext/hash/keys.rb +6 -4
- data/lib/active_support/core_ext/hash/reverse_merge.rb +9 -14
- data/lib/active_support/core_ext/hash/slice.rb +3 -1
- data/lib/active_support/core_ext/hash.rb +1 -0
- data/lib/active_support/core_ext/integer/inflections.rb +7 -4
- data/lib/active_support/core_ext/kernel/reporting.rb +31 -0
- data/lib/active_support/core_ext/kernel/requires.rb +2 -0
- data/lib/active_support/core_ext/logger.rb +11 -38
- data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +12 -12
- data/lib/active_support/core_ext/module/attr_internal.rb +13 -6
- data/lib/active_support/core_ext/module/delegation.rb +1 -5
- data/lib/active_support/core_ext/module/remove_method.rb +7 -2
- data/lib/active_support/core_ext/numeric/time.rb +2 -0
- data/lib/active_support/core_ext/object/blank.rb +45 -12
- data/lib/active_support/core_ext/object/duplicable.rb +50 -9
- data/lib/active_support/core_ext/object/inclusion.rb +15 -0
- data/lib/active_support/core_ext/object/instance_variables.rb +1 -35
- data/lib/active_support/core_ext/object/to_param.rb +13 -8
- data/lib/active_support/core_ext/object/to_query.rb +2 -2
- data/lib/active_support/core_ext/object/try.rb +29 -10
- data/lib/active_support/core_ext/object/with_options.rb +25 -8
- data/lib/active_support/core_ext/object.rb +1 -1
- data/lib/active_support/core_ext/range/cover.rb +3 -0
- data/lib/active_support/core_ext/range.rb +1 -0
- data/lib/active_support/core_ext/string/behavior.rb +1 -2
- data/lib/active_support/core_ext/string/conversions.rb +1 -0
- data/lib/active_support/core_ext/string/exclude.rb +1 -1
- data/lib/active_support/core_ext/string/filters.rb +3 -3
- data/lib/active_support/core_ext/string/inflections.rb +1 -1
- data/lib/active_support/core_ext/string/inquiry.rb +13 -0
- data/lib/active_support/core_ext/string/multibyte.rb +2 -2
- data/lib/active_support/core_ext/string/output_safety.rb +45 -62
- data/lib/active_support/core_ext/string.rb +1 -0
- data/lib/active_support/core_ext/time/calculations.rb +19 -16
- data/lib/active_support/core_ext/time/conversions.rb +2 -24
- data/lib/active_support/core_ext/time/zones.rb +32 -21
- data/lib/active_support/core_ext/uri.rb +8 -0
- data/lib/active_support/dependencies.rb +74 -28
- data/lib/active_support/deprecation/behaviors.rb +7 -0
- data/lib/active_support/deprecation/proxy_wrappers.rb +1 -1
- data/lib/active_support/deprecation/reporting.rb +4 -0
- data/lib/active_support/deprecation.rb +2 -2
- data/lib/active_support/descendants_tracker.rb +9 -7
- data/lib/active_support/duration.rb +5 -0
- data/lib/active_support/file_update_checker.rb +1 -1
- data/lib/active_support/file_watcher.rb +36 -0
- data/lib/active_support/hash_with_indifferent_access.rb +20 -8
- data/lib/active_support/i18n.rb +0 -1
- data/lib/active_support/i18n_railtie.rb +2 -2
- data/lib/active_support/inflections.rb +1 -0
- data/lib/active_support/inflector/inflections.rb +1 -1
- data/lib/active_support/inflector/methods.rb +5 -3
- data/lib/active_support/json/decoding.rb +37 -23
- data/lib/active_support/json/encoding.rb +12 -4
- data/lib/active_support/lazy_load_hooks.rb +7 -7
- data/lib/active_support/log_subscriber/test_helper.rb +5 -3
- data/lib/active_support/log_subscriber.rb +6 -6
- data/lib/active_support/message_encryptor.rb +1 -1
- data/lib/active_support/message_verifier.rb +1 -1
- data/lib/active_support/multibyte/chars.rb +5 -5
- data/lib/active_support/multibyte/unicode.rb +2 -1
- data/lib/active_support/notifications/fanout.rb +3 -3
- data/lib/active_support/notifications/instrumenter.rb +1 -1
- data/lib/active_support/notifications.rb +9 -10
- data/lib/active_support/ordered_hash.rb +23 -2
- data/lib/active_support/ordered_options.rb +37 -3
- data/lib/active_support/railtie.rb +1 -1
- data/lib/active_support/rescuable.rb +1 -0
- data/lib/active_support/secure_random.rb +3 -196
- data/lib/active_support/test_case.rb +2 -10
- data/lib/active_support/testing/assertions.rb +20 -7
- data/lib/active_support/testing/mochaing.rb +7 -0
- data/lib/active_support/testing/pending.rb +27 -23
- data/lib/active_support/testing/performance/jruby.rb +115 -0
- data/lib/active_support/testing/performance/rubinius.rb +113 -0
- data/lib/active_support/testing/performance/ruby/mri.rb +57 -0
- data/lib/active_support/testing/performance/ruby/yarv.rb +57 -0
- data/lib/active_support/testing/performance/ruby.rb +152 -0
- data/lib/active_support/testing/performance.rb +214 -322
- data/lib/active_support/testing/setup_and_teardown.rb +8 -11
- data/lib/active_support/time_with_zone.rb +6 -3
- data/lib/active_support/values/time_zone.rb +26 -8
- data/lib/active_support/version.rb +2 -2
- data/lib/active_support/whiny_nil.rb +1 -1
- data/lib/active_support/xml_mini/jdom.rb +1 -1
- data/lib/active_support/xml_mini/libxml.rb +1 -0
- data/lib/active_support/xml_mini/libxmlsax.rb +2 -1
- data/lib/active_support/xml_mini/nokogiri.rb +1 -0
- data/lib/active_support/xml_mini/nokogirisax.rb +1 -0
- data/lib/active_support/xml_mini/rexml.rb +1 -0
- data/lib/active_support/xml_mini.rb +8 -3
- data/lib/active_support.rb +4 -2
- metadata +70 -32
- checksums.yaml +0 -7
- data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +0 -19
- data/lib/active_support/core_ext/cgi.rb +0 -1
- data/lib/active_support/core_ext/object/returning.rb +0 -43
- data/lib/active_support/json/backends/jsongem.rb +0 -47
- data/lib/active_support/json/backends/okjson.rb +0 -644
- data/lib/active_support/json/backends/yajl.rb +0 -44
- data/lib/active_support/json/backends/yaml.rb +0 -19
- data/lib/active_support/testing/default.rb +0 -9
|
@@ -3,38 +3,28 @@ require 'active_support/core_ext/kernel/singleton_class'
|
|
|
3
3
|
|
|
4
4
|
class ERB
|
|
5
5
|
module Util
|
|
6
|
-
HTML_ESCAPE = { '&' => '&', '>' => '>', '<' => '<', '"' => '"'
|
|
6
|
+
HTML_ESCAPE = { '&' => '&', '>' => '>', '<' => '<', '"' => '"' }
|
|
7
7
|
JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003E', '<' => '\u003C' }
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
s.gsub(/[&"'><]/, HTML_ESCAPE).html_safe
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
else
|
|
28
|
-
def html_escape(s) #:nodoc:
|
|
29
|
-
s = s.to_s
|
|
30
|
-
if s.html_safe?
|
|
31
|
-
s
|
|
32
|
-
else
|
|
33
|
-
s.gsub(/[&"'><]/n) { |special| HTML_ESCAPE[special] }.html_safe
|
|
34
|
-
end
|
|
9
|
+
# A utility method for escaping HTML tag characters.
|
|
10
|
+
# This method is also aliased as <tt>h</tt>.
|
|
11
|
+
#
|
|
12
|
+
# In your ERB templates, use this method to escape any unsafe content. For example:
|
|
13
|
+
# <%=h @person.name %>
|
|
14
|
+
#
|
|
15
|
+
# ==== Example:
|
|
16
|
+
# puts html_escape("is a > 0 & a < 10?")
|
|
17
|
+
# # => is a > 0 & a < 10?
|
|
18
|
+
def html_escape(s)
|
|
19
|
+
s = s.to_s
|
|
20
|
+
if s.html_safe?
|
|
21
|
+
s
|
|
22
|
+
else
|
|
23
|
+
s.to_s.gsub(/&/, "&").gsub(/\"/, """).gsub(/>/, ">").gsub(/</, "<").html_safe
|
|
35
24
|
end
|
|
36
25
|
end
|
|
37
26
|
|
|
27
|
+
# Aliasing twice issues a warning "discarding old...". Remove first to avoid it.
|
|
38
28
|
remove_method(:h)
|
|
39
29
|
alias h html_escape
|
|
40
30
|
|
|
@@ -77,7 +67,7 @@ class Object
|
|
|
77
67
|
end
|
|
78
68
|
end
|
|
79
69
|
|
|
80
|
-
class
|
|
70
|
+
class Numeric
|
|
81
71
|
def html_safe?
|
|
82
72
|
true
|
|
83
73
|
end
|
|
@@ -85,7 +75,7 @@ end
|
|
|
85
75
|
|
|
86
76
|
module ActiveSupport #:nodoc:
|
|
87
77
|
class SafeBuffer < String
|
|
88
|
-
UNSAFE_STRING_METHODS = ["capitalize", "chomp", "chop", "delete", "downcase", "gsub", "lstrip", "next", "reverse", "rstrip", "slice", "squeeze", "strip", "sub", "succ", "swapcase", "tr", "tr_s", "upcase"
|
|
78
|
+
UNSAFE_STRING_METHODS = ["capitalize", "chomp", "chop", "delete", "downcase", "gsub", "lstrip", "next", "reverse", "rstrip", "slice", "squeeze", "strip", "sub", "succ", "swapcase", "tr", "tr_s", "upcase"].freeze
|
|
89
79
|
|
|
90
80
|
alias_method :original_concat, :concat
|
|
91
81
|
private :original_concat
|
|
@@ -96,39 +86,23 @@ module ActiveSupport #:nodoc:
|
|
|
96
86
|
end
|
|
97
87
|
end
|
|
98
88
|
|
|
99
|
-
def [](*args)
|
|
100
|
-
return super if args.size < 2
|
|
101
|
-
|
|
102
|
-
if html_safe?
|
|
103
|
-
new_safe_buffer = super
|
|
104
|
-
new_safe_buffer.instance_eval { @html_safe = true }
|
|
105
|
-
new_safe_buffer
|
|
106
|
-
else
|
|
107
|
-
to_str[*args]
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
|
|
111
89
|
def safe_concat(value)
|
|
112
|
-
raise SafeConcatError
|
|
90
|
+
raise SafeConcatError if dirty?
|
|
113
91
|
original_concat(value)
|
|
114
92
|
end
|
|
115
93
|
|
|
116
94
|
def initialize(*)
|
|
117
|
-
@
|
|
95
|
+
@dirty = false
|
|
118
96
|
super
|
|
119
97
|
end
|
|
120
98
|
|
|
121
99
|
def initialize_copy(other)
|
|
122
100
|
super
|
|
123
|
-
@
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
def clone_empty
|
|
127
|
-
self[0, 0]
|
|
101
|
+
@dirty = other.dirty?
|
|
128
102
|
end
|
|
129
103
|
|
|
130
104
|
def concat(value)
|
|
131
|
-
if
|
|
105
|
+
if dirty? || value.html_safe?
|
|
132
106
|
super(value)
|
|
133
107
|
else
|
|
134
108
|
super(ERB::Util.h(value))
|
|
@@ -141,7 +115,7 @@ module ActiveSupport #:nodoc:
|
|
|
141
115
|
end
|
|
142
116
|
|
|
143
117
|
def html_safe?
|
|
144
|
-
|
|
118
|
+
!dirty?
|
|
145
119
|
end
|
|
146
120
|
|
|
147
121
|
def to_s
|
|
@@ -152,23 +126,32 @@ module ActiveSupport #:nodoc:
|
|
|
152
126
|
to_str
|
|
153
127
|
end
|
|
154
128
|
|
|
129
|
+
def encode_with(coder)
|
|
130
|
+
coder.represent_scalar nil, to_str
|
|
131
|
+
end
|
|
132
|
+
|
|
155
133
|
def to_yaml(*args)
|
|
134
|
+
return super() if defined?(YAML::ENGINE) && !YAML::ENGINE.syck?
|
|
156
135
|
to_str.to_yaml(*args)
|
|
157
136
|
end
|
|
158
137
|
|
|
159
138
|
for unsafe_method in UNSAFE_STRING_METHODS
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
139
|
+
class_eval <<-EOT, __FILE__, __LINE__
|
|
140
|
+
def #{unsafe_method}(*args)
|
|
141
|
+
super.to_str
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def #{unsafe_method}!(*args)
|
|
145
|
+
@dirty = true
|
|
146
|
+
super
|
|
147
|
+
end
|
|
148
|
+
EOT
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
protected
|
|
152
|
+
|
|
153
|
+
def dirty?
|
|
154
|
+
@dirty
|
|
172
155
|
end
|
|
173
156
|
end
|
|
174
157
|
end
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
require 'active_support/duration'
|
|
2
|
-
require 'active_support/core_ext/
|
|
3
|
-
require 'active_support/core_ext/
|
|
4
|
-
require 'active_support/core_ext/date_time/conversions'
|
|
2
|
+
require 'active_support/core_ext/time/zones'
|
|
3
|
+
require 'active_support/core_ext/time/conversions'
|
|
5
4
|
|
|
6
5
|
class Time
|
|
7
6
|
COMMON_YEAR_DAYS_IN_MONTH = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
|
@@ -10,7 +9,7 @@ class Time
|
|
|
10
9
|
class << self
|
|
11
10
|
# Overriding case equality method so that it returns true for ActiveSupport::TimeWithZone instances
|
|
12
11
|
def ===(other)
|
|
13
|
-
|
|
12
|
+
other.is_a?(::Time)
|
|
14
13
|
end
|
|
15
14
|
|
|
16
15
|
# Return the number of days in the given month.
|
|
@@ -22,7 +21,7 @@ class Time
|
|
|
22
21
|
|
|
23
22
|
# Returns a new Time if requested year can be accommodated by Ruby's Time class
|
|
24
23
|
# (i.e., if year is within either 1970..2038 or 1902..2038, depending on system architecture);
|
|
25
|
-
# otherwise returns a DateTime
|
|
24
|
+
# otherwise returns a DateTime.
|
|
26
25
|
def time_with_datetime_fallback(utc_or_local, year, month=1, day=1, hour=0, min=0, sec=0, usec=0)
|
|
27
26
|
time = ::Time.send(utc_or_local, year, month, day, hour, min, sec, usec)
|
|
28
27
|
# This check is needed because Time.utc(y) returns a time object in the 2000s for 0 <= y <= 138.
|
|
@@ -117,6 +116,11 @@ class Time
|
|
|
117
116
|
end
|
|
118
117
|
alias :in :since
|
|
119
118
|
|
|
119
|
+
# Returns a new Time representing the time a number of specified weeks ago.
|
|
120
|
+
def weeks_ago(weeks)
|
|
121
|
+
advance(:weeks => -weeks)
|
|
122
|
+
end
|
|
123
|
+
|
|
120
124
|
# Returns a new Time representing the time a number of specified months ago
|
|
121
125
|
def months_ago(months)
|
|
122
126
|
advance(:months => -months)
|
|
@@ -172,6 +176,11 @@ class Time
|
|
|
172
176
|
end
|
|
173
177
|
alias :at_end_of_week :end_of_week
|
|
174
178
|
|
|
179
|
+
# Returns a new Time representing the start of the given day in the previous week (default is Monday).
|
|
180
|
+
def prev_week(day = :monday)
|
|
181
|
+
ago(1.week).beginning_of_week.since(DAYS_INTO_WEEK[day].day).change(:hour => 0)
|
|
182
|
+
end
|
|
183
|
+
|
|
175
184
|
# Returns a new Time representing the start of the given day in next week (default is Monday).
|
|
176
185
|
def next_week(day = :monday)
|
|
177
186
|
since(1.week).beginning_of_week.since(DAYS_INTO_WEEK[day].day).change(:hour => 0)
|
|
@@ -180,7 +189,7 @@ class Time
|
|
|
180
189
|
# Returns a new Time representing the start of the day (0:00)
|
|
181
190
|
def beginning_of_day
|
|
182
191
|
#(self - seconds_since_midnight).change(:usec => 0)
|
|
183
|
-
change(:hour => 0
|
|
192
|
+
change(:hour => 0)
|
|
184
193
|
end
|
|
185
194
|
alias :midnight :beginning_of_day
|
|
186
195
|
alias :at_midnight :beginning_of_day
|
|
@@ -194,7 +203,7 @@ class Time
|
|
|
194
203
|
# Returns a new Time representing the start of the month (1st of the month, 0:00)
|
|
195
204
|
def beginning_of_month
|
|
196
205
|
#self - ((self.mday-1).days + self.seconds_since_midnight)
|
|
197
|
-
change(:day => 1
|
|
206
|
+
change(:day => 1, :hour => 0)
|
|
198
207
|
end
|
|
199
208
|
alias :at_beginning_of_month :beginning_of_month
|
|
200
209
|
|
|
@@ -220,7 +229,7 @@ class Time
|
|
|
220
229
|
|
|
221
230
|
# Returns a new Time representing the start of the year (1st of january, 0:00)
|
|
222
231
|
def beginning_of_year
|
|
223
|
-
change(:month => 1, :day => 1, :hour => 0
|
|
232
|
+
change(:month => 1, :day => 1, :hour => 0)
|
|
224
233
|
end
|
|
225
234
|
alias :at_beginning_of_year :beginning_of_year
|
|
226
235
|
|
|
@@ -273,14 +282,8 @@ class Time
|
|
|
273
282
|
# Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
|
|
274
283
|
# can be chronologically compared with a Time
|
|
275
284
|
def compare_with_coercion(other)
|
|
276
|
-
#
|
|
277
|
-
other
|
|
278
|
-
if other.acts_like?(:date)
|
|
279
|
-
# other is a Date/DateTime, so coerce self #to_datetime and hand off to DateTime#<=>
|
|
280
|
-
to_datetime.compare_without_coercion(other)
|
|
281
|
-
else
|
|
282
|
-
compare_without_coercion(other)
|
|
283
|
-
end
|
|
285
|
+
# we're avoiding Time#to_datetime cause it's expensive
|
|
286
|
+
other.is_a?(Time) ? compare_without_coercion(other.to_time) : to_datetime <=> other
|
|
284
287
|
end
|
|
285
288
|
alias_method :compare_without_coercion, :<=>
|
|
286
289
|
alias_method :<=>, :compare_with_coercion
|
|
@@ -19,8 +19,8 @@ class Time
|
|
|
19
19
|
#
|
|
20
20
|
# time = Time.now # => Thu Jan 18 06:10:17 CST 2007
|
|
21
21
|
#
|
|
22
|
-
# time.to_formatted_s(:time) # => "06:10
|
|
23
|
-
# time.to_s(:time) # => "06:10
|
|
22
|
+
# time.to_formatted_s(:time) # => "06:10"
|
|
23
|
+
# time.to_s(:time) # => "06:10"
|
|
24
24
|
#
|
|
25
25
|
# time.to_formatted_s(:db) # => "2007-01-18 06:10:17"
|
|
26
26
|
# time.to_formatted_s(:number) # => "20070118061017"
|
|
@@ -55,31 +55,9 @@ class Time
|
|
|
55
55
|
utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon)
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
-
# Converts a Time object to a Date, dropping hour, minute, and second precision.
|
|
59
|
-
#
|
|
60
|
-
# my_time = Time.now # => Mon Nov 12 22:59:51 -0500 2007
|
|
61
|
-
# my_time.to_date # => Mon, 12 Nov 2007
|
|
62
|
-
#
|
|
63
|
-
# your_time = Time.parse("1/13/2009 1:13:03 P.M.") # => Tue Jan 13 13:13:03 -0500 2009
|
|
64
|
-
# your_time.to_date # => Tue, 13 Jan 2009
|
|
65
|
-
def to_date
|
|
66
|
-
::Date.new(year, month, day)
|
|
67
|
-
end unless method_defined?(:to_date)
|
|
68
|
-
|
|
69
58
|
# A method to keep Time, Date and DateTime instances interchangeable on conversions.
|
|
70
59
|
# In this case, it simply returns +self+.
|
|
71
60
|
def to_time
|
|
72
61
|
self
|
|
73
62
|
end unless method_defined?(:to_time)
|
|
74
|
-
|
|
75
|
-
# Converts a Time instance to a Ruby DateTime instance, preserving UTC offset.
|
|
76
|
-
#
|
|
77
|
-
# my_time = Time.now # => Mon Nov 12 23:04:21 -0500 2007
|
|
78
|
-
# my_time.to_datetime # => Mon, 12 Nov 2007 23:04:21 -0500
|
|
79
|
-
#
|
|
80
|
-
# your_time = Time.parse("1/13/2009 1:13:03 P.M.") # => Tue Jan 13 13:13:03 -0500 2009
|
|
81
|
-
# your_time.to_datetime # => Tue, 13 Jan 2009 13:13:03 -0500
|
|
82
|
-
def to_datetime
|
|
83
|
-
::DateTime.civil(year, month, day, hour, min, sec, Rational(utc_offset, 86400))
|
|
84
|
-
end unless method_defined?(:to_datetime)
|
|
85
63
|
end
|
|
@@ -19,40 +19,51 @@ class Time
|
|
|
19
19
|
# * A TZInfo::Timezone object.
|
|
20
20
|
# * An identifier for a TZInfo::Timezone object (e.g., "America/New_York").
|
|
21
21
|
#
|
|
22
|
-
# Here's an example of how you might set <tt>Time.zone</tt> on a per request basis
|
|
23
|
-
# just needs to return a string identifying the user's preferred
|
|
22
|
+
# Here's an example of how you might set <tt>Time.zone</tt> on a per request basis and reset it when the request is done.
|
|
23
|
+
# <tt>current_user.time_zone</tt> just needs to return a string identifying the user's preferred time zone:
|
|
24
24
|
#
|
|
25
25
|
# class ApplicationController < ActionController::Base
|
|
26
|
-
#
|
|
26
|
+
# around_filter :set_time_zone
|
|
27
27
|
#
|
|
28
28
|
# def set_time_zone
|
|
29
|
-
#
|
|
29
|
+
# old_time_zone = Time.zone
|
|
30
|
+
# Time.zone = current_user.time_zone if logged_in?
|
|
31
|
+
# yield
|
|
32
|
+
# ensure
|
|
33
|
+
# Time.zone = old_time_zone
|
|
30
34
|
# end
|
|
31
35
|
# end
|
|
32
36
|
def zone=(time_zone)
|
|
33
|
-
Thread.current[:time_zone] =
|
|
37
|
+
Thread.current[:time_zone] = find_zone!(time_zone)
|
|
34
38
|
end
|
|
35
39
|
|
|
36
40
|
# Allows override of <tt>Time.zone</tt> locally inside supplied block; resets <tt>Time.zone</tt> to existing value when done.
|
|
37
41
|
def use_zone(time_zone)
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
+
new_zone = find_zone!(time_zone)
|
|
43
|
+
begin
|
|
44
|
+
old_zone, ::Time.zone = ::Time.zone, new_zone
|
|
45
|
+
yield
|
|
46
|
+
ensure
|
|
47
|
+
::Time.zone = old_zone
|
|
48
|
+
end
|
|
42
49
|
end
|
|
43
50
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
end
|
|
51
|
-
# Return if a TimeZone instance, or wrap in a TimeZone instance if a TZInfo::Timezone
|
|
52
|
-
if time_zone
|
|
53
|
-
time_zone.is_a?(ActiveSupport::TimeZone) ? time_zone : ActiveSupport::TimeZone.create(time_zone.name, nil, time_zone)
|
|
54
|
-
end
|
|
51
|
+
# Returns a TimeZone instance or nil, or raises an ArgumentError for invalid timezones.
|
|
52
|
+
def find_zone!(time_zone)
|
|
53
|
+
return time_zone if time_zone.nil? || time_zone.is_a?(ActiveSupport::TimeZone)
|
|
54
|
+
# lookup timezone based on identifier (unless we've been passed a TZInfo::Timezone)
|
|
55
|
+
unless time_zone.respond_to?(:period_for_local)
|
|
56
|
+
time_zone = ActiveSupport::TimeZone[time_zone] || TZInfo::Timezone.get(time_zone)
|
|
55
57
|
end
|
|
58
|
+
# Return if a TimeZone instance, or wrap in a TimeZone instance if a TZInfo::Timezone
|
|
59
|
+
time_zone.is_a?(ActiveSupport::TimeZone) ? time_zone : ActiveSupport::TimeZone.create(time_zone.name, nil, time_zone)
|
|
60
|
+
rescue TZInfo::InvalidTimezoneIdentifier
|
|
61
|
+
raise ArgumentError, "Invalid Timezone: #{time_zone}"
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def find_zone(time_zone)
|
|
65
|
+
find_zone!(time_zone) rescue nil
|
|
66
|
+
end
|
|
56
67
|
end
|
|
57
68
|
|
|
58
69
|
# Returns the simultaneous time in <tt>Time.zone</tt>.
|
|
@@ -70,6 +81,6 @@ class Time
|
|
|
70
81
|
def in_time_zone(zone = ::Time.zone)
|
|
71
82
|
return self unless zone
|
|
72
83
|
|
|
73
|
-
ActiveSupport::TimeWithZone.new(utc? ? self : getutc, ::Time.
|
|
84
|
+
ActiveSupport::TimeWithZone.new(utc? ? self : getutc, ::Time.find_zone!(zone))
|
|
74
85
|
end
|
|
75
86
|
end
|
|
@@ -5,6 +5,7 @@ require 'active_support/core_ext/module/aliasing'
|
|
|
5
5
|
require 'active_support/core_ext/module/attribute_accessors'
|
|
6
6
|
require 'active_support/core_ext/module/introspection'
|
|
7
7
|
require 'active_support/core_ext/module/anonymous'
|
|
8
|
+
require 'active_support/core_ext/module/deprecation'
|
|
8
9
|
require 'active_support/core_ext/object/blank'
|
|
9
10
|
require 'active_support/core_ext/load_error'
|
|
10
11
|
require 'active_support/core_ext/name_error'
|
|
@@ -47,9 +48,6 @@ module ActiveSupport #:nodoc:
|
|
|
47
48
|
mattr_accessor :autoloaded_constants
|
|
48
49
|
self.autoloaded_constants = []
|
|
49
50
|
|
|
50
|
-
mattr_accessor :references
|
|
51
|
-
self.references = {}
|
|
52
|
-
|
|
53
51
|
# An array of constant names that need to be unloaded on every request. Used
|
|
54
52
|
# to allow arbitrary constants to be marked for unloading.
|
|
55
53
|
mattr_accessor :explicitly_unloadable_constants
|
|
@@ -64,8 +62,8 @@ module ActiveSupport #:nodoc:
|
|
|
64
62
|
self.log_activity = false
|
|
65
63
|
|
|
66
64
|
# The WatchStack keeps a stack of the modules being watched as files are loaded.
|
|
67
|
-
# If a file in the process of being loaded (parent.rb) triggers the load of
|
|
68
|
-
# another file (child.rb) the stack will ensure that child.rb handles the new
|
|
65
|
+
# If a file in the process of being loaded (parent.rb) triggers the load of
|
|
66
|
+
# another file (child.rb) the stack will ensure that child.rb handles the new
|
|
69
67
|
# constants.
|
|
70
68
|
#
|
|
71
69
|
# If child.rb is being autoloaded, its constants will be added to
|
|
@@ -83,13 +81,13 @@ module ActiveSupport #:nodoc:
|
|
|
83
81
|
super { |h,k| h[k] = [] }
|
|
84
82
|
end
|
|
85
83
|
|
|
86
|
-
# return a list of new constants found since the last call to
|
|
84
|
+
# return a list of new constants found since the last call to watch_namespaces
|
|
87
85
|
def new_constants
|
|
88
86
|
constants = []
|
|
89
87
|
|
|
90
88
|
# Grab the list of namespaces that we're looking for new constants under
|
|
91
89
|
@watching.last.each do |namespace|
|
|
92
|
-
# Retrieve the constants that were present under the namespace when
|
|
90
|
+
# Retrieve the constants that were present under the namespace when watch_namespaces
|
|
93
91
|
# was originally called
|
|
94
92
|
original_constants = self[namespace].last
|
|
95
93
|
|
|
@@ -115,7 +113,7 @@ module ActiveSupport #:nodoc:
|
|
|
115
113
|
end
|
|
116
114
|
constants
|
|
117
115
|
ensure
|
|
118
|
-
# A call to new_constants is always called after a call to
|
|
116
|
+
# A call to new_constants is always called after a call to watch_namespaces
|
|
119
117
|
pop_modules(@watching.pop)
|
|
120
118
|
end
|
|
121
119
|
|
|
@@ -166,7 +164,7 @@ module ActiveSupport #:nodoc:
|
|
|
166
164
|
def const_missing(const_name, nesting = nil)
|
|
167
165
|
klass_name = name.presence || "Object"
|
|
168
166
|
|
|
169
|
-
|
|
167
|
+
unless nesting
|
|
170
168
|
# We'll assume that the nesting of Foo::Bar is ["Foo::Bar", "Foo"]
|
|
171
169
|
# even though it might not be, such as in the case of
|
|
172
170
|
# class Foo::Bar; Baz; end
|
|
@@ -480,7 +478,7 @@ module ActiveSupport #:nodoc:
|
|
|
480
478
|
raise ArgumentError, "A copy of #{from_mod} has been removed from the module tree but is still active!"
|
|
481
479
|
end
|
|
482
480
|
|
|
483
|
-
raise
|
|
481
|
+
raise NameError, "#{from_mod} is not missing constant #{const_name}!" if local_const_defined?(from_mod, const_name)
|
|
484
482
|
|
|
485
483
|
qualified_name = qualified_name_for from_mod, const_name
|
|
486
484
|
path_suffix = qualified_name.underscore
|
|
@@ -516,7 +514,7 @@ module ActiveSupport #:nodoc:
|
|
|
516
514
|
# to its class/module if it implements +before_remove_const+.
|
|
517
515
|
#
|
|
518
516
|
# The callback implementation should be restricted to cleaning up caches, etc.
|
|
519
|
-
# as the
|
|
517
|
+
# as the environment will be in an inconsistent state, e.g. other constants
|
|
520
518
|
# may have already been unloaded and not accessible.
|
|
521
519
|
def remove_unloadable_constants!
|
|
522
520
|
autoloaded_constants.each { |const| remove_constant const }
|
|
@@ -525,31 +523,76 @@ module ActiveSupport #:nodoc:
|
|
|
525
523
|
explicitly_unloadable_constants.each { |const| remove_constant const }
|
|
526
524
|
end
|
|
527
525
|
|
|
528
|
-
class
|
|
529
|
-
|
|
526
|
+
class ClassCache
|
|
527
|
+
def initialize
|
|
528
|
+
@store = Hash.new { |h, k| h[k] = Inflector.constantize(k) }
|
|
529
|
+
end
|
|
530
530
|
|
|
531
|
-
|
|
531
|
+
def empty?
|
|
532
|
+
@store.empty?
|
|
533
|
+
end
|
|
532
534
|
|
|
533
|
-
def
|
|
534
|
-
@
|
|
535
|
-
@@constants[@name] = name if name.respond_to?(:name)
|
|
535
|
+
def key?(key)
|
|
536
|
+
@store.key?(key)
|
|
536
537
|
end
|
|
537
538
|
|
|
538
|
-
def
|
|
539
|
-
|
|
539
|
+
def []=(key, value)
|
|
540
|
+
return unless key.respond_to?(:name)
|
|
541
|
+
|
|
542
|
+
raise(ArgumentError, 'anonymous classes cannot be cached') if key.name.blank?
|
|
543
|
+
|
|
544
|
+
@store[key.name] = value
|
|
540
545
|
end
|
|
541
546
|
|
|
542
|
-
def
|
|
543
|
-
|
|
547
|
+
def [](key)
|
|
548
|
+
key = key.name if key.respond_to?(:name)
|
|
549
|
+
|
|
550
|
+
@store[key]
|
|
551
|
+
end
|
|
552
|
+
alias :get :[]
|
|
553
|
+
|
|
554
|
+
class Getter # :nodoc:
|
|
555
|
+
def initialize(name)
|
|
556
|
+
@name = name
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
def get
|
|
560
|
+
Reference.get @name
|
|
561
|
+
end
|
|
562
|
+
deprecate :get
|
|
563
|
+
end
|
|
564
|
+
|
|
565
|
+
def new(name)
|
|
566
|
+
self[name] = name
|
|
567
|
+
Getter.new(name)
|
|
568
|
+
end
|
|
569
|
+
deprecate :new
|
|
570
|
+
|
|
571
|
+
def store(name)
|
|
572
|
+
self[name] = name
|
|
573
|
+
self
|
|
574
|
+
end
|
|
575
|
+
|
|
576
|
+
def clear!
|
|
577
|
+
@store.clear
|
|
544
578
|
end
|
|
545
579
|
end
|
|
546
580
|
|
|
581
|
+
Reference = ClassCache.new
|
|
582
|
+
|
|
547
583
|
def ref(name)
|
|
548
|
-
|
|
584
|
+
Reference.new(name)
|
|
585
|
+
end
|
|
586
|
+
deprecate :ref
|
|
587
|
+
|
|
588
|
+
# Store a reference to a class +klass+.
|
|
589
|
+
def reference(klass)
|
|
590
|
+
Reference.store klass
|
|
549
591
|
end
|
|
550
592
|
|
|
593
|
+
# Get the reference for class named +name+.
|
|
551
594
|
def constantize(name)
|
|
552
|
-
|
|
595
|
+
Reference.get(name)
|
|
553
596
|
end
|
|
554
597
|
|
|
555
598
|
# Determine if the given constant has been automatically loaded.
|
|
@@ -631,7 +674,8 @@ module ActiveSupport #:nodoc:
|
|
|
631
674
|
parent = Inflector.constantize(names * '::')
|
|
632
675
|
|
|
633
676
|
log "removing constant #{const}"
|
|
634
|
-
|
|
677
|
+
constantized = constantize(const)
|
|
678
|
+
constantized.before_remove_const if constantized.respond_to?(:before_remove_const)
|
|
635
679
|
parent.instance_eval { remove_const to_remove }
|
|
636
680
|
|
|
637
681
|
return true
|
|
@@ -639,7 +683,7 @@ module ActiveSupport #:nodoc:
|
|
|
639
683
|
|
|
640
684
|
protected
|
|
641
685
|
def log_call(*args)
|
|
642
|
-
if
|
|
686
|
+
if log_activity?
|
|
643
687
|
arg_str = args.collect { |arg| arg.inspect } * ', '
|
|
644
688
|
/in `([a-z_\?\!]+)'/ =~ caller(1).first
|
|
645
689
|
selector = $1 || '<unknown>'
|
|
@@ -648,9 +692,11 @@ module ActiveSupport #:nodoc:
|
|
|
648
692
|
end
|
|
649
693
|
|
|
650
694
|
def log(msg)
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
695
|
+
logger.debug "Dependencies: #{msg}" if log_activity?
|
|
696
|
+
end
|
|
697
|
+
|
|
698
|
+
def log_activity?
|
|
699
|
+
logger && log_activity
|
|
654
700
|
end
|
|
655
701
|
end
|
|
656
702
|
end
|
|
@@ -7,10 +7,17 @@ module ActiveSupport
|
|
|
7
7
|
# Whether to print a backtrace along with the warning.
|
|
8
8
|
attr_accessor :debug
|
|
9
9
|
|
|
10
|
+
# Returns the set behavior or if one isn't set, defaults to +:stderr+
|
|
10
11
|
def behavior
|
|
11
12
|
@behavior ||= [DEFAULT_BEHAVIORS[:stderr]]
|
|
12
13
|
end
|
|
13
14
|
|
|
15
|
+
# Sets the behavior to the specified value. Can be a single value or an array.
|
|
16
|
+
#
|
|
17
|
+
# Examples
|
|
18
|
+
#
|
|
19
|
+
# ActiveSupport::Deprecation.behavior = :stderr
|
|
20
|
+
# ActiveSupport::Deprecation.behavior = [:stderr, :log]
|
|
14
21
|
def behavior=(behavior)
|
|
15
22
|
@behavior = Array.wrap(behavior).map { |b| DEFAULT_BEHAVIORS[b] || b }
|
|
16
23
|
end
|
|
@@ -3,6 +3,10 @@ module ActiveSupport
|
|
|
3
3
|
class << self
|
|
4
4
|
attr_accessor :silenced
|
|
5
5
|
|
|
6
|
+
# Outputs a deprecation warning to the output configured by <tt>ActiveSupport::Deprecation.behavior</tt>
|
|
7
|
+
#
|
|
8
|
+
# ActiveSupport::Deprecation.warn("something broke!")
|
|
9
|
+
# # => "DEPRECATION WARNING: something broke! (called from your_code.rb:1)"
|
|
6
10
|
def warn(message = nil, callstack = caller)
|
|
7
11
|
return if silenced
|
|
8
12
|
deprecation_message(callstack, message).tap do |m|
|
|
@@ -4,12 +4,12 @@ require 'active_support/deprecation/method_wrappers'
|
|
|
4
4
|
require 'active_support/deprecation/proxy_wrappers'
|
|
5
5
|
|
|
6
6
|
module ActiveSupport
|
|
7
|
-
module Deprecation
|
|
7
|
+
module Deprecation
|
|
8
8
|
class << self
|
|
9
9
|
# The version the deprecated behavior will be removed, by default.
|
|
10
10
|
attr_accessor :deprecation_horizon
|
|
11
11
|
end
|
|
12
|
-
self.deprecation_horizon = '3.
|
|
12
|
+
self.deprecation_horizon = '3.2'
|
|
13
13
|
|
|
14
14
|
# By default, warnings are not silenced and debugging is off.
|
|
15
15
|
self.silenced = false
|