activesupport 4.0.13 → 4.2.11.3

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 (166) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +406 -418
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +7 -2
  5. data/lib/active_support/backtrace_cleaner.rb +8 -8
  6. data/lib/active_support/benchmarkable.rb +0 -10
  7. data/lib/active_support/cache/file_store.rb +32 -22
  8. data/lib/active_support/cache/mem_cache_store.rb +5 -7
  9. data/lib/active_support/cache/memory_store.rb +1 -0
  10. data/lib/active_support/cache/strategy/local_cache.rb +11 -30
  11. data/lib/active_support/cache/strategy/local_cache_middleware.rb +44 -0
  12. data/lib/active_support/cache.rb +75 -41
  13. data/lib/active_support/callbacks.rb +482 -261
  14. data/lib/active_support/concern.rb +23 -7
  15. data/lib/active_support/configurable.rb +1 -1
  16. data/lib/active_support/core_ext/array/access.rb +11 -1
  17. data/lib/active_support/core_ext/array/conversions.rb +2 -17
  18. data/lib/active_support/core_ext/array/grouping.rb +29 -12
  19. data/lib/active_support/core_ext/array/prepend_and_append.rb +2 -2
  20. data/lib/active_support/core_ext/array.rb +0 -1
  21. data/lib/active_support/core_ext/big_decimal/conversions.rb +0 -15
  22. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +16 -0
  23. data/lib/active_support/core_ext/class/attribute.rb +1 -2
  24. data/lib/active_support/core_ext/class/attribute_accessors.rb +4 -170
  25. data/lib/active_support/core_ext/class/delegating_attributes.rb +13 -8
  26. data/lib/active_support/core_ext/class/subclasses.rb +0 -2
  27. data/lib/active_support/core_ext/class.rb +0 -1
  28. data/lib/active_support/core_ext/date/calculations.rb +10 -0
  29. data/lib/active_support/core_ext/date/conversions.rb +9 -1
  30. data/lib/active_support/core_ext/date/zones.rb +2 -33
  31. data/lib/active_support/core_ext/date_and_time/calculations.rb +41 -11
  32. data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
  33. data/lib/active_support/core_ext/date_and_time/zones.rb +41 -0
  34. data/lib/active_support/core_ext/date_time/calculations.rb +45 -22
  35. data/lib/active_support/core_ext/date_time/compatibility.rb +16 -0
  36. data/lib/active_support/core_ext/date_time/conversions.rb +4 -2
  37. data/lib/active_support/core_ext/date_time/zones.rb +3 -21
  38. data/lib/active_support/core_ext/date_time.rb +1 -0
  39. data/lib/active_support/core_ext/digest/uuid.rb +51 -0
  40. data/lib/active_support/core_ext/enumerable.rb +17 -1
  41. data/lib/active_support/core_ext/file/atomic.rb +1 -1
  42. data/lib/active_support/core_ext/hash/compact.rb +24 -0
  43. data/lib/active_support/core_ext/hash/conversions.rb +9 -8
  44. data/lib/active_support/core_ext/hash/except.rb +8 -2
  45. data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -0
  46. data/lib/active_support/core_ext/hash/keys.rb +25 -19
  47. data/lib/active_support/core_ext/hash/slice.rb +8 -2
  48. data/lib/active_support/core_ext/hash/transform_values.rb +23 -0
  49. data/lib/active_support/core_ext/hash.rb +2 -1
  50. data/lib/active_support/core_ext/integer/time.rb +0 -15
  51. data/lib/active_support/core_ext/kernel/concern.rb +10 -0
  52. data/lib/active_support/core_ext/kernel/debugger.rb +1 -1
  53. data/lib/active_support/core_ext/kernel/reporting.rb +13 -2
  54. data/lib/active_support/core_ext/kernel.rb +3 -2
  55. data/lib/active_support/core_ext/load_error.rb +4 -1
  56. data/lib/active_support/core_ext/marshal.rb +8 -5
  57. data/lib/active_support/core_ext/module/aliasing.rb +2 -2
  58. data/lib/active_support/core_ext/module/attr_internal.rb +2 -1
  59. data/lib/active_support/core_ext/module/attribute_accessors.rb +160 -14
  60. data/lib/active_support/core_ext/module/concerning.rb +135 -0
  61. data/lib/active_support/core_ext/module/delegation.rb +53 -25
  62. data/lib/active_support/core_ext/module/deprecation.rb +0 -2
  63. data/lib/active_support/core_ext/module/introspection.rb +0 -16
  64. data/lib/active_support/core_ext/module/method_transplanting.rb +13 -0
  65. data/lib/active_support/core_ext/module.rb +1 -0
  66. data/lib/active_support/core_ext/numeric/conversions.rb +11 -3
  67. data/lib/active_support/core_ext/numeric/time.rb +4 -29
  68. data/lib/active_support/core_ext/object/blank.rb +44 -18
  69. data/lib/active_support/core_ext/object/deep_dup.rb +6 -6
  70. data/lib/active_support/core_ext/object/duplicable.rb +72 -33
  71. data/lib/active_support/core_ext/object/inclusion.rb +16 -15
  72. data/lib/active_support/core_ext/object/itself.rb +15 -0
  73. data/lib/active_support/core_ext/object/json.rb +197 -0
  74. data/lib/active_support/core_ext/object/to_query.rb +14 -6
  75. data/lib/active_support/core_ext/object/try.rb +36 -14
  76. data/lib/active_support/core_ext/object/with_options.rb +30 -3
  77. data/lib/active_support/core_ext/object.rb +2 -1
  78. data/lib/active_support/core_ext/string/access.rb +35 -35
  79. data/lib/active_support/core_ext/string/conversions.rb +10 -9
  80. data/lib/active_support/core_ext/string/exclude.rb +3 -3
  81. data/lib/active_support/core_ext/string/filters.rb +51 -3
  82. data/lib/active_support/core_ext/string/inflections.rb +15 -10
  83. data/lib/active_support/core_ext/string/output_safety.rb +97 -33
  84. data/lib/active_support/core_ext/string/zones.rb +1 -0
  85. data/lib/active_support/core_ext/thread.rb +12 -5
  86. data/lib/active_support/core_ext/time/calculations.rb +47 -68
  87. data/lib/active_support/core_ext/time/compatibility.rb +14 -0
  88. data/lib/active_support/core_ext/time/conversions.rb +4 -2
  89. data/lib/active_support/core_ext/time/zones.rb +2 -20
  90. data/lib/active_support/core_ext/time.rb +1 -0
  91. data/lib/active_support/core_ext.rb +0 -1
  92. data/lib/active_support/dependencies/autoload.rb +1 -1
  93. data/lib/active_support/dependencies.rb +64 -25
  94. data/lib/active_support/deprecation/behaviors.rb +4 -4
  95. data/lib/active_support/deprecation.rb +4 -4
  96. data/lib/active_support/duration.rb +55 -11
  97. data/lib/active_support/file_update_checker.rb +1 -1
  98. data/lib/active_support/gem_version.rb +15 -0
  99. data/lib/active_support/hash_with_indifferent_access.rb +39 -11
  100. data/lib/active_support/i18n.rb +4 -4
  101. data/lib/active_support/i18n_railtie.rb +1 -7
  102. data/lib/active_support/inflections.rb +6 -1
  103. data/lib/active_support/inflector/inflections.rb +19 -19
  104. data/lib/active_support/inflector/methods.rb +66 -25
  105. data/lib/active_support/json/decoding.rb +15 -22
  106. data/lib/active_support/json/encoding.rb +125 -286
  107. data/lib/active_support/key_generator.rb +8 -10
  108. data/lib/active_support/lazy_load_hooks.rb +1 -1
  109. data/lib/active_support/log_subscriber/test_helper.rb +1 -1
  110. data/lib/active_support/logger.rb +51 -1
  111. data/lib/active_support/logger_silence.rb +7 -4
  112. data/lib/active_support/logger_thread_safe_level.rb +32 -0
  113. data/lib/active_support/message_encryptor.rb +14 -6
  114. data/lib/active_support/message_verifier.rb +16 -12
  115. data/lib/active_support/multibyte/chars.rb +2 -3
  116. data/lib/active_support/multibyte/unicode.rb +46 -58
  117. data/lib/active_support/notifications/fanout.rb +12 -7
  118. data/lib/active_support/notifications/instrumenter.rb +2 -1
  119. data/lib/active_support/notifications.rb +11 -6
  120. data/lib/active_support/number_helper/number_converter.rb +182 -0
  121. data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
  122. data/lib/active_support/number_helper/number_to_delimited_converter.rb +23 -0
  123. data/lib/active_support/number_helper/number_to_human_converter.rb +66 -0
  124. data/lib/active_support/number_helper/number_to_human_size_converter.rb +58 -0
  125. data/lib/active_support/number_helper/number_to_percentage_converter.rb +12 -0
  126. data/lib/active_support/number_helper/number_to_phone_converter.rb +49 -0
  127. data/lib/active_support/number_helper/number_to_rounded_converter.rb +87 -0
  128. data/lib/active_support/number_helper.rb +32 -324
  129. data/lib/active_support/ordered_options.rb +8 -0
  130. data/lib/active_support/per_thread_registry.rb +13 -10
  131. data/lib/active_support/security_utils.rb +27 -0
  132. data/lib/active_support/subscriber.rb +35 -3
  133. data/lib/active_support/test_case.rb +52 -19
  134. data/lib/active_support/testing/assertions.rb +1 -31
  135. data/lib/active_support/testing/autorun.rb +2 -2
  136. data/lib/active_support/testing/constant_lookup.rb +1 -5
  137. data/lib/active_support/testing/declarative.rb +7 -21
  138. data/lib/active_support/testing/isolation.rb +29 -69
  139. data/lib/active_support/testing/setup_and_teardown.rb +17 -2
  140. data/lib/active_support/testing/tagged_logging.rb +2 -2
  141. data/lib/active_support/testing/time_helpers.rb +134 -0
  142. data/lib/active_support/time.rb +0 -2
  143. data/lib/active_support/time_with_zone.rb +60 -40
  144. data/lib/active_support/values/time_zone.rb +101 -101
  145. data/lib/active_support/values/unicode_tables.dat +0 -0
  146. data/lib/active_support/version.rb +4 -7
  147. data/lib/active_support/xml_mini/jdom.rb +6 -5
  148. data/lib/active_support/xml_mini/libxml.rb +1 -3
  149. data/lib/active_support/xml_mini/libxmlsax.rb +1 -4
  150. data/lib/active_support/xml_mini/nokogiri.rb +1 -3
  151. data/lib/active_support/xml_mini/nokogirisax.rb +1 -3
  152. data/lib/active_support/xml_mini/rexml.rb +7 -8
  153. data/lib/active_support/xml_mini.rb +33 -15
  154. data/lib/active_support.rb +27 -2
  155. metadata +43 -43
  156. data/lib/active_support/basic_object.rb +0 -11
  157. data/lib/active_support/buffered_logger.rb +0 -21
  158. data/lib/active_support/core_ext/array/uniq_by.rb +0 -19
  159. data/lib/active_support/core_ext/hash/diff.rb +0 -14
  160. data/lib/active_support/core_ext/logger.rb +0 -67
  161. data/lib/active_support/core_ext/object/to_json.rb +0 -27
  162. data/lib/active_support/core_ext/proc.rb +0 -17
  163. data/lib/active_support/core_ext/string/encoding.rb +0 -8
  164. data/lib/active_support/file_watcher.rb +0 -36
  165. data/lib/active_support/json/variable.rb +0 -18
  166. data/lib/active_support/testing/pending.rb +0 -14
@@ -3,7 +3,7 @@ require 'active_support/core_ext/time/conversions'
3
3
  require 'active_support/time_with_zone'
4
4
  require 'active_support/core_ext/time/zones'
5
5
  require 'active_support/core_ext/date_and_time/calculations'
6
- require 'active_support/deprecation'
6
+ require 'active_support/core_ext/date/calculations'
7
7
 
8
8
  class Time
9
9
  include DateAndTime::Calculations
@@ -26,41 +26,6 @@ class Time
26
26
  end
27
27
  end
28
28
 
29
- # *DEPRECATED*: Use +Time#utc+ or +Time#local+ instead.
30
- #
31
- # Returns a new Time if requested year can be accommodated by Ruby's Time class
32
- # (i.e., if year is within either 1970..2038 or 1902..2038, depending on system architecture);
33
- # otherwise returns a DateTime.
34
- def time_with_datetime_fallback(utc_or_local, year, month=1, day=1, hour=0, min=0, sec=0, usec=0)
35
- ActiveSupport::Deprecation.warn 'time_with_datetime_fallback is deprecated. Use Time#utc or Time#local instead', caller
36
- time = ::Time.send(utc_or_local, year, month, day, hour, min, sec, usec)
37
-
38
- # This check is needed because Time.utc(y) returns a time object in the 2000s for 0 <= y <= 138.
39
- if time.year == year
40
- time
41
- else
42
- ::DateTime.civil_from_format(utc_or_local, year, month, day, hour, min, sec)
43
- end
44
- rescue
45
- ::DateTime.civil_from_format(utc_or_local, year, month, day, hour, min, sec)
46
- end
47
-
48
- # *DEPRECATED*: Use +Time#utc+ instead.
49
- #
50
- # Wraps class method +time_with_datetime_fallback+ with +utc_or_local+ set to <tt>:utc</tt>.
51
- def utc_time(*args)
52
- ActiveSupport::Deprecation.warn 'utc_time is deprecated. Use Time#utc instead', caller
53
- time_with_datetime_fallback(:utc, *args)
54
- end
55
-
56
- # *DEPRECATED*: Use +Time#local+ instead.
57
- #
58
- # Wraps class method +time_with_datetime_fallback+ with +utc_or_local+ set to <tt>:local</tt>.
59
- def local_time(*args)
60
- ActiveSupport::Deprecation.warn 'local_time is deprecated. Use Time#local instead', caller
61
- time_with_datetime_fallback(:local, *args)
62
- end
63
-
64
29
  # 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>.
65
30
  def current
66
31
  ::Time.zone ? ::Time.zone.now : ::Time.now
@@ -98,13 +63,21 @@ class Time
98
63
  end_of_day.to_i - to_i
99
64
  end
100
65
 
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
+
101
73
  # Returns a new Time where one or more of the elements have been changed according
102
74
  # to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
103
- # <tt>:sec</tt>, <tt>:usec</tt>) reset cascadingly, so if only the hour is passed,
104
- # then minute, sec, and usec is set to 0. If the hour and minute is passed, then
105
- # sec and usec is set to 0. The +options+ parameter takes a hash with any of these
106
- # keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>, <tt>:hour</tt>, <tt>:min</tt>,
107
- # <tt>:sec</tt>, <tt>:usec</tt>.
75
+ # <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly, so if only
76
+ # the hour is passed, then minute, sec, usec and nsec is set to 0. If the hour
77
+ # and minute is passed, then sec, usec and nsec is set to 0. The +options+
78
+ # parameter takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>,
79
+ # <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.
108
81
  #
109
82
  # Time.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => Time.new(2012, 8, 1, 22, 35, 0)
110
83
  # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => Time.new(1981, 8, 1, 22, 35, 0)
@@ -116,21 +89,35 @@ class Time
116
89
  new_hour = options.fetch(:hour, hour)
117
90
  new_min = options.fetch(:min, options[:hour] ? 0 : min)
118
91
  new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
119
- new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
92
+
93
+ if new_nsec = options[:nsec]
94
+ raise ArgumentError, "Can't change both :nsec and :usec at the same time: #{options.inspect}" if options[:usec]
95
+ new_usec = Rational(new_nsec, 1000)
96
+ else
97
+ new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
98
+ end
120
99
 
121
100
  if utc?
122
101
  ::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec)
123
102
  elsif zone
124
103
  ::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec)
125
104
  else
105
+ raise ArgumentError, 'argument out of range' if new_usec >= 1000000
126
106
  ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec + (new_usec.to_r / 1000000), utc_offset)
127
107
  end
128
108
  end
129
109
 
130
- # Uses Date to provide precise Time calculations for years, months, and days.
131
- # The +options+ parameter takes a hash with any of these keys: <tt>:years</tt>,
132
- # <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>,
133
- # <tt>:minutes</tt>, <tt>:seconds</tt>.
110
+ # Uses Date to provide precise Time calculations for years, months, and days
111
+ # according to the proleptic Gregorian calendar. The +options+ parameter
112
+ # takes a hash with any of these keys: <tt>:years</tt>, <tt>:months</tt>,
113
+ # <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>, <tt>:minutes</tt>,
114
+ # <tt>:seconds</tt>.
115
+ #
116
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(seconds: 1) # => 2015-08-01 14:35:01 -0700
117
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(minutes: 1) # => 2015-08-01 14:36:00 -0700
118
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(hours: 1) # => 2015-08-01 15:35:00 -0700
119
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(days: 1) # => 2015-08-02 14:35:00 -0700
120
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(weeks: 1) # => 2015-08-08 14:35:00 -0700
134
121
  def advance(options)
135
122
  unless options[:weeks].nil?
136
123
  options[:weeks], partial_weeks = options[:weeks].divmod(1)
@@ -143,6 +130,7 @@ class Time
143
130
  end
144
131
 
145
132
  d = to_date.advance(options)
133
+ d = d.gregorian if d.julian?
146
134
  time_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
147
135
  seconds_to_advance = \
148
136
  options.fetch(:seconds, 0) +
@@ -178,6 +166,16 @@ class Time
178
166
  alias :at_midnight :beginning_of_day
179
167
  alias :at_beginning_of_day :beginning_of_day
180
168
 
169
+ # Returns a new Time representing the middle of the day (12:00)
170
+ def middle_of_day
171
+ change(:hour => 12)
172
+ end
173
+ alias :midday :middle_of_day
174
+ alias :noon :middle_of_day
175
+ alias :at_midday :middle_of_day
176
+ alias :at_noon :middle_of_day
177
+ alias :at_middle_of_day :middle_of_day
178
+
181
179
  # Returns a new Time representing the end of the day, 23:59:59.999999 (.999999999 in ruby1.9)
182
180
  def end_of_day
183
181
  change(
@@ -225,27 +223,6 @@ class Time
225
223
  beginning_of_day..end_of_day
226
224
  end
227
225
 
228
- # Returns a Range representing the whole week of the current time.
229
- # Week starts on start_day, default is <tt>Date.week_start</tt> or <tt>config.week_start</tt> when set.
230
- def all_week(start_day = Date.beginning_of_week)
231
- beginning_of_week(start_day)..end_of_week(start_day)
232
- end
233
-
234
- # Returns a Range representing the whole month of the current time.
235
- def all_month
236
- beginning_of_month..end_of_month
237
- end
238
-
239
- # Returns a Range representing the whole quarter of the current time.
240
- def all_quarter
241
- beginning_of_quarter..end_of_quarter
242
- end
243
-
244
- # Returns a Range representing the whole year of the current time.
245
- def all_year
246
- beginning_of_year..end_of_year
247
- end
248
-
249
226
  def plus_with_duration(other) #:nodoc:
250
227
  if ActiveSupport::Duration === other
251
228
  other.since(self)
@@ -280,7 +257,9 @@ class Time
280
257
  # can be chronologically compared with a Time
281
258
  def compare_with_coercion(other)
282
259
  # we're avoiding Time#to_datetime cause it's expensive
283
- if other.is_a?(Time)
260
+ if other.class == Time
261
+ compare_without_coercion(other)
262
+ elsif other.is_a?(Time)
284
263
  compare_without_coercion(other.to_time)
285
264
  else
286
265
  to_datetime <=> other
@@ -0,0 +1,14 @@
1
+ require "active_support/core_ext/date_and_time/compatibility"
2
+ require "active_support/core_ext/module/remove_method"
3
+
4
+ class Time
5
+ include DateAndTime::Compatibility
6
+
7
+ remove_possible_method :to_time
8
+
9
+ # Either return +self+ or the time in the local system timezone depending
10
+ # on the setting of +ActiveSupport.to_time_preserves_timezone+.
11
+ def to_time
12
+ preserve_timezone ? self : getlocal
13
+ end
14
+ end
@@ -16,10 +16,11 @@ class Time
16
16
  :rfc822 => lambda { |time|
17
17
  offset_format = time.formatted_offset(false)
18
18
  time.strftime("%a, %d %b %Y %H:%M:%S #{offset_format}")
19
- }
19
+ },
20
+ :iso8601 => lambda { |time| time.iso8601 }
20
21
  }
21
22
 
22
- # Converts to a formatted string. See DATE_FORMATS for builtin formats.
23
+ # Converts to a formatted string. See DATE_FORMATS for built-in formats.
23
24
  #
24
25
  # This method is aliased to <tt>to_s</tt>.
25
26
  #
@@ -34,6 +35,7 @@ class Time
34
35
  # time.to_formatted_s(:long) # => "January 18, 2007 06:10"
35
36
  # time.to_formatted_s(:long_ordinal) # => "January 18th, 2007 06:10"
36
37
  # time.to_formatted_s(:rfc822) # => "Thu, 18 Jan 2007 06:10:17 -0600"
38
+ # time.to_formatted_s(:iso8601) # => "2007-01-18T06:10:17-06:00"
37
39
  #
38
40
  # == Adding your own time formats to +to_formatted_s+
39
41
  # You can add your own formats to the Time::DATE_FORMATS hash.
@@ -1,7 +1,9 @@
1
1
  require 'active_support/time_with_zone'
2
2
  require 'active_support/core_ext/time/acts_like'
3
+ require 'active_support/core_ext/date_and_time/zones'
3
4
 
4
5
  class Time
6
+ include DateAndTime::Zones
5
7
  class << self
6
8
  attr_accessor :zone_default
7
9
 
@@ -74,24 +76,4 @@ class Time
74
76
  find_zone!(time_zone) rescue nil
75
77
  end
76
78
  end
77
-
78
- # Returns the simultaneous time in <tt>Time.zone</tt>.
79
- #
80
- # Time.zone = 'Hawaii' # => 'Hawaii'
81
- # Time.utc(2000).in_time_zone # => Fri, 31 Dec 1999 14:00:00 HST -10:00
82
- #
83
- # This method is similar to Time#localtime, except that it uses <tt>Time.zone</tt> as the local zone
84
- # instead of the operating system's time zone.
85
- #
86
- # You can also pass in a TimeZone instance or string that identifies a TimeZone as an argument,
87
- # and the conversion will be based on that zone instead of <tt>Time.zone</tt>.
88
- #
89
- # Time.utc(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
90
- def in_time_zone(zone = ::Time.zone)
91
- if zone
92
- ActiveSupport::TimeWithZone.new(utc? ? self : getutc, ::Time.find_zone!(zone))
93
- else
94
- self
95
- end
96
- end
97
79
  end
@@ -1,5 +1,6 @@
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'
3
4
  require 'active_support/core_ext/time/conversions'
4
5
  require 'active_support/core_ext/time/marshal'
5
6
  require 'active_support/core_ext/time/zones'
@@ -1,4 +1,3 @@
1
1
  Dir["#{File.dirname(__FILE__)}/core_ext/*.rb"].each do |path|
2
- next if File.basename(path, '.rb') == 'logger'
3
2
  require path
4
3
  end
@@ -67,7 +67,7 @@ module ActiveSupport
67
67
  end
68
68
 
69
69
  def eager_load!
70
- @_autoloads.values.each { |file| require file }
70
+ @_autoloads.each_value { |file| require file }
71
71
  end
72
72
 
73
73
  def autoloads
@@ -30,6 +30,10 @@ module ActiveSupport #:nodoc:
30
30
  mattr_accessor :loaded
31
31
  self.loaded = Set.new
32
32
 
33
+ # Stack of files being loaded.
34
+ mattr_accessor :loading
35
+ self.loading = []
36
+
33
37
  # Should we load files or require them?
34
38
  mattr_accessor :mechanism
35
39
  self.mechanism = ENV['NO_RELOAD'] ? :require : :load
@@ -176,14 +180,23 @@ module ActiveSupport #:nodoc:
176
180
  end
177
181
 
178
182
  def const_missing(const_name)
179
- # The interpreter does not pass nesting information, and in the
180
- # case of anonymous modules we cannot even make the trade-off of
181
- # assuming their name reflects the nesting. Resort to Object as
182
- # the only meaningful guess we can make.
183
- from_mod = anonymous? ? ::Object : self
183
+ from_mod = anonymous? ? guess_for_anonymous(const_name) : self
184
184
  Dependencies.load_missing_constant(from_mod, const_name)
185
185
  end
186
186
 
187
+ # We assume that the name of the module reflects the nesting
188
+ # (unless it can be proven that is not the case) and the path to the file
189
+ # that defines the constant. Anonymous modules cannot follow these
190
+ # conventions and therefore we assume that the user wants to refer to a
191
+ # top-level constant.
192
+ def guess_for_anonymous(const_name)
193
+ if Object.const_defined?(const_name)
194
+ raise NameError.new "#{const_name} cannot be autoloaded from an anonymous class or module", const_name
195
+ else
196
+ Object
197
+ end
198
+ end
199
+
187
200
  def unloadable(const_desc = self)
188
201
  super(const_desc)
189
202
  end
@@ -192,16 +205,29 @@ module ActiveSupport #:nodoc:
192
205
  # Object includes this module.
193
206
  module Loadable #:nodoc:
194
207
  def self.exclude_from(base)
195
- base.class_eval { define_method(:load, Kernel.instance_method(:load)) }
208
+ base.class_eval do
209
+ define_method(:load, Kernel.instance_method(:load))
210
+ private :load
211
+ end
196
212
  end
197
213
 
198
214
  def require_or_load(file_name)
199
215
  Dependencies.require_or_load(file_name)
200
216
  end
201
217
 
218
+ # Interprets a file using <tt>mechanism</tt> and marks its defined
219
+ # constants as autoloaded. <tt>file_name</tt> can be either a string or
220
+ # respond to <tt>to_path</tt>.
221
+ #
222
+ # Use this method in code that absolutely needs a certain constant to be
223
+ # defined at that point. A typical use case is to make constant name
224
+ # resolution deterministic for constants with the same relative name in
225
+ # different namespaces whose evaluation would depend on load order
226
+ # otherwise.
202
227
  def require_dependency(file_name, message = "No such file to load -- %s")
228
+ file_name = file_name.to_path if file_name.respond_to?(:to_path)
203
229
  unless file_name.is_a?(String)
204
- raise ArgumentError, "the file name must be a String -- you passed #{file_name.inspect}"
230
+ raise ArgumentError, "the file name must either be a String or implement #to_path -- you passed #{file_name.inspect}"
205
231
  end
206
232
 
207
233
  Dependencies.depend_on(file_name, message)
@@ -218,18 +244,6 @@ module ActiveSupport #:nodoc:
218
244
  raise
219
245
  end
220
246
 
221
- def load(file, wrap = false)
222
- result = false
223
- load_dependency(file) { result = super }
224
- result
225
- end
226
-
227
- def require(file)
228
- result = false
229
- load_dependency(file) { result = super }
230
- result
231
- end
232
-
233
247
  # Mark the given constant as unloadable. Unloadable constants are removed
234
248
  # each time dependencies are cleared.
235
249
  #
@@ -246,6 +260,20 @@ module ActiveSupport #:nodoc:
246
260
  def unloadable(const_desc)
247
261
  Dependencies.mark_for_unload const_desc
248
262
  end
263
+
264
+ private
265
+
266
+ def load(file, wrap = false)
267
+ result = false
268
+ load_dependency(file) { result = super }
269
+ result
270
+ end
271
+
272
+ def require(file)
273
+ result = false
274
+ load_dependency(file) { result = super }
275
+ result
276
+ end
249
277
  end
250
278
 
251
279
  # Exception file-blaming.
@@ -298,6 +326,7 @@ module ActiveSupport #:nodoc:
298
326
  def clear
299
327
  log_call
300
328
  loaded.clear
329
+ loading.clear
301
330
  remove_unloadable_constants!
302
331
  end
303
332
 
@@ -310,6 +339,7 @@ module ActiveSupport #:nodoc:
310
339
  # Record that we've seen this file *before* loading it to avoid an
311
340
  # infinite loop with mutual dependencies.
312
341
  loaded << expanded
342
+ loading << expanded
313
343
 
314
344
  begin
315
345
  if load?
@@ -332,6 +362,8 @@ module ActiveSupport #:nodoc:
332
362
  rescue Exception
333
363
  loaded.delete expanded
334
364
  raise
365
+ ensure
366
+ loading.pop
335
367
  end
336
368
 
337
369
  # Record history *after* loading so first load gets warnings.
@@ -389,7 +421,8 @@ module ActiveSupport #:nodoc:
389
421
  end
390
422
 
391
423
  def load_once_path?(path)
392
- # to_s works around a ruby1.9 issue where #starts_with?(Pathname) will always return false
424
+ # to_s works around a ruby1.9 issue where String#starts_with?(Pathname)
425
+ # will raise a TypeError: no implicit conversion of Pathname into String
393
426
  autoload_once_paths.any? { |base| path.starts_with? base.to_s }
394
427
  end
395
428
 
@@ -417,7 +450,7 @@ module ActiveSupport #:nodoc:
417
450
  def load_file(path, const_paths = loadable_constants_for_path(path))
418
451
  log_call path, const_paths
419
452
  const_paths = [const_paths].compact unless const_paths.is_a? Array
420
- parent_paths = const_paths.collect { |const_path| const_path[/.*(?=::)/] || :Object }
453
+ parent_paths = const_paths.collect { |const_path| const_path[/.*(?=::)/] || ::Object }
421
454
 
422
455
  result = nil
423
456
  newly_defined_paths = new_constants_in(*parent_paths) do
@@ -446,8 +479,6 @@ module ActiveSupport #:nodoc:
446
479
  raise ArgumentError, "A copy of #{from_mod} has been removed from the module tree but is still active!"
447
480
  end
448
481
 
449
- raise NameError.new("#{from_mod} is not missing constant #{const_name}!", const_name) if from_mod.const_defined?(const_name, false)
450
-
451
482
  qualified_name = qualified_name_for from_mod, const_name
452
483
  path_suffix = qualified_name.underscore
453
484
 
@@ -457,7 +488,7 @@ module ActiveSupport #:nodoc:
457
488
  expanded = File.expand_path(file_path)
458
489
  expanded.sub!(/\.rb\z/, '')
459
490
 
460
- if loaded.include?(expanded)
491
+ if loading.include?(expanded)
461
492
  raise "Circular dependency detected while autoloading constant #{qualified_name}"
462
493
  else
463
494
  require_or_load(expanded, qualified_name)
@@ -635,7 +666,7 @@ module ActiveSupport #:nodoc:
635
666
  when String then desc.sub(/^::/, '')
636
667
  when Symbol then desc.to_s
637
668
  when Module
638
- desc.name.presence ||
669
+ desc.name ||
639
670
  raise(ArgumentError, "Anonymous modules have no name to be referenced by")
640
671
  else raise TypeError, "Not a valid constant descriptor: #{desc.inspect}"
641
672
  end
@@ -649,6 +680,14 @@ module ActiveSupport #:nodoc:
649
680
  constants = normalized.split('::')
650
681
  to_remove = constants.pop
651
682
 
683
+ # Remove the file path from the loaded list.
684
+ file_path = search_for_file(const.underscore)
685
+ if file_path
686
+ expanded = File.expand_path(file_path)
687
+ expanded.sub!(/\.rb\z/, '')
688
+ self.loaded.delete(expanded)
689
+ end
690
+
652
691
  if constants.empty?
653
692
  parent = Object
654
693
  else
@@ -17,10 +17,10 @@ module ActiveSupport
17
17
  $stderr.puts(message)
18
18
  $stderr.puts callstack.join("\n ") if debug
19
19
  },
20
-
20
+
21
21
  log: ->(message, callstack) {
22
22
  logger =
23
- if defined?(Rails) && Rails.logger
23
+ if defined?(Rails.logger) && Rails.logger
24
24
  Rails.logger
25
25
  else
26
26
  require 'active_support/logger'
@@ -29,12 +29,12 @@ module ActiveSupport
29
29
  logger.warn message
30
30
  logger.debug callstack.join("\n ") if debug
31
31
  },
32
-
32
+
33
33
  notify: ->(message, callstack) {
34
34
  ActiveSupport::Notifications.instrument("deprecation.rails",
35
35
  :message => message, :callstack => callstack)
36
36
  },
37
-
37
+
38
38
  silence: ->(message, callstack) {},
39
39
  }
40
40
 
@@ -25,14 +25,14 @@ module ActiveSupport
25
25
  include Reporting
26
26
  include MethodWrapper
27
27
 
28
- # The version the deprecated behavior will be removed, by default.
28
+ # The version number in which the deprecated behavior will be removed, by default.
29
29
  attr_accessor :deprecation_horizon
30
30
 
31
- # It accepts two parameters on initialization. The first is an version of library
32
- # and the second is an library name
31
+ # It accepts two parameters on initialization. The first is a version of library
32
+ # and the second is a library name
33
33
  #
34
34
  # ActiveSupport::Deprecation.new('2.0', 'MyLibrary')
35
- def initialize(deprecation_horizon = '4.1', gem_name = 'Rails')
35
+ def initialize(deprecation_horizon = '5.0', gem_name = 'Rails')
36
36
  self.gem_name = gem_name
37
37
  self.deprecation_horizon = deprecation_horizon
38
38
  # By default, warnings are not silenced and debugging is off.
@@ -1,4 +1,3 @@
1
- require 'active_support/proxy_object'
2
1
  require 'active_support/core_ext/array/conversions'
3
2
  require 'active_support/core_ext/object/acts_like'
4
3
 
@@ -7,7 +6,7 @@ module ActiveSupport
7
6
  # Time#advance, respectively. It mainly supports the methods on Numeric.
8
7
  #
9
8
  # 1.month.ago # equivalent to Time.now.advance(months: -1)
10
- class Duration < ProxyObject
9
+ class Duration
11
10
  attr_accessor :value, :parts
12
11
 
13
12
  def initialize(value, parts) #:nodoc:
@@ -39,6 +38,10 @@ module ActiveSupport
39
38
  end
40
39
  alias :kind_of? :is_a?
41
40
 
41
+ def instance_of?(klass) # :nodoc:
42
+ Duration == klass || value.instance_of?(klass)
43
+ end
44
+
42
45
  # Returns +true+ if +other+ is also a Duration instance with the
43
46
  # same +value+, or if <tt>other == value</tt>.
44
47
  def ==(other)
@@ -49,6 +52,44 @@ module ActiveSupport
49
52
  end
50
53
  end
51
54
 
55
+ def to_s
56
+ @value.to_s
57
+ end
58
+
59
+ # Returns the number of seconds that this Duration represents.
60
+ #
61
+ # 1.minute.to_i # => 60
62
+ # 1.hour.to_i # => 3600
63
+ # 1.day.to_i # => 86400
64
+ #
65
+ # Note that this conversion makes some assumptions about the
66
+ # duration of some periods, e.g. months are always 30 days
67
+ # and years are 365.25 days:
68
+ #
69
+ # # equivalent to 30.days.to_i
70
+ # 1.month.to_i # => 2592000
71
+ #
72
+ # # equivalent to 365.25.days.to_i
73
+ # 1.year.to_i # => 31557600
74
+ #
75
+ # In such cases, Ruby's core
76
+ # Date[http://ruby-doc.org/stdlib/libdoc/date/rdoc/Date.html] and
77
+ # Time[http://ruby-doc.org/stdlib/libdoc/time/rdoc/Time.html] should be used for precision
78
+ # date and time arithmetic.
79
+ def to_i
80
+ @value.to_i
81
+ end
82
+
83
+ # Returns +true+ if +other+ is also a Duration instance, which has the
84
+ # same parts as this one.
85
+ def eql?(other)
86
+ Duration === other && other.value.eql?(value)
87
+ end
88
+
89
+ def hash
90
+ @value.hash
91
+ end
92
+
52
93
  def self.===(other) #:nodoc:
53
94
  other.is_a?(Duration)
54
95
  rescue ::NoMethodError
@@ -70,19 +111,23 @@ module ActiveSupport
70
111
  alias :until :ago
71
112
 
72
113
  def inspect #:nodoc:
73
- consolidated = parts.inject(::Hash.new(0)) { |h,(l,r)| h[l] += r; h }
74
- parts = [:years, :months, :days, :minutes, :seconds].map do |length|
75
- n = consolidated[length]
76
- "#{n} #{n == 1 ? length.to_s.singularize : length.to_s}" if n.nonzero?
77
- end.compact
78
- parts = ["0 seconds"] if parts.empty?
79
- parts.to_sentence(:locale => :en)
114
+ parts.
115
+ reduce(::Hash.new(0)) { |h,(l,r)| h[l] += r; h }.
116
+ sort_by {|unit, _ | [:years, :months, :days, :minutes, :seconds].index(unit)}.
117
+ map {|unit, val| "#{val} #{val == 1 ? unit.to_s.chop : unit.to_s}"}.
118
+ to_sentence(locale: ::I18n.default_locale)
80
119
  end
81
120
 
82
121
  def as_json(options = nil) #:nodoc:
83
122
  to_i
84
123
  end
85
124
 
125
+ def respond_to_missing?(method, include_private=false) #:nodoc
126
+ @value.respond_to?(method, include_private)
127
+ end
128
+
129
+ delegate :<=>, to: :value
130
+
86
131
  protected
87
132
 
88
133
  def sum(sign, time = ::Time.current) #:nodoc:
@@ -103,8 +148,7 @@ module ActiveSupport
103
148
 
104
149
  # We define it as a workaround to Ruby 2.0.0-p353 bug.
105
150
  # For more information, check rails/rails#13055.
106
- # It should be dropped once a new Ruby patch-level
107
- # release after 2.0.0-p353 happens.
151
+ # Remove it when we drop support for 2.0.0-p353.
108
152
  def ===(other) #:nodoc:
109
153
  value === other
110
154
  end
@@ -115,7 +115,7 @@ module ActiveSupport
115
115
  end
116
116
 
117
117
  def compile_glob(hash)
118
- hash.freeze # Freeze so changes aren't accidently pushed
118
+ hash.freeze # Freeze so changes aren't accidentally pushed
119
119
  return if hash.empty?
120
120
 
121
121
  globs = hash.map do |key, value|
@@ -0,0 +1,15 @@
1
+ module ActiveSupport
2
+ # Returns the version of the currently loaded Active Support as a <tt>Gem::Version</tt>
3
+ def self.gem_version
4
+ Gem::Version.new VERSION::STRING
5
+ end
6
+
7
+ module VERSION
8
+ MAJOR = 4
9
+ MINOR = 2
10
+ TINY = 11
11
+ PRE = "3"
12
+
13
+ STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
14
+ end
15
+ end