activesupport 4.2.11.3 → 5.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +309 -485
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -3
- data/lib/active_support.rb +8 -15
- data/lib/active_support/array_inquirer.rb +44 -0
- data/lib/active_support/backtrace_cleaner.rb +1 -1
- data/lib/active_support/cache.rb +59 -72
- data/lib/active_support/cache/file_store.rb +27 -19
- data/lib/active_support/cache/mem_cache_store.rb +71 -60
- data/lib/active_support/cache/memory_store.rb +16 -21
- data/lib/active_support/cache/null_store.rb +1 -4
- data/lib/active_support/cache/strategy/local_cache.rb +31 -20
- data/lib/active_support/callbacks.rb +107 -111
- data/lib/active_support/concern.rb +1 -1
- data/lib/active_support/concurrency/latch.rb +7 -15
- data/lib/active_support/concurrency/share_lock.rb +142 -0
- data/lib/active_support/configurable.rb +1 -0
- data/lib/active_support/core_ext.rb +2 -1
- data/lib/active_support/core_ext/array.rb +1 -0
- data/lib/active_support/core_ext/array/access.rb +13 -1
- data/lib/active_support/core_ext/array/conversions.rb +6 -4
- data/lib/active_support/core_ext/array/inquiry.rb +17 -0
- data/lib/active_support/core_ext/array/wrap.rb +5 -4
- data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -10
- data/lib/active_support/core_ext/class.rb +0 -1
- data/lib/active_support/core_ext/class/attribute.rb +10 -9
- data/lib/active_support/core_ext/class/subclasses.rb +5 -2
- data/lib/active_support/core_ext/date.rb +1 -1
- data/lib/active_support/core_ext/date/blank.rb +12 -0
- data/lib/active_support/core_ext/date/calculations.rb +1 -1
- data/lib/active_support/core_ext/date/conversions.rb +3 -3
- data/lib/active_support/core_ext/date_and_time/calculations.rb +93 -27
- data/lib/active_support/core_ext/date_and_time/zones.rb +1 -2
- data/lib/active_support/core_ext/date_time.rb +1 -1
- data/lib/active_support/core_ext/date_time/blank.rb +12 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +7 -23
- data/lib/active_support/core_ext/date_time/conversions.rb +2 -0
- data/lib/active_support/core_ext/enumerable.rb +27 -17
- data/lib/active_support/core_ext/file/atomic.rb +30 -25
- data/lib/active_support/core_ext/hash/compact.rb +15 -19
- data/lib/active_support/core_ext/hash/conversions.rb +21 -2
- data/lib/active_support/core_ext/hash/deep_merge.rb +1 -1
- data/lib/active_support/core_ext/hash/except.rb +9 -8
- data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -1
- data/lib/active_support/core_ext/hash/keys.rb +22 -18
- data/lib/active_support/core_ext/hash/slice.rb +1 -1
- data/lib/active_support/core_ext/hash/transform_values.rb +13 -7
- data/lib/active_support/core_ext/integer/time.rb +1 -1
- data/lib/active_support/core_ext/kernel.rb +0 -1
- data/lib/active_support/core_ext/kernel/debugger.rb +3 -10
- data/lib/active_support/core_ext/kernel/reporting.rb +0 -84
- data/lib/active_support/core_ext/load_error.rb +4 -2
- data/lib/active_support/core_ext/marshal.rb +8 -13
- data/lib/active_support/core_ext/module.rb +1 -0
- data/lib/active_support/core_ext/module/aliasing.rb +6 -1
- data/lib/active_support/core_ext/module/anonymous.rb +10 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -5
- data/lib/active_support/core_ext/module/attribute_accessors.rb +7 -7
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +141 -0
- data/lib/active_support/core_ext/module/concerning.rb +4 -4
- data/lib/active_support/core_ext/module/delegation.rb +7 -14
- data/lib/active_support/core_ext/module/method_transplanting.rb +3 -13
- data/lib/active_support/core_ext/module/qualified_const.rb +30 -12
- data/lib/active_support/core_ext/module/remove_method.rb +23 -0
- data/lib/active_support/core_ext/name_error.rb +15 -2
- data/lib/active_support/core_ext/numeric.rb +1 -0
- data/lib/active_support/core_ext/numeric/bytes.rb +20 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +12 -23
- data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
- data/lib/active_support/core_ext/numeric/time.rb +20 -0
- data/lib/active_support/core_ext/object.rb +0 -1
- data/lib/active_support/core_ext/object/blank.rb +11 -2
- data/lib/active_support/core_ext/object/deep_dup.rb +10 -3
- data/lib/active_support/core_ext/object/duplicable.rb +39 -70
- data/lib/active_support/core_ext/object/inclusion.rb +2 -2
- data/lib/active_support/core_ext/object/instance_variables.rb +1 -1
- data/lib/active_support/core_ext/object/json.rb +9 -7
- data/lib/active_support/core_ext/object/to_query.rb +1 -1
- data/lib/active_support/core_ext/object/try.rb +67 -21
- data/lib/active_support/core_ext/object/with_options.rb +1 -1
- data/lib/active_support/core_ext/range/conversions.rb +18 -6
- data/lib/active_support/core_ext/range/each.rb +16 -18
- data/lib/active_support/core_ext/range/include_range.rb +20 -20
- data/lib/active_support/core_ext/securerandom.rb +23 -0
- data/lib/active_support/core_ext/string/access.rb +1 -1
- data/lib/active_support/core_ext/string/behavior.rb +1 -1
- data/lib/active_support/core_ext/string/conversions.rb +2 -2
- data/lib/active_support/core_ext/string/filters.rb +1 -2
- data/lib/active_support/core_ext/string/inflections.rb +23 -5
- data/lib/active_support/core_ext/string/multibyte.rb +11 -7
- data/lib/active_support/core_ext/string/output_safety.rb +8 -9
- data/lib/active_support/core_ext/string/strip.rb +3 -6
- data/lib/active_support/core_ext/struct.rb +3 -6
- data/lib/active_support/core_ext/time.rb +0 -2
- data/lib/active_support/core_ext/time/calculations.rb +18 -16
- data/lib/active_support/core_ext/time/conversions.rb +4 -2
- data/lib/active_support/core_ext/time/marshal.rb +2 -29
- data/lib/active_support/core_ext/time/zones.rb +19 -3
- data/lib/active_support/core_ext/uri.rb +1 -3
- data/lib/active_support/dependencies.rb +79 -44
- data/lib/active_support/dependencies/interlock.rb +47 -0
- data/lib/active_support/deprecation/behaviors.rb +12 -0
- data/lib/active_support/deprecation/method_wrappers.rb +42 -16
- data/lib/active_support/deprecation/proxy_wrappers.rb +47 -24
- data/lib/active_support/deprecation/reporting.rb +13 -2
- data/lib/active_support/duration.rb +5 -8
- data/lib/active_support/evented_file_update_checker.rb +150 -0
- data/lib/active_support/file_update_checker.rb +1 -1
- data/lib/active_support/gem_version.rb +5 -5
- data/lib/active_support/hash_with_indifferent_access.rb +15 -17
- data/lib/active_support/i18n_railtie.rb +25 -4
- data/lib/active_support/inflector/inflections.rb +36 -5
- data/lib/active_support/inflector/methods.rb +87 -89
- data/lib/active_support/inflector/transliterate.rb +36 -21
- data/lib/active_support/json/decoding.rb +2 -8
- data/lib/active_support/json/encoding.rb +0 -50
- data/lib/active_support/key_generator.rb +4 -4
- data/lib/active_support/log_subscriber.rb +1 -1
- data/lib/active_support/log_subscriber/test_helper.rb +3 -3
- data/lib/active_support/logger.rb +4 -52
- data/lib/active_support/logger_silence.rb +3 -5
- data/lib/active_support/message_encryptor.rb +4 -11
- data/lib/active_support/message_verifier.rb +64 -8
- data/lib/active_support/multibyte/chars.rb +12 -3
- data/lib/active_support/multibyte/unicode.rb +6 -8
- data/lib/active_support/notifications.rb +2 -2
- data/lib/active_support/notifications/fanout.rb +5 -5
- data/lib/active_support/notifications/instrumenter.rb +19 -2
- data/lib/active_support/number_helper.rb +21 -15
- data/lib/active_support/number_helper/number_to_currency_converter.rb +4 -4
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +7 -2
- data/lib/active_support/number_helper/number_to_human_converter.rb +6 -4
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +5 -1
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +28 -25
- data/lib/active_support/ordered_options.rb +15 -1
- data/lib/active_support/per_thread_registry.rb +3 -0
- data/lib/active_support/rails.rb +2 -2
- data/lib/active_support/railtie.rb +6 -1
- data/lib/active_support/rescuable.rb +4 -4
- data/lib/active_support/security_utils.rb +0 -7
- data/lib/active_support/string_inquirer.rb +1 -1
- data/lib/active_support/subscriber.rb +5 -10
- data/lib/active_support/tagged_logging.rb +3 -1
- data/lib/active_support/test_case.rb +13 -25
- data/lib/active_support/testing/assertions.rb +15 -13
- data/lib/active_support/testing/autorun.rb +8 -1
- data/lib/active_support/testing/composite_filter.rb +54 -0
- data/lib/active_support/testing/deprecation.rb +9 -8
- data/lib/active_support/testing/file_fixtures.rb +34 -0
- data/lib/active_support/testing/isolation.rb +22 -8
- data/lib/active_support/testing/method_call_assertions.rb +41 -0
- data/lib/active_support/testing/stream.rb +42 -0
- data/lib/active_support/testing/time_helpers.rb +6 -6
- data/lib/active_support/time_with_zone.rb +135 -53
- data/lib/active_support/values/time_zone.rb +80 -46
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/xml_mini.rb +15 -30
- data/lib/active_support/xml_mini/jdom.rb +1 -1
- data/lib/active_support/xml_mini/libxml.rb +5 -3
- data/lib/active_support/xml_mini/libxmlsax.rb +4 -1
- data/lib/active_support/xml_mini/nokogiri.rb +5 -3
- data/lib/active_support/xml_mini/nokogirisax.rb +3 -1
- data/lib/active_support/xml_mini/rexml.rb +3 -1
- metadata +57 -21
- data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +0 -15
- data/lib/active_support/core_ext/date_time/compatibility.rb +0 -16
- data/lib/active_support/core_ext/object/itself.rb +0 -15
- data/lib/active_support/core_ext/thread.rb +0 -86
- data/lib/active_support/core_ext/time/compatibility.rb +0 -14
- data/lib/active_support/logger_thread_safe_level.rb +0 -32
@@ -75,10 +75,10 @@ class Date
|
|
75
75
|
#
|
76
76
|
# date = Date.new(2007, 11, 10) # => Sat, 10 Nov 2007
|
77
77
|
#
|
78
|
-
# date.to_time # =>
|
79
|
-
# date.to_time(:local) # =>
|
78
|
+
# date.to_time # => 2007-11-10 00:00:00 0800
|
79
|
+
# date.to_time(:local) # => 2007-11-10 00:00:00 0800
|
80
80
|
#
|
81
|
-
# date.to_time(:utc) # =>
|
81
|
+
# date.to_time(:utc) # => 2007-11-10 00:00:00 UTC
|
82
82
|
def to_time(form = :local)
|
83
83
|
::Time.send(form, year, month, day)
|
84
84
|
end
|
@@ -9,15 +9,26 @@ module DateAndTime
|
|
9
9
|
:saturday => 5,
|
10
10
|
:sunday => 6
|
11
11
|
}
|
12
|
+
WEEKEND_DAYS = [ 6, 0 ]
|
12
13
|
|
13
14
|
# Returns a new date/time representing yesterday.
|
14
15
|
def yesterday
|
15
|
-
advance(:
|
16
|
+
advance(days: -1)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns a new date/time representing the previous day.
|
20
|
+
def prev_day
|
21
|
+
advance(days: -1)
|
16
22
|
end
|
17
23
|
|
18
24
|
# Returns a new date/time representing tomorrow.
|
19
25
|
def tomorrow
|
20
|
-
advance(:
|
26
|
+
advance(days: 1)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns a new date/time representing the next day.
|
30
|
+
def next_day
|
31
|
+
advance(days: 1)
|
21
32
|
end
|
22
33
|
|
23
34
|
# Returns true if the date/time is today.
|
@@ -35,6 +46,11 @@ module DateAndTime
|
|
35
46
|
self > self.class.current
|
36
47
|
end
|
37
48
|
|
49
|
+
# Returns true if the date/time falls on a Saturday or Sunday.
|
50
|
+
def on_weekend?
|
51
|
+
WEEKEND_DAYS.include?(wday)
|
52
|
+
end
|
53
|
+
|
38
54
|
# Returns a new date/time the specified number of days ago.
|
39
55
|
def days_ago(days)
|
40
56
|
advance(:days => -days)
|
@@ -76,15 +92,28 @@ module DateAndTime
|
|
76
92
|
end
|
77
93
|
|
78
94
|
# Returns a new date/time at the start of the month.
|
79
|
-
#
|
95
|
+
#
|
96
|
+
# today = Date.today # => Thu, 18 Jun 2015
|
97
|
+
# today.beginning_of_month # => Mon, 01 Jun 2015
|
98
|
+
#
|
99
|
+
# +DateTime+ objects will have a time set to 0:00.
|
100
|
+
#
|
101
|
+
# now = DateTime.current # => Thu, 18 Jun 2015 15:23:13 +0000
|
102
|
+
# now.beginning_of_month # => Mon, 01 Jun 2015 00:00:00 +0000
|
80
103
|
def beginning_of_month
|
81
104
|
first_hour(change(:day => 1))
|
82
105
|
end
|
83
106
|
alias :at_beginning_of_month :beginning_of_month
|
84
107
|
|
85
108
|
# Returns a new date/time at the start of the quarter.
|
86
|
-
#
|
87
|
-
#
|
109
|
+
#
|
110
|
+
# today = Date.today # => Fri, 10 Jul 2015
|
111
|
+
# today.beginning_of_quarter # => Wed, 01 Jul 2015
|
112
|
+
#
|
113
|
+
# +DateTime+ objects will have a time set to 0:00.
|
114
|
+
#
|
115
|
+
# now = DateTime.current # => Fri, 10 Jul 2015 18:41:29 +0000
|
116
|
+
# now.beginning_of_quarter # => Wed, 01 Jul 2015 00:00:00 +0000
|
88
117
|
def beginning_of_quarter
|
89
118
|
first_quarter_month = [10, 7, 4, 1].detect { |m| m <= month }
|
90
119
|
beginning_of_month.change(:month => first_quarter_month)
|
@@ -92,17 +121,29 @@ module DateAndTime
|
|
92
121
|
alias :at_beginning_of_quarter :beginning_of_quarter
|
93
122
|
|
94
123
|
# Returns a new date/time at the end of the quarter.
|
95
|
-
#
|
96
|
-
#
|
124
|
+
#
|
125
|
+
# today = Date.today # => Fri, 10 Jul 2015
|
126
|
+
# today.end_of_quarter # => Wed, 30 Sep 2015
|
127
|
+
#
|
128
|
+
# +DateTime+ objects will have a time set to 23:59:59.
|
129
|
+
#
|
130
|
+
# now = DateTime.current # => Fri, 10 Jul 2015 18:41:29 +0000
|
131
|
+
# now.end_of_quarter # => Wed, 30 Sep 2015 23:59:59 +0000
|
97
132
|
def end_of_quarter
|
98
133
|
last_quarter_month = [3, 6, 9, 12].detect { |m| m >= month }
|
99
134
|
beginning_of_month.change(:month => last_quarter_month).end_of_month
|
100
135
|
end
|
101
136
|
alias :at_end_of_quarter :end_of_quarter
|
102
137
|
|
103
|
-
#
|
104
|
-
#
|
105
|
-
#
|
138
|
+
# Returns a new date/time at the beginning of the year.
|
139
|
+
#
|
140
|
+
# today = Date.today # => Fri, 10 Jul 2015
|
141
|
+
# today.beginning_of_year # => Thu, 01 Jan 2015
|
142
|
+
#
|
143
|
+
# +DateTime+ objects will have a time set to 0:00.
|
144
|
+
#
|
145
|
+
# now = DateTime.current # => Fri, 10 Jul 2015 18:41:29 +0000
|
146
|
+
# now.beginning_of_year # => Thu, 01 Jan 2015 00:00:00 +0000
|
106
147
|
def beginning_of_year
|
107
148
|
change(:month => 1).beginning_of_month
|
108
149
|
end
|
@@ -115,16 +156,27 @@ module DateAndTime
|
|
115
156
|
#
|
116
157
|
# The +given_day_in_next_week+ defaults to the beginning of the week
|
117
158
|
# which is determined by +Date.beginning_of_week+ or +config.beginning_of_week+
|
159
|
+
# when set.
|
118
160
|
#
|
119
161
|
# today = Date.today # => Thu, 07 May 2015
|
120
162
|
# today.next_week(:friday) # => Fri, 15 May 2015
|
121
163
|
#
|
122
|
-
#
|
164
|
+
# +DateTime+ objects have their time set to 0:00 unless +same_time+ is true.
|
123
165
|
#
|
124
|
-
# now =
|
125
|
-
# now.next_week # => Mon, 11 May 2015 00:00:00
|
126
|
-
def next_week(given_day_in_next_week = Date.beginning_of_week)
|
127
|
-
first_hour(weeks_since(1).beginning_of_week.days_since(days_span(given_day_in_next_week)))
|
166
|
+
# now = DateTime.current # => Thu, 07 May 2015 13:31:16 +0000
|
167
|
+
# now.next_week # => Mon, 11 May 2015 00:00:00 +0000
|
168
|
+
def next_week(given_day_in_next_week = Date.beginning_of_week, same_time: false)
|
169
|
+
result = first_hour(weeks_since(1).beginning_of_week.days_since(days_span(given_day_in_next_week)))
|
170
|
+
same_time ? copy_time_to(result) : result
|
171
|
+
end
|
172
|
+
|
173
|
+
# Returns a new date/time representing the next weekday.
|
174
|
+
def next_weekday
|
175
|
+
if next_day.on_weekend?
|
176
|
+
next_week(:monday, same_time: true)
|
177
|
+
else
|
178
|
+
next_day
|
179
|
+
end
|
128
180
|
end
|
129
181
|
|
130
182
|
# Short-hand for months_since(1).
|
@@ -145,12 +197,23 @@ module DateAndTime
|
|
145
197
|
# Returns a new date/time representing the given day in the previous week.
|
146
198
|
# Week is assumed to start on +start_day+, default is
|
147
199
|
# +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
|
148
|
-
# DateTime objects have their time set to 0:00.
|
149
|
-
def prev_week(start_day = Date.beginning_of_week)
|
150
|
-
first_hour(weeks_ago(1).beginning_of_week.days_since(days_span(start_day)))
|
200
|
+
# DateTime objects have their time set to 0:00 unless +same_time+ is true.
|
201
|
+
def prev_week(start_day = Date.beginning_of_week, same_time: false)
|
202
|
+
result = first_hour(weeks_ago(1).beginning_of_week.days_since(days_span(start_day)))
|
203
|
+
same_time ? copy_time_to(result) : result
|
151
204
|
end
|
152
205
|
alias_method :last_week, :prev_week
|
153
206
|
|
207
|
+
# Returns a new date/time representing the previous weekday.
|
208
|
+
def prev_weekday
|
209
|
+
if prev_day.on_weekend?
|
210
|
+
copy_time_to(beginning_of_week(:friday))
|
211
|
+
else
|
212
|
+
prev_day
|
213
|
+
end
|
214
|
+
end
|
215
|
+
alias_method :last_weekday, :prev_weekday
|
216
|
+
|
154
217
|
# Short-hand for months_ago(1).
|
155
218
|
def prev_month
|
156
219
|
months_ago(1)
|
@@ -246,17 +309,20 @@ module DateAndTime
|
|
246
309
|
end
|
247
310
|
|
248
311
|
private
|
312
|
+
def first_hour(date_or_time)
|
313
|
+
date_or_time.acts_like?(:time) ? date_or_time.beginning_of_day : date_or_time
|
314
|
+
end
|
249
315
|
|
250
|
-
|
251
|
-
|
252
|
-
|
316
|
+
def last_hour(date_or_time)
|
317
|
+
date_or_time.acts_like?(:time) ? date_or_time.end_of_day : date_or_time
|
318
|
+
end
|
253
319
|
|
254
|
-
|
255
|
-
|
256
|
-
|
320
|
+
def days_span(day)
|
321
|
+
(DAYS_INTO_WEEK[day] - DAYS_INTO_WEEK[Date.beginning_of_week]) % 7
|
322
|
+
end
|
257
323
|
|
258
|
-
|
259
|
-
|
260
|
-
|
324
|
+
def copy_time_to(other)
|
325
|
+
other.change(hour: hour, min: min, sec: sec, usec: try(:usec))
|
326
|
+
end
|
261
327
|
end
|
262
328
|
end
|
@@ -4,7 +4,7 @@ module DateAndTime
|
|
4
4
|
# if Time.zone_default is set. Otherwise, it returns the current time.
|
5
5
|
#
|
6
6
|
# Time.zone = 'Hawaii' # => 'Hawaii'
|
7
|
-
#
|
7
|
+
# Time.utc(2000).in_time_zone # => Fri, 31 Dec 1999 14:00:00 HST -10:00
|
8
8
|
# Date.new(2000).in_time_zone # => Sat, 01 Jan 2000 00:00:00 HST -10:00
|
9
9
|
#
|
10
10
|
# This method is similar to Time#localtime, except that it uses <tt>Time.zone</tt> as the local zone
|
@@ -14,7 +14,6 @@ module DateAndTime
|
|
14
14
|
# and the conversion will be based on that zone instead of <tt>Time.zone</tt>.
|
15
15
|
#
|
16
16
|
# Time.utc(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
|
17
|
-
# DateTime.utc(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
|
18
17
|
# Date.new(2000).in_time_zone('Alaska') # => Sat, 01 Jan 2000 00:00:00 AKST -09:00
|
19
18
|
def in_time_zone(zone = ::Time.zone)
|
20
19
|
time_zone = ::Time.find_zone! zone
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'active_support/core_ext/date_time/acts_like'
|
2
|
+
require 'active_support/core_ext/date_time/blank'
|
2
3
|
require 'active_support/core_ext/date_time/calculations'
|
3
|
-
require 'active_support/core_ext/date_time/compatibility'
|
4
4
|
require 'active_support/core_ext/date_time/conversions'
|
5
5
|
require 'active_support/core_ext/date_time/zones'
|
@@ -10,7 +10,11 @@ class DateTime
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
-
#
|
13
|
+
# Returns the number of seconds since 00:00:00.
|
14
|
+
#
|
15
|
+
# DateTime.new(2012, 8, 29, 0, 0, 0).seconds_since_midnight # => 0
|
16
|
+
# DateTime.new(2012, 8, 29, 12, 34, 56).seconds_since_midnight # => 45296
|
17
|
+
# DateTime.new(2012, 8, 29, 23, 59, 59).seconds_since_midnight # => 86399
|
14
18
|
def seconds_since_midnight
|
15
19
|
sec + (min * 60) + (hour * 3600)
|
16
20
|
end
|
@@ -24,13 +28,6 @@ class DateTime
|
|
24
28
|
end_of_day.to_i - to_i
|
25
29
|
end
|
26
30
|
|
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
|
-
|
34
31
|
# Returns a new DateTime where one or more of the elements have been changed
|
35
32
|
# according to the +options+ parameter. The time options (<tt>:hour</tt>,
|
36
33
|
# <tt>:min</tt>, <tt>:sec</tt>) reset cascadingly, so if only the hour is
|
@@ -146,27 +143,14 @@ class DateTime
|
|
146
143
|
end
|
147
144
|
alias :at_end_of_minute :end_of_minute
|
148
145
|
|
149
|
-
#
|
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.
|
146
|
+
# Adjusts DateTime to UTC by adding its offset value; offset is set to 0.
|
161
147
|
#
|
162
148
|
# DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)) # => Mon, 21 Feb 2005 10:11:12 -0600
|
163
|
-
# DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc # => Mon, 21 Feb 2005 16:11:12
|
149
|
+
# DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc # => Mon, 21 Feb 2005 16:11:12 +0000
|
164
150
|
def utc
|
165
151
|
new_offset(0)
|
166
152
|
end
|
167
|
-
alias_method :getgm, :utc
|
168
153
|
alias_method :getutc, :utc
|
169
|
-
alias_method :gmtime, :utc
|
170
154
|
|
171
155
|
# Returns +true+ if <tt>offset == 0</tt>.
|
172
156
|
def utc?
|
@@ -40,6 +40,8 @@ class DateTime
|
|
40
40
|
alias_method :to_default_s, :to_s if instance_methods(false).include?(:to_s)
|
41
41
|
alias_method :to_s, :to_formatted_s
|
42
42
|
|
43
|
+
# Returns a formatted string of the offset from UTC, or an alternative
|
44
|
+
# string if the time zone is already UTC.
|
43
45
|
#
|
44
46
|
# datetime = DateTime.civil(2000, 1, 1, 0, 0, 0, Rational(-6, 24))
|
45
47
|
# datetime.formatted_offset # => "-06:00"
|
@@ -21,7 +21,7 @@ module Enumerable
|
|
21
21
|
if block_given?
|
22
22
|
map(&block).sum(identity)
|
23
23
|
else
|
24
|
-
inject
|
24
|
+
inject(:+) || identity
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
@@ -60,6 +60,32 @@ module Enumerable
|
|
60
60
|
def exclude?(object)
|
61
61
|
!include?(object)
|
62
62
|
end
|
63
|
+
|
64
|
+
# Returns a copy of the enumerable without the specified elements.
|
65
|
+
#
|
66
|
+
# ["David", "Rafael", "Aaron", "Todd"].without "Aaron", "Todd"
|
67
|
+
# => ["David", "Rafael"]
|
68
|
+
#
|
69
|
+
# {foo: 1, bar: 2, baz: 3}.without :bar
|
70
|
+
# => {foo: 1, baz: 3}
|
71
|
+
def without(*elements)
|
72
|
+
reject { |element| elements.include?(element) }
|
73
|
+
end
|
74
|
+
|
75
|
+
# Convert an enumerable to an array based on the given key.
|
76
|
+
#
|
77
|
+
# [{ name: "David" }, { name: "Rafael" }, { name: "Aaron" }].pluck(:name)
|
78
|
+
# => ["David", "Rafael", "Aaron"]
|
79
|
+
#
|
80
|
+
# [{ id: 1, name: "David" }, { id: 2, name: "Rafael" }].pluck(:id, :name)
|
81
|
+
# => [[1, "David"], [2, "Rafael"]]
|
82
|
+
def pluck(*keys)
|
83
|
+
if keys.many?
|
84
|
+
map { |element| keys.map { |key| element[key] } }
|
85
|
+
else
|
86
|
+
map { |element| element[keys.first] }
|
87
|
+
end
|
88
|
+
end
|
63
89
|
end
|
64
90
|
|
65
91
|
class Range #:nodoc:
|
@@ -78,19 +104,3 @@ class Range #:nodoc:
|
|
78
104
|
end
|
79
105
|
end
|
80
106
|
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
|
@@ -8,40 +8,45 @@ class File
|
|
8
8
|
# file.write('hello')
|
9
9
|
# end
|
10
10
|
#
|
11
|
-
#
|
12
|
-
#
|
11
|
+
# This method needs to create a temporary file. By default it will create it
|
12
|
+
# in the same directory as the destination file. If you don't like this
|
13
|
+
# behavior you can provide a different directory but it must be on the
|
14
|
+
# same physical filesystem as the file you're trying to write.
|
13
15
|
#
|
14
16
|
# File.atomic_write('/data/something.important', '/data/tmp') do |file|
|
15
17
|
# file.write('hello')
|
16
18
|
# end
|
17
|
-
def self.atomic_write(file_name, temp_dir =
|
19
|
+
def self.atomic_write(file_name, temp_dir = dirname(file_name))
|
18
20
|
require 'tempfile' unless defined?(Tempfile)
|
19
|
-
require 'fileutils' unless defined?(FileUtils)
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
Tempfile.open(".#{basename(file_name)}", temp_dir) do |temp_file|
|
23
|
+
temp_file.binmode
|
24
|
+
return_val = yield temp_file
|
25
|
+
temp_file.close
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
27
|
+
old_stat = if exist?(file_name)
|
28
|
+
# Get original file permissions
|
29
|
+
stat(file_name)
|
30
|
+
elsif temp_dir != dirname(file_name)
|
31
|
+
# If not possible, probe which are the default permissions in the
|
32
|
+
# destination directory.
|
33
|
+
probe_stat_in(dirname(file_name))
|
34
|
+
end
|
34
35
|
|
35
|
-
|
36
|
-
|
36
|
+
if old_stat
|
37
|
+
# Set correct permissions on new file
|
38
|
+
begin
|
39
|
+
chown(old_stat.uid, old_stat.gid, temp_file.path)
|
40
|
+
# This operation will affect filesystem ACL's
|
41
|
+
chmod(old_stat.mode, temp_file.path)
|
42
|
+
rescue Errno::EPERM, Errno::EACCES
|
43
|
+
# Changing file ownership failed, moving on.
|
44
|
+
end
|
45
|
+
end
|
37
46
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
# This operation will affect filesystem ACL's
|
42
|
-
chmod(old_stat.mode, file_name)
|
43
|
-
rescue Errno::EPERM, Errno::EACCES
|
44
|
-
# Changing file ownership failed, moving on.
|
47
|
+
# Overwrite original file with temp file
|
48
|
+
rename(temp_file.path, file_name)
|
49
|
+
return_val
|
45
50
|
end
|
46
51
|
end
|
47
52
|
|
@@ -1,24 +1,20 @@
|
|
1
1
|
class Hash
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
self.select { |_, value| !value.nil? }
|
11
|
-
end
|
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? }
|
12
10
|
end
|
13
11
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
self.reject! { |_, value| value.nil? }
|
22
|
-
end
|
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? }
|
23
19
|
end
|
24
20
|
end
|