activesupport 4.2.0 → 4.2.10

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 (65) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +280 -0
  3. data/lib/active_support/cache/mem_cache_store.rb +1 -1
  4. data/lib/active_support/cache.rb +3 -3
  5. data/lib/active_support/callbacks.rb +126 -82
  6. data/lib/active_support/concern.rb +1 -1
  7. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +2 -0
  8. data/lib/active_support/core_ext/class/subclasses.rb +0 -2
  9. data/lib/active_support/core_ext/date/conversions.rb +6 -0
  10. data/lib/active_support/core_ext/date_and_time/calculations.rb +11 -0
  11. data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
  12. data/lib/active_support/core_ext/date_time/calculations.rb +23 -3
  13. data/lib/active_support/core_ext/date_time/compatibility.rb +15 -0
  14. data/lib/active_support/core_ext/date_time.rb +1 -0
  15. data/lib/active_support/core_ext/enumerable.rb +16 -0
  16. data/lib/active_support/core_ext/hash/compact.rb +19 -15
  17. data/lib/active_support/core_ext/hash/conversions.rb +1 -2
  18. data/lib/active_support/core_ext/hash/transform_values.rb +2 -2
  19. data/lib/active_support/core_ext/integer/time.rb +0 -15
  20. data/lib/active_support/core_ext/kernel/debugger.rb +1 -1
  21. data/lib/active_support/core_ext/kernel/reporting.rb +1 -0
  22. data/lib/active_support/core_ext/marshal.rb +8 -5
  23. data/lib/active_support/core_ext/module/delegation.rb +24 -12
  24. data/lib/active_support/core_ext/module/method_transplanting.rb +3 -1
  25. data/lib/active_support/core_ext/numeric/conversions.rb +11 -3
  26. data/lib/active_support/core_ext/numeric/time.rb +0 -15
  27. data/lib/active_support/core_ext/object/blank.rb +2 -2
  28. data/lib/active_support/core_ext/object/duplicable.rb +58 -32
  29. data/lib/active_support/core_ext/object/json.rb +2 -2
  30. data/lib/active_support/core_ext/object/try.rb +2 -2
  31. data/lib/active_support/core_ext/string/access.rb +1 -1
  32. data/lib/active_support/core_ext/string/conversions.rb +1 -1
  33. data/lib/active_support/core_ext/string/filters.rb +4 -3
  34. data/lib/active_support/core_ext/string/output_safety.rb +6 -2
  35. data/lib/active_support/core_ext/time/calculations.rb +18 -2
  36. data/lib/active_support/core_ext/time/compatibility.rb +14 -0
  37. data/lib/active_support/core_ext/time.rb +1 -0
  38. data/lib/active_support/deprecation/behaviors.rb +1 -1
  39. data/lib/active_support/duration.rb +25 -1
  40. data/lib/active_support/gem_version.rb +1 -1
  41. data/lib/active_support/hash_with_indifferent_access.rb +22 -3
  42. data/lib/active_support/inflector/methods.rb +1 -1
  43. data/lib/active_support/json/encoding.rb +5 -0
  44. data/lib/active_support/logger.rb +50 -0
  45. data/lib/active_support/logger_silence.rb +7 -4
  46. data/lib/active_support/logger_thread_safe_level.rb +32 -0
  47. data/lib/active_support/message_encryptor.rb +8 -1
  48. data/lib/active_support/message_verifier.rb +1 -1
  49. data/lib/active_support/multibyte/chars.rb +1 -1
  50. data/lib/active_support/notifications/fanout.rb +1 -1
  51. data/lib/active_support/number_helper/number_to_rounded_converter.rb +1 -1
  52. data/lib/active_support/per_thread_registry.rb +5 -3
  53. data/lib/active_support/security_utils.rb +7 -0
  54. data/lib/active_support/testing/time_helpers.rb +16 -13
  55. data/lib/active_support/time_with_zone.rb +29 -17
  56. data/lib/active_support/values/time_zone.rb +10 -5
  57. data/lib/active_support/xml_mini/jdom.rb +6 -5
  58. data/lib/active_support/xml_mini/libxml.rb +1 -3
  59. data/lib/active_support/xml_mini/libxmlsax.rb +1 -4
  60. data/lib/active_support/xml_mini/nokogiri.rb +1 -3
  61. data/lib/active_support/xml_mini/nokogirisax.rb +1 -3
  62. data/lib/active_support/xml_mini/rexml.rb +7 -8
  63. data/lib/active_support/xml_mini.rb +33 -15
  64. data/lib/active_support.rb +9 -0
  65. metadata +7 -23
@@ -83,9 +83,9 @@ module ActiveSupport
83
83
 
84
84
  private
85
85
 
86
- def _run_callbacks(callbacks, &block)
86
+ def __run_callbacks__(callbacks, &block)
87
87
  if callbacks.empty?
88
- block.call if block
88
+ yield if block_given?
89
89
  else
90
90
  runner = callbacks.compile
91
91
  e = Filters::Environment.new(self, false, nil, block)
@@ -121,22 +121,22 @@ module ActiveSupport
121
121
  ENDING = End.new
122
122
 
123
123
  class Before
124
- def self.build(next_callback, user_callback, user_conditions, chain_config, filter)
124
+ def self.build(callback_sequence, user_callback, user_conditions, chain_config, filter)
125
125
  halted_lambda = chain_config[:terminator]
126
126
 
127
127
  if chain_config.key?(:terminator) && user_conditions.any?
128
- halting_and_conditional(next_callback, user_callback, user_conditions, halted_lambda, filter)
128
+ halting_and_conditional(callback_sequence, user_callback, user_conditions, halted_lambda, filter)
129
129
  elsif chain_config.key? :terminator
130
- halting(next_callback, user_callback, halted_lambda, filter)
130
+ halting(callback_sequence, user_callback, halted_lambda, filter)
131
131
  elsif user_conditions.any?
132
- conditional(next_callback, user_callback, user_conditions)
132
+ conditional(callback_sequence, user_callback, user_conditions)
133
133
  else
134
- simple next_callback, user_callback
134
+ simple callback_sequence, user_callback
135
135
  end
136
136
  end
137
137
 
138
- def self.halting_and_conditional(next_callback, user_callback, user_conditions, halted_lambda, filter)
139
- lambda { |env|
138
+ def self.halting_and_conditional(callback_sequence, user_callback, user_conditions, halted_lambda, filter)
139
+ callback_sequence.before do |env|
140
140
  target = env.target
141
141
  value = env.value
142
142
  halted = env.halted
@@ -148,13 +148,14 @@ module ActiveSupport
148
148
  target.send :halted_callback_hook, filter
149
149
  end
150
150
  end
151
- next_callback.call env
152
- }
151
+
152
+ env
153
+ end
153
154
  end
154
155
  private_class_method :halting_and_conditional
155
156
 
156
- def self.halting(next_callback, user_callback, halted_lambda, filter)
157
- lambda { |env|
157
+ def self.halting(callback_sequence, user_callback, halted_lambda, filter)
158
+ callback_sequence.before do |env|
158
159
  target = env.target
159
160
  value = env.value
160
161
  halted = env.halted
@@ -166,57 +167,59 @@ module ActiveSupport
166
167
  target.send :halted_callback_hook, filter
167
168
  end
168
169
  end
169
- next_callback.call env
170
- }
170
+
171
+ env
172
+ end
171
173
  end
172
174
  private_class_method :halting
173
175
 
174
- def self.conditional(next_callback, user_callback, user_conditions)
175
- lambda { |env|
176
+ def self.conditional(callback_sequence, user_callback, user_conditions)
177
+ callback_sequence.before do |env|
176
178
  target = env.target
177
179
  value = env.value
178
180
 
179
181
  if user_conditions.all? { |c| c.call(target, value) }
180
182
  user_callback.call target, value
181
183
  end
182
- next_callback.call env
183
- }
184
+
185
+ env
186
+ end
184
187
  end
185
188
  private_class_method :conditional
186
189
 
187
- def self.simple(next_callback, user_callback)
188
- lambda { |env|
190
+ def self.simple(callback_sequence, user_callback)
191
+ callback_sequence.before do |env|
189
192
  user_callback.call env.target, env.value
190
- next_callback.call env
191
- }
193
+
194
+ env
195
+ end
192
196
  end
193
197
  private_class_method :simple
194
198
  end
195
199
 
196
200
  class After
197
- def self.build(next_callback, user_callback, user_conditions, chain_config)
201
+ def self.build(callback_sequence, user_callback, user_conditions, chain_config)
198
202
  if chain_config[:skip_after_callbacks_if_terminated]
199
203
  if chain_config.key?(:terminator) && user_conditions.any?
200
- halting_and_conditional(next_callback, user_callback, user_conditions)
204
+ halting_and_conditional(callback_sequence, user_callback, user_conditions)
201
205
  elsif chain_config.key?(:terminator)
202
- halting(next_callback, user_callback)
206
+ halting(callback_sequence, user_callback)
203
207
  elsif user_conditions.any?
204
- conditional next_callback, user_callback, user_conditions
208
+ conditional callback_sequence, user_callback, user_conditions
205
209
  else
206
- simple next_callback, user_callback
210
+ simple callback_sequence, user_callback
207
211
  end
208
212
  else
209
213
  if user_conditions.any?
210
- conditional next_callback, user_callback, user_conditions
214
+ conditional callback_sequence, user_callback, user_conditions
211
215
  else
212
- simple next_callback, user_callback
216
+ simple callback_sequence, user_callback
213
217
  end
214
218
  end
215
219
  end
216
220
 
217
- def self.halting_and_conditional(next_callback, user_callback, user_conditions)
218
- lambda { |env|
219
- env = next_callback.call env
221
+ def self.halting_and_conditional(callback_sequence, user_callback, user_conditions)
222
+ callback_sequence.after do |env|
220
223
  target = env.target
221
224
  value = env.value
222
225
  halted = env.halted
@@ -224,122 +227,124 @@ module ActiveSupport
224
227
  if !halted && user_conditions.all? { |c| c.call(target, value) }
225
228
  user_callback.call target, value
226
229
  end
230
+
227
231
  env
228
- }
232
+ end
229
233
  end
230
234
  private_class_method :halting_and_conditional
231
235
 
232
- def self.halting(next_callback, user_callback)
233
- lambda { |env|
234
- env = next_callback.call env
236
+ def self.halting(callback_sequence, user_callback)
237
+ callback_sequence.after do |env|
235
238
  unless env.halted
236
239
  user_callback.call env.target, env.value
237
240
  end
241
+
238
242
  env
239
- }
243
+ end
240
244
  end
241
245
  private_class_method :halting
242
246
 
243
- def self.conditional(next_callback, user_callback, user_conditions)
244
- lambda { |env|
245
- env = next_callback.call env
247
+ def self.conditional(callback_sequence, user_callback, user_conditions)
248
+ callback_sequence.after do |env|
246
249
  target = env.target
247
250
  value = env.value
248
251
 
249
252
  if user_conditions.all? { |c| c.call(target, value) }
250
253
  user_callback.call target, value
251
254
  end
255
+
252
256
  env
253
- }
257
+ end
254
258
  end
255
259
  private_class_method :conditional
256
260
 
257
- def self.simple(next_callback, user_callback)
258
- lambda { |env|
259
- env = next_callback.call env
261
+ def self.simple(callback_sequence, user_callback)
262
+ callback_sequence.after do |env|
260
263
  user_callback.call env.target, env.value
264
+
261
265
  env
262
- }
266
+ end
263
267
  end
264
268
  private_class_method :simple
265
269
  end
266
270
 
267
271
  class Around
268
- def self.build(next_callback, user_callback, user_conditions, chain_config)
272
+ def self.build(callback_sequence, user_callback, user_conditions, chain_config)
269
273
  if chain_config.key?(:terminator) && user_conditions.any?
270
- halting_and_conditional(next_callback, user_callback, user_conditions)
274
+ halting_and_conditional(callback_sequence, user_callback, user_conditions)
271
275
  elsif chain_config.key? :terminator
272
- halting(next_callback, user_callback)
276
+ halting(callback_sequence, user_callback)
273
277
  elsif user_conditions.any?
274
- conditional(next_callback, user_callback, user_conditions)
278
+ conditional(callback_sequence, user_callback, user_conditions)
275
279
  else
276
- simple(next_callback, user_callback)
280
+ simple(callback_sequence, user_callback)
277
281
  end
278
282
  end
279
283
 
280
- def self.halting_and_conditional(next_callback, user_callback, user_conditions)
281
- lambda { |env|
284
+ def self.halting_and_conditional(callback_sequence, user_callback, user_conditions)
285
+ callback_sequence.around do |env, &run|
282
286
  target = env.target
283
287
  value = env.value
284
288
  halted = env.halted
285
289
 
286
290
  if !halted && user_conditions.all? { |c| c.call(target, value) }
287
291
  user_callback.call(target, value) {
288
- env = next_callback.call env
292
+ env = run.call env
289
293
  env.value
290
294
  }
295
+
291
296
  env
292
297
  else
293
- next_callback.call env
298
+ run.call env
294
299
  end
295
- }
300
+ end
296
301
  end
297
302
  private_class_method :halting_and_conditional
298
303
 
299
- def self.halting(next_callback, user_callback)
300
- lambda { |env|
304
+ def self.halting(callback_sequence, user_callback)
305
+ callback_sequence.around do |env, &run|
301
306
  target = env.target
302
307
  value = env.value
303
308
 
304
309
  if env.halted
305
- next_callback.call env
310
+ run.call env
306
311
  else
307
312
  user_callback.call(target, value) {
308
- env = next_callback.call env
313
+ env = run.call env
309
314
  env.value
310
315
  }
311
316
  env
312
317
  end
313
- }
318
+ end
314
319
  end
315
320
  private_class_method :halting
316
321
 
317
- def self.conditional(next_callback, user_callback, user_conditions)
318
- lambda { |env|
322
+ def self.conditional(callback_sequence, user_callback, user_conditions)
323
+ callback_sequence.around do |env, &run|
319
324
  target = env.target
320
325
  value = env.value
321
326
 
322
327
  if user_conditions.all? { |c| c.call(target, value) }
323
328
  user_callback.call(target, value) {
324
- env = next_callback.call env
329
+ env = run.call env
325
330
  env.value
326
331
  }
327
332
  env
328
333
  else
329
- next_callback.call env
334
+ run.call env
330
335
  end
331
- }
336
+ end
332
337
  end
333
338
  private_class_method :conditional
334
339
 
335
- def self.simple(next_callback, user_callback)
336
- lambda { |env|
340
+ def self.simple(callback_sequence, user_callback)
341
+ callback_sequence.around do |env, &run|
337
342
  user_callback.call(env.target, env.value) {
338
- env = next_callback.call env
343
+ env = run.call env
339
344
  env.value
340
345
  }
341
346
  env
342
- }
347
+ end
343
348
  end
344
349
  private_class_method :simple
345
350
  end
@@ -392,17 +397,17 @@ module ActiveSupport
392
397
  end
393
398
 
394
399
  # Wraps code with filter
395
- def apply(next_callback)
400
+ def apply(callback_sequence)
396
401
  user_conditions = conditions_lambdas
397
402
  user_callback = make_lambda @filter
398
403
 
399
404
  case kind
400
405
  when :before
401
- Filters::Before.build(next_callback, user_callback, user_conditions, chain_config, @filter)
406
+ Filters::Before.build(callback_sequence, user_callback, user_conditions, chain_config, @filter)
402
407
  when :after
403
- Filters::After.build(next_callback, user_callback, user_conditions, chain_config)
408
+ Filters::After.build(callback_sequence, user_callback, user_conditions, chain_config)
404
409
  when :around
405
- Filters::Around.build(next_callback, user_callback, user_conditions, chain_config)
410
+ Filters::Around.build(callback_sequence, user_callback, user_conditions, chain_config)
406
411
  end
407
412
  end
408
413
 
@@ -467,6 +472,42 @@ module ActiveSupport
467
472
  end
468
473
  end
469
474
 
475
+ # Execute before and after filters in a sequence instead of
476
+ # chaining them with nested lambda calls, see:
477
+ # https://github.com/rails/rails/issues/18011
478
+ class CallbackSequence
479
+ def initialize(&call)
480
+ @call = call
481
+ @before = []
482
+ @after = []
483
+ end
484
+
485
+ def before(&before)
486
+ @before.unshift(before)
487
+ self
488
+ end
489
+
490
+ def after(&after)
491
+ @after.push(after)
492
+ self
493
+ end
494
+
495
+ def around(&around)
496
+ CallbackSequence.new do |*args|
497
+ around.call(*args) {
498
+ self.call(*args)
499
+ }
500
+ end
501
+ end
502
+
503
+ def call(*args)
504
+ @before.each { |b| b.call(*args) }
505
+ value = @call.call(*args)
506
+ @after.each { |a| a.call(*args) }
507
+ value
508
+ end
509
+ end
510
+
470
511
  # An Array with a compile method.
471
512
  class CallbackChain #:nodoc:#
472
513
  include Enumerable
@@ -511,8 +552,9 @@ module ActiveSupport
511
552
 
512
553
  def compile
513
554
  @callbacks || @mutex.synchronize do
514
- @callbacks ||= @chain.reverse.inject(Filters::ENDING) do |chain, callback|
515
- callback.apply chain
555
+ final_sequence = CallbackSequence.new { |env| Filters::ENDING.call(env) }
556
+ @callbacks ||= @chain.reverse.inject(final_sequence) do |callback_sequence, callback|
557
+ callback.apply callback_sequence
516
558
  end
517
559
  end
518
560
  end
@@ -594,10 +636,12 @@ module ActiveSupport
594
636
  #
595
637
  # ===== Options
596
638
  #
597
- # * <tt>:if</tt> - A symbol naming an instance method or a proc; the
598
- # callback will be called only when it returns a +true+ value.
599
- # * <tt>:unless</tt> - A symbol naming an instance method or a proc; the
600
- # 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.
601
645
  # * <tt>:prepend</tt> - If +true+, the callback will be prepended to the
602
646
  # existing chain rather than appended.
603
647
  def set_callback(name, *filter_list, &block)
@@ -726,12 +770,12 @@ module ActiveSupport
726
770
  options = names.extract_options!
727
771
 
728
772
  names.each do |name|
729
- class_attribute "_#{name}_callbacks"
773
+ class_attribute "_#{name}_callbacks", instance_writer: false
730
774
  set_callbacks name, CallbackChain.new(name, options)
731
775
 
732
776
  module_eval <<-RUBY, __FILE__, __LINE__ + 1
733
777
  def _run_#{name}_callbacks(&block)
734
- _run_callbacks(_#{name}_callbacks, &block)
778
+ __run_callbacks__(_#{name}_callbacks, &block)
735
779
  end
736
780
  RUBY
737
781
  end
@@ -132,7 +132,7 @@ module ActiveSupport
132
132
  end
133
133
 
134
134
  def class_methods(&class_methods_module_definition)
135
- mod = const_defined?(:ClassMethods) ?
135
+ mod = const_defined?(:ClassMethods, false) ?
136
136
  const_get(:ClassMethods) :
137
137
  const_set(:ClassMethods, Module.new)
138
138
 
@@ -1,3 +1,5 @@
1
+ require 'active_support/deprecation'
2
+
1
3
  ActiveSupport::Deprecation.warn 'core_ext/big_decimal/yaml_conversions is deprecated and will be removed in the future.'
2
4
 
3
5
  require 'bigdecimal'
@@ -25,8 +25,6 @@ class Class
25
25
 
26
26
  # Returns an array with the direct children of +self+.
27
27
  #
28
- # Integer.subclasses # => [Fixnum, Bignum]
29
- #
30
28
  # class Foo; end
31
29
  # class Bar < Foo; end
32
30
  # class Baz < Bar; end
@@ -35,6 +35,7 @@ class Date
35
35
  # date.to_s(:db) # => "2007-11-10"
36
36
  #
37
37
  # date.to_formatted_s(:short) # => "10 Nov"
38
+ # date.to_formatted_s(:number) # => "20071110"
38
39
  # date.to_formatted_s(:long) # => "November 10, 2007"
39
40
  # date.to_formatted_s(:long_ordinal) # => "November 10th, 2007"
40
41
  # date.to_formatted_s(:rfc822) # => "10 Nov 2007"
@@ -82,6 +83,11 @@ class Date
82
83
  ::Time.send(form, year, month, day)
83
84
  end
84
85
 
86
+ # Returns a string which represents the time in used time zone as DateTime
87
+ # defined by XML Schema:
88
+ #
89
+ # date = Date.new(2015, 05, 23) # => Sat, 23 May 2015
90
+ # date.xmlschema # => "2015-05-23T00:00:00+04:00"
85
91
  def xmlschema
86
92
  in_time_zone.xmlschema
87
93
  end
@@ -109,9 +109,20 @@ module DateAndTime
109
109
  alias :at_beginning_of_year :beginning_of_year
110
110
 
111
111
  # Returns a new date/time representing the given day in the next week.
112
+ #
113
+ # today = Date.today # => Thu, 07 May 2015
114
+ # today.next_week # => Mon, 11 May 2015
115
+ #
112
116
  # The +given_day_in_next_week+ defaults to the beginning of the week
113
117
  # which is determined by +Date.beginning_of_week+ or +config.beginning_of_week+
118
+ #
119
+ # today = Date.today # => Thu, 07 May 2015
120
+ # today.next_week(:friday) # => Fri, 15 May 2015
121
+ #
114
122
  # when set. +DateTime+ objects have their time set to 0:00.
123
+ #
124
+ # now = Time.current # => Thu, 07 May 2015 13:31:16 UTC +00:00
125
+ # now.next_week # => Mon, 11 May 2015 00:00:00 UTC +00:00
115
126
  def next_week(given_day_in_next_week = Date.beginning_of_week)
116
127
  first_hour(weeks_since(1).beginning_of_week.days_since(days_span(given_day_in_next_week)))
117
128
  end
@@ -0,0 +1,15 @@
1
+ require 'active_support/core_ext/module/attribute_accessors'
2
+ require 'active_support/core_ext/module/remove_method'
3
+
4
+ module DateAndTime
5
+ module Compatibility
6
+ # If true, +to_time+ preserves the timezone offset of receiver.
7
+ #
8
+ # NOTE: With Ruby 2.4+ the default for +to_time+ changed from
9
+ # converting to the local system time, to preserving the offset
10
+ # of the receiver. For backwards compatibility we're overriding
11
+ # this behavior, but new apps will have an initializer that sets
12
+ # this to true, because the new behavior is preferred.
13
+ mattr_accessor(:preserve_timezone, instance_writer: false) { false }
14
+ end
15
+ end
@@ -24,6 +24,13 @@ class DateTime
24
24
  end_of_day.to_i - to_i
25
25
  end
26
26
 
27
+ # Returns the fraction of a second as a +Rational+
28
+ #
29
+ # DateTime.new(2012, 8, 29, 0, 0, 0.5).subsec # => (1/2)
30
+ def subsec
31
+ sec_fraction
32
+ end
33
+
27
34
  # Returns a new DateTime where one or more of the elements have been changed
28
35
  # according to the +options+ parameter. The time options (<tt>:hour</tt>,
29
36
  # <tt>:min</tt>, <tt>:sec</tt>) reset cascadingly, so if only the hour is
@@ -139,14 +146,27 @@ class DateTime
139
146
  end
140
147
  alias :at_end_of_minute :end_of_minute
141
148
 
142
- # Adjusts DateTime to UTC by adding its offset value; offset is set to 0.
149
+ # Returns a <tt>Time</tt> instance of the simultaneous time in the system timezone.
150
+ def localtime(utc_offset = nil)
151
+ utc = new_offset(0)
152
+
153
+ Time.utc(
154
+ utc.year, utc.month, utc.day,
155
+ utc.hour, utc.min, utc.sec + utc.sec_fraction
156
+ ).getlocal(utc_offset)
157
+ end
158
+ alias_method :getlocal, :localtime
159
+
160
+ # Returns a <tt>DateTime</tt> instance of the simultaneous time in the UTC timezone.
143
161
  #
144
162
  # DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)) # => Mon, 21 Feb 2005 10:11:12 -0600
145
- # DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc # => Mon, 21 Feb 2005 16:11:12 +0000
163
+ # DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc # => Mon, 21 Feb 2005 16:11:12 UTC
146
164
  def utc
147
165
  new_offset(0)
148
166
  end
167
+ alias_method :getgm, :utc
149
168
  alias_method :getutc, :utc
169
+ alias_method :gmtime, :utc
150
170
 
151
171
  # Returns +true+ if <tt>offset == 0</tt>.
152
172
  def utc?
@@ -164,7 +184,7 @@ class DateTime
164
184
  if other.kind_of?(Infinity)
165
185
  super
166
186
  elsif other.respond_to? :to_datetime
167
- super other.to_datetime
187
+ super other.to_datetime rescue nil
168
188
  else
169
189
  nil
170
190
  end
@@ -0,0 +1,15 @@
1
+ require 'active_support/core_ext/date_and_time/compatibility'
2
+
3
+ class DateTime
4
+ include DateAndTime::Compatibility
5
+
6
+ remove_possible_method :to_time
7
+
8
+ # Either return an instance of `Time` with the same UTC offset
9
+ # as +self+ or an instance of `Time` representing the same time
10
+ # in the the local system timezone depending on the setting of
11
+ # on the setting of +ActiveSupport.to_time_preserves_timezone+.
12
+ def to_time
13
+ preserve_timezone ? getlocal(utc_offset) : getlocal
14
+ end
15
+ end
@@ -1,4 +1,5 @@
1
1
  require 'active_support/core_ext/date_time/acts_like'
2
2
  require 'active_support/core_ext/date_time/calculations'
3
+ require 'active_support/core_ext/date_time/compatibility'
3
4
  require 'active_support/core_ext/date_time/conversions'
4
5
  require 'active_support/core_ext/date_time/zones'
@@ -78,3 +78,19 @@ class Range #:nodoc:
78
78
  end
79
79
  end
80
80
  end
81
+
82
+ # Array#sum was added in Ruby 2.4 but it only works with Numeric elements.
83
+ #
84
+ # We tried shimming it to attempt the fast native method, rescue TypeError,
85
+ # and fall back to the compatible implementation, but that's much slower than
86
+ # just calling the compat method in the first place.
87
+ if Array.instance_methods(false).include?(:sum) && !(%w[a].sum rescue false)
88
+ class Array
89
+ remove_method :sum
90
+
91
+ def sum(*args) #:nodoc:
92
+ # Use Enumerable#sum instead.
93
+ super
94
+ end
95
+ end
96
+ end
@@ -1,20 +1,24 @@
1
1
  class Hash
2
- # Returns a hash with non +nil+ values.
3
- #
4
- # hash = { a: true, b: false, c: nil}
5
- # hash.compact # => { a: true, b: false}
6
- # hash # => { a: true, b: false, c: nil}
7
- # { c: nil }.compact # => {}
8
- def compact
9
- self.select { |_, value| !value.nil? }
2
+ unless Hash.instance_methods(false).include?(:compact)
3
+ # Returns a hash with non +nil+ values.
4
+ #
5
+ # hash = { a: true, b: false, c: nil}
6
+ # hash.compact # => { a: true, b: false}
7
+ # hash # => { a: true, b: false, c: nil}
8
+ # { c: nil }.compact # => {}
9
+ def compact
10
+ self.select { |_, value| !value.nil? }
11
+ end
10
12
  end
11
13
 
12
- # Replaces current hash with non +nil+ values.
13
- #
14
- # hash = { a: true, b: false, c: nil}
15
- # hash.compact! # => { a: true, b: false}
16
- # hash # => { a: true, b: false}
17
- def compact!
18
- self.reject! { |_, value| value.nil? }
14
+ unless Hash.instance_methods(false).include?(:compact!)
15
+ # Replaces current hash with non +nil+ values.
16
+ #
17
+ # hash = { a: true, b: false, c: nil}
18
+ # hash.compact! # => { a: true, b: false}
19
+ # hash # => { a: true, b: false}
20
+ def compact!
21
+ self.reject! { |_, value| value.nil? }
22
+ end
19
23
  end
20
24
  end
@@ -55,8 +55,7 @@ class Hash
55
55
  #
56
56
  # XML_TYPE_NAMES = {
57
57
  # "Symbol" => "symbol",
58
- # "Fixnum" => "integer",
59
- # "Bignum" => "integer",
58
+ # "Integer" => "integer",
60
59
  # "BigDecimal" => "decimal",
61
60
  # "Float" => "float",
62
61
  # "TrueClass" => "boolean",
@@ -11,7 +11,7 @@ class Hash
11
11
  result[key] = yield(value)
12
12
  end
13
13
  result
14
- end
14
+ end unless method_defined? :transform_values
15
15
 
16
16
  # Destructive +transform_values+
17
17
  def transform_values!
@@ -19,5 +19,5 @@ class Hash
19
19
  each do |key, value|
20
20
  self[key] = yield(value)
21
21
  end
22
- end
22
+ end unless method_defined? :transform_values!
23
23
  end