activesupport 5.0.0.beta3 → 5.0.0.beta4

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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +171 -4
  3. data/lib/active_support.rb +12 -0
  4. data/lib/active_support/cache.rb +32 -23
  5. data/lib/active_support/cache/strategy/local_cache.rb +1 -1
  6. data/lib/active_support/callbacks.rb +4 -4
  7. data/lib/active_support/concurrency/share_lock.rb +2 -2
  8. data/lib/active_support/core_ext/array/grouping.rb +6 -10
  9. data/lib/active_support/core_ext/date/conversions.rb +1 -0
  10. data/lib/active_support/core_ext/date_and_time/calculations.rb +2 -0
  11. data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -0
  12. data/lib/active_support/core_ext/date_time.rb +1 -1
  13. data/lib/active_support/core_ext/date_time/calculations.rb +30 -8
  14. data/lib/active_support/core_ext/date_time/compatibility.rb +5 -0
  15. data/lib/active_support/core_ext/enumerable.rb +16 -0
  16. data/lib/active_support/core_ext/hash/conversions.rb +1 -1
  17. data/lib/active_support/core_ext/hash/keys.rb +1 -1
  18. data/lib/active_support/core_ext/marshal.rb +5 -2
  19. data/lib/active_support/core_ext/module/attribute_accessors.rb +2 -2
  20. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +2 -2
  21. data/lib/active_support/core_ext/module/delegation.rb +2 -5
  22. data/lib/active_support/core_ext/module/introspection.rb +4 -0
  23. data/lib/active_support/core_ext/object/blank.rb +7 -3
  24. data/lib/active_support/core_ext/object/json.rb +6 -0
  25. data/lib/active_support/core_ext/string/conversions.rb +3 -2
  26. data/lib/active_support/core_ext/string/inflections.rb +9 -0
  27. data/lib/active_support/core_ext/string/output_safety.rb +1 -1
  28. data/lib/active_support/core_ext/time.rb +1 -0
  29. data/lib/active_support/core_ext/time/calculations.rb +7 -0
  30. data/lib/active_support/core_ext/time/compatibility.rb +5 -0
  31. data/lib/active_support/dependencies.rb +9 -52
  32. data/lib/active_support/dependencies/interlock.rb +6 -8
  33. data/lib/active_support/deprecation/reporting.rb +0 -1
  34. data/lib/active_support/duration.rb +20 -0
  35. data/lib/active_support/duration/iso8601_parser.rb +122 -0
  36. data/lib/active_support/duration/iso8601_serializer.rb +51 -0
  37. data/lib/active_support/evented_file_update_checker.rb +18 -13
  38. data/lib/active_support/execution_wrapper.rb +117 -0
  39. data/lib/active_support/executor.rb +6 -0
  40. data/lib/active_support/file_update_checker.rb +22 -2
  41. data/lib/active_support/gem_version.rb +1 -1
  42. data/lib/active_support/i18n_railtie.rb +2 -2
  43. data/lib/active_support/inflector/methods.rb +9 -0
  44. data/lib/active_support/number_helper.rb +8 -1
  45. data/lib/active_support/number_helper/number_to_delimited_converter.rb +1 -1
  46. data/lib/active_support/number_helper/number_to_phone_converter.rb +11 -2
  47. data/lib/active_support/number_helper/number_to_rounded_converter.rb +5 -3
  48. data/lib/active_support/reloader.rb +129 -0
  49. data/lib/active_support/rescuable.rb +10 -0
  50. data/lib/active_support/time_with_zone.rb +9 -14
  51. data/lib/active_support/values/time_zone.rb +14 -5
  52. metadata +12 -5
  53. data/lib/active_support/core_ext/date_time/zones.rb +0 -6
@@ -8,7 +8,7 @@ module ActiveSupport
8
8
  MAJOR = 5
9
9
  MINOR = 0
10
10
  TINY = 0
11
- PRE = "beta3"
11
+ PRE = "beta4"
12
12
 
13
13
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
14
14
  end
@@ -64,8 +64,8 @@ module I18n
64
64
  end
65
65
 
66
66
  app.reloaders << reloader
67
- ActionDispatch::Reloader.to_prepare do
68
- reloader.execute_if_updated
67
+ app.reloader.to_run do
68
+ reloader.execute_if_updated { require_unload_lock! }
69
69
  # TODO: remove the following line as soon as the return value of
70
70
  # callbacks is ignored, that is, returning `false` does not
71
71
  # display a deprecation warning or halts the callback chain.
@@ -140,6 +140,15 @@ module ActiveSupport
140
140
  result
141
141
  end
142
142
 
143
+ # Converts just the first character to uppercase.
144
+ #
145
+ # upcase_first('what a Lovely Day') # => "What a Lovely Day"
146
+ # upcase_first('w') # => "W"
147
+ # upcase_first('') # => ""
148
+ def upcase_first(string)
149
+ string.length > 0 ? string[0].upcase.concat(string[1..-1]) : ''
150
+ end
151
+
143
152
  # Capitalizes all the words and replaces some characters in the string to
144
153
  # create a nicer looking title. +titleize+ is meant for creating pretty
145
154
  # output. It is not used in the Rails internals.
@@ -15,7 +15,7 @@ module ActiveSupport
15
15
 
16
16
  extend self
17
17
 
18
- # Formats a +number+ into a US phone number (e.g., (555)
18
+ # Formats a +number+ into a phone number (US by default e.g., (555)
19
19
  # 123-9876). You can customize the format in the +options+ hash.
20
20
  #
21
21
  # ==== Options
@@ -27,6 +27,8 @@ module ActiveSupport
27
27
  # end of the generated number.
28
28
  # * <tt>:country_code</tt> - Sets the country code for the phone
29
29
  # number.
30
+ # * <tt>:pattern</tt> - Specifies how the number is divided into three
31
+ # groups with the custom regexp to override the default format.
30
32
  # ==== Examples
31
33
  #
32
34
  # number_to_phone(5551234) # => "555-1234"
@@ -40,6 +42,11 @@ module ActiveSupport
40
42
  #
41
43
  # number_to_phone(1235551234, country_code: 1, extension: 1343, delimiter: '.')
42
44
  # # => "+1.123.555.1234 x 1343"
45
+ #
46
+ # number_to_phone(75561234567, pattern: /(\d{1,4})(\d{4})(\d{4})$/, area_code: true)
47
+ # # => "(755) 6123-4567"
48
+ # number_to_phone(13312345678, pattern: /(\d{3})(\d{4})(\d{4})$/))
49
+ # # => "133-1234-5678"
43
50
  def number_to_phone(number, options = {})
44
51
  NumberToPhoneConverter.convert(number, options)
45
52
  end
@@ -12,7 +12,7 @@ module ActiveSupport
12
12
  private
13
13
 
14
14
  def parts
15
- left, right = number.to_s.split('.')
15
+ left, right = number.to_s.split('.'.freeze)
16
16
  left.gsub!(delimiter_pattern) do |digit_to_delimit|
17
17
  "#{digit_to_delimit}#{options[:delimiter]}"
18
18
  end
@@ -18,12 +18,16 @@ module ActiveSupport
18
18
  end
19
19
 
20
20
  def convert_with_area_code(number)
21
- number.gsub!(/(\d{1,3})(\d{3})(\d{4}$)/,"(\\1) \\2#{delimiter}\\3")
21
+ default_pattern = /(\d{1,3})(\d{3})(\d{4}$)/
22
+ number.gsub!(regexp_pattern(default_pattern),
23
+ "(\\1) \\2#{delimiter}\\3")
22
24
  number
23
25
  end
24
26
 
25
27
  def convert_without_area_code(number)
26
- number.gsub!(/(\d{0,3})(\d{3})(\d{4})$/,"\\1#{delimiter}\\2#{delimiter}\\3")
28
+ default_pattern = /(\d{0,3})(\d{3})(\d{4})$/
29
+ number.gsub!(regexp_pattern(default_pattern),
30
+ "\\1#{delimiter}\\2#{delimiter}\\3")
27
31
  number.slice!(0, 1) if start_with_delimiter?(number)
28
32
  number
29
33
  end
@@ -43,6 +47,11 @@ module ActiveSupport
43
47
  def phone_ext(ext)
44
48
  ext.blank? ? "" : " x #{ext}"
45
49
  end
50
+
51
+ def regexp_pattern(default_pattern)
52
+ opts.fetch :pattern, default_pattern
53
+ end
54
+
46
55
  end
47
56
  end
48
57
  end
@@ -29,9 +29,11 @@ module ActiveSupport
29
29
 
30
30
  formatted_string =
31
31
  if BigDecimal === rounded_number && rounded_number.finite?
32
- s = rounded_number.to_s('F') + '0'*precision
33
- a, b = s.split('.', 2)
34
- a + '.' + b[0, precision]
32
+ s = rounded_number.to_s('F')
33
+ s << '0'.freeze * precision
34
+ a, b = s.split('.'.freeze, 2)
35
+ a << '.'.freeze
36
+ a << b[0, precision]
35
37
  else
36
38
  "%00.#{precision}f" % rounded_number
37
39
  end
@@ -0,0 +1,129 @@
1
+ require 'active_support/execution_wrapper'
2
+
3
+ module ActiveSupport
4
+ #--
5
+ # This class defines several callbacks:
6
+ #
7
+ # to_prepare -- Run once at application startup, and also from
8
+ # +to_run+.
9
+ #
10
+ # to_run -- Run before a work run that is reloading. If
11
+ # +reload_classes_only_on_change+ is true (the default), the class
12
+ # unload will have already occurred.
13
+ #
14
+ # to_complete -- Run after a work run that has reloaded. If
15
+ # +reload_classes_only_on_change+ is false, the class unload will
16
+ # have occurred after the work run, but before this callback.
17
+ #
18
+ # before_class_unload -- Run immediately before the classes are
19
+ # unloaded.
20
+ #
21
+ # after_class_unload -- Run immediately after the classes are
22
+ # unloaded.
23
+ #
24
+ class Reloader < ExecutionWrapper
25
+ define_callbacks :prepare
26
+
27
+ define_callbacks :class_unload
28
+
29
+ def self.to_prepare(*args, &block)
30
+ set_callback(:prepare, *args, &block)
31
+ end
32
+
33
+ def self.before_class_unload(*args, &block)
34
+ set_callback(:class_unload, *args, &block)
35
+ end
36
+
37
+ def self.after_class_unload(*args, &block)
38
+ set_callback(:class_unload, :after, *args, &block)
39
+ end
40
+
41
+ to_run(:after) { self.class.prepare! }
42
+
43
+ # Initiate a manual reload
44
+ def self.reload!
45
+ executor.wrap do
46
+ new.tap do |instance|
47
+ begin
48
+ instance.run!
49
+ ensure
50
+ instance.complete!
51
+ end
52
+ end
53
+ end
54
+ prepare!
55
+ end
56
+
57
+ def self.run! # :nodoc:
58
+ if check!
59
+ super
60
+ else
61
+ Null
62
+ end
63
+ end
64
+
65
+ # Run the supplied block as a work unit, reloading code as needed
66
+ def self.wrap
67
+ executor.wrap do
68
+ super
69
+ end
70
+ end
71
+
72
+ class_attribute :executor
73
+ class_attribute :check
74
+
75
+ self.executor = Executor
76
+ self.check = lambda { false }
77
+
78
+ def self.check! # :nodoc:
79
+ @should_reload ||= check.call
80
+ end
81
+
82
+ def self.reloaded! # :nodoc:
83
+ @should_reload = false
84
+ end
85
+
86
+ def self.prepare! # :nodoc:
87
+ new.run_callbacks(:prepare)
88
+ end
89
+
90
+ def initialize
91
+ super
92
+ @locked = false
93
+ end
94
+
95
+ # Acquire the ActiveSupport::Dependencies::Interlock unload lock,
96
+ # ensuring it will be released automatically
97
+ def require_unload_lock!
98
+ unless @locked
99
+ ActiveSupport::Dependencies.interlock.start_unloading
100
+ @locked = true
101
+ end
102
+ end
103
+
104
+ # Release the unload lock if it has been previously obtained
105
+ def release_unload_lock!
106
+ if @locked
107
+ @locked = false
108
+ ActiveSupport::Dependencies.interlock.done_unloading
109
+ end
110
+ end
111
+
112
+ def run! # :nodoc:
113
+ super
114
+ release_unload_lock!
115
+ end
116
+
117
+ def class_unload!(&block) # :nodoc:
118
+ require_unload_lock!
119
+ run_callbacks(:class_unload, &block)
120
+ end
121
+
122
+ def complete! # :nodoc:
123
+ super
124
+ self.class.reloaded!
125
+ ensure
126
+ release_unload_lock!
127
+ end
128
+ end
129
+ end
@@ -115,5 +115,15 @@ module ActiveSupport
115
115
  end
116
116
  end
117
117
  end
118
+
119
+ def index_of_handler_for_rescue(exception)
120
+ handlers = self.class.rescue_handlers.reverse_each.with_index
121
+ _, index = handlers.detect do |(klass_name, _), _|
122
+ klass = self.class.const_get(klass_name) rescue nil
123
+ klass ||= (klass_name.constantize rescue nil)
124
+ klass === exception if klass
125
+ end
126
+ index
127
+ end
118
128
  end
119
129
  end
@@ -1,6 +1,7 @@
1
1
  require 'active_support/duration'
2
2
  require 'active_support/values/time_zone'
3
3
  require 'active_support/core_ext/object/acts_like'
4
+ require 'active_support/core_ext/date_and_time/compatibility'
4
5
 
5
6
  module ActiveSupport
6
7
  # A Time-like class that can represent a time in any time zone. Necessary
@@ -44,20 +45,21 @@ module ActiveSupport
44
45
  PRECISIONS = Hash.new { |h, n| h[n] = "%FT%T.%#{n}N".freeze }
45
46
  PRECISIONS[0] = '%FT%T'.freeze
46
47
 
47
- include Comparable
48
+ include Comparable, DateAndTime::Compatibility
48
49
  attr_reader :time_zone
49
50
 
50
51
  def initialize(utc_time, time_zone, local_time = nil, period = nil)
51
- @utc, @time_zone, @time = utc_time, time_zone, local_time
52
+ @utc = utc_time ? transfer_time_values_to_utc_constructor(utc_time) : nil
53
+ @time_zone, @time = time_zone, local_time
52
54
  @period = @utc ? period : get_period_and_ensure_valid_local_time(period)
53
55
  end
54
56
 
55
- # Returns a Time or DateTime instance that represents the time in +time_zone+.
57
+ # Returns a <tt>Time</tt> instance that represents the time in +time_zone+.
56
58
  def time
57
59
  @time ||= period.to_local(@utc)
58
60
  end
59
61
 
60
- # Returns a Time or DateTime instance that represents the time in UTC.
62
+ # Returns a <tt>Time</tt> instance of the simultaneous time in the UTC timezone.
61
63
  def utc
62
64
  @utc ||= period.to_utc(@time)
63
65
  end
@@ -77,10 +79,9 @@ module ActiveSupport
77
79
  utc.in_time_zone(new_zone)
78
80
  end
79
81
 
80
- # Returns a <tt>Time.local()</tt> instance of the simultaneous time in your
81
- # system's <tt>ENV['TZ']</tt> zone.
82
+ # Returns a <tt>Time</tt> instance of the simultaneous time in the system timezone.
82
83
  def localtime(utc_offset = nil)
83
- utc.respond_to?(:getlocal) ? utc.getlocal(utc_offset) : utc.to_time.getlocal(utc_offset)
84
+ utc.getlocal(utc_offset)
84
85
  end
85
86
  alias_method :getlocal, :localtime
86
87
 
@@ -401,11 +402,6 @@ module ActiveSupport
401
402
  utc.to_r
402
403
  end
403
404
 
404
- # Returns an instance of Time in the system timezone.
405
- def to_time
406
- utc.to_time
407
- end
408
-
409
405
  # Returns an instance of DateTime with the timezone's UTC offset
410
406
  #
411
407
  # Time.zone.now.to_datetime # => Tue, 18 Aug 2015 02:32:20 +0000
@@ -454,7 +450,6 @@ module ActiveSupport
454
450
  # Ensure proxy class responds to all methods that underlying time instance
455
451
  # responds to.
456
452
  def respond_to_missing?(sym, include_priv)
457
- # consistently respond false to acts_like?(:date), regardless of whether #time is a Time or DateTime
458
453
  return false if sym.to_sym == :acts_like_date?
459
454
  time.respond_to?(sym, include_priv)
460
455
  end
@@ -482,7 +477,7 @@ module ActiveSupport
482
477
  end
483
478
 
484
479
  def transfer_time_values_to_utc_constructor(time)
485
- ::Time.utc(time.year, time.month, time.day, time.hour, time.min, time.sec, Rational(time.nsec, 1000))
480
+ ::Time.utc(time.year, time.month, time.day, time.hour, time.min, time.sec + time.subsec)
486
481
  end
487
482
 
488
483
  def duration_of_variable_length?(obj)
@@ -1,7 +1,6 @@
1
1
  require 'tzinfo'
2
2
  require 'concurrent/map'
3
3
  require 'active_support/core_ext/object/blank'
4
- require 'active_support/core_ext/object/try'
5
4
 
6
5
  module ActiveSupport
7
6
  # The TimeZone class serves as a wrapper around TZInfo::Timezone instances.
@@ -185,6 +184,7 @@ module ActiveSupport
185
184
  UTC_OFFSET_WITHOUT_COLON = UTC_OFFSET_WITH_COLON.tr(':', '')
186
185
 
187
186
  @lazy_zones_map = Concurrent::Map.new
187
+ @country_zones = Concurrent::Map.new
188
188
 
189
189
  class << self
190
190
  # Assumes self represents an offset from UTC in seconds (as returned from
@@ -243,7 +243,18 @@ module ActiveSupport
243
243
  # A convenience method for returning a collection of TimeZone objects
244
244
  # for time zones in the USA.
245
245
  def us_zones
246
- @us_zones ||= all.find_all { |z| z.name =~ /US|Arizona|Indiana|Hawaii|Alaska/ }
246
+ country_zones(:us)
247
+ end
248
+
249
+ # A convenience method for returning a collection of TimeZone objects
250
+ # for time zones in the country specified by its ISO 3166-1 Alpha2 code.
251
+ def country_zones(country_code)
252
+ code = country_code.to_s.upcase
253
+ @country_zones[code] ||=
254
+ TZInfo::Country.get(code).zone_identifiers.map do |tz_id|
255
+ name = MAPPING.key(tz_id)
256
+ name && self[name]
257
+ end.compact.sort!
247
258
  end
248
259
 
249
260
  private
@@ -267,7 +278,6 @@ module ActiveSupport
267
278
  @name = name
268
279
  @utc_offset = utc_offset
269
280
  @tzinfo = tzinfo || TimeZone.find_tzinfo(name)
270
- @current_period = nil
271
281
  end
272
282
 
273
283
  # Returns the offset of this time zone from UTC in seconds.
@@ -275,8 +285,7 @@ module ActiveSupport
275
285
  if @utc_offset
276
286
  @utc_offset
277
287
  else
278
- @current_period ||= tzinfo.current_period if tzinfo
279
- @current_period.utc_offset if @current_period
288
+ tzinfo.current_period.utc_offset if tzinfo && tzinfo.current_period
280
289
  end
281
290
  end
282
291
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activesupport
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.0.beta3
4
+ version: 5.0.0.beta4
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-24 00:00:00.000000000 Z
11
+ date: 2016-04-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: i18n
@@ -118,13 +118,14 @@ files:
118
118
  - lib/active_support/core_ext/date/conversions.rb
119
119
  - lib/active_support/core_ext/date/zones.rb
120
120
  - lib/active_support/core_ext/date_and_time/calculations.rb
121
+ - lib/active_support/core_ext/date_and_time/compatibility.rb
121
122
  - lib/active_support/core_ext/date_and_time/zones.rb
122
123
  - lib/active_support/core_ext/date_time.rb
123
124
  - lib/active_support/core_ext/date_time/acts_like.rb
124
125
  - lib/active_support/core_ext/date_time/blank.rb
125
126
  - lib/active_support/core_ext/date_time/calculations.rb
127
+ - lib/active_support/core_ext/date_time/compatibility.rb
126
128
  - lib/active_support/core_ext/date_time/conversions.rb
127
- - lib/active_support/core_ext/date_time/zones.rb
128
129
  - lib/active_support/core_ext/digest/uuid.rb
129
130
  - lib/active_support/core_ext/enumerable.rb
130
131
  - lib/active_support/core_ext/file.rb
@@ -209,6 +210,7 @@ files:
209
210
  - lib/active_support/core_ext/time.rb
210
211
  - lib/active_support/core_ext/time/acts_like.rb
211
212
  - lib/active_support/core_ext/time/calculations.rb
213
+ - lib/active_support/core_ext/time/compatibility.rb
212
214
  - lib/active_support/core_ext/time/conversions.rb
213
215
  - lib/active_support/core_ext/time/marshal.rb
214
216
  - lib/active_support/core_ext/time/zones.rb
@@ -224,7 +226,11 @@ files:
224
226
  - lib/active_support/deprecation/reporting.rb
225
227
  - lib/active_support/descendants_tracker.rb
226
228
  - lib/active_support/duration.rb
229
+ - lib/active_support/duration/iso8601_parser.rb
230
+ - lib/active_support/duration/iso8601_serializer.rb
227
231
  - lib/active_support/evented_file_update_checker.rb
232
+ - lib/active_support/execution_wrapper.rb
233
+ - lib/active_support/executor.rb
228
234
  - lib/active_support/file_update_checker.rb
229
235
  - lib/active_support/gem_version.rb
230
236
  - lib/active_support/gzip.rb
@@ -271,6 +277,7 @@ files:
271
277
  - lib/active_support/proxy_object.rb
272
278
  - lib/active_support/rails.rb
273
279
  - lib/active_support/railtie.rb
280
+ - lib/active_support/reloader.rb
274
281
  - lib/active_support/rescuable.rb
275
282
  - lib/active_support/security_utils.rb
276
283
  - lib/active_support/string_inquirer.rb
@@ -301,7 +308,7 @@ files:
301
308
  - lib/active_support/xml_mini/nokogiri.rb
302
309
  - lib/active_support/xml_mini/nokogirisax.rb
303
310
  - lib/active_support/xml_mini/rexml.rb
304
- homepage: http://www.rubyonrails.org
311
+ homepage: http://rubyonrails.org
305
312
  licenses:
306
313
  - MIT
307
314
  metadata: {}
@@ -323,7 +330,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
323
330
  version: 1.3.1
324
331
  requirements: []
325
332
  rubyforge_project:
326
- rubygems_version: 2.5.1
333
+ rubygems_version: 2.6.4
327
334
  signing_key:
328
335
  specification_version: 4
329
336
  summary: A toolkit of support libraries and Ruby core extensions extracted from the