activesupport 3.0.20 → 3.1.0.beta1
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 +14 -66
- data/README.rdoc +1 -1
- data/lib/active_support/backtrace_cleaner.rb +1 -1
- data/lib/active_support/buffered_logger.rb +4 -11
- data/lib/active_support/cache.rb +12 -15
- data/lib/active_support/cache/file_store.rb +3 -2
- data/lib/active_support/cache/mem_cache_store.rb +11 -3
- data/lib/active_support/cache/strategy/local_cache.rb +28 -23
- data/lib/active_support/callbacks.rb +195 -175
- data/lib/active_support/concern.rb +105 -35
- data/lib/active_support/configurable.rb +41 -2
- data/lib/active_support/core_ext/array/access.rb +2 -2
- data/lib/active_support/core_ext/array/random_access.rb +10 -7
- data/lib/active_support/core_ext/big_decimal/conversions.rb +0 -2
- data/lib/active_support/core_ext/class/attribute.rb +27 -17
- data/lib/active_support/core_ext/class/inheritable_attributes.rb +12 -86
- data/lib/active_support/core_ext/class/subclasses.rb +20 -34
- data/lib/active_support/core_ext/date/calculations.rb +14 -2
- data/lib/active_support/core_ext/date/conversions.rb +6 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +26 -9
- data/lib/active_support/core_ext/date_time/conversions.rb +1 -1
- data/lib/active_support/core_ext/date_time/zones.rb +1 -1
- data/lib/active_support/core_ext/enumerable.rb +2 -5
- data/lib/active_support/core_ext/float/rounding.rb +1 -1
- data/lib/active_support/core_ext/hash.rb +1 -0
- data/lib/active_support/core_ext/hash/conversions.rb +23 -36
- data/lib/active_support/core_ext/hash/deep_dup.rb +11 -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/kernel/reporting.rb +19 -0
- data/lib/active_support/core_ext/logger.rb +11 -38
- data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +11 -12
- data/lib/active_support/core_ext/module/attr_internal.rb +13 -6
- data/lib/active_support/core_ext/module/deprecation.rb +2 -0
- data/lib/active_support/core_ext/object.rb +1 -1
- data/lib/active_support/core_ext/object/blank.rb +42 -9
- data/lib/active_support/core_ext/object/duplicable.rb +48 -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 +27 -10
- data/lib/active_support/core_ext/object/with_options.rb +19 -5
- data/lib/active_support/core_ext/range.rb +1 -0
- data/lib/active_support/core_ext/range/cover.rb +3 -0
- data/lib/active_support/core_ext/string.rb +1 -0
- 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 +1 -1
- data/lib/active_support/core_ext/string/output_safety.rb +33 -89
- data/lib/active_support/core_ext/time/calculations.rb +14 -13
- data/lib/active_support/core_ext/time/conversions.rb +2 -24
- data/lib/active_support/core_ext/time/marshal.rb +0 -1
- 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 +93 -37
- data/lib/active_support/deprecation.rb +2 -2
- 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/duration.rb +4 -0
- data/lib/active_support/file_update_checker.rb +1 -1
- data/lib/active_support/file_watcher.rb +36 -0
- data/lib/active_support/gzip.rb +0 -1
- data/lib/active_support/hash_with_indifferent_access.rb +6 -4
- data/lib/active_support/i18n.rb +0 -1
- data/lib/active_support/i18n_railtie.rb +2 -2
- data/lib/active_support/inflector/inflections.rb +1 -1
- data/lib/active_support/json/decoding.rb +37 -23
- data/lib/active_support/json/encoding.rb +8 -3
- data/lib/active_support/lazy_load_hooks.rb +7 -7
- data/lib/active_support/log_subscriber.rb +3 -3
- data/lib/active_support/log_subscriber/test_helper.rb +4 -3
- 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 +4 -3
- data/lib/active_support/multibyte/unicode.rb +1 -1
- data/lib/active_support/notifications.rb +9 -8
- data/lib/active_support/notifications/fanout.rb +3 -3
- data/lib/active_support/ordered_hash.rb +19 -2
- data/lib/active_support/ordered_options.rb +33 -3
- data/lib/active_support/railtie.rb +1 -1
- data/lib/active_support/rescuable.rb +1 -0
- data/lib/active_support/secure_random.rb +11 -5
- data/lib/active_support/test_case.rb +2 -10
- data/lib/active_support/testing/assertions.rb +17 -6
- data/lib/active_support/testing/mochaing.rb +7 -0
- data/lib/active_support/testing/pending.rb +27 -23
- 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/version.rb +3 -3
- data/lib/active_support/whiny_nil.rb +1 -1
- data/lib/active_support/xml_mini.rb +4 -2
- data/lib/active_support/xml_mini/jdom.rb +9 -16
- 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
- metadata +50 -32
- checksums.yaml +0 -7
- data/lib/active_support/core_ext/cgi.rb +0 -1
- data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +0 -19
- 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,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
|
@@ -153,6 +153,12 @@ class Object
|
|
153
153
|
end
|
154
154
|
end
|
155
155
|
|
156
|
+
class Struct
|
157
|
+
def as_json(options = nil) #:nodoc:
|
158
|
+
Hash[members.zip(values)]
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
156
162
|
class TrueClass
|
157
163
|
AS_JSON = ActiveSupport::JSON::Variable.new('true').freeze
|
158
164
|
def as_json(options = nil) AS_JSON end #:nodoc:
|
@@ -232,9 +238,8 @@ class Hash
|
|
232
238
|
|
233
239
|
# use encoder as a proxy to call as_json on all values in the subset, to protect from circular references
|
234
240
|
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 }
|
241
|
+
result = self.is_a?(ActiveSupport::OrderedHash) ? ActiveSupport::OrderedHash : Hash
|
242
|
+
result[subset.map { |k, v| [k.to_s, encoder.as_json(v)] }]
|
238
243
|
end
|
239
244
|
|
240
245
|
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] = [] }
|
@@ -4,7 +4,7 @@ require 'active_support/core_ext/class/attribute'
|
|
4
4
|
module ActiveSupport
|
5
5
|
# ActiveSupport::LogSubscriber is an object set to consume ActiveSupport::Notifications
|
6
6
|
# with solely purpose of logging. The log subscriber dispatches notifications to a
|
7
|
-
#
|
7
|
+
# 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
|
@@ -23,11 +23,11 @@ module ActiveSupport
|
|
23
23
|
# end
|
24
24
|
#
|
25
25
|
# 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
|
26
|
+
# as in the second line of the code above. The test helpers are responsible for setting
|
27
27
|
# up the queue, subscriptions and turning colors in logs off.
|
28
28
|
#
|
29
29
|
# The messages are available in the @logger instance, which is a logger with limited
|
30
|
-
# powers (it actually
|
30
|
+
# powers (it actually does not send anything to your output), and you can collect them
|
31
31
|
# doing @logger.logged(level), where level is the level used in logging, like info,
|
32
32
|
# debug, warn and so on.
|
33
33
|
#
|
@@ -38,13 +38,14 @@ module ActiveSupport
|
|
38
38
|
|
39
39
|
ActiveSupport::LogSubscriber.colorize_logging = false
|
40
40
|
|
41
|
+
@old_notifier = ActiveSupport::Notifications.notifier
|
41
42
|
set_logger(@logger)
|
42
43
|
ActiveSupport::Notifications.notifier = @notifier
|
43
44
|
end
|
44
45
|
|
45
46
|
def teardown
|
46
47
|
set_logger(nil)
|
47
|
-
ActiveSupport::Notifications.notifier =
|
48
|
+
ActiveSupport::Notifications.notifier = @old_notifier
|
48
49
|
end
|
49
50
|
|
50
51
|
class MockLogger
|
@@ -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
|
@@ -247,7 +247,7 @@ module ActiveSupport
|
|
247
247
|
if is_unused || is_restricted
|
248
248
|
bytes[i] = tidy_byte(byte)
|
249
249
|
elsif is_cont
|
250
|
-
# Not expecting
|
250
|
+
# Not expecting continuation byte? Clean up. Otherwise, now expect one less.
|
251
251
|
conts_expected == 0 ? bytes[i] = tidy_byte(byte) : conts_expected -= 1
|
252
252
|
else
|
253
253
|
if conts_expected > 0
|
@@ -44,8 +44,11 @@ module ActiveSupport
|
|
44
44
|
@instrumenters = Hash.new { |h,k| h[k] = notifier.listening?(k) }
|
45
45
|
|
46
46
|
class << self
|
47
|
-
|
48
|
-
|
47
|
+
attr_accessor :notifier
|
48
|
+
|
49
|
+
def publish(name, *args)
|
50
|
+
notifier.publish(name, *args)
|
51
|
+
end
|
49
52
|
|
50
53
|
def instrument(name, payload = {})
|
51
54
|
if @instrumenters[name]
|
@@ -61,18 +64,16 @@ module ActiveSupport
|
|
61
64
|
end
|
62
65
|
end
|
63
66
|
|
64
|
-
def unsubscribe(
|
65
|
-
notifier.unsubscribe(
|
67
|
+
def unsubscribe(args)
|
68
|
+
notifier.unsubscribe(args)
|
66
69
|
@instrumenters.clear
|
67
70
|
end
|
68
71
|
|
69
|
-
def notifier
|
70
|
-
@notifier ||= Fanout.new
|
71
|
-
end
|
72
|
-
|
73
72
|
def instrumenter
|
74
73
|
Thread.current[:"instrumentation_#{notifier.object_id}"] ||= Instrumenter.new(notifier)
|
75
74
|
end
|
76
75
|
end
|
76
|
+
|
77
|
+
self.notifier = Fanout.new
|
77
78
|
end
|
78
79
|
end
|
@@ -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
|
|
@@ -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"
|
@@ -83,7 +92,7 @@ module ActiveSupport
|
|
83
92
|
end
|
84
93
|
|
85
94
|
def []=(key, value)
|
86
|
-
@keys << key
|
95
|
+
@keys << key unless has_key?(key)
|
87
96
|
super
|
88
97
|
end
|
89
98
|
|
@@ -128,19 +137,27 @@ module ActiveSupport
|
|
128
137
|
end
|
129
138
|
|
130
139
|
def each_key
|
140
|
+
return to_enum(:each_key) unless block_given?
|
131
141
|
@keys.each { |key| yield key }
|
142
|
+
self
|
132
143
|
end
|
133
144
|
|
134
145
|
def each_value
|
146
|
+
return to_enum(:each_value) unless block_given?
|
135
147
|
@keys.each { |key| yield self[key]}
|
148
|
+
self
|
136
149
|
end
|
137
150
|
|
138
151
|
def each
|
152
|
+
return to_enum(:each) unless block_given?
|
139
153
|
@keys.each {|key| yield [key, self[key]]}
|
154
|
+
self
|
140
155
|
end
|
141
156
|
|
142
157
|
alias_method :each_pair, :each
|
143
158
|
|
159
|
+
alias_method :select, :find_all
|
160
|
+
|
144
161
|
def clear
|
145
162
|
super
|
146
163
|
@keys.clear
|
@@ -1,7 +1,26 @@
|
|
1
1
|
require 'active_support/ordered_hash'
|
2
2
|
|
3
|
+
# Usually key value pairs are handled something like this:
|
4
|
+
#
|
5
|
+
# h = {}
|
6
|
+
# h[:boy] = 'John'
|
7
|
+
# h[:girl] = 'Mary'
|
8
|
+
# h[:boy] # => 'John'
|
9
|
+
# h[:girl] # => 'Mary'
|
10
|
+
#
|
11
|
+
# Using <tt>OrderedOptions</tt>, the above code could be reduced to:
|
12
|
+
#
|
13
|
+
# h = ActiveSupport::OrderedOptions.new
|
14
|
+
# h.boy = 'John'
|
15
|
+
# h.girl = 'Mary'
|
16
|
+
# h.boy # => 'John'
|
17
|
+
# h.girl # => 'Mary'
|
18
|
+
#
|
3
19
|
module ActiveSupport #:nodoc:
|
4
20
|
class OrderedOptions < OrderedHash
|
21
|
+
alias_method :_get, :[] # preserve the original #[] method
|
22
|
+
protected :_get # make it protected
|
23
|
+
|
5
24
|
def []=(key, value)
|
6
25
|
super(key.to_sym, value)
|
7
26
|
end
|
@@ -12,7 +31,7 @@ module ActiveSupport #:nodoc:
|
|
12
31
|
|
13
32
|
def method_missing(name, *args)
|
14
33
|
if name.to_s =~ /(.*)=$/
|
15
|
-
self[$1
|
34
|
+
self[$1] = args.first
|
16
35
|
else
|
17
36
|
self[name]
|
18
37
|
end
|
@@ -20,8 +39,19 @@ module ActiveSupport #:nodoc:
|
|
20
39
|
end
|
21
40
|
|
22
41
|
class InheritableOptions < OrderedOptions
|
23
|
-
def initialize(parent)
|
24
|
-
|
42
|
+
def initialize(parent = nil)
|
43
|
+
if parent.kind_of?(OrderedOptions)
|
44
|
+
# use the faster _get when dealing with OrderedOptions
|
45
|
+
super() { |h,k| parent._get(k) }
|
46
|
+
elsif parent
|
47
|
+
super() { |h,k| parent[k] }
|
48
|
+
else
|
49
|
+
super()
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def inheritable_copy
|
54
|
+
self.class.new(self)
|
25
55
|
end
|
26
56
|
end
|
27
57
|
end
|
@@ -46,7 +46,7 @@ module ActiveSupport
|
|
46
46
|
# If assigned value cannot be matched to a TimeZone, an exception will be raised.
|
47
47
|
initializer "active_support.initialize_time_zone" do |app|
|
48
48
|
require 'active_support/core_ext/time/zones'
|
49
|
-
zone_default = Time.
|
49
|
+
zone_default = Time.find_zone!(app.config.time_zone)
|
50
50
|
|
51
51
|
unless zone_default
|
52
52
|
raise \
|
@@ -46,8 +46,10 @@ module ActiveSupport
|
|
46
46
|
# p SecureRandom.random_bytes(10) # => "\016\t{\370g\310pbr\301"
|
47
47
|
# p SecureRandom.random_bytes(10) # => "\323U\030TO\234\357\020\a\337"
|
48
48
|
# ...
|
49
|
+
#
|
49
50
|
module SecureRandom
|
50
|
-
|
51
|
+
|
52
|
+
# Generates a random binary string.
|
51
53
|
#
|
52
54
|
# The argument n specifies the length of the result string.
|
53
55
|
#
|
@@ -56,6 +58,7 @@ module ActiveSupport
|
|
56
58
|
#
|
57
59
|
# If secure random number generator is not available,
|
58
60
|
# NotImplementedError is raised.
|
61
|
+
#
|
59
62
|
def self.random_bytes(n=nil)
|
60
63
|
n ||= 16
|
61
64
|
|
@@ -92,7 +95,7 @@ module ActiveSupport
|
|
92
95
|
end
|
93
96
|
end
|
94
97
|
|
95
|
-
|
98
|
+
unless defined?(@has_win32)
|
96
99
|
begin
|
97
100
|
require 'Win32API'
|
98
101
|
|
@@ -124,7 +127,7 @@ module ActiveSupport
|
|
124
127
|
raise NotImplementedError, "No random device"
|
125
128
|
end
|
126
129
|
|
127
|
-
#
|
130
|
+
# Generates a random hex string.
|
128
131
|
#
|
129
132
|
# The argument n specifies the length of the random length.
|
130
133
|
# The length of the result string is twice of n.
|
@@ -134,11 +137,12 @@ module ActiveSupport
|
|
134
137
|
#
|
135
138
|
# If secure random number generator is not available,
|
136
139
|
# NotImplementedError is raised.
|
140
|
+
#
|
137
141
|
def self.hex(n=nil)
|
138
142
|
random_bytes(n).unpack("H*")[0]
|
139
143
|
end
|
140
144
|
|
141
|
-
#
|
145
|
+
# Generates a random base64 string.
|
142
146
|
#
|
143
147
|
# The argument n specifies the length of the random length.
|
144
148
|
# The length of the result string is about 4/3 of n.
|
@@ -148,11 +152,12 @@ module ActiveSupport
|
|
148
152
|
#
|
149
153
|
# If secure random number generator is not available,
|
150
154
|
# NotImplementedError is raised.
|
155
|
+
#
|
151
156
|
def self.base64(n=nil)
|
152
157
|
[random_bytes(n)].pack("m*").delete("\n")
|
153
158
|
end
|
154
159
|
|
155
|
-
#
|
160
|
+
# Generates a random number.
|
156
161
|
#
|
157
162
|
# If an positive integer is given as n,
|
158
163
|
# SecureRandom.random_number returns an integer:
|
@@ -161,6 +166,7 @@ module ActiveSupport
|
|
161
166
|
# If 0 is given or an argument is not given,
|
162
167
|
# SecureRandom.random_number returns an float:
|
163
168
|
# 0.0 <= SecureRandom.random_number() < 1.0.
|
169
|
+
#
|
164
170
|
def self.random_number(n=0)
|
165
171
|
if 0 < n
|
166
172
|
hex = n.to_s(16)
|