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
@@ -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
- @@direct_descendants.each do |klass, descendants|
22
- if ActiveSupport::Dependencies.autoloaded?(klass)
23
- @@direct_descendants.delete(klass)
24
- else
25
- descendants.reject! { |v| ActiveSupport::Dependencies.autoloaded?(v) }
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:
@@ -8,7 +8,7 @@ module ActiveSupport
8
8
  # I18n.reload!
9
9
  # end
10
10
  #
11
- # ActionDispatch::Callbacks.to_prepare do
11
+ # ActionDispatch::Reloader.to_prepare do
12
12
  # i18n_reloader.execute_if_updated
13
13
  # end
14
14
  #
@@ -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
- ActiveSupport::HashWithIndifferentAccess.new(hash).tap do |new_hash|
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.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
62
- self
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
- HashWithIndifferentAccess.new(self)
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.class == Hash
142
- self.class.new_from_hash_copying_default(value)
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
@@ -7,4 +7,3 @@ rescue LoadError => e
7
7
  end
8
8
 
9
9
  I18n.load_path << "#{File.dirname(__FILE__)}/locale/en.yml"
10
- ActiveSupport.run_load_hooks(:i18n)
@@ -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::Callbacks.to_prepare do
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
@@ -96,7 +96,7 @@ module ActiveSupport
96
96
  def clear(scope = :all)
97
97
  case scope
98
98
  when :all
99
- @plurals, @singulars, @uncountables = [], [], []
99
+ @plurals, @singulars, @uncountables, @humans = [], [], [], []
100
100
  else
101
101
  instance_variable_set "@#{scope}", []
102
102
  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
- 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
@@ -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) to_a end #:nodoc:
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
- 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 }
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
- # 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] = [] }
@@ -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 is reponsible for setting
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 do not send anything to your output), and you can collect them
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 = nil
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 solely purpose of logging. The log subscriber dispatches notifications to a
7
- # regirested object based on its given namespace.
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 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
@@ -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 it automatically appends CLEAR to the end
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, 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
@@ -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
- # s = 'こんにちは'
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 contination byte? Clean up. Otherwise, now expect one less.
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. 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
 
@@ -29,7 +29,7 @@ module ActiveSupport
29
29
 
30
30
  private
31
31
  def unique_id
32
- SecureRandom.hex(10)
32
+ ::SecureRandom.hex(10)
33
33
  end
34
34
  end
35
35
 
@@ -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
- attr_writer :notifier
48
- delegate :publish, :to => :notifier
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(*args)
65
- notifier.unsubscribe(*args)
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 if !has_key?(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