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
@@ -1,5 +1,3 @@
1
- require 'active_support/core_ext/object/try'
2
-
3
1
  class String
4
2
  # Strips indentation in heredocs.
5
3
  #
@@ -17,10 +15,9 @@ class String
17
15
  #
18
16
  # the user would see the usage message aligned against the left margin.
19
17
  #
20
- # Technically, it looks for the least indented line in the whole string, and removes
21
- # that amount of leading whitespace.
18
+ # Technically, it looks for the least indented non-empty line
19
+ # in the whole string, and removes that amount of leading whitespace.
22
20
  def strip_heredoc
23
- indent = scan(/^[ \t]*(?=\S)/).min.try(:size) || 0
24
- gsub(/^[ \t]{#{indent}}/, '')
21
+ gsub(/^#{scan(/^[ \t]*(?=\S)/).min}/, ''.freeze)
25
22
  end
26
23
  end
@@ -1,6 +1,3 @@
1
- # Backport of Struct#to_h from Ruby 2.0
2
- class Struct # :nodoc:
3
- def to_h
4
- Hash[members.zip(values)]
5
- end
6
- end unless Struct.instance_methods.include?(:to_h)
1
+ require 'active_support/deprecation'
2
+
3
+ ActiveSupport::Deprecation.warn("This file is deprecated and will be removed in Rails 5.1 with no replacement.")
@@ -1,6 +1,4 @@
1
1
  require 'active_support/core_ext/time/acts_like'
2
2
  require 'active_support/core_ext/time/calculations'
3
- require 'active_support/core_ext/time/compatibility'
4
3
  require 'active_support/core_ext/time/conversions'
5
- require 'active_support/core_ext/time/marshal'
6
4
  require 'active_support/core_ext/time/zones'
@@ -16,9 +16,9 @@ class Time
16
16
  super || (self == Time && other.is_a?(ActiveSupport::TimeWithZone))
17
17
  end
18
18
 
19
- # Return the number of days in the given month.
19
+ # Returns the number of days in the given month.
20
20
  # If no year is specified, it will use the current year.
21
- def days_in_month(month, year = now.year)
21
+ def days_in_month(month, year = current.year)
22
22
  if month == 2 && ::Date.gregorian_leap?(year)
23
23
  29
24
24
  else
@@ -26,6 +26,12 @@ class Time
26
26
  end
27
27
  end
28
28
 
29
+ # Returns the number of days in the given year.
30
+ # If no year is specified, it will use the current year.
31
+ def days_in_year(year = current.year)
32
+ days_in_month(2, year) + 337
33
+ end
34
+
29
35
  # Returns <tt>Time.zone.now</tt> when <tt>Time.zone</tt> or <tt>config.time_zone</tt> are set, otherwise just returns <tt>Time.now</tt>.
30
36
  def current
31
37
  ::Time.zone ? ::Time.zone.now : ::Time.now
@@ -49,7 +55,11 @@ class Time
49
55
  alias_method :at, :at_with_coercion
50
56
  end
51
57
 
52
- # Seconds since midnight: Time.now.seconds_since_midnight
58
+ # Returns the number of seconds since 00:00:00.
59
+ #
60
+ # Time.new(2012, 8, 29, 0, 0, 0).seconds_since_midnight # => 0.0
61
+ # Time.new(2012, 8, 29, 12, 34, 56).seconds_since_midnight # => 45296.0
62
+ # Time.new(2012, 8, 29, 23, 59, 59).seconds_since_midnight # => 86399.0
53
63
  def seconds_since_midnight
54
64
  to_i - change(:hour => 0).to_i + (usec / 1.0e+6)
55
65
  end
@@ -63,13 +73,6 @@ class Time
63
73
  end_of_day.to_i - to_i
64
74
  end
65
75
 
66
- # Returns the fraction of a second as a +Rational+
67
- #
68
- # Time.new(2012, 8, 29, 0, 0, 0.5).sec_fraction # => (1/2)
69
- def sec_fraction
70
- subsec
71
- end
72
-
73
76
  # Returns a new Time where one or more of the elements have been changed according
74
77
  # to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
75
78
  # <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly, so if only
@@ -77,7 +80,7 @@ class Time
77
80
  # and minute is passed, then sec, usec and nsec is set to 0. The +options+
78
81
  # parameter takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>,
79
82
  # <tt>:day</tt>, <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>
80
- # <tt>:nsec</tt>. Path either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
83
+ # <tt>:nsec</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
81
84
  #
82
85
  # Time.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => Time.new(2012, 8, 1, 22, 35, 0)
83
86
  # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => Time.new(1981, 8, 1, 22, 35, 0)
@@ -159,7 +162,6 @@ class Time
159
162
 
160
163
  # Returns a new Time representing the start of the day (0:00)
161
164
  def beginning_of_day
162
- #(self - seconds_since_midnight).change(usec: 0)
163
165
  change(:hour => 0)
164
166
  end
165
167
  alias :midnight :beginning_of_day
@@ -176,7 +178,7 @@ class Time
176
178
  alias :at_noon :middle_of_day
177
179
  alias :at_middle_of_day :middle_of_day
178
180
 
179
- # Returns a new Time representing the end of the day, 23:59:59.999999 (.999999999 in ruby1.9)
181
+ # Returns a new Time representing the end of the day, 23:59:59.999999
180
182
  def end_of_day
181
183
  change(
182
184
  :hour => 23,
@@ -193,7 +195,7 @@ class Time
193
195
  end
194
196
  alias :at_beginning_of_hour :beginning_of_hour
195
197
 
196
- # Returns a new Time representing the end of the hour, x:59:59.999999 (.999999999 in ruby1.9)
198
+ # Returns a new Time representing the end of the hour, x:59:59.999999
197
199
  def end_of_hour
198
200
  change(
199
201
  :min => 59,
@@ -209,7 +211,7 @@ class Time
209
211
  end
210
212
  alias :at_beginning_of_minute :beginning_of_minute
211
213
 
212
- # Returns a new Time representing the end of the minute, x:xx:59.999999 (.999999999 in ruby1.9)
214
+ # Returns a new Time representing the end of the minute, x:xx:59.999999
213
215
  def end_of_minute
214
216
  change(
215
217
  :sec => 59,
@@ -256,7 +258,7 @@ class Time
256
258
  # Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
257
259
  # can be chronologically compared with a Time
258
260
  def compare_with_coercion(other)
259
- # we're avoiding Time#to_datetime cause it's expensive
261
+ # we're avoiding Time#to_datetime and Time#to_time because they're expensive
260
262
  if other.class == Time
261
263
  compare_without_coercion(other)
262
264
  elsif other.is_a?(Time)
@@ -6,6 +6,7 @@ class Time
6
6
  :db => '%Y-%m-%d %H:%M:%S',
7
7
  :number => '%Y%m%d%H%M%S',
8
8
  :nsec => '%Y%m%d%H%M%S%9N',
9
+ :usec => '%Y%m%d%H%M%S%6N',
9
10
  :time => '%H:%M',
10
11
  :short => '%d %b %H:%M',
11
12
  :long => '%B %d, %Y %H:%M',
@@ -24,7 +25,7 @@ class Time
24
25
  #
25
26
  # This method is aliased to <tt>to_s</tt>.
26
27
  #
27
- # time = Time.now # => Thu Jan 18 06:10:17 CST 2007
28
+ # time = Time.now # => 2007-01-18 06:10:17 -06:00
28
29
  #
29
30
  # time.to_formatted_s(:time) # => "06:10"
30
31
  # time.to_s(:time) # => "06:10"
@@ -55,7 +56,8 @@ class Time
55
56
  alias_method :to_default_s, :to_s
56
57
  alias_method :to_s, :to_formatted_s
57
58
 
58
- # Returns the UTC offset as an +HH:MM formatted string.
59
+ # Returns a formatted string of the offset from UTC, or an alternative
60
+ # string if the time zone is already UTC.
59
61
  #
60
62
  # Time.local(2000).formatted_offset # => "-06:00"
61
63
  # Time.local(2000).formatted_offset(false) # => "-0600"
@@ -1,30 +1,3 @@
1
- # Ruby 1.9.2 adds utc_offset and zone to Time, but marshaling only
2
- # preserves utc_offset. Preserve zone also, even though it may not
3
- # work in some edge cases.
4
- if Time.local(2010).zone != Marshal.load(Marshal.dump(Time.local(2010))).zone
5
- class Time
6
- class << self
7
- alias_method :_load_without_zone, :_load
8
- def _load(marshaled_time)
9
- time = _load_without_zone(marshaled_time)
10
- time.instance_eval do
11
- if zone = defined?(@_zone) && remove_instance_variable('@_zone')
12
- ary = to_a
13
- ary[0] += subsec if ary[0] == sec
14
- ary[-1] = zone
15
- utc? ? Time.utc(*ary) : Time.local(*ary)
16
- else
17
- self
18
- end
19
- end
20
- end
21
- end
1
+ require 'active_support/deprecation'
22
2
 
23
- alias_method :_dump_without_zone, :_dump
24
- def _dump(*args)
25
- obj = dup
26
- obj.instance_variable_set('@_zone', zone)
27
- obj.send :_dump_without_zone, *args
28
- end
29
- end
30
- end
3
+ ActiveSupport::Deprecation.warn("This is deprecated and will be removed in Rails 5.1 with no replacement.")
@@ -26,7 +26,7 @@ class Time
26
26
  # <tt>current_user.time_zone</tt> just needs to return a string identifying the user's preferred time zone:
27
27
  #
28
28
  # class ApplicationController < ActionController::Base
29
- # around_filter :set_time_zone
29
+ # around_action :set_time_zone
30
30
  #
31
31
  # def set_time_zone
32
32
  # if logged_in?
@@ -51,12 +51,22 @@ class Time
51
51
  end
52
52
  end
53
53
 
54
- # Returns a TimeZone instance or nil, or raises an ArgumentError for invalid timezones.
54
+ # Returns a TimeZone instance matching the time zone provided.
55
+ # Accepts the time zone in any format supported by <tt>Time.zone=</tt>.
56
+ # Raises an +ArgumentError+ for invalid time zones.
57
+ #
58
+ # Time.find_zone! "America/New_York" # => #<ActiveSupport::TimeZone @name="America/New_York" ...>
59
+ # Time.find_zone! "EST" # => #<ActiveSupport::TimeZone @name="EST" ...>
60
+ # Time.find_zone! -5.hours # => #<ActiveSupport::TimeZone @name="Bogota" ...>
61
+ # Time.find_zone! nil # => nil
62
+ # Time.find_zone! false # => false
63
+ # Time.find_zone! "NOT-A-TIMEZONE" # => ArgumentError: Invalid Timezone: NOT-A-TIMEZONE
55
64
  def find_zone!(time_zone)
56
65
  if !time_zone || time_zone.is_a?(ActiveSupport::TimeZone)
57
66
  time_zone
58
67
  else
59
- # lookup timezone based on identifier (unless we've been passed a TZInfo::Timezone)
68
+ # Look up the timezone based on the identifier (unless we've been
69
+ # passed a TZInfo::Timezone)
60
70
  unless time_zone.respond_to?(:period_for_local)
61
71
  time_zone = ActiveSupport::TimeZone[time_zone] || TZInfo::Timezone.get(time_zone)
62
72
  end
@@ -72,6 +82,12 @@ class Time
72
82
  raise ArgumentError, "Invalid Timezone: #{time_zone}"
73
83
  end
74
84
 
85
+ # Returns a TimeZone instance matching the time zone provided.
86
+ # Accepts the time zone in any format supported by <tt>Time.zone=</tt>.
87
+ # Returns +nil+ for invalid time zones.
88
+ #
89
+ # Time.find_zone "America/New_York" # => #<ActiveSupport::TimeZone @name="America/New_York" ...>
90
+ # Time.find_zone "NOT-A-TIMEZONE" # => nil
75
91
  def find_zone(time_zone)
76
92
  find_zone!(time_zone) rescue nil
77
93
  end
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  require 'uri'
4
2
  str = "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E" # Ni-ho-nn-go in UTF-8, means Japanese.
5
3
  parser = URI::Parser.new
@@ -12,7 +10,7 @@ unless str == parser.unescape(parser.escape(str))
12
10
  # YK: My initial experiments say yes, but let's be sure please
13
11
  enc = str.encoding
14
12
  enc = Encoding::UTF_8 if enc == Encoding::US_ASCII
15
- str.gsub(escaped) { [$&[1, 2].hex].pack('C') }.force_encoding(enc)
13
+ str.gsub(escaped) { |match| [match[1, 2].hex].pack('C') }.force_encoding(enc)
16
14
  end
17
15
  end
18
16
  end
@@ -1,6 +1,6 @@
1
1
  require 'set'
2
2
  require 'thread'
3
- require 'thread_safe'
3
+ require 'concurrent/map'
4
4
  require 'pathname'
5
5
  require 'active_support/core_ext/module/aliasing'
6
6
  require 'active_support/core_ext/module/attribute_accessors'
@@ -12,12 +12,40 @@ require 'active_support/core_ext/kernel/reporting'
12
12
  require 'active_support/core_ext/load_error'
13
13
  require 'active_support/core_ext/name_error'
14
14
  require 'active_support/core_ext/string/starts_ends_with'
15
+ require "active_support/dependencies/interlock"
15
16
  require 'active_support/inflector'
16
17
 
17
18
  module ActiveSupport #:nodoc:
18
19
  module Dependencies #:nodoc:
19
20
  extend self
20
21
 
22
+ mattr_accessor :interlock
23
+ self.interlock = Interlock.new
24
+
25
+ # :doc:
26
+
27
+ # Execute the supplied block without interference from any
28
+ # concurrent loads.
29
+ def self.run_interlock
30
+ Dependencies.interlock.running { yield }
31
+ end
32
+
33
+ # Execute the supplied block while holding an exclusive lock,
34
+ # preventing any other thread from being inside a #run_interlock
35
+ # block at the same time.
36
+ def self.load_interlock
37
+ Dependencies.interlock.loading { yield }
38
+ end
39
+
40
+ # Execute the supplied block while holding an exclusive lock,
41
+ # preventing any other thread from being inside a #run_interlock
42
+ # block at the same time.
43
+ def self.unload_interlock
44
+ Dependencies.interlock.unloading { yield }
45
+ end
46
+
47
+ # :nodoc:
48
+
21
49
  # Should we turn on Ruby warnings on the first load of dependent files?
22
50
  mattr_accessor :warnings_on_first_load
23
51
  self.warnings_on_first_load = false
@@ -128,7 +156,7 @@ module ActiveSupport #:nodoc:
128
156
 
129
157
  # Normalize the list of new constants, and add them to the list we will return
130
158
  new_constants.each do |suffix|
131
- constants << ([namespace, suffix] - ["Object"]).join("::")
159
+ constants << ([namespace, suffix] - ["Object"]).join("::".freeze)
132
160
  end
133
161
  end
134
162
  constants
@@ -325,9 +353,11 @@ module ActiveSupport #:nodoc:
325
353
 
326
354
  def clear
327
355
  log_call
328
- loaded.clear
329
- loading.clear
330
- remove_unloadable_constants!
356
+ Dependencies.unload_interlock do
357
+ loaded.clear
358
+ loading.clear
359
+ remove_unloadable_constants!
360
+ end
331
361
  end
332
362
 
333
363
  def require_or_load(file_name, const_path = nil)
@@ -336,44 +366,49 @@ module ActiveSupport #:nodoc:
336
366
  expanded = File.expand_path(file_name)
337
367
  return if loaded.include?(expanded)
338
368
 
339
- # Record that we've seen this file *before* loading it to avoid an
340
- # infinite loop with mutual dependencies.
341
- loaded << expanded
342
- loading << expanded
369
+ Dependencies.load_interlock do
370
+ # Maybe it got loaded while we were waiting for our lock:
371
+ return if loaded.include?(expanded)
343
372
 
344
- begin
345
- if load?
346
- log "loading #{file_name}"
373
+ # Record that we've seen this file *before* loading it to avoid an
374
+ # infinite loop with mutual dependencies.
375
+ loaded << expanded
376
+ loading << expanded
347
377
 
348
- # Enable warnings if this file has not been loaded before and
349
- # warnings_on_first_load is set.
350
- load_args = ["#{file_name}.rb"]
351
- load_args << const_path unless const_path.nil?
352
-
353
- if !warnings_on_first_load or history.include?(expanded)
354
- result = load_file(*load_args)
378
+ begin
379
+ if load?
380
+ log "loading #{file_name}"
381
+
382
+ # Enable warnings if this file has not been loaded before and
383
+ # warnings_on_first_load is set.
384
+ load_args = ["#{file_name}.rb"]
385
+ load_args << const_path unless const_path.nil?
386
+
387
+ if !warnings_on_first_load or history.include?(expanded)
388
+ result = load_file(*load_args)
389
+ else
390
+ enable_warnings { result = load_file(*load_args) }
391
+ end
355
392
  else
356
- enable_warnings { result = load_file(*load_args) }
393
+ log "requiring #{file_name}"
394
+ result = require file_name
357
395
  end
358
- else
359
- log "requiring #{file_name}"
360
- result = require file_name
396
+ rescue Exception
397
+ loaded.delete expanded
398
+ raise
399
+ ensure
400
+ loading.pop
361
401
  end
362
- rescue Exception
363
- loaded.delete expanded
364
- raise
365
- ensure
366
- loading.pop
367
- end
368
402
 
369
- # Record history *after* loading so first load gets warnings.
370
- history << expanded
371
- result
403
+ # Record history *after* loading so first load gets warnings.
404
+ history << expanded
405
+ result
406
+ end
372
407
  end
373
408
 
374
409
  # Is the provided constant path defined?
375
410
  def qualified_const_defined?(path)
376
- Object.qualified_const_defined?(path.sub(/^::/, ''), false)
411
+ Object.const_defined?(path, false)
377
412
  end
378
413
 
379
414
  # Given +path+, a filesystem path to a ruby file, return an array of
@@ -386,13 +421,13 @@ module ActiveSupport #:nodoc:
386
421
 
387
422
  bases.each do |root|
388
423
  expanded_root = File.expand_path(root)
389
- next unless %r{\A#{Regexp.escape(expanded_root)}(/|\\)} =~ expanded_path
424
+ next unless expanded_path.start_with?(expanded_root)
390
425
 
391
- nesting = expanded_path[(expanded_root.size)..-1]
392
- nesting = nesting[1..-1] if nesting && nesting[0] == ?/
393
- next if nesting.blank?
426
+ root_size = expanded_root.size
427
+ next if expanded_path[root_size] != ?/.freeze
394
428
 
395
- paths << nesting.camelize
429
+ nesting = expanded_path[(root_size + 1)..-1]
430
+ paths << nesting.camelize unless nesting.blank?
396
431
  end
397
432
 
398
433
  paths.uniq!
@@ -401,7 +436,7 @@ module ActiveSupport #:nodoc:
401
436
 
402
437
  # Search for a file in autoload_paths matching the provided suffix.
403
438
  def search_for_file(path_suffix)
404
- path_suffix = path_suffix.sub(/(\.rb)?$/, ".rb")
439
+ path_suffix = path_suffix.sub(/(\.rb)?$/, ".rb".freeze)
405
440
 
406
441
  autoload_paths.each do |root|
407
442
  path = File.join(root, path_suffix)
@@ -421,7 +456,7 @@ module ActiveSupport #:nodoc:
421
456
  end
422
457
 
423
458
  def load_once_path?(path)
424
- # to_s works around a ruby1.9 issue where String#starts_with?(Pathname)
459
+ # to_s works around a ruby issue where String#starts_with?(Pathname)
425
460
  # will raise a TypeError: no implicit conversion of Pathname into String
426
461
  autoload_once_paths.any? { |base| path.starts_with? base.to_s }
427
462
  end
@@ -486,7 +521,7 @@ module ActiveSupport #:nodoc:
486
521
 
487
522
  if file_path
488
523
  expanded = File.expand_path(file_path)
489
- expanded.sub!(/\.rb\z/, '')
524
+ expanded.sub!(/\.rb\z/, ''.freeze)
490
525
 
491
526
  if loading.include?(expanded)
492
527
  raise "Circular dependency detected while autoloading constant #{qualified_name}"
@@ -550,7 +585,7 @@ module ActiveSupport #:nodoc:
550
585
 
551
586
  class ClassCache
552
587
  def initialize
553
- @store = ThreadSafe::Cache.new
588
+ @store = Concurrent::Map.new
554
589
  end
555
590
 
556
591
  def empty?
@@ -607,7 +642,7 @@ module ActiveSupport #:nodoc:
607
642
  def autoloaded?(desc)
608
643
  return false if desc.is_a?(Module) && desc.anonymous?
609
644
  name = to_constant_name desc
610
- return false unless qualified_const_defined? name
645
+ return false unless qualified_const_defined?(name)
611
646
  return autoloaded_constants.include?(name)
612
647
  end
613
648
 
@@ -742,7 +777,7 @@ module ActiveSupport #:nodoc:
742
777
  protected
743
778
  def log_call(*args)
744
779
  if log_activity?
745
- arg_str = args.collect { |arg| arg.inspect } * ', '
780
+ arg_str = args.collect(&:inspect) * ', '
746
781
  /in `([a-z_\?\!]+)'/ =~ caller(1).first
747
782
  selector = $1 || '<unknown>'
748
783
  log "called #{selector}(#{arg_str})"