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.

Files changed (110) hide show
  1. data/CHANGELOG +14 -66
  2. data/README.rdoc +1 -1
  3. data/lib/active_support/backtrace_cleaner.rb +1 -1
  4. data/lib/active_support/buffered_logger.rb +4 -11
  5. data/lib/active_support/cache.rb +12 -15
  6. data/lib/active_support/cache/file_store.rb +3 -2
  7. data/lib/active_support/cache/mem_cache_store.rb +11 -3
  8. data/lib/active_support/cache/strategy/local_cache.rb +28 -23
  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 +41 -2
  12. data/lib/active_support/core_ext/array/access.rb +2 -2
  13. data/lib/active_support/core_ext/array/random_access.rb +10 -7
  14. data/lib/active_support/core_ext/big_decimal/conversions.rb +0 -2
  15. data/lib/active_support/core_ext/class/attribute.rb +27 -17
  16. data/lib/active_support/core_ext/class/inheritable_attributes.rb +12 -86
  17. data/lib/active_support/core_ext/class/subclasses.rb +20 -34
  18. data/lib/active_support/core_ext/date/calculations.rb +14 -2
  19. data/lib/active_support/core_ext/date/conversions.rb +6 -0
  20. data/lib/active_support/core_ext/date_time/calculations.rb +26 -9
  21. data/lib/active_support/core_ext/date_time/conversions.rb +1 -1
  22. data/lib/active_support/core_ext/date_time/zones.rb +1 -1
  23. data/lib/active_support/core_ext/enumerable.rb +2 -5
  24. data/lib/active_support/core_ext/float/rounding.rb +1 -1
  25. data/lib/active_support/core_ext/hash.rb +1 -0
  26. data/lib/active_support/core_ext/hash/conversions.rb +23 -36
  27. data/lib/active_support/core_ext/hash/deep_dup.rb +11 -0
  28. data/lib/active_support/core_ext/hash/keys.rb +6 -4
  29. data/lib/active_support/core_ext/hash/reverse_merge.rb +9 -14
  30. data/lib/active_support/core_ext/kernel/reporting.rb +19 -0
  31. data/lib/active_support/core_ext/logger.rb +11 -38
  32. data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +11 -12
  33. data/lib/active_support/core_ext/module/attr_internal.rb +13 -6
  34. data/lib/active_support/core_ext/module/deprecation.rb +2 -0
  35. data/lib/active_support/core_ext/object.rb +1 -1
  36. data/lib/active_support/core_ext/object/blank.rb +42 -9
  37. data/lib/active_support/core_ext/object/duplicable.rb +48 -9
  38. data/lib/active_support/core_ext/object/inclusion.rb +15 -0
  39. data/lib/active_support/core_ext/object/instance_variables.rb +1 -35
  40. data/lib/active_support/core_ext/object/to_param.rb +13 -8
  41. data/lib/active_support/core_ext/object/to_query.rb +2 -2
  42. data/lib/active_support/core_ext/object/try.rb +27 -10
  43. data/lib/active_support/core_ext/object/with_options.rb +19 -5
  44. data/lib/active_support/core_ext/range.rb +1 -0
  45. data/lib/active_support/core_ext/range/cover.rb +3 -0
  46. data/lib/active_support/core_ext/string.rb +1 -0
  47. data/lib/active_support/core_ext/string/filters.rb +3 -3
  48. data/lib/active_support/core_ext/string/inflections.rb +1 -1
  49. data/lib/active_support/core_ext/string/inquiry.rb +13 -0
  50. data/lib/active_support/core_ext/string/multibyte.rb +1 -1
  51. data/lib/active_support/core_ext/string/output_safety.rb +33 -89
  52. data/lib/active_support/core_ext/time/calculations.rb +14 -13
  53. data/lib/active_support/core_ext/time/conversions.rb +2 -24
  54. data/lib/active_support/core_ext/time/marshal.rb +0 -1
  55. data/lib/active_support/core_ext/time/zones.rb +32 -21
  56. data/lib/active_support/core_ext/uri.rb +8 -0
  57. data/lib/active_support/dependencies.rb +93 -37
  58. data/lib/active_support/deprecation.rb +2 -2
  59. data/lib/active_support/deprecation/behaviors.rb +7 -0
  60. data/lib/active_support/deprecation/proxy_wrappers.rb +1 -1
  61. data/lib/active_support/deprecation/reporting.rb +4 -0
  62. data/lib/active_support/duration.rb +4 -0
  63. data/lib/active_support/file_update_checker.rb +1 -1
  64. data/lib/active_support/file_watcher.rb +36 -0
  65. data/lib/active_support/gzip.rb +0 -1
  66. data/lib/active_support/hash_with_indifferent_access.rb +6 -4
  67. data/lib/active_support/i18n.rb +0 -1
  68. data/lib/active_support/i18n_railtie.rb +2 -2
  69. data/lib/active_support/inflector/inflections.rb +1 -1
  70. data/lib/active_support/json/decoding.rb +37 -23
  71. data/lib/active_support/json/encoding.rb +8 -3
  72. data/lib/active_support/lazy_load_hooks.rb +7 -7
  73. data/lib/active_support/log_subscriber.rb +3 -3
  74. data/lib/active_support/log_subscriber/test_helper.rb +4 -3
  75. data/lib/active_support/message_encryptor.rb +1 -1
  76. data/lib/active_support/message_verifier.rb +1 -1
  77. data/lib/active_support/multibyte/chars.rb +4 -3
  78. data/lib/active_support/multibyte/unicode.rb +1 -1
  79. data/lib/active_support/notifications.rb +9 -8
  80. data/lib/active_support/notifications/fanout.rb +3 -3
  81. data/lib/active_support/ordered_hash.rb +19 -2
  82. data/lib/active_support/ordered_options.rb +33 -3
  83. data/lib/active_support/railtie.rb +1 -1
  84. data/lib/active_support/rescuable.rb +1 -0
  85. data/lib/active_support/secure_random.rb +11 -5
  86. data/lib/active_support/test_case.rb +2 -10
  87. data/lib/active_support/testing/assertions.rb +17 -6
  88. data/lib/active_support/testing/mochaing.rb +7 -0
  89. data/lib/active_support/testing/pending.rb +27 -23
  90. data/lib/active_support/testing/setup_and_teardown.rb +8 -11
  91. data/lib/active_support/time_with_zone.rb +6 -3
  92. data/lib/active_support/version.rb +3 -3
  93. data/lib/active_support/whiny_nil.rb +1 -1
  94. data/lib/active_support/xml_mini.rb +4 -2
  95. data/lib/active_support/xml_mini/jdom.rb +9 -16
  96. data/lib/active_support/xml_mini/libxml.rb +1 -0
  97. data/lib/active_support/xml_mini/libxmlsax.rb +2 -1
  98. data/lib/active_support/xml_mini/nokogiri.rb +1 -0
  99. data/lib/active_support/xml_mini/nokogirisax.rb +1 -0
  100. data/lib/active_support/xml_mini/rexml.rb +1 -0
  101. metadata +50 -32
  102. checksums.yaml +0 -7
  103. data/lib/active_support/core_ext/cgi.rb +0 -1
  104. data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +0 -19
  105. data/lib/active_support/core_ext/object/returning.rb +0 -43
  106. data/lib/active_support/json/backends/jsongem.rb +0 -47
  107. data/lib/active_support/json/backends/okjson.rb +0 -644
  108. data/lib/active_support/json/backends/yajl.rb +0 -44
  109. data/lib/active_support/json/backends/yaml.rb +0 -19
  110. 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
- attr_reader :parse_error
14
- delegate :decode, :to => :backend
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 backend
17
- set_default_backend unless defined?(@backend)
18
- @backend
20
+ def engine
21
+ MultiJson.engine
19
22
  end
23
+ alias :backend :engine
20
24
 
21
- def backend=(name)
22
- if name.is_a?(Module)
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 set_default_backend
39
- DECODERS.find do |name|
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
- self.backend = name
42
- true
43
- rescue LoadError
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
- 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 }
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
- # 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
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
- # ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base)
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
- # regirested object based on its given namespace.
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 registed as:
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 is reponsible for setting
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 do not send anything to your output), and you can collect them
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 = nil
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, but where you don't
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) || false
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
- if args[0].is_a?(Fixnum)
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
- elsif args.first.is_a?(Range)
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 contination byte? Clean up. Otherwise, now expect one less.
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
- attr_writer :notifier
48
- delegate :publish, :to => :notifier
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(*args)
65
- notifier.unsubscribe(*args)
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. It
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 not waiting.
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 if !has_key?(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.to_sym] = args.first
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
- super() { |h,k| parent[k] }
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.__send__(:get_zone, app.config.time_zone)
49
+ zone_default = Time.find_zone!(app.config.time_zone)
50
50
 
51
51
  unless zone_default
52
52
  raise \
@@ -47,6 +47,7 @@ module ActiveSupport
47
47
  # exception.record.new_record? ? ...
48
48
  # end
49
49
  # end
50
+ #
50
51
  def rescue_from(*klasses, &block)
51
52
  options = klasses.extract_options!
52
53
 
@@ -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
- # SecureRandom.random_bytes generates a random binary string.
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
- if !defined?(@has_win32)
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
- # SecureRandom.hex generates a random hex string.
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
- # SecureRandom.base64 generates a random base64 string.
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
- # SecureRandom.random_number generates a random number.
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)