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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +280 -0
- data/lib/active_support/cache/mem_cache_store.rb +1 -1
- data/lib/active_support/cache.rb +3 -3
- data/lib/active_support/callbacks.rb +126 -82
- data/lib/active_support/concern.rb +1 -1
- data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +2 -0
- data/lib/active_support/core_ext/class/subclasses.rb +0 -2
- data/lib/active_support/core_ext/date/conversions.rb +6 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +11 -0
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +23 -3
- data/lib/active_support/core_ext/date_time/compatibility.rb +15 -0
- data/lib/active_support/core_ext/date_time.rb +1 -0
- data/lib/active_support/core_ext/enumerable.rb +16 -0
- data/lib/active_support/core_ext/hash/compact.rb +19 -15
- data/lib/active_support/core_ext/hash/conversions.rb +1 -2
- data/lib/active_support/core_ext/hash/transform_values.rb +2 -2
- data/lib/active_support/core_ext/integer/time.rb +0 -15
- data/lib/active_support/core_ext/kernel/debugger.rb +1 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +1 -0
- data/lib/active_support/core_ext/marshal.rb +8 -5
- data/lib/active_support/core_ext/module/delegation.rb +24 -12
- data/lib/active_support/core_ext/module/method_transplanting.rb +3 -1
- data/lib/active_support/core_ext/numeric/conversions.rb +11 -3
- data/lib/active_support/core_ext/numeric/time.rb +0 -15
- data/lib/active_support/core_ext/object/blank.rb +2 -2
- data/lib/active_support/core_ext/object/duplicable.rb +58 -32
- data/lib/active_support/core_ext/object/json.rb +2 -2
- data/lib/active_support/core_ext/object/try.rb +2 -2
- data/lib/active_support/core_ext/string/access.rb +1 -1
- data/lib/active_support/core_ext/string/conversions.rb +1 -1
- data/lib/active_support/core_ext/string/filters.rb +4 -3
- data/lib/active_support/core_ext/string/output_safety.rb +6 -2
- data/lib/active_support/core_ext/time/calculations.rb +18 -2
- data/lib/active_support/core_ext/time/compatibility.rb +14 -0
- data/lib/active_support/core_ext/time.rb +1 -0
- data/lib/active_support/deprecation/behaviors.rb +1 -1
- data/lib/active_support/duration.rb +25 -1
- data/lib/active_support/gem_version.rb +1 -1
- data/lib/active_support/hash_with_indifferent_access.rb +22 -3
- data/lib/active_support/inflector/methods.rb +1 -1
- data/lib/active_support/json/encoding.rb +5 -0
- data/lib/active_support/logger.rb +50 -0
- data/lib/active_support/logger_silence.rb +7 -4
- data/lib/active_support/logger_thread_safe_level.rb +32 -0
- data/lib/active_support/message_encryptor.rb +8 -1
- data/lib/active_support/message_verifier.rb +1 -1
- data/lib/active_support/multibyte/chars.rb +1 -1
- data/lib/active_support/notifications/fanout.rb +1 -1
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +1 -1
- data/lib/active_support/per_thread_registry.rb +5 -3
- data/lib/active_support/security_utils.rb +7 -0
- data/lib/active_support/testing/time_helpers.rb +16 -13
- data/lib/active_support/time_with_zone.rb +29 -17
- data/lib/active_support/values/time_zone.rb +10 -5
- data/lib/active_support/xml_mini/jdom.rb +6 -5
- data/lib/active_support/xml_mini/libxml.rb +1 -3
- data/lib/active_support/xml_mini/libxmlsax.rb +1 -4
- data/lib/active_support/xml_mini/nokogiri.rb +1 -3
- data/lib/active_support/xml_mini/nokogirisax.rb +1 -3
- data/lib/active_support/xml_mini/rexml.rb +7 -8
- data/lib/active_support/xml_mini.rb +33 -15
- data/lib/active_support.rb +9 -0
- metadata +7 -23
@@ -83,9 +83,9 @@ module ActiveSupport
|
|
83
83
|
|
84
84
|
private
|
85
85
|
|
86
|
-
def
|
86
|
+
def __run_callbacks__(callbacks, &block)
|
87
87
|
if callbacks.empty?
|
88
|
-
|
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(
|
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(
|
128
|
+
halting_and_conditional(callback_sequence, user_callback, user_conditions, halted_lambda, filter)
|
129
129
|
elsif chain_config.key? :terminator
|
130
|
-
halting(
|
130
|
+
halting(callback_sequence, user_callback, halted_lambda, filter)
|
131
131
|
elsif user_conditions.any?
|
132
|
-
conditional(
|
132
|
+
conditional(callback_sequence, user_callback, user_conditions)
|
133
133
|
else
|
134
|
-
simple
|
134
|
+
simple callback_sequence, user_callback
|
135
135
|
end
|
136
136
|
end
|
137
137
|
|
138
|
-
def self.halting_and_conditional(
|
139
|
-
|
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
|
-
|
152
|
-
|
151
|
+
|
152
|
+
env
|
153
|
+
end
|
153
154
|
end
|
154
155
|
private_class_method :halting_and_conditional
|
155
156
|
|
156
|
-
def self.halting(
|
157
|
-
|
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
|
-
|
170
|
-
|
170
|
+
|
171
|
+
env
|
172
|
+
end
|
171
173
|
end
|
172
174
|
private_class_method :halting
|
173
175
|
|
174
|
-
def self.conditional(
|
175
|
-
|
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
|
-
|
183
|
-
|
184
|
+
|
185
|
+
env
|
186
|
+
end
|
184
187
|
end
|
185
188
|
private_class_method :conditional
|
186
189
|
|
187
|
-
def self.simple(
|
188
|
-
|
190
|
+
def self.simple(callback_sequence, user_callback)
|
191
|
+
callback_sequence.before do |env|
|
189
192
|
user_callback.call env.target, env.value
|
190
|
-
|
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(
|
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(
|
204
|
+
halting_and_conditional(callback_sequence, user_callback, user_conditions)
|
201
205
|
elsif chain_config.key?(:terminator)
|
202
|
-
halting(
|
206
|
+
halting(callback_sequence, user_callback)
|
203
207
|
elsif user_conditions.any?
|
204
|
-
conditional
|
208
|
+
conditional callback_sequence, user_callback, user_conditions
|
205
209
|
else
|
206
|
-
simple
|
210
|
+
simple callback_sequence, user_callback
|
207
211
|
end
|
208
212
|
else
|
209
213
|
if user_conditions.any?
|
210
|
-
conditional
|
214
|
+
conditional callback_sequence, user_callback, user_conditions
|
211
215
|
else
|
212
|
-
simple
|
216
|
+
simple callback_sequence, user_callback
|
213
217
|
end
|
214
218
|
end
|
215
219
|
end
|
216
220
|
|
217
|
-
def self.halting_and_conditional(
|
218
|
-
|
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(
|
233
|
-
|
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(
|
244
|
-
|
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(
|
258
|
-
|
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(
|
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(
|
274
|
+
halting_and_conditional(callback_sequence, user_callback, user_conditions)
|
271
275
|
elsif chain_config.key? :terminator
|
272
|
-
halting(
|
276
|
+
halting(callback_sequence, user_callback)
|
273
277
|
elsif user_conditions.any?
|
274
|
-
conditional(
|
278
|
+
conditional(callback_sequence, user_callback, user_conditions)
|
275
279
|
else
|
276
|
-
simple(
|
280
|
+
simple(callback_sequence, user_callback)
|
277
281
|
end
|
278
282
|
end
|
279
283
|
|
280
|
-
def self.halting_and_conditional(
|
281
|
-
|
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 =
|
292
|
+
env = run.call env
|
289
293
|
env.value
|
290
294
|
}
|
295
|
+
|
291
296
|
env
|
292
297
|
else
|
293
|
-
|
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(
|
300
|
-
|
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
|
-
|
310
|
+
run.call env
|
306
311
|
else
|
307
312
|
user_callback.call(target, value) {
|
308
|
-
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(
|
318
|
-
|
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 =
|
329
|
+
env = run.call env
|
325
330
|
env.value
|
326
331
|
}
|
327
332
|
env
|
328
333
|
else
|
329
|
-
|
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(
|
336
|
-
|
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 =
|
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(
|
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(
|
406
|
+
Filters::Before.build(callback_sequence, user_callback, user_conditions, chain_config, @filter)
|
402
407
|
when :after
|
403
|
-
Filters::After.build(
|
408
|
+
Filters::After.build(callback_sequence, user_callback, user_conditions, chain_config)
|
404
409
|
when :around
|
405
|
-
Filters::Around.build(
|
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
|
-
|
515
|
-
|
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
|
598
|
-
#
|
599
|
-
#
|
600
|
-
#
|
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
|
-
|
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
|
|
@@ -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
|
-
#
|
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
|
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
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
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
|
@@ -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
|