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
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require 'active_support/dependencies'
|
|
2
|
-
|
|
3
1
|
module ActiveSupport
|
|
4
2
|
# This module provides an internal implementation to track descendants
|
|
5
3
|
# which is faster than iterating through ObjectSpace.
|
|
@@ -18,12 +16,16 @@ module ActiveSupport
|
|
|
18
16
|
end
|
|
19
17
|
|
|
20
18
|
def self.clear
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
if defined? ActiveSupport::Dependencies
|
|
20
|
+
@@direct_descendants.each do |klass, descendants|
|
|
21
|
+
if ActiveSupport::Dependencies.autoloaded?(klass)
|
|
22
|
+
@@direct_descendants.delete(klass)
|
|
23
|
+
else
|
|
24
|
+
descendants.reject! { |v| ActiveSupport::Dependencies.autoloaded?(v) }
|
|
25
|
+
end
|
|
26
26
|
end
|
|
27
|
+
else
|
|
28
|
+
@@direct_descendants.clear
|
|
27
29
|
end
|
|
28
30
|
end
|
|
29
31
|
|
|
@@ -10,6 +10,7 @@ module ActiveSupport
|
|
|
10
10
|
# 1.month.ago # equivalent to Time.now.advance(:months => -1)
|
|
11
11
|
class Duration < BasicObject
|
|
12
12
|
attr_accessor :value, :parts
|
|
13
|
+
delegate :duplicable?, :to => :value # required when using ActiveSupport's BasicObject on 1.8
|
|
13
14
|
|
|
14
15
|
def initialize(value, parts) #:nodoc:
|
|
15
16
|
@value, @parts = value, parts
|
|
@@ -80,6 +81,10 @@ module ActiveSupport
|
|
|
80
81
|
parts.to_sentence(:locale => :en)
|
|
81
82
|
end
|
|
82
83
|
|
|
84
|
+
def as_json(options = nil) #:nodoc:
|
|
85
|
+
to_i
|
|
86
|
+
end
|
|
87
|
+
|
|
83
88
|
protected
|
|
84
89
|
|
|
85
90
|
def sum(sign, time = ::Time.current) #:nodoc:
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module ActiveSupport
|
|
2
|
+
class FileWatcher
|
|
3
|
+
class Backend
|
|
4
|
+
def initialize(path, watcher)
|
|
5
|
+
@watcher = watcher
|
|
6
|
+
@path = path
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def trigger(files)
|
|
10
|
+
@watcher.trigger(files)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def initialize
|
|
15
|
+
@regex_matchers = {}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def watch(pattern, &block)
|
|
19
|
+
@regex_matchers[pattern] = block
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def trigger(files)
|
|
23
|
+
trigger_files = Hash.new { |h,k| h[k] = Hash.new { |h2,k2| h2[k2] = [] } }
|
|
24
|
+
|
|
25
|
+
files.each do |file, state|
|
|
26
|
+
@regex_matchers.each do |pattern, block|
|
|
27
|
+
trigger_files[block][state] << file if pattern === file
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
trigger_files.each do |block, payload|
|
|
32
|
+
block.call payload
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
require 'active_support/core_ext/hash/keys'
|
|
2
2
|
|
|
3
3
|
# This class has dubious semantics and we only have it so that
|
|
4
|
-
# people can write params[:key] instead of params['key']
|
|
4
|
+
# people can write <tt>params[:key]</tt> instead of <tt>params['key']</tt>
|
|
5
5
|
# and they get the same value for both keys.
|
|
6
6
|
|
|
7
7
|
module ActiveSupport
|
|
8
8
|
class HashWithIndifferentAccess < Hash
|
|
9
|
+
|
|
10
|
+
# Always returns true, so that <tt>Array#extract_options!</tt> finds members of this class.
|
|
9
11
|
def extractable_options?
|
|
10
12
|
true
|
|
11
13
|
end
|
|
12
14
|
|
|
15
|
+
def with_indifferent_access
|
|
16
|
+
dup
|
|
17
|
+
end
|
|
18
|
+
|
|
13
19
|
def initialize(constructor = {})
|
|
14
20
|
if constructor.is_a?(Hash)
|
|
15
21
|
super()
|
|
@@ -28,7 +34,7 @@ module ActiveSupport
|
|
|
28
34
|
end
|
|
29
35
|
|
|
30
36
|
def self.new_from_hash_copying_default(hash)
|
|
31
|
-
|
|
37
|
+
new(hash).tap do |new_hash|
|
|
32
38
|
new_hash.default = hash.default
|
|
33
39
|
end
|
|
34
40
|
end
|
|
@@ -58,8 +64,12 @@ module ActiveSupport
|
|
|
58
64
|
# hash_1.update(hash_2) # => {"key"=>"New Value!"}
|
|
59
65
|
#
|
|
60
66
|
def update(other_hash)
|
|
61
|
-
other_hash.
|
|
62
|
-
|
|
67
|
+
if other_hash.is_a? HashWithIndifferentAccess
|
|
68
|
+
super(other_hash)
|
|
69
|
+
else
|
|
70
|
+
other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
|
|
71
|
+
self
|
|
72
|
+
end
|
|
63
73
|
end
|
|
64
74
|
|
|
65
75
|
alias_method :merge!, :update
|
|
@@ -97,7 +107,9 @@ module ActiveSupport
|
|
|
97
107
|
|
|
98
108
|
# Returns an exact copy of the hash.
|
|
99
109
|
def dup
|
|
100
|
-
|
|
110
|
+
self.class.new(self).tap do |new_hash|
|
|
111
|
+
new_hash.default = default
|
|
112
|
+
end
|
|
101
113
|
end
|
|
102
114
|
|
|
103
115
|
# Merges the instantized and the specified hashes together, giving precedence to the values from the second hash
|
|
@@ -107,7 +119,7 @@ module ActiveSupport
|
|
|
107
119
|
end
|
|
108
120
|
|
|
109
121
|
# Performs the opposite of merge, with the keys and values from the first hash taking precedence over the second.
|
|
110
|
-
# This overloaded definition prevents returning a regular hash, if reverse_merge is called on a HashWithDifferentAccess
|
|
122
|
+
# This overloaded definition prevents returning a regular hash, if reverse_merge is called on a <tt>HashWithDifferentAccess</tt>.
|
|
111
123
|
def reverse_merge(other_hash)
|
|
112
124
|
super self.class.new_from_hash_copying_default(other_hash)
|
|
113
125
|
end
|
|
@@ -138,8 +150,8 @@ module ActiveSupport
|
|
|
138
150
|
end
|
|
139
151
|
|
|
140
152
|
def convert_value(value)
|
|
141
|
-
if value.
|
|
142
|
-
|
|
153
|
+
if value.is_a? Hash
|
|
154
|
+
value.nested_under_indifferent_access
|
|
143
155
|
elsif value.is_a?(Array)
|
|
144
156
|
value.dup.replace(value.map { |e| convert_value(e) })
|
|
145
157
|
else
|
data/lib/active_support/i18n.rb
CHANGED
|
@@ -14,12 +14,12 @@ module I18n
|
|
|
14
14
|
@reloader ||= ActiveSupport::FileUpdateChecker.new([]){ I18n.reload! }
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
# Add I18n::Railtie.reloader to ActionDispatch callbacks. Since, at this
|
|
17
|
+
# Add <tt>I18n::Railtie.reloader</tt> to ActionDispatch callbacks. Since, at this
|
|
18
18
|
# point, no path was added to the reloader, I18n.reload! is not triggered
|
|
19
19
|
# on to_prepare callbacks. This will only happen on the config.after_initialize
|
|
20
20
|
# callback below.
|
|
21
21
|
initializer "i18n.callbacks" do
|
|
22
|
-
ActionDispatch::
|
|
22
|
+
ActionDispatch::Reloader.to_prepare do
|
|
23
23
|
I18n::Railtie.reloader.execute_if_updated
|
|
24
24
|
end
|
|
25
25
|
end
|
|
@@ -54,6 +54,7 @@ module ActiveSupport
|
|
|
54
54
|
inflect.irregular('sex', 'sexes')
|
|
55
55
|
inflect.irregular('move', 'moves')
|
|
56
56
|
inflect.irregular('cow', 'kine')
|
|
57
|
+
inflect.irregular('zombie', 'zombies')
|
|
57
58
|
|
|
58
59
|
inflect.uncountable(%w(equipment information rice money species series fish sheep jeans))
|
|
59
60
|
end
|
|
@@ -135,11 +135,13 @@ module ActiveSupport
|
|
|
135
135
|
# ordinalize(2) # => "2nd"
|
|
136
136
|
# ordinalize(1002) # => "1002nd"
|
|
137
137
|
# ordinalize(1003) # => "1003rd"
|
|
138
|
+
# ordinalize(-11) # => "-11th"
|
|
139
|
+
# ordinalize(-1021) # => "-1021st"
|
|
138
140
|
def ordinalize(number)
|
|
139
|
-
if (11..13).include?(number.to_i % 100)
|
|
141
|
+
if (11..13).include?(number.to_i.abs % 100)
|
|
140
142
|
"#{number}th"
|
|
141
143
|
else
|
|
142
|
-
case number.to_i % 10
|
|
144
|
+
case number.to_i.abs % 10
|
|
143
145
|
when 1; "#{number}st"
|
|
144
146
|
when 2; "#{number}nd"
|
|
145
147
|
when 3; "#{number}rd"
|
|
@@ -148,4 +150,4 @@ module ActiveSupport
|
|
|
148
150
|
end
|
|
149
151
|
end
|
|
150
152
|
end
|
|
151
|
-
end
|
|
153
|
+
end
|
|
@@ -1,32 +1,31 @@
|
|
|
1
1
|
require 'active_support/core_ext/module/attribute_accessors'
|
|
2
2
|
require 'active_support/core_ext/module/delegation'
|
|
3
|
+
require 'multi_json'
|
|
3
4
|
|
|
4
5
|
module ActiveSupport
|
|
5
6
|
# Look for and parse json strings that look like ISO 8601 times.
|
|
6
7
|
mattr_accessor :parse_json_times
|
|
7
8
|
|
|
8
9
|
module JSON
|
|
9
|
-
# Listed in order of preference.
|
|
10
|
-
DECODERS = %w(Yajl OkJson)
|
|
11
|
-
|
|
12
10
|
class << self
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
def decode(json, options ={})
|
|
12
|
+
data = MultiJson.decode(json, options)
|
|
13
|
+
if ActiveSupport.parse_json_times
|
|
14
|
+
convert_dates_from(data)
|
|
15
|
+
else
|
|
16
|
+
data
|
|
17
|
+
end
|
|
18
|
+
end
|
|
15
19
|
|
|
16
|
-
def
|
|
17
|
-
|
|
18
|
-
@backend
|
|
20
|
+
def engine
|
|
21
|
+
MultiJson.engine
|
|
19
22
|
end
|
|
23
|
+
alias :backend :engine
|
|
20
24
|
|
|
21
|
-
def
|
|
22
|
-
|
|
23
|
-
@backend = name
|
|
24
|
-
else
|
|
25
|
-
require "active_support/json/backends/#{name.to_s.downcase}"
|
|
26
|
-
@backend = ActiveSupport::JSON::Backends::const_get(name)
|
|
27
|
-
end
|
|
28
|
-
@parse_error = @backend::ParseError
|
|
25
|
+
def engine=(name)
|
|
26
|
+
MultiJson.engine = name
|
|
29
27
|
end
|
|
28
|
+
alias :backend= :engine=
|
|
30
29
|
|
|
31
30
|
def with_backend(name)
|
|
32
31
|
old_backend, self.backend = backend, name
|
|
@@ -35,15 +34,30 @@ module ActiveSupport
|
|
|
35
34
|
self.backend = old_backend
|
|
36
35
|
end
|
|
37
36
|
|
|
38
|
-
def
|
|
39
|
-
|
|
37
|
+
def parse_error
|
|
38
|
+
MultiJson::DecodeError
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def convert_dates_from(data)
|
|
44
|
+
case data
|
|
45
|
+
when nil
|
|
46
|
+
nil
|
|
47
|
+
when DATE_REGEX
|
|
40
48
|
begin
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
# Try next decoder.
|
|
45
|
-
false
|
|
49
|
+
DateTime.parse(data)
|
|
50
|
+
rescue ArgumentError
|
|
51
|
+
data
|
|
46
52
|
end
|
|
53
|
+
when Array
|
|
54
|
+
data.map! { |d| convert_dates_from(d) }
|
|
55
|
+
when Hash
|
|
56
|
+
data.each do |key, value|
|
|
57
|
+
data[key] = convert_dates_from(value)
|
|
58
|
+
end
|
|
59
|
+
else
|
|
60
|
+
data
|
|
47
61
|
end
|
|
48
62
|
end
|
|
49
63
|
end
|
|
@@ -2,6 +2,7 @@ require 'active_support/core_ext/object/to_json'
|
|
|
2
2
|
require 'active_support/core_ext/module/delegation'
|
|
3
3
|
require 'active_support/deprecation'
|
|
4
4
|
require 'active_support/json/variable'
|
|
5
|
+
require 'active_support/ordered_hash'
|
|
5
6
|
|
|
6
7
|
require 'bigdecimal'
|
|
7
8
|
require 'active_support/core_ext/big_decimal/conversions' # for #to_s
|
|
@@ -153,6 +154,12 @@ class Object
|
|
|
153
154
|
end
|
|
154
155
|
end
|
|
155
156
|
|
|
157
|
+
class Struct
|
|
158
|
+
def as_json(options = nil) #:nodoc:
|
|
159
|
+
Hash[members.zip(values)]
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
156
163
|
class TrueClass
|
|
157
164
|
AS_JSON = ActiveSupport::JSON::Variable.new('true').freeze
|
|
158
165
|
def as_json(options = nil) AS_JSON end #:nodoc:
|
|
@@ -199,7 +206,9 @@ class Regexp
|
|
|
199
206
|
end
|
|
200
207
|
|
|
201
208
|
module Enumerable
|
|
202
|
-
def as_json(options = nil)
|
|
209
|
+
def as_json(options = nil) #:nodoc:
|
|
210
|
+
to_a.as_json(options)
|
|
211
|
+
end
|
|
203
212
|
end
|
|
204
213
|
|
|
205
214
|
class Array
|
|
@@ -232,9 +241,8 @@ class Hash
|
|
|
232
241
|
|
|
233
242
|
# use encoder as a proxy to call as_json on all values in the subset, to protect from circular references
|
|
234
243
|
encoder = options && options[:encoder] || ActiveSupport::JSON::Encoding::Encoder.new(options)
|
|
235
|
-
|
|
236
|
-
result
|
|
237
|
-
pairs.inject(result) { |hash, pair| hash[pair.first] = pair.last; hash }
|
|
244
|
+
result = self.is_a?(ActiveSupport::OrderedHash) ? ActiveSupport::OrderedHash : Hash
|
|
245
|
+
result[subset.map { |k, v| [k.to_s, encoder.as_json(v)] }]
|
|
238
246
|
end
|
|
239
247
|
|
|
240
248
|
def encode_json(encoder)
|
|
@@ -5,17 +5,17 @@
|
|
|
5
5
|
#
|
|
6
6
|
# Here is an example where +on_load+ method is called to register a hook.
|
|
7
7
|
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
8
|
+
# initializer "active_record.initialize_timezone" do
|
|
9
|
+
# ActiveSupport.on_load(:active_record) do
|
|
10
|
+
# self.time_zone_aware_attributes = true
|
|
11
|
+
# self.default_timezone = :utc
|
|
12
|
+
# end
|
|
13
|
+
# end
|
|
14
14
|
#
|
|
15
15
|
# When the entirety of +activerecord/lib/active_record/base.rb+ has been evaluated then +run_load_hooks+ is invoked.
|
|
16
16
|
# The very last line of +activerecord/lib/active_record/base.rb+ is:
|
|
17
17
|
#
|
|
18
|
-
#
|
|
18
|
+
# ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base)
|
|
19
19
|
#
|
|
20
20
|
module ActiveSupport
|
|
21
21
|
@load_hooks = Hash.new {|h,k| h[k] = [] }
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require 'active_support/log_subscriber'
|
|
2
2
|
require 'active_support/buffered_logger'
|
|
3
|
+
require 'active_support/notifications'
|
|
3
4
|
|
|
4
5
|
module ActiveSupport
|
|
5
6
|
class LogSubscriber
|
|
@@ -23,11 +24,11 @@ module ActiveSupport
|
|
|
23
24
|
# end
|
|
24
25
|
#
|
|
25
26
|
# All you need to do is to ensure that your log subscriber is added to Rails::Subscriber,
|
|
26
|
-
# as in the second line of the code above. The test helpers
|
|
27
|
+
# as in the second line of the code above. The test helpers are responsible for setting
|
|
27
28
|
# up the queue, subscriptions and turning colors in logs off.
|
|
28
29
|
#
|
|
29
30
|
# The messages are available in the @logger instance, which is a logger with limited
|
|
30
|
-
# powers (it actually
|
|
31
|
+
# powers (it actually does not send anything to your output), and you can collect them
|
|
31
32
|
# doing @logger.logged(level), where level is the level used in logging, like info,
|
|
32
33
|
# debug, warn and so on.
|
|
33
34
|
#
|
|
@@ -38,13 +39,14 @@ module ActiveSupport
|
|
|
38
39
|
|
|
39
40
|
ActiveSupport::LogSubscriber.colorize_logging = false
|
|
40
41
|
|
|
42
|
+
@old_notifier = ActiveSupport::Notifications.notifier
|
|
41
43
|
set_logger(@logger)
|
|
42
44
|
ActiveSupport::Notifications.notifier = @notifier
|
|
43
45
|
end
|
|
44
46
|
|
|
45
47
|
def teardown
|
|
46
48
|
set_logger(nil)
|
|
47
|
-
ActiveSupport::Notifications.notifier =
|
|
49
|
+
ActiveSupport::Notifications.notifier = @old_notifier
|
|
48
50
|
end
|
|
49
51
|
|
|
50
52
|
class MockLogger
|
|
@@ -3,8 +3,8 @@ require 'active_support/core_ext/class/attribute'
|
|
|
3
3
|
|
|
4
4
|
module ActiveSupport
|
|
5
5
|
# ActiveSupport::LogSubscriber is an object set to consume ActiveSupport::Notifications
|
|
6
|
-
# with
|
|
7
|
-
#
|
|
6
|
+
# with the sole purpose of logging them. The log subscriber dispatches notifications to
|
|
7
|
+
# a registered object based on its given namespace.
|
|
8
8
|
#
|
|
9
9
|
# An example would be Active Record log subscriber responsible for logging queries:
|
|
10
10
|
#
|
|
@@ -16,12 +16,12 @@ module ActiveSupport
|
|
|
16
16
|
# end
|
|
17
17
|
# end
|
|
18
18
|
#
|
|
19
|
-
# And it's finally
|
|
19
|
+
# And it's finally registered as:
|
|
20
20
|
#
|
|
21
21
|
# ActiveRecord::LogSubscriber.attach_to :active_record
|
|
22
22
|
#
|
|
23
23
|
# Since we need to know all instance methods before attaching the log subscriber,
|
|
24
|
-
# the line above should be called after your ActiveRecord::LogSubscriber definition.
|
|
24
|
+
# the line above should be called after your <tt>ActiveRecord::LogSubscriber</tt> definition.
|
|
25
25
|
#
|
|
26
26
|
# After configured, whenever a "sql.active_record" notification is published,
|
|
27
27
|
# it will properly dispatch the event (ActiveSupport::Notifications::Event) to
|
|
@@ -109,8 +109,8 @@ module ActiveSupport
|
|
|
109
109
|
|
|
110
110
|
# Set color by using a string or one of the defined constants. If a third
|
|
111
111
|
# option is set to true, it also adds bold to the string. This is based
|
|
112
|
-
# on Highline implementation and
|
|
113
|
-
# of the returned String.
|
|
112
|
+
# on the Highline implementation and will automatically append CLEAR to the
|
|
113
|
+
# end of the returned String.
|
|
114
114
|
#
|
|
115
115
|
def color(text, color, bold=false)
|
|
116
116
|
return text unless colorize_logging
|
|
@@ -7,7 +7,7 @@ module ActiveSupport
|
|
|
7
7
|
#
|
|
8
8
|
# The cipher text and initialization vector are base64 encoded and returned to you.
|
|
9
9
|
#
|
|
10
|
-
# This can be used in situations similar to the MessageVerifier
|
|
10
|
+
# This can be used in situations similar to the <tt>MessageVerifier</tt>, but where you don't
|
|
11
11
|
# want users to be able to determine the value of the payload.
|
|
12
12
|
class MessageEncryptor
|
|
13
13
|
class InvalidMessage < StandardError; end
|
|
@@ -2,7 +2,7 @@ require 'active_support/base64'
|
|
|
2
2
|
require 'active_support/core_ext/object/blank'
|
|
3
3
|
|
|
4
4
|
module ActiveSupport
|
|
5
|
-
# MessageVerifier makes it easy to generate and verify messages which are signed
|
|
5
|
+
# +MessageVerifier+ makes it easy to generate and verify messages which are signed
|
|
6
6
|
# to prevent tampering.
|
|
7
7
|
#
|
|
8
8
|
# This is useful for cases like remember-me tokens and auto-unsubscribe links where the
|
|
@@ -64,7 +64,7 @@ module ActiveSupport #:nodoc:
|
|
|
64
64
|
# Returns +true+ if _obj_ responds to the given method. Private methods are included in the search
|
|
65
65
|
# only if the optional second parameter evaluates to +true+.
|
|
66
66
|
def respond_to?(method, include_private=false)
|
|
67
|
-
super || @wrapped_string.respond_to?(method, include_private)
|
|
67
|
+
super || @wrapped_string.respond_to?(method, include_private)
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
# Enable more predictable duck-typing on String-like classes. See Object#acts_like?.
|
|
@@ -270,13 +270,14 @@ module ActiveSupport #:nodoc:
|
|
|
270
270
|
@wrapped_string[*args] = replace_by
|
|
271
271
|
else
|
|
272
272
|
result = Unicode.u_unpack(@wrapped_string)
|
|
273
|
-
|
|
273
|
+
case args.first
|
|
274
|
+
when Fixnum
|
|
274
275
|
raise IndexError, "index #{args[0]} out of string" if args[0] >= result.length
|
|
275
276
|
min = args[0]
|
|
276
277
|
max = args[1].nil? ? min : (min + args[1] - 1)
|
|
277
278
|
range = Range.new(min, max)
|
|
278
279
|
replace_by = [replace_by].pack('U') if replace_by.is_a?(Fixnum)
|
|
279
|
-
|
|
280
|
+
when Range
|
|
280
281
|
raise RangeError, "#{args[0]} out of range" if args[0].min >= result.length
|
|
281
282
|
range = args[0]
|
|
282
283
|
else
|
|
@@ -330,8 +331,7 @@ module ActiveSupport #:nodoc:
|
|
|
330
331
|
# when the storage for a string is limited for some reason.
|
|
331
332
|
#
|
|
332
333
|
# Example:
|
|
333
|
-
#
|
|
334
|
-
# s.mb_chars.limit(7) # => "こに"
|
|
334
|
+
# 'こんにちは'.mb_chars.limit(7).to_s # => "こん"
|
|
335
335
|
def limit(limit)
|
|
336
336
|
slice(0...translate_offset(limit))
|
|
337
337
|
end
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
1
2
|
module ActiveSupport
|
|
2
3
|
module Multibyte
|
|
3
4
|
module Unicode
|
|
@@ -247,7 +248,7 @@ module ActiveSupport
|
|
|
247
248
|
if is_unused || is_restricted
|
|
248
249
|
bytes[i] = tidy_byte(byte)
|
|
249
250
|
elsif is_cont
|
|
250
|
-
# Not expecting
|
|
251
|
+
# Not expecting continuation byte? Clean up. Otherwise, now expect one less.
|
|
251
252
|
conts_expected == 0 ? bytes[i] = tidy_byte(byte) : conts_expected -= 1
|
|
252
253
|
else
|
|
253
254
|
if conts_expected > 0
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module ActiveSupport
|
|
2
2
|
module Notifications
|
|
3
|
-
# This is a default queue implementation that ships with Notifications.
|
|
4
|
-
# just pushes events to all registered log subscribers.
|
|
3
|
+
# This is a default queue implementation that ships with Notifications.
|
|
4
|
+
# It just pushes events to all registered log subscribers.
|
|
5
5
|
class Fanout
|
|
6
6
|
def initialize
|
|
7
7
|
@subscribers = []
|
|
@@ -33,7 +33,7 @@ module ActiveSupport
|
|
|
33
33
|
listeners_for(name).any?
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
# This is a sync queue, so there is
|
|
36
|
+
# This is a sync queue, so there is no waiting.
|
|
37
37
|
def wait
|
|
38
38
|
end
|
|
39
39
|
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require 'active_support/core_ext/module/delegation'
|
|
2
|
-
|
|
3
1
|
module ActiveSupport
|
|
4
2
|
# Notifications provides an instrumentation API for Ruby. To instrument an
|
|
5
3
|
# action in Ruby you just need to do:
|
|
@@ -44,8 +42,11 @@ module ActiveSupport
|
|
|
44
42
|
@instrumenters = Hash.new { |h,k| h[k] = notifier.listening?(k) }
|
|
45
43
|
|
|
46
44
|
class << self
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
attr_accessor :notifier
|
|
46
|
+
|
|
47
|
+
def publish(name, *args)
|
|
48
|
+
notifier.publish(name, *args)
|
|
49
|
+
end
|
|
49
50
|
|
|
50
51
|
def instrument(name, payload = {})
|
|
51
52
|
if @instrumenters[name]
|
|
@@ -61,18 +62,16 @@ module ActiveSupport
|
|
|
61
62
|
end
|
|
62
63
|
end
|
|
63
64
|
|
|
64
|
-
def unsubscribe(
|
|
65
|
-
notifier.unsubscribe(
|
|
65
|
+
def unsubscribe(args)
|
|
66
|
+
notifier.unsubscribe(args)
|
|
66
67
|
@instrumenters.clear
|
|
67
68
|
end
|
|
68
69
|
|
|
69
|
-
def notifier
|
|
70
|
-
@notifier ||= Fanout.new
|
|
71
|
-
end
|
|
72
|
-
|
|
73
70
|
def instrumenter
|
|
74
71
|
Thread.current[:"instrumentation_#{notifier.object_id}"] ||= Instrumenter.new(notifier)
|
|
75
72
|
end
|
|
76
73
|
end
|
|
74
|
+
|
|
75
|
+
self.notifier = Fanout.new
|
|
77
76
|
end
|
|
78
77
|
end
|
|
@@ -9,8 +9,17 @@ YAML.add_builtin_type("omap") do |type, val|
|
|
|
9
9
|
ActiveSupport::OrderedHash[val.map(&:to_a).map(&:first)]
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
# OrderedHash is namespaced to prevent conflicts with other implementations
|
|
13
12
|
module ActiveSupport
|
|
13
|
+
# The order of iteration over hashes in Ruby 1.8 is undefined. For example, you do not know the
|
|
14
|
+
# order in which +keys+ will return keys, or +each+ yield pairs. <tt>ActiveSupport::OrderedHash</tt>
|
|
15
|
+
# implements a hash that preserves insertion order, as in Ruby 1.9:
|
|
16
|
+
#
|
|
17
|
+
# oh = ActiveSupport::OrderedHash.new
|
|
18
|
+
# oh[:a] = 1
|
|
19
|
+
# oh[:b] = 2
|
|
20
|
+
# oh.keys # => [:a, :b], this order is guaranteed
|
|
21
|
+
#
|
|
22
|
+
# <tt>ActiveSupport::OrderedHash</tt> is namespaced to prevent conflicts with other implementations.
|
|
14
23
|
class OrderedHash < ::Hash #:nodoc:
|
|
15
24
|
def to_yaml_type
|
|
16
25
|
"!tag:yaml.org,2002:omap"
|
|
@@ -34,6 +43,10 @@ module ActiveSupport
|
|
|
34
43
|
end
|
|
35
44
|
end
|
|
36
45
|
|
|
46
|
+
def nested_under_indifferent_access
|
|
47
|
+
self
|
|
48
|
+
end
|
|
49
|
+
|
|
37
50
|
# Hash is ordered in Ruby 1.9!
|
|
38
51
|
if RUBY_VERSION < '1.9'
|
|
39
52
|
|
|
@@ -83,7 +96,7 @@ module ActiveSupport
|
|
|
83
96
|
end
|
|
84
97
|
|
|
85
98
|
def []=(key, value)
|
|
86
|
-
@keys << key
|
|
99
|
+
@keys << key unless has_key?(key)
|
|
87
100
|
super
|
|
88
101
|
end
|
|
89
102
|
|
|
@@ -128,19 +141,27 @@ module ActiveSupport
|
|
|
128
141
|
end
|
|
129
142
|
|
|
130
143
|
def each_key
|
|
144
|
+
return to_enum(:each_key) unless block_given?
|
|
131
145
|
@keys.each { |key| yield key }
|
|
146
|
+
self
|
|
132
147
|
end
|
|
133
148
|
|
|
134
149
|
def each_value
|
|
150
|
+
return to_enum(:each_value) unless block_given?
|
|
135
151
|
@keys.each { |key| yield self[key]}
|
|
152
|
+
self
|
|
136
153
|
end
|
|
137
154
|
|
|
138
155
|
def each
|
|
156
|
+
return to_enum(:each) unless block_given?
|
|
139
157
|
@keys.each {|key| yield [key, self[key]]}
|
|
158
|
+
self
|
|
140
159
|
end
|
|
141
160
|
|
|
142
161
|
alias_method :each_pair, :each
|
|
143
162
|
|
|
163
|
+
alias_method :select, :find_all
|
|
164
|
+
|
|
144
165
|
def clear
|
|
145
166
|
super
|
|
146
167
|
@keys.clear
|