activesupport 4.2.0 → 5.0.0

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 (185) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +630 -220
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +2 -3
  5. data/lib/active_support/array_inquirer.rb +44 -0
  6. data/lib/active_support/backtrace_cleaner.rb +1 -1
  7. data/lib/active_support/benchmarkable.rb +1 -1
  8. data/lib/active_support/cache/file_store.rb +36 -22
  9. data/lib/active_support/cache/mem_cache_store.rb +63 -54
  10. data/lib/active_support/cache/memory_store.rb +16 -21
  11. data/lib/active_support/cache/null_store.rb +1 -4
  12. data/lib/active_support/cache/strategy/local_cache.rb +31 -20
  13. data/lib/active_support/cache.rb +73 -89
  14. data/lib/active_support/callbacks.rb +195 -155
  15. data/lib/active_support/concern.rb +2 -2
  16. data/lib/active_support/concurrency/latch.rb +7 -15
  17. data/lib/active_support/concurrency/share_lock.rb +186 -0
  18. data/lib/active_support/configurable.rb +1 -0
  19. data/lib/active_support/core_ext/array/access.rb +27 -1
  20. data/lib/active_support/core_ext/array/conversions.rb +6 -4
  21. data/lib/active_support/core_ext/array/grouping.rb +9 -18
  22. data/lib/active_support/core_ext/array/inquiry.rb +17 -0
  23. data/lib/active_support/core_ext/array/wrap.rb +5 -4
  24. data/lib/active_support/core_ext/array.rb +1 -0
  25. data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -10
  26. data/lib/active_support/core_ext/class/attribute.rb +10 -9
  27. data/lib/active_support/core_ext/class/subclasses.rb +3 -4
  28. data/lib/active_support/core_ext/class.rb +0 -1
  29. data/lib/active_support/core_ext/date/blank.rb +12 -0
  30. data/lib/active_support/core_ext/date/calculations.rb +1 -1
  31. data/lib/active_support/core_ext/date/conversions.rb +13 -6
  32. data/lib/active_support/core_ext/date.rb +1 -1
  33. data/lib/active_support/core_ext/date_and_time/calculations.rb +109 -25
  34. data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -0
  35. data/lib/active_support/core_ext/date_and_time/zones.rb +3 -4
  36. data/lib/active_support/core_ext/date_time/blank.rb +12 -0
  37. data/lib/active_support/core_ext/date_time/calculations.rb +36 -10
  38. data/lib/active_support/core_ext/date_time/compatibility.rb +5 -0
  39. data/lib/active_support/core_ext/date_time/conversions.rb +2 -0
  40. data/lib/active_support/core_ext/date_time.rb +2 -1
  41. data/lib/active_support/core_ext/enumerable.rb +49 -5
  42. data/lib/active_support/core_ext/file/atomic.rb +30 -25
  43. data/lib/active_support/core_ext/hash/conversions.rb +23 -4
  44. data/lib/active_support/core_ext/hash/deep_merge.rb +1 -1
  45. data/lib/active_support/core_ext/hash/except.rb +9 -8
  46. data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -1
  47. data/lib/active_support/core_ext/hash/keys.rb +23 -19
  48. data/lib/active_support/core_ext/hash/slice.rb +1 -1
  49. data/lib/active_support/core_ext/hash/transform_values.rb +11 -5
  50. data/lib/active_support/core_ext/integer/time.rb +1 -16
  51. data/lib/active_support/core_ext/kernel/concern.rb +2 -0
  52. data/lib/active_support/core_ext/kernel/debugger.rb +3 -10
  53. data/lib/active_support/core_ext/kernel/reporting.rb +2 -83
  54. data/lib/active_support/core_ext/kernel.rb +0 -1
  55. data/lib/active_support/core_ext/load_error.rb +4 -2
  56. data/lib/active_support/core_ext/marshal.rb +12 -11
  57. data/lib/active_support/core_ext/module/aliasing.rb +6 -1
  58. data/lib/active_support/core_ext/module/anonymous.rb +10 -1
  59. data/lib/active_support/core_ext/module/attr_internal.rb +2 -5
  60. data/lib/active_support/core_ext/module/attribute_accessors.rb +15 -15
  61. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +141 -0
  62. data/lib/active_support/core_ext/module/concerning.rb +4 -4
  63. data/lib/active_support/core_ext/module/delegation.rb +35 -25
  64. data/lib/active_support/core_ext/module/deprecation.rb +2 -2
  65. data/lib/active_support/core_ext/module/introspection.rb +4 -0
  66. data/lib/active_support/core_ext/module/method_transplanting.rb +3 -11
  67. data/lib/active_support/core_ext/module/qualified_const.rb +30 -12
  68. data/lib/active_support/core_ext/module/remove_method.rb +23 -0
  69. data/lib/active_support/core_ext/module.rb +1 -0
  70. data/lib/active_support/core_ext/name_error.rb +15 -2
  71. data/lib/active_support/core_ext/numeric/bytes.rb +20 -0
  72. data/lib/active_support/core_ext/numeric/conversions.rb +74 -64
  73. data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
  74. data/lib/active_support/core_ext/numeric/time.rb +24 -19
  75. data/lib/active_support/core_ext/numeric.rb +1 -0
  76. data/lib/active_support/core_ext/object/blank.rb +17 -5
  77. data/lib/active_support/core_ext/object/deep_dup.rb +10 -3
  78. data/lib/active_support/core_ext/object/duplicable.rb +8 -13
  79. data/lib/active_support/core_ext/object/inclusion.rb +2 -2
  80. data/lib/active_support/core_ext/object/instance_variables.rb +1 -1
  81. data/lib/active_support/core_ext/object/json.rb +15 -7
  82. data/lib/active_support/core_ext/object/to_query.rb +1 -1
  83. data/lib/active_support/core_ext/object/try.rb +68 -22
  84. data/lib/active_support/core_ext/object/with_options.rb +1 -1
  85. data/lib/active_support/core_ext/object.rb +0 -1
  86. data/lib/active_support/core_ext/range/conversions.rb +18 -6
  87. data/lib/active_support/core_ext/range/each.rb +16 -18
  88. data/lib/active_support/core_ext/range/include_range.rb +20 -20
  89. data/lib/active_support/core_ext/securerandom.rb +23 -0
  90. data/lib/active_support/core_ext/string/access.rb +1 -1
  91. data/lib/active_support/core_ext/string/behavior.rb +1 -1
  92. data/lib/active_support/core_ext/string/conversions.rb +4 -3
  93. data/lib/active_support/core_ext/string/filters.rb +5 -5
  94. data/lib/active_support/core_ext/string/inflections.rb +32 -5
  95. data/lib/active_support/core_ext/string/multibyte.rb +11 -7
  96. data/lib/active_support/core_ext/string/output_safety.rb +18 -16
  97. data/lib/active_support/core_ext/string/strip.rb +3 -6
  98. data/lib/active_support/core_ext/struct.rb +3 -6
  99. data/lib/active_support/core_ext/time/calculations.rb +36 -11
  100. data/lib/active_support/core_ext/time/compatibility.rb +5 -0
  101. data/lib/active_support/core_ext/time/conversions.rb +4 -2
  102. data/lib/active_support/core_ext/time/marshal.rb +2 -29
  103. data/lib/active_support/core_ext/time/zones.rb +36 -4
  104. data/lib/active_support/core_ext/time.rb +1 -1
  105. data/lib/active_support/core_ext/uri.rb +1 -3
  106. data/lib/active_support/core_ext.rb +2 -1
  107. data/lib/active_support/dependencies/interlock.rb +51 -0
  108. data/lib/active_support/dependencies.rb +87 -95
  109. data/lib/active_support/deprecation/behaviors.rb +16 -2
  110. data/lib/active_support/deprecation/method_wrappers.rb +42 -16
  111. data/lib/active_support/deprecation/proxy_wrappers.rb +47 -24
  112. data/lib/active_support/deprecation/reporting.rb +23 -5
  113. data/lib/active_support/deprecation.rb +1 -1
  114. data/lib/active_support/duration/iso8601_parser.rb +122 -0
  115. data/lib/active_support/duration/iso8601_serializer.rb +51 -0
  116. data/lib/active_support/duration.rb +55 -10
  117. data/lib/active_support/evented_file_update_checker.rb +194 -0
  118. data/lib/active_support/execution_wrapper.rb +117 -0
  119. data/lib/active_support/executor.rb +6 -0
  120. data/lib/active_support/file_update_checker.rb +23 -3
  121. data/lib/active_support/gem_version.rb +3 -3
  122. data/lib/active_support/hash_with_indifferent_access.rb +46 -13
  123. data/lib/active_support/i18n_railtie.rb +25 -4
  124. data/lib/active_support/inflector/inflections.rb +36 -5
  125. data/lib/active_support/inflector/methods.rb +97 -90
  126. data/lib/active_support/inflector/transliterate.rb +36 -21
  127. data/lib/active_support/json/decoding.rb +11 -10
  128. data/lib/active_support/json/encoding.rb +4 -49
  129. data/lib/active_support/key_generator.rb +7 -9
  130. data/lib/active_support/locale/en.yml +2 -0
  131. data/lib/active_support/log_subscriber/test_helper.rb +3 -3
  132. data/lib/active_support/log_subscriber.rb +1 -1
  133. data/lib/active_support/logger.rb +50 -1
  134. data/lib/active_support/logger_silence.rb +8 -4
  135. data/lib/active_support/logger_thread_safe_level.rb +31 -0
  136. data/lib/active_support/message_encryptor.rb +4 -4
  137. data/lib/active_support/message_verifier.rb +70 -8
  138. data/lib/active_support/multibyte/chars.rb +13 -4
  139. data/lib/active_support/multibyte/unicode.rb +44 -21
  140. data/lib/active_support/notifications/fanout.rb +6 -6
  141. data/lib/active_support/notifications/instrumenter.rb +20 -2
  142. data/lib/active_support/notifications.rb +2 -2
  143. data/lib/active_support/number_helper/number_to_currency_converter.rb +7 -9
  144. data/lib/active_support/number_helper/number_to_delimited_converter.rb +8 -3
  145. data/lib/active_support/number_helper/number_to_human_converter.rb +6 -4
  146. data/lib/active_support/number_helper/number_to_human_size_converter.rb +6 -2
  147. data/lib/active_support/number_helper/number_to_percentage_converter.rb +1 -1
  148. data/lib/active_support/number_helper/number_to_phone_converter.rb +11 -2
  149. data/lib/active_support/number_helper/number_to_rounded_converter.rb +30 -25
  150. data/lib/active_support/number_helper.rb +90 -67
  151. data/lib/active_support/ordered_hash.rb +1 -1
  152. data/lib/active_support/ordered_options.rb +15 -1
  153. data/lib/active_support/per_thread_registry.rb +8 -3
  154. data/lib/active_support/rails.rb +2 -2
  155. data/lib/active_support/railtie.rb +6 -1
  156. data/lib/active_support/reloader.rb +129 -0
  157. data/lib/active_support/rescuable.rb +93 -47
  158. data/lib/active_support/security_utils.rb +7 -0
  159. data/lib/active_support/string_inquirer.rb +1 -1
  160. data/lib/active_support/subscriber.rb +5 -10
  161. data/lib/active_support/tagged_logging.rb +3 -1
  162. data/lib/active_support/test_case.rb +15 -29
  163. data/lib/active_support/testing/assertions.rb +15 -13
  164. data/lib/active_support/testing/autorun.rb +8 -1
  165. data/lib/active_support/testing/deprecation.rb +9 -8
  166. data/lib/active_support/testing/file_fixtures.rb +34 -0
  167. data/lib/active_support/testing/isolation.rb +22 -8
  168. data/lib/active_support/testing/method_call_assertions.rb +41 -0
  169. data/lib/active_support/testing/stream.rb +42 -0
  170. data/lib/active_support/testing/time_helpers.rb +13 -10
  171. data/lib/active_support/time_with_zone.rb +135 -46
  172. data/lib/active_support/values/time_zone.rb +95 -47
  173. data/lib/active_support/values/unicode_tables.dat +0 -0
  174. data/lib/active_support/xml_mini/jdom.rb +7 -6
  175. data/lib/active_support/xml_mini/libxml.rb +2 -2
  176. data/lib/active_support/xml_mini/nokogiri.rb +2 -2
  177. data/lib/active_support/xml_mini/rexml.rb +7 -8
  178. data/lib/active_support/xml_mini.rb +22 -14
  179. data/lib/active_support.rb +20 -6
  180. metadata +32 -35
  181. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -14
  182. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
  183. data/lib/active_support/core_ext/date_time/zones.rb +0 -6
  184. data/lib/active_support/core_ext/object/itself.rb +0 -15
  185. data/lib/active_support/core_ext/thread.rb +0 -86
@@ -164,25 +164,43 @@ class String
164
164
  #
165
165
  # <%= link_to(@person.name, person_path) %>
166
166
  # # => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a>
167
- def parameterize(sep = '-')
168
- ActiveSupport::Inflector.parameterize(self, sep)
167
+ #
168
+ # To preserve the case of the characters in a string, use the `preserve_case` argument.
169
+ #
170
+ # class Person
171
+ # def to_param
172
+ # "#{id}-#{name.parameterize(preserve_case: true)}"
173
+ # end
174
+ # end
175
+ #
176
+ # @person = Person.find(1)
177
+ # # => #<Person id: 1, name: "Donald E. Knuth">
178
+ #
179
+ # <%= link_to(@person.name, person_path) %>
180
+ # # => <a href="/person/1-Donald-E-Knuth">Donald E. Knuth</a>
181
+ def parameterize(sep = :unused, separator: '-', preserve_case: false)
182
+ unless sep == :unused
183
+ ActiveSupport::Deprecation.warn("Passing the separator argument as a positional parameter is deprecated and will soon be removed. Use `separator: '#{sep}'` instead.")
184
+ separator = sep
185
+ end
186
+ ActiveSupport::Inflector.parameterize(self, separator: separator, preserve_case: preserve_case)
169
187
  end
170
188
 
171
189
  # Creates the name of a table like Rails does for models to table names. This method
172
190
  # uses the +pluralize+ method on the last word in the string.
173
191
  #
174
192
  # 'RawScaledScorer'.tableize # => "raw_scaled_scorers"
175
- # 'egg_and_ham'.tableize # => "egg_and_hams"
193
+ # 'ham_and_egg'.tableize # => "ham_and_eggs"
176
194
  # 'fancyCategory'.tableize # => "fancy_categories"
177
195
  def tableize
178
196
  ActiveSupport::Inflector.tableize(self)
179
197
  end
180
198
 
181
- # Create a class name from a plural table name like Rails does for table names to models.
199
+ # Creates a class name from a plural table name like Rails does for table names to models.
182
200
  # Note that this returns a string and not a class. (To convert to an actual class
183
201
  # follow +classify+ with +constantize+.)
184
202
  #
185
- # 'egg_and_hams'.classify # => "EggAndHam"
203
+ # 'ham_and_eggs'.classify # => "HamAndEgg"
186
204
  # 'posts'.classify # => "Post"
187
205
  def classify
188
206
  ActiveSupport::Inflector.classify(self)
@@ -204,6 +222,15 @@ class String
204
222
  ActiveSupport::Inflector.humanize(self, options)
205
223
  end
206
224
 
225
+ # Converts just the first character to uppercase.
226
+ #
227
+ # 'what a Lovely Day'.upcase_first # => "What a Lovely Day"
228
+ # 'w'.upcase_first # => "W"
229
+ # ''.upcase_first # => ""
230
+ def upcase_first
231
+ ActiveSupport::Inflector.upcase_first(self)
232
+ end
233
+
207
234
  # Creates a foreign key name from a class name.
208
235
  # +separate_class_name_and_id_with_underscore+ sets whether
209
236
  # the method should put '_' between the name and 'id'.
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  require 'active_support/multibyte'
3
2
 
4
3
  class String
@@ -10,12 +9,10 @@ class String
10
9
  # encapsulates the original string. A Unicode safe version of all the String methods are defined on this proxy
11
10
  # class. If the proxy class doesn't respond to a certain method, it's forwarded to the encapsulated string.
12
11
  #
13
- # name = 'Claus Müller'
14
- # name.reverse # => "rell??M sualC"
15
- # name.length # => 13
16
- #
17
- # name.mb_chars.reverse.to_s # => "rellüM sualC"
18
- # name.mb_chars.length # => 12
12
+ # >> "lj".upcase
13
+ # => "lj"
14
+ # >> "lj".mb_chars.upcase.to_s
15
+ # => "LJ"
19
16
  #
20
17
  # == Method chaining
21
18
  #
@@ -36,6 +33,13 @@ class String
36
33
  ActiveSupport::Multibyte.proxy_class.new(self)
37
34
  end
38
35
 
36
+ # Returns +true+ if string has utf_8 encoding.
37
+ #
38
+ # utf_8_str = "some string".encode "UTF-8"
39
+ # iso_str = "some string".encode "ISO-8859-1"
40
+ #
41
+ # utf_8_str.is_utf8? # => true
42
+ # iso_str.is_utf8? # => false
39
43
  def is_utf8?
40
44
  case encoding
41
45
  when Encoding::UTF_8
@@ -1,12 +1,10 @@
1
1
  require 'erb'
2
2
  require 'active_support/core_ext/kernel/singleton_class'
3
- require 'active_support/deprecation'
4
3
 
5
4
  class ERB
6
5
  module Util
7
6
  HTML_ESCAPE = { '&' => '&amp;', '>' => '&gt;', '<' => '&lt;', '"' => '&quot;', "'" => '&#39;' }
8
7
  JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003e', '<' => '\u003c', "\u2028" => '\u2028', "\u2029" => '\u2029' }
9
- HTML_ESCAPE_REGEXP = /[&"'><]/
10
8
  HTML_ESCAPE_ONCE_REGEXP = /["><']|&(?!([a-zA-Z]+|(#\d+)|(#[xX][\dA-Fa-f]+));)/
11
9
  JSON_ESCAPE_REGEXP = /[\u2028\u2029&><]/u
12
10
 
@@ -14,7 +12,7 @@ class ERB
14
12
  # This method is also aliased as <tt>h</tt>.
15
13
  #
16
14
  # In your ERB templates, use this method to escape any unsafe content. For example:
17
- # <%=h @person.name %>
15
+ # <%= h @person.name %>
18
16
  #
19
17
  # puts html_escape('is a > 0 & a < 10?')
20
18
  # # => is a &gt; 0 &amp; a &lt; 10?
@@ -38,7 +36,7 @@ class ERB
38
36
  if s.html_safe?
39
37
  s
40
38
  else
41
- s.gsub(HTML_ESCAPE_REGEXP, HTML_ESCAPE)
39
+ CGI.escapeHTML(ActiveSupport::Multibyte::Unicode.tidy_bytes(s))
42
40
  end
43
41
  end
44
42
  module_function :unwrapped_html_escape
@@ -51,7 +49,7 @@ class ERB
51
49
  # html_escape_once('&lt;&lt; Accept & Checkout')
52
50
  # # => "&lt;&lt; Accept &amp; Checkout"
53
51
  def html_escape_once(s)
54
- result = s.to_s.gsub(HTML_ESCAPE_ONCE_REGEXP, HTML_ESCAPE)
52
+ result = ActiveSupport::Multibyte::Unicode.tidy_bytes(s.to_s).gsub(HTML_ESCAPE_ONCE_REGEXP, HTML_ESCAPE)
55
53
  s.html_safe? ? result.html_safe : result
56
54
  end
57
55
 
@@ -86,6 +84,11 @@ class ERB
86
84
  # automatically flag the result as HTML safe, since the raw value is unsafe to
87
85
  # use inside HTML attributes.
88
86
  #
87
+ # If your JSON is being used downstream for insertion into the DOM, be aware of
88
+ # whether or not it is being inserted via +html()+. Most jQuery plugins do this.
89
+ # If that is the case, be sure to +html_escape+ or +sanitize+ any user-generated
90
+ # content returned by your JSON.
91
+ #
89
92
  # If you need to output JSON elsewhere in your HTML, you can just do something
90
93
  # like this, as any unsafe characters (including quotation marks) will be
91
94
  # automatically escaped for you:
@@ -138,6 +141,7 @@ module ActiveSupport #:nodoc:
138
141
  alias_method :original_concat, :concat
139
142
  private :original_concat
140
143
 
144
+ # Raised when <tt>ActiveSupport::SafeBuffer#safe_concat</tt> is called on unsafe buffers.
141
145
  class SafeConcatError < StandardError
142
146
  def initialize
143
147
  super 'Could not concatenate to the buffer because it is not html safe.'
@@ -150,7 +154,11 @@ module ActiveSupport #:nodoc:
150
154
  else
151
155
  if html_safe?
152
156
  new_safe_buffer = super
153
- new_safe_buffer.instance_variable_set :@html_safe, true
157
+
158
+ if new_safe_buffer
159
+ new_safe_buffer.instance_variable_set :@html_safe, true
160
+ end
161
+
154
162
  new_safe_buffer
155
163
  else
156
164
  to_str[*args]
@@ -163,7 +171,7 @@ module ActiveSupport #:nodoc:
163
171
  original_concat(value)
164
172
  end
165
173
 
166
- def initialize(*)
174
+ def initialize(str = '')
167
175
  @html_safe = true
168
176
  super
169
177
  end
@@ -186,11 +194,6 @@ module ActiveSupport #:nodoc:
186
194
  super(html_escape_interpolated_argument(value))
187
195
  end
188
196
 
189
- def prepend!(value)
190
- ActiveSupport::Deprecation.deprecation_warning "ActiveSupport::SafeBuffer#prepend!", :prepend
191
- prepend value
192
- end
193
-
194
197
  def +(other)
195
198
  dup.concat(other)
196
199
  end
@@ -219,7 +222,7 @@ module ActiveSupport #:nodoc:
219
222
  end
220
223
 
221
224
  def encode_with(coder)
222
- coder.represent_scalar nil, to_str
225
+ coder.represent_object nil, to_str
223
226
  end
224
227
 
225
228
  UNSAFE_STRING_METHODS.each do |unsafe_method|
@@ -240,15 +243,14 @@ module ActiveSupport #:nodoc:
240
243
  private
241
244
 
242
245
  def html_escape_interpolated_argument(arg)
243
- (!html_safe? || arg.html_safe?) ? arg :
244
- arg.to_s.gsub(ERB::Util::HTML_ESCAPE_REGEXP, ERB::Util::HTML_ESCAPE)
246
+ (!html_safe? || arg.html_safe?) ? arg : CGI.escapeHTML(arg.to_s)
245
247
  end
246
248
  end
247
249
  end
248
250
 
249
251
  class String
250
252
  # Marks a string as trusted safe. It will be inserted into HTML with no
251
- # additional escaping performed. It is your responsibilty to ensure that the
253
+ # additional escaping performed. It is your responsibility to ensure that the
252
254
  # string contains no malicious content. This method is equivalent to the
253
255
  # `raw` helper in views. It is recommended that you use `sanitize` instead of
254
256
  # this method. It should never be called on user input.
@@ -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.")
@@ -3,6 +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/core_ext/date/calculations'
6
7
 
7
8
  class Time
8
9
  include DateAndTime::Calculations
@@ -15,9 +16,9 @@ class Time
15
16
  super || (self == Time && other.is_a?(ActiveSupport::TimeWithZone))
16
17
  end
17
18
 
18
- # Return the number of days in the given month.
19
+ # Returns the number of days in the given month.
19
20
  # If no year is specified, it will use the current year.
20
- def days_in_month(month, year = now.year)
21
+ def days_in_month(month, year = current.year)
21
22
  if month == 2 && ::Date.gregorian_leap?(year)
22
23
  29
23
24
  else
@@ -25,6 +26,12 @@ class Time
25
26
  end
26
27
  end
27
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
+
28
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>.
29
36
  def current
30
37
  ::Time.zone ? ::Time.zone.now : ::Time.now
@@ -48,7 +55,11 @@ class Time
48
55
  alias_method :at, :at_with_coercion
49
56
  end
50
57
 
51
- # 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
52
63
  def seconds_since_midnight
53
64
  to_i - change(:hour => 0).to_i + (usec / 1.0e+6)
54
65
  end
@@ -62,6 +73,13 @@ class Time
62
73
  end_of_day.to_i - to_i
63
74
  end
64
75
 
76
+ # Returns the fraction of a second as a +Rational+
77
+ #
78
+ # Time.new(2012, 8, 29, 0, 0, 0.5).sec_fraction # => (1/2)
79
+ def sec_fraction
80
+ subsec
81
+ end
82
+
65
83
  # Returns a new Time where one or more of the elements have been changed according
66
84
  # to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
67
85
  # <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly, so if only
@@ -69,7 +87,7 @@ class Time
69
87
  # and minute is passed, then sec, usec and nsec is set to 0. The +options+
70
88
  # parameter takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>,
71
89
  # <tt>:day</tt>, <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>
72
- # <tt>:nsec</tt>. Path either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
90
+ # <tt>:nsec</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
73
91
  #
74
92
  # Time.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => Time.new(2012, 8, 1, 22, 35, 0)
75
93
  # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => Time.new(1981, 8, 1, 22, 35, 0)
@@ -94,7 +112,7 @@ class Time
94
112
  elsif zone
95
113
  ::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec)
96
114
  else
97
- raise ArgumentError, 'argument out of range' if new_usec > 999999
115
+ raise ArgumentError, 'argument out of range' if new_usec >= 1000000
98
116
  ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec + (new_usec.to_r / 1000000), utc_offset)
99
117
  end
100
118
  end
@@ -104,6 +122,12 @@ class Time
104
122
  # takes a hash with any of these keys: <tt>:years</tt>, <tt>:months</tt>,
105
123
  # <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>, <tt>:minutes</tt>,
106
124
  # <tt>:seconds</tt>.
125
+ #
126
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(seconds: 1) # => 2015-08-01 14:35:01 -0700
127
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(minutes: 1) # => 2015-08-01 14:36:00 -0700
128
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(hours: 1) # => 2015-08-01 15:35:00 -0700
129
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(days: 1) # => 2015-08-02 14:35:00 -0700
130
+ # Time.new(2015, 8, 1, 14, 35, 0).advance(weeks: 1) # => 2015-08-08 14:35:00 -0700
107
131
  def advance(options)
108
132
  unless options[:weeks].nil?
109
133
  options[:weeks], partial_weeks = options[:weeks].divmod(1)
@@ -145,7 +169,6 @@ class Time
145
169
 
146
170
  # Returns a new Time representing the start of the day (0:00)
147
171
  def beginning_of_day
148
- #(self - seconds_since_midnight).change(usec: 0)
149
172
  change(:hour => 0)
150
173
  end
151
174
  alias :midnight :beginning_of_day
@@ -162,7 +185,7 @@ class Time
162
185
  alias :at_noon :middle_of_day
163
186
  alias :at_middle_of_day :middle_of_day
164
187
 
165
- # Returns a new Time representing the end of the day, 23:59:59.999999 (.999999999 in ruby1.9)
188
+ # Returns a new Time representing the end of the day, 23:59:59.999999
166
189
  def end_of_day
167
190
  change(
168
191
  :hour => 23,
@@ -179,7 +202,7 @@ class Time
179
202
  end
180
203
  alias :at_beginning_of_hour :beginning_of_hour
181
204
 
182
- # Returns a new Time representing the end of the hour, x:59:59.999999 (.999999999 in ruby1.9)
205
+ # Returns a new Time representing the end of the hour, x:59:59.999999
183
206
  def end_of_hour
184
207
  change(
185
208
  :min => 59,
@@ -195,7 +218,7 @@ class Time
195
218
  end
196
219
  alias :at_beginning_of_minute :beginning_of_minute
197
220
 
198
- # Returns a new Time representing the end of the minute, x:xx:59.999999 (.999999999 in ruby1.9)
221
+ # Returns a new Time representing the end of the minute, x:xx:59.999999
199
222
  def end_of_minute
200
223
  change(
201
224
  :sec => 59,
@@ -242,8 +265,10 @@ class Time
242
265
  # Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
243
266
  # can be chronologically compared with a Time
244
267
  def compare_with_coercion(other)
245
- # we're avoiding Time#to_datetime cause it's expensive
246
- if other.is_a?(Time)
268
+ # we're avoiding Time#to_datetime and Time#to_time because they're expensive
269
+ if other.class == Time
270
+ compare_without_coercion(other)
271
+ elsif other.is_a?(Time)
247
272
  compare_without_coercion(other.to_time)
248
273
  else
249
274
  to_datetime <=> other
@@ -0,0 +1,5 @@
1
+ require 'active_support/core_ext/date_and_time/compatibility'
2
+
3
+ class Time
4
+ prepend DateAndTime::Compatibility
5
+ end
@@ -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?
@@ -40,7 +40,23 @@ class Time
40
40
  Thread.current[:time_zone] = find_zone!(time_zone)
41
41
  end
42
42
 
43
- # Allows override of <tt>Time.zone</tt> locally inside supplied block; resets <tt>Time.zone</tt> to existing value when done.
43
+ # Allows override of <tt>Time.zone</tt> locally inside supplied block;
44
+ # resets <tt>Time.zone</tt> to existing value when done.
45
+ #
46
+ # class ApplicationController < ActionController::Base
47
+ # around_action :set_time_zone
48
+ #
49
+ # private
50
+ #
51
+ # def set_time_zone
52
+ # Time.use_zone(current_user.timezone) { yield }
53
+ # end
54
+ # end
55
+ #
56
+ # NOTE: This won't affect any <tt>ActiveSupport::TimeWithZone</tt>
57
+ # objects that have already been created, e.g. any model timestamp
58
+ # attributes that have been read before the block will remain in
59
+ # the application's default timezone.
44
60
  def use_zone(time_zone)
45
61
  new_zone = find_zone!(time_zone)
46
62
  begin
@@ -51,12 +67,22 @@ class Time
51
67
  end
52
68
  end
53
69
 
54
- # Returns a TimeZone instance or nil, or raises an ArgumentError for invalid timezones.
70
+ # Returns a TimeZone instance matching the time zone provided.
71
+ # Accepts the time zone in any format supported by <tt>Time.zone=</tt>.
72
+ # Raises an +ArgumentError+ for invalid time zones.
73
+ #
74
+ # Time.find_zone! "America/New_York" # => #<ActiveSupport::TimeZone @name="America/New_York" ...>
75
+ # Time.find_zone! "EST" # => #<ActiveSupport::TimeZone @name="EST" ...>
76
+ # Time.find_zone! -5.hours # => #<ActiveSupport::TimeZone @name="Bogota" ...>
77
+ # Time.find_zone! nil # => nil
78
+ # Time.find_zone! false # => false
79
+ # Time.find_zone! "NOT-A-TIMEZONE" # => ArgumentError: Invalid Timezone: NOT-A-TIMEZONE
55
80
  def find_zone!(time_zone)
56
81
  if !time_zone || time_zone.is_a?(ActiveSupport::TimeZone)
57
82
  time_zone
58
83
  else
59
- # lookup timezone based on identifier (unless we've been passed a TZInfo::Timezone)
84
+ # Look up the timezone based on the identifier (unless we've been
85
+ # passed a TZInfo::Timezone)
60
86
  unless time_zone.respond_to?(:period_for_local)
61
87
  time_zone = ActiveSupport::TimeZone[time_zone] || TZInfo::Timezone.get(time_zone)
62
88
  end
@@ -72,6 +98,12 @@ class Time
72
98
  raise ArgumentError, "Invalid Timezone: #{time_zone}"
73
99
  end
74
100
 
101
+ # Returns a TimeZone instance matching the time zone provided.
102
+ # Accepts the time zone in any format supported by <tt>Time.zone=</tt>.
103
+ # Returns +nil+ for invalid time zones.
104
+ #
105
+ # Time.find_zone "America/New_York" # => #<ActiveSupport::TimeZone @name="America/New_York" ...>
106
+ # Time.find_zone "NOT-A-TIMEZONE" # => nil
75
107
  def find_zone(time_zone)
76
108
  find_zone!(time_zone) rescue nil
77
109
  end
@@ -1,5 +1,5 @@
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
- require 'active_support/core_ext/time/marshal'
5
5
  require 'active_support/core_ext/time/zones'
@@ -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,3 +1,4 @@
1
- Dir["#{File.dirname(__FILE__)}/core_ext/*.rb"].each do |path|
1
+ DEPRECATED_FILES = ["#{File.dirname(__FILE__)}/core_ext/struct.rb"]
2
+ (Dir["#{File.dirname(__FILE__)}/core_ext/*.rb"] - DEPRECATED_FILES).each do |path|
2
3
  require path
3
4
  end
@@ -0,0 +1,51 @@
1
+ require 'active_support/concurrency/share_lock'
2
+
3
+ module ActiveSupport #:nodoc:
4
+ module Dependencies #:nodoc:
5
+ class Interlock
6
+ def initialize # :nodoc:
7
+ @lock = ActiveSupport::Concurrency::ShareLock.new
8
+ end
9
+
10
+ def loading
11
+ @lock.exclusive(purpose: :load, compatible: [:load], after_compatible: [:load]) do
12
+ yield
13
+ end
14
+ end
15
+
16
+ def unloading
17
+ @lock.exclusive(purpose: :unload, compatible: [:load, :unload], after_compatible: [:load, :unload]) do
18
+ yield
19
+ end
20
+ end
21
+
22
+ def start_unloading
23
+ @lock.start_exclusive(purpose: :unload, compatible: [:load, :unload])
24
+ end
25
+
26
+ def done_unloading
27
+ @lock.stop_exclusive(compatible: [:load, :unload])
28
+ end
29
+
30
+ def start_running
31
+ @lock.start_sharing
32
+ end
33
+
34
+ def done_running
35
+ @lock.stop_sharing
36
+ end
37
+
38
+ def running
39
+ @lock.sharing do
40
+ yield
41
+ end
42
+ end
43
+
44
+ def permit_concurrent_loads
45
+ @lock.yield_shares(compatible: [:load]) do
46
+ yield
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end