activesupport 4.1.15 → 4.2.11.3

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 (111) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +395 -574
  3. data/README.rdoc +7 -2
  4. data/lib/active_support.rb +19 -0
  5. data/lib/active_support/backtrace_cleaner.rb +4 -4
  6. data/lib/active_support/cache.rb +17 -19
  7. data/lib/active_support/cache/file_store.rb +5 -0
  8. data/lib/active_support/cache/mem_cache_store.rb +1 -1
  9. data/lib/active_support/cache/strategy/local_cache.rb +5 -4
  10. data/lib/active_support/cache/strategy/local_cache_middleware.rb +5 -0
  11. data/lib/active_support/callbacks.rb +41 -33
  12. data/lib/active_support/concern.rb +10 -2
  13. data/lib/active_support/core_ext/array/access.rb +9 -1
  14. data/lib/active_support/core_ext/array/grouping.rb +5 -0
  15. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +2 -0
  16. data/lib/active_support/core_ext/class/delegating_attributes.rb +4 -0
  17. data/lib/active_support/core_ext/class/subclasses.rb +0 -2
  18. data/lib/active_support/core_ext/date/conversions.rb +6 -0
  19. data/lib/active_support/core_ext/date_and_time/calculations.rb +11 -0
  20. data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
  21. data/lib/active_support/core_ext/date_time.rb +1 -0
  22. data/lib/active_support/core_ext/date_time/calculations.rb +34 -4
  23. data/lib/active_support/core_ext/date_time/compatibility.rb +16 -0
  24. data/lib/active_support/core_ext/date_time/conversions.rb +2 -2
  25. data/lib/active_support/core_ext/digest/uuid.rb +51 -0
  26. data/lib/active_support/core_ext/enumerable.rb +16 -0
  27. data/lib/active_support/core_ext/file/atomic.rb +1 -1
  28. data/lib/active_support/core_ext/hash.rb +1 -0
  29. data/lib/active_support/core_ext/hash/compact.rb +20 -16
  30. data/lib/active_support/core_ext/hash/conversions.rb +3 -5
  31. data/lib/active_support/core_ext/hash/except.rb +8 -2
  32. data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -1
  33. data/lib/active_support/core_ext/hash/keys.rb +10 -6
  34. data/lib/active_support/core_ext/hash/slice.rb +8 -2
  35. data/lib/active_support/core_ext/hash/transform_values.rb +23 -0
  36. data/lib/active_support/core_ext/integer/time.rb +0 -15
  37. data/lib/active_support/core_ext/kernel.rb +3 -2
  38. data/lib/active_support/core_ext/kernel/concern.rb +10 -0
  39. data/lib/active_support/core_ext/kernel/debugger.rb +1 -1
  40. data/lib/active_support/core_ext/kernel/reporting.rb +15 -0
  41. data/lib/active_support/core_ext/load_error.rb +4 -1
  42. data/lib/active_support/core_ext/marshal.rb +8 -5
  43. data/lib/active_support/core_ext/module/aliasing.rb +2 -2
  44. data/lib/active_support/core_ext/module/delegation.rb +34 -18
  45. data/lib/active_support/core_ext/module/method_transplanting.rb +3 -1
  46. data/lib/active_support/core_ext/numeric/conversions.rb +11 -3
  47. data/lib/active_support/core_ext/numeric/time.rb +1 -34
  48. data/lib/active_support/core_ext/object.rb +1 -0
  49. data/lib/active_support/core_ext/object/blank.rb +2 -2
  50. data/lib/active_support/core_ext/object/duplicable.rb +62 -33
  51. data/lib/active_support/core_ext/object/itself.rb +15 -0
  52. data/lib/active_support/core_ext/object/json.rb +2 -2
  53. data/lib/active_support/core_ext/object/to_query.rb +2 -1
  54. data/lib/active_support/core_ext/object/try.rb +35 -13
  55. data/lib/active_support/core_ext/object/with_options.rb +30 -3
  56. data/lib/active_support/core_ext/string/access.rb +5 -5
  57. data/lib/active_support/core_ext/string/conversions.rb +1 -1
  58. data/lib/active_support/core_ext/string/filters.rb +44 -6
  59. data/lib/active_support/core_ext/string/inflections.rb +4 -1
  60. data/lib/active_support/core_ext/string/output_safety.rb +33 -14
  61. data/lib/active_support/core_ext/thread.rb +7 -0
  62. data/lib/active_support/core_ext/time.rb +1 -0
  63. data/lib/active_support/core_ext/time/calculations.rb +31 -7
  64. data/lib/active_support/core_ext/time/compatibility.rb +14 -0
  65. data/lib/active_support/core_ext/time/conversions.rb +1 -1
  66. data/lib/active_support/dependencies.rb +32 -18
  67. data/lib/active_support/dependencies/autoload.rb +1 -1
  68. data/lib/active_support/deprecation.rb +1 -1
  69. data/lib/active_support/deprecation/behaviors.rb +1 -1
  70. data/lib/active_support/duration.rb +47 -5
  71. data/lib/active_support/gem_version.rb +4 -4
  72. data/lib/active_support/hash_with_indifferent_access.rb +35 -7
  73. data/lib/active_support/i18n_railtie.rb +1 -7
  74. data/lib/active_support/inflector/inflections.rb +2 -2
  75. data/lib/active_support/inflector/methods.rb +43 -19
  76. data/lib/active_support/json/decoding.rb +1 -1
  77. data/lib/active_support/json/encoding.rb +3 -2
  78. data/lib/active_support/logger.rb +36 -0
  79. data/lib/active_support/logger_silence.rb +4 -22
  80. data/lib/active_support/logger_thread_safe_level.rb +32 -0
  81. data/lib/active_support/message_encryptor.rb +10 -2
  82. data/lib/active_support/message_verifier.rb +11 -12
  83. data/lib/active_support/multibyte/chars.rb +1 -1
  84. data/lib/active_support/multibyte/unicode.rb +5 -4
  85. data/lib/active_support/notifications.rb +8 -3
  86. data/lib/active_support/notifications/fanout.rb +12 -7
  87. data/lib/active_support/number_helper.rb +12 -13
  88. data/lib/active_support/number_helper/number_to_currency_converter.rb +1 -1
  89. data/lib/active_support/number_helper/number_to_percentage_converter.rb +1 -1
  90. data/lib/active_support/number_helper/number_to_rounded_converter.rb +1 -1
  91. data/lib/active_support/per_thread_registry.rb +5 -3
  92. data/lib/active_support/test_case.rb +46 -12
  93. data/lib/active_support/testing/assertions.rb +1 -1
  94. data/lib/active_support/testing/constant_lookup.rb +1 -5
  95. data/lib/active_support/testing/declarative.rb +1 -25
  96. data/lib/active_support/testing/isolation.rb +16 -6
  97. data/lib/active_support/testing/tagged_logging.rb +1 -1
  98. data/lib/active_support/testing/time_helpers.rb +23 -16
  99. data/lib/active_support/time.rb +0 -2
  100. data/lib/active_support/time_with_zone.rb +48 -29
  101. data/lib/active_support/values/time_zone.rb +81 -75
  102. data/lib/active_support/values/unicode_tables.dat +0 -0
  103. data/lib/active_support/xml_mini.rb +30 -15
  104. data/lib/active_support/xml_mini/libxml.rb +1 -3
  105. data/lib/active_support/xml_mini/libxmlsax.rb +1 -4
  106. data/lib/active_support/xml_mini/nokogiri.rb +1 -3
  107. data/lib/active_support/xml_mini/nokogirisax.rb +1 -3
  108. data/lib/active_support/xml_mini/rexml.rb +1 -3
  109. metadata +21 -36
  110. data/lib/active_support/core_ext/object/to_json.rb +0 -5
  111. data/lib/active_support/file_watcher.rb +0 -36
@@ -14,7 +14,7 @@ The latest version of Active Support can be installed with RubyGems:
14
14
 
15
15
  Source code can be downloaded as part of the Rails project on GitHub:
16
16
 
17
- * https://github.com/rails/rails/tree/4-1-stable/activesupport
17
+ * https://github.com/rails/rails/tree/4-2-stable/activesupport
18
18
 
19
19
 
20
20
  == License
@@ -30,6 +30,11 @@ API documentation is at:
30
30
 
31
31
  * http://api.rubyonrails.org
32
32
 
33
- Bug reports and feature requests can be filed with the rest for the Ruby on Rails project here:
33
+ Bug reports can be filed for the Ruby on Rails project here:
34
34
 
35
35
  * https://github.com/rails/rails/issues
36
+
37
+ Feature requests should be discussed on the rails-core mailing list here:
38
+
39
+ * https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core
40
+
@@ -26,6 +26,7 @@ require "active_support/dependencies/autoload"
26
26
  require "active_support/version"
27
27
  require "active_support/logger"
28
28
  require "active_support/lazy_load_hooks"
29
+ require "active_support/core_ext/date_and_time/compatibility"
29
30
 
30
31
  module ActiveSupport
31
32
  extend ActiveSupport::Autoload
@@ -70,6 +71,24 @@ module ActiveSupport
70
71
 
71
72
  NumberHelper.eager_load!
72
73
  end
74
+
75
+ @@test_order = nil
76
+
77
+ def self.test_order=(new_order) # :nodoc:
78
+ @@test_order = new_order
79
+ end
80
+
81
+ def self.test_order # :nodoc:
82
+ @@test_order
83
+ end
84
+
85
+ def self.to_time_preserves_timezone
86
+ DateAndTime::Compatibility.preserve_timezone
87
+ end
88
+
89
+ def self.to_time_preserves_timezone=(value)
90
+ DateAndTime::Compatibility.preserve_timezone = value
91
+ end
73
92
  end
74
93
 
75
94
  autoload :I18n, "active_support/i18n"
@@ -13,7 +13,7 @@ module ActiveSupport
13
13
  # can focus on the rest.
14
14
  #
15
15
  # bc = BacktraceCleaner.new
16
- # bc.add_filter { |line| line.gsub(Rails.root, '') } # strip the Rails.root prefix
16
+ # bc.add_filter { |line| line.gsub(Rails.root.to_s, '') } # strip the Rails.root prefix
17
17
  # bc.add_silencer { |line| line =~ /mongrel|rubygems/ } # skip any lines from mongrel or rubygems
18
18
  # bc.clean(exception.backtrace) # perform the cleanup
19
19
  #
@@ -65,14 +65,14 @@ module ActiveSupport
65
65
  @silencers << block
66
66
  end
67
67
 
68
- # Will remove all silencers, but leave in the filters. This is useful if
69
- # your context of debugging suddenly expands as you suspect a bug in one of
68
+ # Removes all silencers, but leaves in the filters. Useful if your
69
+ # context of debugging suddenly expands as you suspect a bug in one of
70
70
  # the libraries you use.
71
71
  def remove_silencers!
72
72
  @silencers = []
73
73
  end
74
74
 
75
- # Removes all filters, but leaves in silencers. Useful if you suddenly
75
+ # Removes all filters, but leaves in the silencers. Useful if you suddenly
76
76
  # need to see entire filepaths in the backtrace that you had already
77
77
  # filtered out.
78
78
  def remove_filters!
@@ -8,6 +8,7 @@ require 'active_support/core_ext/numeric/bytes'
8
8
  require 'active_support/core_ext/numeric/time'
9
9
  require 'active_support/core_ext/object/to_param'
10
10
  require 'active_support/core_ext/string/inflections'
11
+ require 'active_support/deprecation'
11
12
 
12
13
  module ActiveSupport
13
14
  # See ActiveSupport::Cache::Store for documentation.
@@ -26,7 +27,7 @@ module ActiveSupport
26
27
  end
27
28
 
28
29
  class << self
29
- # Creates a new CacheStore object according to the given options.
30
+ # Creates a new Store object according to the given options.
30
31
  #
31
32
  # If no arguments are passed to this method, then a new
32
33
  # ActiveSupport::Cache::MemoryStore object will be returned.
@@ -178,14 +179,16 @@ module ActiveSupport
178
179
  @silence = previous_silence
179
180
  end
180
181
 
181
- # Set to +true+ if cache stores should be instrumented.
182
- # Default is +false+.
182
+ # :deprecated:
183
183
  def self.instrument=(boolean)
184
- Thread.current[:instrument_cache_store] = boolean
184
+ ActiveSupport::Deprecation.warn "ActiveSupport::Cache.instrument= is deprecated and will be removed in Rails 5. Instrumentation is now always on so you can safely stop using it."
185
+ true
185
186
  end
186
187
 
188
+ # :deprecated:
187
189
  def self.instrument
188
- Thread.current[:instrument_cache_store] || false
190
+ ActiveSupport::Deprecation.warn "ActiveSupport::Cache.instrument is deprecated and will be removed in Rails 5. Instrumentation is now always on so you can safely stop using it."
191
+ true
189
192
  end
190
193
 
191
194
  # Fetches data from the cache, using the given key. If there is data in
@@ -234,7 +237,7 @@ module ActiveSupport
234
237
  # seconds. Because of extended life of the previous cache, other processes
235
238
  # will continue to use slightly stale data for a just a bit longer. In the
236
239
  # meantime that first process will go ahead and will write into cache the
237
- # new value. After that all the processes will start getting new value.
240
+ # new value. After that all the processes will start getting the new value.
238
241
  # The key is to keep <tt>:race_condition_ttl</tt> small.
239
242
  #
240
243
  # If the process regenerating the entry errors out, the entry will be
@@ -357,20 +360,19 @@ module ActiveSupport
357
360
  #
358
361
  # Options are passed to the underlying cache implementation.
359
362
  #
360
- # Returns an array with the data for each of the names. For example:
363
+ # Returns a hash with the data for each of the names. For example:
361
364
  #
362
365
  # cache.write("bim", "bam")
363
- # cache.fetch_multi("bim", "boom") {|key| key * 2 }
364
- # # => ["bam", "boomboom"]
366
+ # cache.fetch_multi("bim", "boom") { |key| key * 2 }
367
+ # # => { "bam" => "bam", "boom" => "boomboom" }
365
368
  #
366
369
  def fetch_multi(*names)
367
370
  options = names.extract_options!
368
371
  options = merged_options(options)
369
-
370
372
  results = read_multi(*names, options)
371
373
 
372
- names.map do |name|
373
- results.fetch(name) do
374
+ names.each_with_object({}) do |name, memo|
375
+ memo[name] = results.fetch(name) do
374
376
  value = yield name
375
377
  write(name, value, options)
376
378
  value
@@ -540,13 +542,9 @@ module ActiveSupport
540
542
  def instrument(operation, key, options = nil)
541
543
  log(operation, key, options)
542
544
 
543
- if self.class.instrument
544
- payload = { :key => key }
545
- payload.merge!(options) if options.is_a?(Hash)
546
- ActiveSupport::Notifications.instrument("cache_#{operation}.active_support", payload){ yield(payload) }
547
- else
548
- yield(nil)
549
- end
545
+ payload = { :key => key }
546
+ payload.merge!(options) if options.is_a?(Hash)
547
+ ActiveSupport::Notifications.instrument("cache_#{operation}.active_support", payload){ yield(payload) }
550
548
  end
551
549
 
552
550
  def log(operation, key, options = nil)
@@ -14,6 +14,7 @@ module ActiveSupport
14
14
 
15
15
  DIR_FORMATTER = "%03X"
16
16
  FILENAME_MAX_SIZE = 228 # max filename size on file system is 255, minus room for timestamp and random characters appended by Tempfile (used by atomic write)
17
+ FILEPATH_MAX_SIZE = 900 # max is 1024, plus some room
17
18
  EXCLUDED_DIRS = ['.', '..'].freeze
18
19
 
19
20
  def initialize(cache_path, options = nil)
@@ -117,6 +118,10 @@ module ActiveSupport
117
118
 
118
119
  # Translate a key into a file path.
119
120
  def key_file_path(key)
121
+ if key.size > FILEPATH_MAX_SIZE
122
+ key = Digest::MD5.hexdigest(key)
123
+ end
124
+
120
125
  fname = URI.encode_www_form_component(key)
121
126
  hash = Zlib.adler32(fname)
122
127
  hash, dir_1 = hash.divmod(0x1000)
@@ -67,7 +67,7 @@ module ActiveSupport
67
67
  options = names.extract_options!
68
68
  options = merged_options(options)
69
69
  keys_to_names = Hash[names.map{|name| [escape_key(namespaced_key(name, options)), name]}]
70
- raw_values = @data.get_multi(keys_to_names.keys, :raw => true)
70
+ raw_values = @data.get_multi(keys_to_names.keys)
71
71
  values = {}
72
72
  raw_values.each do |key, value|
73
73
  entry = deserialize_entry(value)
@@ -86,13 +86,13 @@ module ActiveSupport
86
86
 
87
87
  def increment(name, amount = 1, options = nil) # :nodoc:
88
88
  value = bypass_local_cache{super}
89
- increment_or_decrement(value, name, amount, options)
89
+ set_cache_value(value, name, amount, options)
90
90
  value
91
91
  end
92
92
 
93
93
  def decrement(name, amount = 1, options = nil) # :nodoc:
94
94
  value = bypass_local_cache{super}
95
- increment_or_decrement(value, name, amount, options)
95
+ set_cache_value(value, name, amount, options)
96
96
  value
97
97
  end
98
98
 
@@ -120,8 +120,7 @@ module ActiveSupport
120
120
  super
121
121
  end
122
122
 
123
- private
124
- def increment_or_decrement(value, name, amount, options)
123
+ def set_cache_value(value, name, amount, options)
125
124
  if local_cache
126
125
  local_cache.mute do
127
126
  if value
@@ -133,6 +132,8 @@ module ActiveSupport
133
132
  end
134
133
  end
135
134
 
135
+ private
136
+
136
137
  def local_cache_key
137
138
  @local_cache_key ||= "#{self.class.name.underscore}_local_cache_#{object_id}".gsub(/[\/-]/, '_').to_sym
138
139
  end
@@ -1,4 +1,6 @@
1
1
  require 'rack/body_proxy'
2
+ require 'rack/utils'
3
+
2
4
  module ActiveSupport
3
5
  module Cache
4
6
  module Strategy
@@ -28,6 +30,9 @@ module ActiveSupport
28
30
  LocalCacheRegistry.set_cache_for(local_cache_key, nil)
29
31
  end
30
32
  response
33
+ rescue Rack::Utils::InvalidParameterError
34
+ LocalCacheRegistry.set_cache_for(local_cache_key, nil)
35
+ [400, {}, []]
31
36
  rescue Exception
32
37
  LocalCacheRegistry.set_cache_for(local_cache_key, nil)
33
38
  raise
@@ -71,24 +71,28 @@ module ActiveSupport
71
71
  # order.
72
72
  #
73
73
  # If the callback chain was halted, returns +false+. Otherwise returns the
74
- # result of the block, or +true+ if no block is given.
74
+ # result of the block, +nil+ if no callbacks have been set, or +true+
75
+ # if callbacks have been set but no block is given.
75
76
  #
76
77
  # run_callbacks :save do
77
78
  # save
78
79
  # end
79
80
  def run_callbacks(kind, &block)
80
- cbs = send("_#{kind}_callbacks")
81
- if cbs.empty?
81
+ send "_run_#{kind}_callbacks", &block
82
+ end
83
+
84
+ private
85
+
86
+ def __run_callbacks__(callbacks, &block)
87
+ if callbacks.empty?
82
88
  yield if block_given?
83
89
  else
84
- runner = cbs.compile
90
+ runner = callbacks.compile
85
91
  e = Filters::Environment.new(self, false, nil, block)
86
92
  runner.call(e).value
87
93
  end
88
94
  end
89
95
 
90
- private
91
-
92
96
  # A hook invoked every time a before callback is halted.
93
97
  # This can be overridden in AS::Callback implementors in order
94
98
  # to provide better debugging/logging.
@@ -131,8 +135,6 @@ module ActiveSupport
131
135
  end
132
136
  end
133
137
 
134
- private
135
-
136
138
  def self.halting_and_conditional(callback_sequence, user_callback, user_conditions, halted_lambda, filter)
137
139
  callback_sequence.before do |env|
138
140
  target = env.target
@@ -150,6 +152,7 @@ module ActiveSupport
150
152
  env
151
153
  end
152
154
  end
155
+ private_class_method :halting_and_conditional
153
156
 
154
157
  def self.halting(callback_sequence, user_callback, halted_lambda, filter)
155
158
  callback_sequence.before do |env|
@@ -168,6 +171,7 @@ module ActiveSupport
168
171
  env
169
172
  end
170
173
  end
174
+ private_class_method :halting
171
175
 
172
176
  def self.conditional(callback_sequence, user_callback, user_conditions)
173
177
  callback_sequence.before do |env|
@@ -181,6 +185,7 @@ module ActiveSupport
181
185
  env
182
186
  end
183
187
  end
188
+ private_class_method :conditional
184
189
 
185
190
  def self.simple(callback_sequence, user_callback)
186
191
  callback_sequence.before do |env|
@@ -189,6 +194,7 @@ module ActiveSupport
189
194
  env
190
195
  end
191
196
  end
197
+ private_class_method :simple
192
198
  end
193
199
 
194
200
  class After
@@ -212,8 +218,6 @@ module ActiveSupport
212
218
  end
213
219
  end
214
220
 
215
- private
216
-
217
221
  def self.halting_and_conditional(callback_sequence, user_callback, user_conditions)
218
222
  callback_sequence.after do |env|
219
223
  target = env.target
@@ -227,6 +231,7 @@ module ActiveSupport
227
231
  env
228
232
  end
229
233
  end
234
+ private_class_method :halting_and_conditional
230
235
 
231
236
  def self.halting(callback_sequence, user_callback)
232
237
  callback_sequence.after do |env|
@@ -237,6 +242,7 @@ module ActiveSupport
237
242
  env
238
243
  end
239
244
  end
245
+ private_class_method :halting
240
246
 
241
247
  def self.conditional(callback_sequence, user_callback, user_conditions)
242
248
  callback_sequence.after do |env|
@@ -250,6 +256,7 @@ module ActiveSupport
250
256
  env
251
257
  end
252
258
  end
259
+ private_class_method :conditional
253
260
 
254
261
  def self.simple(callback_sequence, user_callback)
255
262
  callback_sequence.after do |env|
@@ -258,6 +265,7 @@ module ActiveSupport
258
265
  env
259
266
  end
260
267
  end
268
+ private_class_method :simple
261
269
  end
262
270
 
263
271
  class Around
@@ -273,8 +281,6 @@ module ActiveSupport
273
281
  end
274
282
  end
275
283
 
276
- private
277
-
278
284
  def self.halting_and_conditional(callback_sequence, user_callback, user_conditions)
279
285
  callback_sequence.around do |env, &run|
280
286
  target = env.target
@@ -293,6 +299,7 @@ module ActiveSupport
293
299
  end
294
300
  end
295
301
  end
302
+ private_class_method :halting_and_conditional
296
303
 
297
304
  def self.halting(callback_sequence, user_callback)
298
305
  callback_sequence.around do |env, &run|
@@ -310,6 +317,7 @@ module ActiveSupport
310
317
  end
311
318
  end
312
319
  end
320
+ private_class_method :halting
313
321
 
314
322
  def self.conditional(callback_sequence, user_callback, user_conditions)
315
323
  callback_sequence.around do |env, &run|
@@ -327,6 +335,7 @@ module ActiveSupport
327
335
  end
328
336
  end
329
337
  end
338
+ private_class_method :conditional
330
339
 
331
340
  def self.simple(callback_sequence, user_callback)
332
341
  callback_sequence.around do |env, &run|
@@ -337,6 +346,7 @@ module ActiveSupport
337
346
  env
338
347
  end
339
348
  end
349
+ private_class_method :simple
340
350
  end
341
351
  end
342
352
 
@@ -414,15 +424,8 @@ module ActiveSupport
414
424
  # Procs:: A proc to call with the object.
415
425
  # Objects:: An object with a <tt>before_foo</tt> method on it to call.
416
426
  #
417
- # All of these objects are compiled into methods and handled
418
- # the same after this point:
419
- #
420
- # Symbols:: Already methods.
421
- # Strings:: class_eval'd into methods.
422
- # Procs:: using define_method compiled into methods.
423
- # Objects::
424
- # a method is created that calls the before_foo method
425
- # on the object.
427
+ # All of these objects are converted into a lambda and handled
428
+ # the same after this point.
426
429
  def make_lambda(filter)
427
430
  case filter
428
431
  when Symbol
@@ -598,7 +601,7 @@ module ActiveSupport
598
601
  # This is used internally to append, prepend and skip callbacks to the
599
602
  # CallbackChain.
600
603
  def __update_callbacks(name) #:nodoc:
601
- ([self] + ActiveSupport::DescendantsTracker.descendants(self)).reverse.each do |target|
604
+ ([self] + ActiveSupport::DescendantsTracker.descendants(self)).reverse_each do |target|
602
605
  chain = target.get_callbacks name
603
606
  yield target, chain.dup
604
607
  end
@@ -608,7 +611,7 @@ module ActiveSupport
608
611
  #
609
612
  # set_callback :save, :before, :before_meth
610
613
  # set_callback :save, :after, :after_meth, if: :condition
611
- # set_callback :save, :around, ->(r, &block) { stuff; result = block.call; stuff }
614
+ # set_callback :save, :around, ->(r, block) { stuff; result = block.call; stuff }
612
615
  #
613
616
  # The second arguments indicates whether the callback is to be run +:before+,
614
617
  # +:after+, or +:around+ the event. If omitted, +:before+ is assumed. This
@@ -633,10 +636,12 @@ module ActiveSupport
633
636
  #
634
637
  # ===== Options
635
638
  #
636
- # * <tt>:if</tt> - A symbol naming an instance method or a proc; the
637
- # callback will be called only when it returns a +true+ value.
638
- # * <tt>:unless</tt> - A symbol naming an instance method or a proc; the
639
- # callback will be called only when it returns a +false+ value.
639
+ # * <tt>:if</tt> - A symbol, a string or an array of symbols and strings,
640
+ # each naming an instance method or a proc; the callback will be called
641
+ # only when they all return a true value.
642
+ # * <tt>:unless</tt> - A symbol, a string or an array of symbols and
643
+ # strings, each naming an instance method or a proc; the callback will
644
+ # be called only when they all return a false value.
640
645
  # * <tt>:prepend</tt> - If +true+, the callback will be prepended to the
641
646
  # existing chain rather than appended.
642
647
  def set_callback(name, *filter_list, &block)
@@ -758,18 +763,21 @@ module ActiveSupport
758
763
  # define_callbacks :save, scope: [:name]
759
764
  #
760
765
  # would call <tt>Audit#save</tt>.
766
+ #
767
+ # NOTE: +method_name+ passed to `define_model_callbacks` must not end with
768
+ # `!`, `?` or `=`.
761
769
  def define_callbacks(*names)
762
770
  options = names.extract_options!
763
- if options.key?(:terminator) && String === options[:terminator]
764
- ActiveSupport::Deprecation.warn "String based terminators are deprecated, please use a lambda"
765
- value = options[:terminator]
766
- line = class_eval "lambda { |result| #{value} }", __FILE__, __LINE__
767
- options[:terminator] = lambda { |target, result| target.instance_exec(result, &line) }
768
- end
769
771
 
770
772
  names.each do |name|
771
773
  class_attribute "_#{name}_callbacks", instance_writer: false
772
774
  set_callbacks name, CallbackChain.new(name, options)
775
+
776
+ module_eval <<-RUBY, __FILE__, __LINE__ + 1
777
+ def _run_#{name}_callbacks(&block)
778
+ __run_callbacks__(_#{name}_callbacks, &block)
779
+ end
780
+ RUBY
773
781
  end
774
782
  end
775
783