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.
Files changed (132) hide show
  1. data/CHANGELOG +24 -28
  2. data/README.rdoc +2 -2
  3. data/lib/active_support/backtrace_cleaner.rb +17 -12
  4. data/lib/active_support/buffered_logger.rb +7 -9
  5. data/lib/active_support/cache/file_store.rb +4 -3
  6. data/lib/active_support/cache/mem_cache_store.rb +10 -2
  7. data/lib/active_support/cache/strategy/local_cache.rb +28 -23
  8. data/lib/active_support/cache.rb +11 -14
  9. data/lib/active_support/callbacks.rb +195 -175
  10. data/lib/active_support/concern.rb +105 -35
  11. data/lib/active_support/configurable.rb +50 -8
  12. data/lib/active_support/core_ext/array/access.rb +2 -2
  13. data/lib/active_support/core_ext/array/conversions.rb +2 -2
  14. data/lib/active_support/core_ext/array/random_access.rb +10 -7
  15. data/lib/active_support/core_ext/array/uniq_by.rb +2 -3
  16. data/lib/active_support/core_ext/array/wrap.rb +1 -1
  17. data/lib/active_support/core_ext/big_decimal/conversions.rb +0 -2
  18. data/lib/active_support/core_ext/class/attribute.rb +15 -1
  19. data/lib/active_support/core_ext/class/inheritable_attributes.rb +10 -86
  20. data/lib/active_support/core_ext/class/subclasses.rb +20 -34
  21. data/lib/active_support/core_ext/date/calculations.rb +17 -5
  22. data/lib/active_support/core_ext/date/conversions.rb +9 -2
  23. data/lib/active_support/core_ext/date_time/calculations.rb +26 -9
  24. data/lib/active_support/core_ext/date_time/conversions.rb +9 -9
  25. data/lib/active_support/core_ext/date_time/zones.rb +1 -1
  26. data/lib/active_support/core_ext/enumerable.rb +3 -6
  27. data/lib/active_support/core_ext/float/rounding.rb +1 -1
  28. data/lib/active_support/core_ext/hash/conversions.rb +22 -34
  29. data/lib/active_support/core_ext/hash/deep_dup.rb +11 -0
  30. data/lib/active_support/core_ext/hash/indifferent_access.rb +12 -0
  31. data/lib/active_support/core_ext/hash/keys.rb +6 -4
  32. data/lib/active_support/core_ext/hash/reverse_merge.rb +9 -14
  33. data/lib/active_support/core_ext/hash/slice.rb +3 -1
  34. data/lib/active_support/core_ext/hash.rb +1 -0
  35. data/lib/active_support/core_ext/integer/inflections.rb +7 -4
  36. data/lib/active_support/core_ext/kernel/reporting.rb +31 -0
  37. data/lib/active_support/core_ext/kernel/requires.rb +2 -0
  38. data/lib/active_support/core_ext/logger.rb +11 -38
  39. data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +12 -12
  40. data/lib/active_support/core_ext/module/attr_internal.rb +13 -6
  41. data/lib/active_support/core_ext/module/delegation.rb +1 -5
  42. data/lib/active_support/core_ext/module/remove_method.rb +7 -2
  43. data/lib/active_support/core_ext/numeric/time.rb +2 -0
  44. data/lib/active_support/core_ext/object/blank.rb +45 -12
  45. data/lib/active_support/core_ext/object/duplicable.rb +50 -9
  46. data/lib/active_support/core_ext/object/inclusion.rb +15 -0
  47. data/lib/active_support/core_ext/object/instance_variables.rb +1 -35
  48. data/lib/active_support/core_ext/object/to_param.rb +13 -8
  49. data/lib/active_support/core_ext/object/to_query.rb +2 -2
  50. data/lib/active_support/core_ext/object/try.rb +29 -10
  51. data/lib/active_support/core_ext/object/with_options.rb +25 -8
  52. data/lib/active_support/core_ext/object.rb +1 -1
  53. data/lib/active_support/core_ext/range/cover.rb +3 -0
  54. data/lib/active_support/core_ext/range.rb +1 -0
  55. data/lib/active_support/core_ext/string/behavior.rb +1 -2
  56. data/lib/active_support/core_ext/string/conversions.rb +1 -0
  57. data/lib/active_support/core_ext/string/exclude.rb +1 -1
  58. data/lib/active_support/core_ext/string/filters.rb +3 -3
  59. data/lib/active_support/core_ext/string/inflections.rb +1 -1
  60. data/lib/active_support/core_ext/string/inquiry.rb +13 -0
  61. data/lib/active_support/core_ext/string/multibyte.rb +2 -2
  62. data/lib/active_support/core_ext/string/output_safety.rb +45 -62
  63. data/lib/active_support/core_ext/string.rb +1 -0
  64. data/lib/active_support/core_ext/time/calculations.rb +19 -16
  65. data/lib/active_support/core_ext/time/conversions.rb +2 -24
  66. data/lib/active_support/core_ext/time/zones.rb +32 -21
  67. data/lib/active_support/core_ext/uri.rb +8 -0
  68. data/lib/active_support/dependencies.rb +74 -28
  69. data/lib/active_support/deprecation/behaviors.rb +7 -0
  70. data/lib/active_support/deprecation/proxy_wrappers.rb +1 -1
  71. data/lib/active_support/deprecation/reporting.rb +4 -0
  72. data/lib/active_support/deprecation.rb +2 -2
  73. data/lib/active_support/descendants_tracker.rb +9 -7
  74. data/lib/active_support/duration.rb +5 -0
  75. data/lib/active_support/file_update_checker.rb +1 -1
  76. data/lib/active_support/file_watcher.rb +36 -0
  77. data/lib/active_support/hash_with_indifferent_access.rb +20 -8
  78. data/lib/active_support/i18n.rb +0 -1
  79. data/lib/active_support/i18n_railtie.rb +2 -2
  80. data/lib/active_support/inflections.rb +1 -0
  81. data/lib/active_support/inflector/inflections.rb +1 -1
  82. data/lib/active_support/inflector/methods.rb +5 -3
  83. data/lib/active_support/json/decoding.rb +37 -23
  84. data/lib/active_support/json/encoding.rb +12 -4
  85. data/lib/active_support/lazy_load_hooks.rb +7 -7
  86. data/lib/active_support/log_subscriber/test_helper.rb +5 -3
  87. data/lib/active_support/log_subscriber.rb +6 -6
  88. data/lib/active_support/message_encryptor.rb +1 -1
  89. data/lib/active_support/message_verifier.rb +1 -1
  90. data/lib/active_support/multibyte/chars.rb +5 -5
  91. data/lib/active_support/multibyte/unicode.rb +2 -1
  92. data/lib/active_support/notifications/fanout.rb +3 -3
  93. data/lib/active_support/notifications/instrumenter.rb +1 -1
  94. data/lib/active_support/notifications.rb +9 -10
  95. data/lib/active_support/ordered_hash.rb +23 -2
  96. data/lib/active_support/ordered_options.rb +37 -3
  97. data/lib/active_support/railtie.rb +1 -1
  98. data/lib/active_support/rescuable.rb +1 -0
  99. data/lib/active_support/secure_random.rb +3 -196
  100. data/lib/active_support/test_case.rb +2 -10
  101. data/lib/active_support/testing/assertions.rb +20 -7
  102. data/lib/active_support/testing/mochaing.rb +7 -0
  103. data/lib/active_support/testing/pending.rb +27 -23
  104. data/lib/active_support/testing/performance/jruby.rb +115 -0
  105. data/lib/active_support/testing/performance/rubinius.rb +113 -0
  106. data/lib/active_support/testing/performance/ruby/mri.rb +57 -0
  107. data/lib/active_support/testing/performance/ruby/yarv.rb +57 -0
  108. data/lib/active_support/testing/performance/ruby.rb +152 -0
  109. data/lib/active_support/testing/performance.rb +214 -322
  110. data/lib/active_support/testing/setup_and_teardown.rb +8 -11
  111. data/lib/active_support/time_with_zone.rb +6 -3
  112. data/lib/active_support/values/time_zone.rb +26 -8
  113. data/lib/active_support/version.rb +2 -2
  114. data/lib/active_support/whiny_nil.rb +1 -1
  115. data/lib/active_support/xml_mini/jdom.rb +1 -1
  116. data/lib/active_support/xml_mini/libxml.rb +1 -0
  117. data/lib/active_support/xml_mini/libxmlsax.rb +2 -1
  118. data/lib/active_support/xml_mini/nokogiri.rb +1 -0
  119. data/lib/active_support/xml_mini/nokogirisax.rb +1 -0
  120. data/lib/active_support/xml_mini/rexml.rb +1 -0
  121. data/lib/active_support/xml_mini.rb +8 -3
  122. data/lib/active_support.rb +4 -2
  123. metadata +70 -32
  124. checksums.yaml +0 -7
  125. data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +0 -19
  126. data/lib/active_support/core_ext/cgi.rb +0 -1
  127. data/lib/active_support/core_ext/object/returning.rb +0 -43
  128. data/lib/active_support/json/backends/jsongem.rb +0 -47
  129. data/lib/active_support/json/backends/okjson.rb +0 -644
  130. data/lib/active_support/json/backends/yajl.rb +0 -44
  131. data/lib/active_support/json/backends/yaml.rb +0 -19
  132. 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 = { '&' => '&amp;', '>' => '&gt;', '<' => '&lt;', '"' => '&quot;', "'" => '&#x27;' }
6
+ HTML_ESCAPE = { '&' => '&amp;', '>' => '&gt;', '<' => '&lt;', '"' => '&quot;' }
7
7
  JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003E', '<' => '\u003C' }
8
8
 
9
- if RUBY_VERSION >= '1.9'
10
- # A utility method for escaping HTML tag characters.
11
- # This method is also aliased as <tt>h</tt>.
12
- #
13
- # In your ERB templates, use this method to escape any unsafe content. For example:
14
- # <%=h @person.name %>
15
- #
16
- # ==== Example:
17
- # puts html_escape("is a > 0 & a < 10?")
18
- # # => is a &gt; 0 &amp; a &lt; 10?
19
- def html_escape(s)
20
- s = s.to_s
21
- if s.html_safe?
22
- s
23
- else
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 &gt; 0 &amp; a &lt; 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(/&/, "&amp;").gsub(/\"/, "&quot;").gsub(/>/, "&gt;").gsub(/</, "&lt;").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 Fixnum
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", "prepend"].freeze
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 unless html_safe?
90
+ raise SafeConcatError if dirty?
113
91
  original_concat(value)
114
92
  end
115
93
 
116
94
  def initialize(*)
117
- @html_safe = true
95
+ @dirty = false
118
96
  super
119
97
  end
120
98
 
121
99
  def initialize_copy(other)
122
100
  super
123
- @html_safe = other.html_safe?
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 !html_safe? || value.html_safe?
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
- defined?(@html_safe) && @html_safe
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
- if 'String'.respond_to?(unsafe_method)
161
- class_eval <<-EOT, __FILE__, __LINE__ + 1
162
- def #{unsafe_method}(*args, &block) # def capitalize(*args, &block)
163
- to_str.#{unsafe_method}(*args, &block) # to_str.capitalize(*args, &block)
164
- end # end
165
-
166
- def #{unsafe_method}!(*args) # def capitalize!(*args)
167
- @html_safe = false # @html_safe = false
168
- super # super
169
- end # end
170
- EOT
171
- end
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
@@ -11,3 +11,4 @@ require 'active_support/core_ext/string/output_safety'
11
11
  require 'active_support/core_ext/string/exclude'
12
12
  require 'active_support/core_ext/string/encoding'
13
13
  require 'active_support/core_ext/string/strip'
14
+ require 'active_support/core_ext/string/inquiry'
@@ -1,7 +1,6 @@
1
1
  require 'active_support/duration'
2
- require 'active_support/core_ext/date/acts_like'
3
- require 'active_support/core_ext/date/calculations'
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
- super || (self == Time && other.is_a?(ActiveSupport::TimeWithZone))
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, :min => 0, :sec => 0, :usec => 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,:hour => 0, :min => 0, :sec => 0, :usec => 0)
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, :min => 0, :sec => 0, :usec => 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
- # if other is an ActiveSupport::TimeWithZone, coerce a Time instance from it so we can do <=> comparison
277
- other = other.comparable_time if other.respond_to?(:comparable_time)
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:17"
23
- # time.to_s(:time) # => "06:10:17"
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 -- <tt>current_user.time_zone</tt>
23
- # just needs to return a string identifying the user's preferred TimeZone:
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
- # before_filter :set_time_zone
26
+ # around_filter :set_time_zone
27
27
  #
28
28
  # def set_time_zone
29
- # Time.zone = current_user.time_zone
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] = get_zone(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
- old_zone, ::Time.zone = ::Time.zone, get_zone(time_zone)
39
- yield
40
- ensure
41
- ::Time.zone = old_zone
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
- private
45
- def get_zone(time_zone)
46
- return time_zone if time_zone.nil? || time_zone.is_a?(ActiveSupport::TimeZone)
47
- # lookup timezone based on identifier (unless we've been passed a TZInfo::Timezone)
48
- unless time_zone.respond_to?(:period_for_local)
49
- time_zone = ActiveSupport::TimeZone[time_zone] || TZInfo::Timezone.get(time_zone) rescue nil
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.__send__(:get_zone, zone))
84
+ ActiveSupport::TimeWithZone.new(utc? ? self : getutc, ::Time.find_zone!(zone))
74
85
  end
75
86
  end
@@ -20,3 +20,11 @@ if RUBY_VERSION >= '1.9'
20
20
  end
21
21
  end
22
22
  end
23
+
24
+ module URI
25
+ class << self
26
+ def parser
27
+ @parser ||= URI.const_defined?(:Parser) ? URI::Parser.new : URI
28
+ end
29
+ end
30
+ 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 watch_modules
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 watch_modules
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 watch_modules
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
- if !nesting
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 ArgumentError, "#{from_mod} is not missing constant #{const_name}!" if local_const_defined?(from_mod, const_name)
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 enviroment will be in an inconsistent state, e.g. other constants
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 Reference
529
- @@constants = Hash.new { |h, k| h[k] = Inflector.constantize(k) }
526
+ class ClassCache
527
+ def initialize
528
+ @store = Hash.new { |h, k| h[k] = Inflector.constantize(k) }
529
+ end
530
530
 
531
- attr_reader :name
531
+ def empty?
532
+ @store.empty?
533
+ end
532
534
 
533
- def initialize(name)
534
- @name = name.to_s
535
- @@constants[@name] = name if name.respond_to?(:name)
535
+ def key?(key)
536
+ @store.key?(key)
536
537
  end
537
538
 
538
- def get
539
- @@constants[@name]
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 self.clear!
543
- @@constants.clear
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
- references[name] ||= Reference.new(name)
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
- ref(name).get
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
- constantize(const).before_remove_const if constantize(const).respond_to?(:before_remove_const)
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 logger && log_activity
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
- if logger && log_activity
652
- logger.debug "Dependencies: #{msg}"
653
- end
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
@@ -58,7 +58,7 @@ module ActiveSupport
58
58
  end
59
59
  end
60
60
 
61
- class DeprecatedConstantProxy < DeprecationProxy #:nodoc:
61
+ class DeprecatedConstantProxy < DeprecationProxy #:nodoc:all
62
62
  def initialize(old_const, new_const)
63
63
  @old_const = old_const
64
64
  @new_const = new_const
@@ -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 #:nodoc:
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.0'
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