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.

Files changed (174) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +309 -485
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +2 -3
  5. data/lib/active_support.rb +8 -15
  6. data/lib/active_support/array_inquirer.rb +44 -0
  7. data/lib/active_support/backtrace_cleaner.rb +1 -1
  8. data/lib/active_support/cache.rb +59 -72
  9. data/lib/active_support/cache/file_store.rb +27 -19
  10. data/lib/active_support/cache/mem_cache_store.rb +71 -60
  11. data/lib/active_support/cache/memory_store.rb +16 -21
  12. data/lib/active_support/cache/null_store.rb +1 -4
  13. data/lib/active_support/cache/strategy/local_cache.rb +31 -20
  14. data/lib/active_support/callbacks.rb +107 -111
  15. data/lib/active_support/concern.rb +1 -1
  16. data/lib/active_support/concurrency/latch.rb +7 -15
  17. data/lib/active_support/concurrency/share_lock.rb +142 -0
  18. data/lib/active_support/configurable.rb +1 -0
  19. data/lib/active_support/core_ext.rb +2 -1
  20. data/lib/active_support/core_ext/array.rb +1 -0
  21. data/lib/active_support/core_ext/array/access.rb +13 -1
  22. data/lib/active_support/core_ext/array/conversions.rb +6 -4
  23. data/lib/active_support/core_ext/array/inquiry.rb +17 -0
  24. data/lib/active_support/core_ext/array/wrap.rb +5 -4
  25. data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -10
  26. data/lib/active_support/core_ext/class.rb +0 -1
  27. data/lib/active_support/core_ext/class/attribute.rb +10 -9
  28. data/lib/active_support/core_ext/class/subclasses.rb +5 -2
  29. data/lib/active_support/core_ext/date.rb +1 -1
  30. data/lib/active_support/core_ext/date/blank.rb +12 -0
  31. data/lib/active_support/core_ext/date/calculations.rb +1 -1
  32. data/lib/active_support/core_ext/date/conversions.rb +3 -3
  33. data/lib/active_support/core_ext/date_and_time/calculations.rb +93 -27
  34. data/lib/active_support/core_ext/date_and_time/zones.rb +1 -2
  35. data/lib/active_support/core_ext/date_time.rb +1 -1
  36. data/lib/active_support/core_ext/date_time/blank.rb +12 -0
  37. data/lib/active_support/core_ext/date_time/calculations.rb +7 -23
  38. data/lib/active_support/core_ext/date_time/conversions.rb +2 -0
  39. data/lib/active_support/core_ext/enumerable.rb +27 -17
  40. data/lib/active_support/core_ext/file/atomic.rb +30 -25
  41. data/lib/active_support/core_ext/hash/compact.rb +15 -19
  42. data/lib/active_support/core_ext/hash/conversions.rb +21 -2
  43. data/lib/active_support/core_ext/hash/deep_merge.rb +1 -1
  44. data/lib/active_support/core_ext/hash/except.rb +9 -8
  45. data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -1
  46. data/lib/active_support/core_ext/hash/keys.rb +22 -18
  47. data/lib/active_support/core_ext/hash/slice.rb +1 -1
  48. data/lib/active_support/core_ext/hash/transform_values.rb +13 -7
  49. data/lib/active_support/core_ext/integer/time.rb +1 -1
  50. data/lib/active_support/core_ext/kernel.rb +0 -1
  51. data/lib/active_support/core_ext/kernel/debugger.rb +3 -10
  52. data/lib/active_support/core_ext/kernel/reporting.rb +0 -84
  53. data/lib/active_support/core_ext/load_error.rb +4 -2
  54. data/lib/active_support/core_ext/marshal.rb +8 -13
  55. data/lib/active_support/core_ext/module.rb +1 -0
  56. data/lib/active_support/core_ext/module/aliasing.rb +6 -1
  57. data/lib/active_support/core_ext/module/anonymous.rb +10 -1
  58. data/lib/active_support/core_ext/module/attr_internal.rb +2 -5
  59. data/lib/active_support/core_ext/module/attribute_accessors.rb +7 -7
  60. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +141 -0
  61. data/lib/active_support/core_ext/module/concerning.rb +4 -4
  62. data/lib/active_support/core_ext/module/delegation.rb +7 -14
  63. data/lib/active_support/core_ext/module/method_transplanting.rb +3 -13
  64. data/lib/active_support/core_ext/module/qualified_const.rb +30 -12
  65. data/lib/active_support/core_ext/module/remove_method.rb +23 -0
  66. data/lib/active_support/core_ext/name_error.rb +15 -2
  67. data/lib/active_support/core_ext/numeric.rb +1 -0
  68. data/lib/active_support/core_ext/numeric/bytes.rb +20 -0
  69. data/lib/active_support/core_ext/numeric/conversions.rb +12 -23
  70. data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
  71. data/lib/active_support/core_ext/numeric/time.rb +20 -0
  72. data/lib/active_support/core_ext/object.rb +0 -1
  73. data/lib/active_support/core_ext/object/blank.rb +11 -2
  74. data/lib/active_support/core_ext/object/deep_dup.rb +10 -3
  75. data/lib/active_support/core_ext/object/duplicable.rb +39 -70
  76. data/lib/active_support/core_ext/object/inclusion.rb +2 -2
  77. data/lib/active_support/core_ext/object/instance_variables.rb +1 -1
  78. data/lib/active_support/core_ext/object/json.rb +9 -7
  79. data/lib/active_support/core_ext/object/to_query.rb +1 -1
  80. data/lib/active_support/core_ext/object/try.rb +67 -21
  81. data/lib/active_support/core_ext/object/with_options.rb +1 -1
  82. data/lib/active_support/core_ext/range/conversions.rb +18 -6
  83. data/lib/active_support/core_ext/range/each.rb +16 -18
  84. data/lib/active_support/core_ext/range/include_range.rb +20 -20
  85. data/lib/active_support/core_ext/securerandom.rb +23 -0
  86. data/lib/active_support/core_ext/string/access.rb +1 -1
  87. data/lib/active_support/core_ext/string/behavior.rb +1 -1
  88. data/lib/active_support/core_ext/string/conversions.rb +2 -2
  89. data/lib/active_support/core_ext/string/filters.rb +1 -2
  90. data/lib/active_support/core_ext/string/inflections.rb +23 -5
  91. data/lib/active_support/core_ext/string/multibyte.rb +11 -7
  92. data/lib/active_support/core_ext/string/output_safety.rb +8 -9
  93. data/lib/active_support/core_ext/string/strip.rb +3 -6
  94. data/lib/active_support/core_ext/struct.rb +3 -6
  95. data/lib/active_support/core_ext/time.rb +0 -2
  96. data/lib/active_support/core_ext/time/calculations.rb +18 -16
  97. data/lib/active_support/core_ext/time/conversions.rb +4 -2
  98. data/lib/active_support/core_ext/time/marshal.rb +2 -29
  99. data/lib/active_support/core_ext/time/zones.rb +19 -3
  100. data/lib/active_support/core_ext/uri.rb +1 -3
  101. data/lib/active_support/dependencies.rb +79 -44
  102. data/lib/active_support/dependencies/interlock.rb +47 -0
  103. data/lib/active_support/deprecation/behaviors.rb +12 -0
  104. data/lib/active_support/deprecation/method_wrappers.rb +42 -16
  105. data/lib/active_support/deprecation/proxy_wrappers.rb +47 -24
  106. data/lib/active_support/deprecation/reporting.rb +13 -2
  107. data/lib/active_support/duration.rb +5 -8
  108. data/lib/active_support/evented_file_update_checker.rb +150 -0
  109. data/lib/active_support/file_update_checker.rb +1 -1
  110. data/lib/active_support/gem_version.rb +5 -5
  111. data/lib/active_support/hash_with_indifferent_access.rb +15 -17
  112. data/lib/active_support/i18n_railtie.rb +25 -4
  113. data/lib/active_support/inflector/inflections.rb +36 -5
  114. data/lib/active_support/inflector/methods.rb +87 -89
  115. data/lib/active_support/inflector/transliterate.rb +36 -21
  116. data/lib/active_support/json/decoding.rb +2 -8
  117. data/lib/active_support/json/encoding.rb +0 -50
  118. data/lib/active_support/key_generator.rb +4 -4
  119. data/lib/active_support/log_subscriber.rb +1 -1
  120. data/lib/active_support/log_subscriber/test_helper.rb +3 -3
  121. data/lib/active_support/logger.rb +4 -52
  122. data/lib/active_support/logger_silence.rb +3 -5
  123. data/lib/active_support/message_encryptor.rb +4 -11
  124. data/lib/active_support/message_verifier.rb +64 -8
  125. data/lib/active_support/multibyte/chars.rb +12 -3
  126. data/lib/active_support/multibyte/unicode.rb +6 -8
  127. data/lib/active_support/notifications.rb +2 -2
  128. data/lib/active_support/notifications/fanout.rb +5 -5
  129. data/lib/active_support/notifications/instrumenter.rb +19 -2
  130. data/lib/active_support/number_helper.rb +21 -15
  131. data/lib/active_support/number_helper/number_to_currency_converter.rb +4 -4
  132. data/lib/active_support/number_helper/number_to_delimited_converter.rb +7 -2
  133. data/lib/active_support/number_helper/number_to_human_converter.rb +6 -4
  134. data/lib/active_support/number_helper/number_to_human_size_converter.rb +5 -1
  135. data/lib/active_support/number_helper/number_to_percentage_converter.rb +1 -1
  136. data/lib/active_support/number_helper/number_to_rounded_converter.rb +28 -25
  137. data/lib/active_support/ordered_options.rb +15 -1
  138. data/lib/active_support/per_thread_registry.rb +3 -0
  139. data/lib/active_support/rails.rb +2 -2
  140. data/lib/active_support/railtie.rb +6 -1
  141. data/lib/active_support/rescuable.rb +4 -4
  142. data/lib/active_support/security_utils.rb +0 -7
  143. data/lib/active_support/string_inquirer.rb +1 -1
  144. data/lib/active_support/subscriber.rb +5 -10
  145. data/lib/active_support/tagged_logging.rb +3 -1
  146. data/lib/active_support/test_case.rb +13 -25
  147. data/lib/active_support/testing/assertions.rb +15 -13
  148. data/lib/active_support/testing/autorun.rb +8 -1
  149. data/lib/active_support/testing/composite_filter.rb +54 -0
  150. data/lib/active_support/testing/deprecation.rb +9 -8
  151. data/lib/active_support/testing/file_fixtures.rb +34 -0
  152. data/lib/active_support/testing/isolation.rb +22 -8
  153. data/lib/active_support/testing/method_call_assertions.rb +41 -0
  154. data/lib/active_support/testing/stream.rb +42 -0
  155. data/lib/active_support/testing/time_helpers.rb +6 -6
  156. data/lib/active_support/time_with_zone.rb +135 -53
  157. data/lib/active_support/values/time_zone.rb +80 -46
  158. data/lib/active_support/values/unicode_tables.dat +0 -0
  159. data/lib/active_support/xml_mini.rb +15 -30
  160. data/lib/active_support/xml_mini/jdom.rb +1 -1
  161. data/lib/active_support/xml_mini/libxml.rb +5 -3
  162. data/lib/active_support/xml_mini/libxmlsax.rb +4 -1
  163. data/lib/active_support/xml_mini/nokogiri.rb +5 -3
  164. data/lib/active_support/xml_mini/nokogirisax.rb +3 -1
  165. data/lib/active_support/xml_mini/rexml.rb +3 -1
  166. metadata +57 -21
  167. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
  168. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
  169. data/lib/active_support/core_ext/date_and_time/compatibility.rb +0 -15
  170. data/lib/active_support/core_ext/date_time/compatibility.rb +0 -16
  171. data/lib/active_support/core_ext/object/itself.rb +0 -15
  172. data/lib/active_support/core_ext/thread.rb +0 -86
  173. data/lib/active_support/core_ext/time/compatibility.rb +0 -14
  174. 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 # => Sat Nov 10 00:00:00 0800 2007
79
- # date.to_time(:local) # => Sat Nov 10 00:00:00 0800 2007
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) # => Sat Nov 10 00:00:00 UTC 2007
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(:days => -1)
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(:days => 1)
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
- # DateTime objects will have a time set to 0:00.
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
- # Example: 1st January, 1st July, 1st October.
87
- # DateTime objects will have a time set to 0:00.
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
- # Example: 31st March, 30th June, 30th September.
96
- # DateTime objects will have a time set to 23:59:59.
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
- # Return a new date/time at the beginning of the year.
104
- # Example: 1st January.
105
- # DateTime objects will have a time set to 0:00.
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
- # when set. +DateTime+ objects have their time set to 0:00.
164
+ # +DateTime+ objects have their time set to 0:00 unless +same_time+ is true.
123
165
  #
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
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
- def first_hour(date_or_time)
251
- date_or_time.acts_like?(:time) ? date_or_time.beginning_of_day : date_or_time
252
- end
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
- def last_hour(date_or_time)
255
- date_or_time.acts_like?(:time) ? date_or_time.end_of_day : date_or_time
256
- end
320
+ def days_span(day)
321
+ (DAYS_INTO_WEEK[day] - DAYS_INTO_WEEK[Date.beginning_of_week]) % 7
322
+ end
257
323
 
258
- def days_span(day)
259
- (DAYS_INTO_WEEK[day] - DAYS_INTO_WEEK[Date.beginning_of_week]) % 7
260
- end
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
- # DateTime.utc(2000).in_time_zone # => Fri, 31 Dec 1999 14:00:00 HST -10:00
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'
@@ -0,0 +1,12 @@
1
+ require 'date'
2
+
3
+ class DateTime #:nodoc:
4
+ # No DateTime is ever blank:
5
+ #
6
+ # DateTime.now.blank? # => false
7
+ #
8
+ # @return [false]
9
+ def blank?
10
+ false
11
+ end
12
+ end
@@ -10,7 +10,11 @@ class DateTime
10
10
  end
11
11
  end
12
12
 
13
- # Seconds since midnight: DateTime.now.seconds_since_midnight.
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
- # 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.
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 UTC
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 { |sum, element| sum + element } || identity
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
- # If your temp directory is not on the same filesystem as the file you're
12
- # trying to write, you can provide a different temporary directory.
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 = Dir.tmpdir)
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
- temp_file = Tempfile.new(basename(file_name), temp_dir)
22
- temp_file.binmode
23
- yield temp_file
24
- temp_file.close
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
- if File.exist?(file_name)
27
- # Get original file permissions
28
- old_stat = stat(file_name)
29
- else
30
- # If not possible, probe which are the default permissions in the
31
- # destination directory.
32
- old_stat = probe_stat_in(dirname(file_name))
33
- end
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
- # Overwrite original file with temp file
36
- FileUtils.mv(temp_file.path, file_name)
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
- # Set correct permissions on new file
39
- begin
40
- chown(old_stat.uid, old_stat.gid, file_name)
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
- 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
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
- 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
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