activesupport 3.0.1 → 3.0.2
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 +7 -1
- data/lib/active_support.rb +1 -0
- data/lib/active_support/cache.rb +2 -2
- data/lib/active_support/cache/file_store.rb +3 -4
- data/lib/active_support/cache/mem_cache_store.rb +1 -1
- data/lib/active_support/callbacks.rb +1 -1
- data/lib/active_support/core_ext/module/delegation.rb +1 -1
- data/lib/active_support/core_ext/numeric/time.rb +2 -2
- data/lib/active_support/core_ext/object/to_param.rb +3 -2
- data/lib/active_support/core_ext/string/strip.rb +5 -3
- data/lib/active_support/dependencies.rb +7 -1
- data/lib/active_support/duration.rb +1 -1
- data/lib/active_support/hash_with_indifferent_access.rb +2 -0
- data/lib/active_support/i18n.rb +1 -0
- data/lib/active_support/inflector/transliterate.rb +1 -0
- data/lib/active_support/json/encoding.rb +44 -6
- data/lib/active_support/memoizable.rb +2 -0
- data/lib/active_support/testing/performance.rb +4 -4
- data/lib/active_support/time_with_zone.rb +1 -1
- data/lib/active_support/version.rb +2 -2
- data/lib/active_support/xml_mini.rb +1 -1
- metadata +9 -4
data/CHANGELOG
CHANGED
@@ -1,6 +1,12 @@
|
|
1
|
+
*Rails 3.0.2 (November 15, 2010)*
|
2
|
+
|
3
|
+
* Added before_remove_const callback to ActiveSupport::Dependencies.remove_unloadable_constants! [Andrew White]
|
4
|
+
|
5
|
+
|
1
6
|
*Rails 3.0.1 (October 15, 2010)*
|
2
7
|
|
3
|
-
* No
|
8
|
+
* No changes.
|
9
|
+
|
4
10
|
|
5
11
|
*Rails 3.0.0 (August 29, 2010)*
|
6
12
|
|
data/lib/active_support.rb
CHANGED
data/lib/active_support/cache.rb
CHANGED
@@ -61,8 +61,8 @@ module ActiveSupport
|
|
61
61
|
store_class =
|
62
62
|
begin
|
63
63
|
require "active_support/cache/#{store}"
|
64
|
-
rescue LoadError
|
65
|
-
raise "Could not find cache store adapter for #{store} (#{
|
64
|
+
rescue LoadError => e
|
65
|
+
raise "Could not find cache store adapter for #{store} (#{e})"
|
66
66
|
else
|
67
67
|
ActiveSupport::Cache.const_get(store_class_name)
|
68
68
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'active_support/core_ext/file/atomic'
|
2
2
|
require 'active_support/core_ext/string/conversions'
|
3
|
+
require 'rack/utils'
|
3
4
|
|
4
5
|
module ActiveSupport
|
5
6
|
module Cache
|
@@ -11,8 +12,6 @@ module ActiveSupport
|
|
11
12
|
attr_reader :cache_path
|
12
13
|
|
13
14
|
DIR_FORMATTER = "%03X"
|
14
|
-
ESCAPE_FILENAME_CHARS = /[^a-z0-9_.-]/i
|
15
|
-
UNESCAPE_FILENAME_CHARS = /%[0-9A-F]{2}/
|
16
15
|
|
17
16
|
def initialize(cache_path, options = nil)
|
18
17
|
super(options)
|
@@ -136,7 +135,7 @@ module ActiveSupport
|
|
136
135
|
|
137
136
|
# Translate a key into a file path.
|
138
137
|
def key_file_path(key)
|
139
|
-
fname =
|
138
|
+
fname = Rack::Utils.escape(key)
|
140
139
|
hash = Zlib.adler32(fname)
|
141
140
|
hash, dir_1 = hash.divmod(0x1000)
|
142
141
|
dir_2 = hash.modulo(0x1000)
|
@@ -156,7 +155,7 @@ module ActiveSupport
|
|
156
155
|
# Translate a file path into a key.
|
157
156
|
def file_path_key(path)
|
158
157
|
fname = path[cache_path.size, path.size].split(File::SEPARATOR, 4).last
|
159
|
-
|
158
|
+
Rack::Utils.unescape(fname)
|
160
159
|
end
|
161
160
|
|
162
161
|
# Delete empty directories in the cache.
|
@@ -1,7 +1,7 @@
|
|
1
1
|
begin
|
2
2
|
require 'memcache'
|
3
3
|
rescue LoadError => e
|
4
|
-
$stderr.puts "You don't have memcache installed in your application. Please add it to your Gemfile and run bundle install"
|
4
|
+
$stderr.puts "You don't have memcache-client installed in your application. Please add it to your Gemfile and run bundle install"
|
5
5
|
raise e
|
6
6
|
end
|
7
7
|
require 'digest/md5'
|
@@ -487,7 +487,7 @@ module ActiveSupport
|
|
487
487
|
chain.delete_if {|c| c.matches?(type, filter) }
|
488
488
|
end
|
489
489
|
|
490
|
-
options[:prepend] ? chain.unshift(*mapped) : chain.push(*mapped)
|
490
|
+
options[:prepend] ? chain.unshift(*(mapped.reverse)) : chain.push(*mapped)
|
491
491
|
end
|
492
492
|
end
|
493
493
|
|
@@ -113,7 +113,7 @@ class Module
|
|
113
113
|
raise ArgumentError, "Can only automatically set the delegation prefix when delegating to a method."
|
114
114
|
end
|
115
115
|
|
116
|
-
prefix = options[:prefix] && "#{options[:prefix] == true ? to : options[:prefix]}_"
|
116
|
+
prefix = options[:prefix] && "#{options[:prefix] == true ? to : options[:prefix]}_" || ''
|
117
117
|
|
118
118
|
file, line = caller.first.split(':', 2)
|
119
119
|
line = line.to_i
|
@@ -60,7 +60,7 @@ class Numeric
|
|
60
60
|
alias :fortnight :fortnights
|
61
61
|
|
62
62
|
# Reads best without arguments: 10.minutes.ago
|
63
|
-
def ago(time = ::Time.
|
63
|
+
def ago(time = ::Time.current)
|
64
64
|
time - self
|
65
65
|
end
|
66
66
|
|
@@ -68,7 +68,7 @@ class Numeric
|
|
68
68
|
alias :until :ago
|
69
69
|
|
70
70
|
# Reads best with argument: 10.minutes.since(time)
|
71
|
-
def since(time = ::Time.
|
71
|
+
def since(time = ::Time.current)
|
72
72
|
time + self
|
73
73
|
end
|
74
74
|
|
@@ -35,7 +35,8 @@ end
|
|
35
35
|
|
36
36
|
class Hash
|
37
37
|
# Converts a hash into a string suitable for use as a URL query string. An optional <tt>namespace</tt> can be
|
38
|
-
# passed to enclose the param names (see example below).
|
38
|
+
# passed to enclose the param names (see example below). The string pairs "key=value" that conform the query
|
39
|
+
# string are sorted lexicographically in ascending order.
|
39
40
|
#
|
40
41
|
# ==== Examples
|
41
42
|
# { :name => 'David', :nationality => 'Danish' }.to_param # => "name=David&nationality=Danish"
|
@@ -44,6 +45,6 @@ class Hash
|
|
44
45
|
def to_param(namespace = nil)
|
45
46
|
collect do |key, value|
|
46
47
|
value.to_query(namespace ? "#{namespace}[#{key}]" : key)
|
47
|
-
end * '&'
|
48
|
+
end.sort * '&'
|
48
49
|
end
|
49
50
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'active_support/core_ext/object/try'
|
2
|
+
|
1
3
|
class String
|
2
4
|
# Strips indentation in heredocs.
|
3
5
|
#
|
@@ -18,7 +20,7 @@ class String
|
|
18
20
|
# Technically, it looks for the least indented line in the whole string, and removes
|
19
21
|
# that amount of leading whitespace.
|
20
22
|
def strip_heredoc
|
21
|
-
indent =
|
22
|
-
gsub(
|
23
|
+
indent = scan(/^[ \t]*(?=\S)/).min.try(:size) || 0
|
24
|
+
gsub(/^[ \t]{#{indent}}/, '')
|
23
25
|
end
|
24
|
-
end
|
26
|
+
end
|
@@ -511,7 +511,12 @@ module ActiveSupport #:nodoc:
|
|
511
511
|
end
|
512
512
|
|
513
513
|
# Remove the constants that have been autoloaded, and those that have been
|
514
|
-
# marked for unloading.
|
514
|
+
# marked for unloading. Before each constant is removed a callback is sent
|
515
|
+
# to its class/module if it implements +before_remove_const+.
|
516
|
+
#
|
517
|
+
# The callback implementation should be restricted to cleaning up caches, etc.
|
518
|
+
# as the enviroment will be in an inconsistent state, e.g. other constants
|
519
|
+
# may have already been unloaded and not accessible.
|
515
520
|
def remove_unloadable_constants!
|
516
521
|
autoloaded_constants.each { |const| remove_constant const }
|
517
522
|
autoloaded_constants.clear
|
@@ -636,6 +641,7 @@ module ActiveSupport #:nodoc:
|
|
636
641
|
parent = Inflector.constantize(names * '::')
|
637
642
|
|
638
643
|
log "removing constant #{const}"
|
644
|
+
constantize(const).before_remove_const if constantize(const).respond_to?(:before_remove_const)
|
639
645
|
parent.instance_eval { remove_const to_remove }
|
640
646
|
|
641
647
|
return true
|
data/lib/active_support/i18n.rb
CHANGED
@@ -41,9 +41,26 @@ module ActiveSupport
|
|
41
41
|
@seen = []
|
42
42
|
end
|
43
43
|
|
44
|
-
def encode(value)
|
44
|
+
def encode(value, use_options = true)
|
45
45
|
check_for_circular_references(value) do
|
46
|
-
value.as_json(
|
46
|
+
jsonified = use_options ? value.as_json(options_for(value)) : value.as_json
|
47
|
+
jsonified.encode_json(self)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# like encode, but only calls as_json, without encoding to string
|
52
|
+
def as_json(value)
|
53
|
+
check_for_circular_references(value) do
|
54
|
+
value.as_json(options_for(value))
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def options_for(value)
|
59
|
+
if value.is_a?(Array) || value.is_a?(Hash)
|
60
|
+
# hashes and arrays need to get encoder in the options, so that they can detect circular references
|
61
|
+
(options || {}).merge(:encoder => self)
|
62
|
+
else
|
63
|
+
options
|
47
64
|
end
|
48
65
|
end
|
49
66
|
|
@@ -186,13 +203,22 @@ module Enumerable
|
|
186
203
|
end
|
187
204
|
|
188
205
|
class Array
|
189
|
-
def as_json(options = nil)
|
190
|
-
|
206
|
+
def as_json(options = nil) #:nodoc:
|
207
|
+
# use encoder as a proxy to call as_json on all elements, to protect from circular references
|
208
|
+
encoder = options && options[:encoder] || ActiveSupport::JSON::Encoding::Encoder.new(options)
|
209
|
+
map { |v| encoder.as_json(v) }
|
210
|
+
end
|
211
|
+
|
212
|
+
def encode_json(encoder) #:nodoc:
|
213
|
+
# we assume here that the encoder has already run as_json on self and the elements, so we run encode_json directly
|
214
|
+
"[#{map { |v| v.encode_json(encoder) } * ','}]"
|
215
|
+
end
|
191
216
|
end
|
192
217
|
|
193
218
|
class Hash
|
194
219
|
def as_json(options = nil) #:nodoc:
|
195
|
-
|
220
|
+
# create a subset of the hash by applying :only or :except
|
221
|
+
subset = if options
|
196
222
|
if attrs = options[:only]
|
197
223
|
slice(*Array.wrap(attrs))
|
198
224
|
elsif attrs = options[:except]
|
@@ -203,10 +229,22 @@ class Hash
|
|
203
229
|
else
|
204
230
|
self
|
205
231
|
end
|
232
|
+
|
233
|
+
# use encoder as a proxy to call as_json on all values in the subset, to protect from circular references
|
234
|
+
encoder = options && options[:encoder] || ActiveSupport::JSON::Encoding::Encoder.new(options)
|
235
|
+
pairs = subset.map { |k, v| [k.to_s, encoder.as_json(v)] }
|
236
|
+
result = self.is_a?(ActiveSupport::OrderedHash) ? ActiveSupport::OrderedHash.new : Hash.new
|
237
|
+
pairs.inject(result) { |hash, pair| hash[pair.first] = pair.last; hash }
|
206
238
|
end
|
207
239
|
|
208
240
|
def encode_json(encoder)
|
209
|
-
|
241
|
+
# values are encoded with use_options = false, because we don't want hash representations from ActiveModel to be
|
242
|
+
# processed once again with as_json with options, as this could cause unexpected results (i.e. missing fields);
|
243
|
+
|
244
|
+
# on the other hand, we need to run as_json on the elements, because the model representation may contain fields
|
245
|
+
# like Time/Date in their original (not jsonified) form, etc.
|
246
|
+
|
247
|
+
"{#{map { |k,v| "#{encoder.encode(k.to_s)}:#{encoder.encode(v, false)}" } * ','}}"
|
210
248
|
end
|
211
249
|
end
|
212
250
|
|
@@ -95,6 +95,8 @@ module ActiveSupport
|
|
95
95
|
#
|
96
96
|
if private_method_defined?(#{original_method.inspect}) # if private_method_defined?(:_unmemoized_mime_type)
|
97
97
|
private #{symbol.inspect} # private :mime_type
|
98
|
+
elsif protected_method_defined?(#{original_method.inspect}) # elsif protected_method_defined?(:_unmemoized_mime_type)
|
99
|
+
protected #{symbol.inspect} # protected :mime_type
|
98
100
|
end # end
|
99
101
|
EOS
|
100
102
|
end
|
@@ -58,16 +58,16 @@ begin
|
|
58
58
|
metric.send(mode) { __send__ @method_name }
|
59
59
|
rescue ::Test::Unit::AssertionFailedError => e
|
60
60
|
add_failure(e.message, e.backtrace)
|
61
|
-
rescue StandardError, ScriptError
|
62
|
-
add_error(
|
61
|
+
rescue StandardError, ScriptError => e
|
62
|
+
add_error(e)
|
63
63
|
ensure
|
64
64
|
begin
|
65
65
|
teardown
|
66
66
|
run_callbacks :teardown, :enumerator => :reverse_each
|
67
67
|
rescue ::Test::Unit::AssertionFailedError => e
|
68
68
|
add_failure(e.message, e.backtrace)
|
69
|
-
rescue StandardError, ScriptError
|
70
|
-
add_error(
|
69
|
+
rescue StandardError, ScriptError => e
|
70
|
+
add_error(e)
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
@@ -72,7 +72,7 @@ module ActiveSupport
|
|
72
72
|
|
73
73
|
# Returns a <tt>Time.local()</tt> instance of the simultaneous time in your system's <tt>ENV['TZ']</tt> zone
|
74
74
|
def localtime
|
75
|
-
utc.getlocal
|
75
|
+
utc.respond_to?(:getlocal) ? utc.getlocal : utc.to_time.getlocal
|
76
76
|
end
|
77
77
|
alias_method :getlocal, :localtime
|
78
78
|
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activesupport
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 3
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 3
|
7
8
|
- 0
|
8
|
-
-
|
9
|
-
version: 3.0.
|
9
|
+
- 2
|
10
|
+
version: 3.0.2
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- David Heinemeier Hansson
|
@@ -14,7 +15,7 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2010-
|
18
|
+
date: 2010-11-15 00:00:00 -06:00
|
18
19
|
default_executable:
|
19
20
|
dependencies: []
|
20
21
|
|
@@ -246,25 +247,29 @@ rdoc_options: []
|
|
246
247
|
require_paths:
|
247
248
|
- lib
|
248
249
|
required_ruby_version: !ruby/object:Gem::Requirement
|
250
|
+
none: false
|
249
251
|
requirements:
|
250
252
|
- - ">="
|
251
253
|
- !ruby/object:Gem::Version
|
254
|
+
hash: 57
|
252
255
|
segments:
|
253
256
|
- 1
|
254
257
|
- 8
|
255
258
|
- 7
|
256
259
|
version: 1.8.7
|
257
260
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
261
|
+
none: false
|
258
262
|
requirements:
|
259
263
|
- - ">="
|
260
264
|
- !ruby/object:Gem::Version
|
265
|
+
hash: 3
|
261
266
|
segments:
|
262
267
|
- 0
|
263
268
|
version: "0"
|
264
269
|
requirements: []
|
265
270
|
|
266
271
|
rubyforge_project: activesupport
|
267
|
-
rubygems_version: 1.3.
|
272
|
+
rubygems_version: 1.3.7
|
268
273
|
signing_key:
|
269
274
|
specification_version: 3
|
270
275
|
summary: A toolkit of support libraries and Ruby core extensions extracted from the Rails framework.
|