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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +630 -220
- data/MIT-LICENSE +2 -2
- data/README.rdoc +2 -3
- data/lib/active_support/array_inquirer.rb +44 -0
- data/lib/active_support/backtrace_cleaner.rb +1 -1
- data/lib/active_support/benchmarkable.rb +1 -1
- data/lib/active_support/cache/file_store.rb +36 -22
- data/lib/active_support/cache/mem_cache_store.rb +63 -54
- data/lib/active_support/cache/memory_store.rb +16 -21
- data/lib/active_support/cache/null_store.rb +1 -4
- data/lib/active_support/cache/strategy/local_cache.rb +31 -20
- data/lib/active_support/cache.rb +73 -89
- data/lib/active_support/callbacks.rb +195 -155
- data/lib/active_support/concern.rb +2 -2
- data/lib/active_support/concurrency/latch.rb +7 -15
- data/lib/active_support/concurrency/share_lock.rb +186 -0
- data/lib/active_support/configurable.rb +1 -0
- data/lib/active_support/core_ext/array/access.rb +27 -1
- data/lib/active_support/core_ext/array/conversions.rb +6 -4
- data/lib/active_support/core_ext/array/grouping.rb +9 -18
- data/lib/active_support/core_ext/array/inquiry.rb +17 -0
- data/lib/active_support/core_ext/array/wrap.rb +5 -4
- data/lib/active_support/core_ext/array.rb +1 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -10
- data/lib/active_support/core_ext/class/attribute.rb +10 -9
- data/lib/active_support/core_ext/class/subclasses.rb +3 -4
- data/lib/active_support/core_ext/class.rb +0 -1
- data/lib/active_support/core_ext/date/blank.rb +12 -0
- data/lib/active_support/core_ext/date/calculations.rb +1 -1
- data/lib/active_support/core_ext/date/conversions.rb +13 -6
- data/lib/active_support/core_ext/date.rb +1 -1
- data/lib/active_support/core_ext/date_and_time/calculations.rb +109 -25
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -0
- data/lib/active_support/core_ext/date_and_time/zones.rb +3 -4
- data/lib/active_support/core_ext/date_time/blank.rb +12 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +36 -10
- data/lib/active_support/core_ext/date_time/compatibility.rb +5 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +2 -0
- data/lib/active_support/core_ext/date_time.rb +2 -1
- data/lib/active_support/core_ext/enumerable.rb +49 -5
- data/lib/active_support/core_ext/file/atomic.rb +30 -25
- data/lib/active_support/core_ext/hash/conversions.rb +23 -4
- data/lib/active_support/core_ext/hash/deep_merge.rb +1 -1
- data/lib/active_support/core_ext/hash/except.rb +9 -8
- data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -1
- data/lib/active_support/core_ext/hash/keys.rb +23 -19
- data/lib/active_support/core_ext/hash/slice.rb +1 -1
- data/lib/active_support/core_ext/hash/transform_values.rb +11 -5
- data/lib/active_support/core_ext/integer/time.rb +1 -16
- data/lib/active_support/core_ext/kernel/concern.rb +2 -0
- data/lib/active_support/core_ext/kernel/debugger.rb +3 -10
- data/lib/active_support/core_ext/kernel/reporting.rb +2 -83
- data/lib/active_support/core_ext/kernel.rb +0 -1
- data/lib/active_support/core_ext/load_error.rb +4 -2
- data/lib/active_support/core_ext/marshal.rb +12 -11
- data/lib/active_support/core_ext/module/aliasing.rb +6 -1
- data/lib/active_support/core_ext/module/anonymous.rb +10 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -5
- data/lib/active_support/core_ext/module/attribute_accessors.rb +15 -15
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +141 -0
- data/lib/active_support/core_ext/module/concerning.rb +4 -4
- data/lib/active_support/core_ext/module/delegation.rb +35 -25
- data/lib/active_support/core_ext/module/deprecation.rb +2 -2
- data/lib/active_support/core_ext/module/introspection.rb +4 -0
- data/lib/active_support/core_ext/module/method_transplanting.rb +3 -11
- data/lib/active_support/core_ext/module/qualified_const.rb +30 -12
- data/lib/active_support/core_ext/module/remove_method.rb +23 -0
- data/lib/active_support/core_ext/module.rb +1 -0
- data/lib/active_support/core_ext/name_error.rb +15 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +20 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +74 -64
- data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
- data/lib/active_support/core_ext/numeric/time.rb +24 -19
- data/lib/active_support/core_ext/numeric.rb +1 -0
- data/lib/active_support/core_ext/object/blank.rb +17 -5
- data/lib/active_support/core_ext/object/deep_dup.rb +10 -3
- data/lib/active_support/core_ext/object/duplicable.rb +8 -13
- data/lib/active_support/core_ext/object/inclusion.rb +2 -2
- data/lib/active_support/core_ext/object/instance_variables.rb +1 -1
- data/lib/active_support/core_ext/object/json.rb +15 -7
- data/lib/active_support/core_ext/object/to_query.rb +1 -1
- data/lib/active_support/core_ext/object/try.rb +68 -22
- data/lib/active_support/core_ext/object/with_options.rb +1 -1
- data/lib/active_support/core_ext/object.rb +0 -1
- data/lib/active_support/core_ext/range/conversions.rb +18 -6
- data/lib/active_support/core_ext/range/each.rb +16 -18
- data/lib/active_support/core_ext/range/include_range.rb +20 -20
- data/lib/active_support/core_ext/securerandom.rb +23 -0
- data/lib/active_support/core_ext/string/access.rb +1 -1
- data/lib/active_support/core_ext/string/behavior.rb +1 -1
- data/lib/active_support/core_ext/string/conversions.rb +4 -3
- data/lib/active_support/core_ext/string/filters.rb +5 -5
- data/lib/active_support/core_ext/string/inflections.rb +32 -5
- data/lib/active_support/core_ext/string/multibyte.rb +11 -7
- data/lib/active_support/core_ext/string/output_safety.rb +18 -16
- data/lib/active_support/core_ext/string/strip.rb +3 -6
- data/lib/active_support/core_ext/struct.rb +3 -6
- data/lib/active_support/core_ext/time/calculations.rb +36 -11
- data/lib/active_support/core_ext/time/compatibility.rb +5 -0
- data/lib/active_support/core_ext/time/conversions.rb +4 -2
- data/lib/active_support/core_ext/time/marshal.rb +2 -29
- data/lib/active_support/core_ext/time/zones.rb +36 -4
- data/lib/active_support/core_ext/time.rb +1 -1
- data/lib/active_support/core_ext/uri.rb +1 -3
- data/lib/active_support/core_ext.rb +2 -1
- data/lib/active_support/dependencies/interlock.rb +51 -0
- data/lib/active_support/dependencies.rb +87 -95
- data/lib/active_support/deprecation/behaviors.rb +16 -2
- data/lib/active_support/deprecation/method_wrappers.rb +42 -16
- data/lib/active_support/deprecation/proxy_wrappers.rb +47 -24
- data/lib/active_support/deprecation/reporting.rb +23 -5
- data/lib/active_support/deprecation.rb +1 -1
- data/lib/active_support/duration/iso8601_parser.rb +122 -0
- data/lib/active_support/duration/iso8601_serializer.rb +51 -0
- data/lib/active_support/duration.rb +55 -10
- data/lib/active_support/evented_file_update_checker.rb +194 -0
- data/lib/active_support/execution_wrapper.rb +117 -0
- data/lib/active_support/executor.rb +6 -0
- data/lib/active_support/file_update_checker.rb +23 -3
- data/lib/active_support/gem_version.rb +3 -3
- data/lib/active_support/hash_with_indifferent_access.rb +46 -13
- data/lib/active_support/i18n_railtie.rb +25 -4
- data/lib/active_support/inflector/inflections.rb +36 -5
- data/lib/active_support/inflector/methods.rb +97 -90
- data/lib/active_support/inflector/transliterate.rb +36 -21
- data/lib/active_support/json/decoding.rb +11 -10
- data/lib/active_support/json/encoding.rb +4 -49
- data/lib/active_support/key_generator.rb +7 -9
- data/lib/active_support/locale/en.yml +2 -0
- data/lib/active_support/log_subscriber/test_helper.rb +3 -3
- data/lib/active_support/log_subscriber.rb +1 -1
- data/lib/active_support/logger.rb +50 -1
- data/lib/active_support/logger_silence.rb +8 -4
- data/lib/active_support/logger_thread_safe_level.rb +31 -0
- data/lib/active_support/message_encryptor.rb +4 -4
- data/lib/active_support/message_verifier.rb +70 -8
- data/lib/active_support/multibyte/chars.rb +13 -4
- data/lib/active_support/multibyte/unicode.rb +44 -21
- data/lib/active_support/notifications/fanout.rb +6 -6
- data/lib/active_support/notifications/instrumenter.rb +20 -2
- data/lib/active_support/notifications.rb +2 -2
- data/lib/active_support/number_helper/number_to_currency_converter.rb +7 -9
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +8 -3
- data/lib/active_support/number_helper/number_to_human_converter.rb +6 -4
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +6 -2
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +11 -2
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +30 -25
- data/lib/active_support/number_helper.rb +90 -67
- data/lib/active_support/ordered_hash.rb +1 -1
- data/lib/active_support/ordered_options.rb +15 -1
- data/lib/active_support/per_thread_registry.rb +8 -3
- data/lib/active_support/rails.rb +2 -2
- data/lib/active_support/railtie.rb +6 -1
- data/lib/active_support/reloader.rb +129 -0
- data/lib/active_support/rescuable.rb +93 -47
- data/lib/active_support/security_utils.rb +7 -0
- data/lib/active_support/string_inquirer.rb +1 -1
- data/lib/active_support/subscriber.rb +5 -10
- data/lib/active_support/tagged_logging.rb +3 -1
- data/lib/active_support/test_case.rb +15 -29
- data/lib/active_support/testing/assertions.rb +15 -13
- data/lib/active_support/testing/autorun.rb +8 -1
- data/lib/active_support/testing/deprecation.rb +9 -8
- data/lib/active_support/testing/file_fixtures.rb +34 -0
- data/lib/active_support/testing/isolation.rb +22 -8
- data/lib/active_support/testing/method_call_assertions.rb +41 -0
- data/lib/active_support/testing/stream.rb +42 -0
- data/lib/active_support/testing/time_helpers.rb +13 -10
- data/lib/active_support/time_with_zone.rb +135 -46
- data/lib/active_support/values/time_zone.rb +95 -47
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/xml_mini/jdom.rb +7 -6
- data/lib/active_support/xml_mini/libxml.rb +2 -2
- data/lib/active_support/xml_mini/nokogiri.rb +2 -2
- data/lib/active_support/xml_mini/rexml.rb +7 -8
- data/lib/active_support/xml_mini.rb +22 -14
- data/lib/active_support.rb +20 -6
- metadata +32 -35
- data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -14
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
- data/lib/active_support/core_ext/date_time/zones.rb +0 -6
- data/lib/active_support/core_ext/object/itself.rb +0 -15
- 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
|
-
|
168
|
-
|
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
|
-
# '
|
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
|
-
#
|
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
|
-
# '
|
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
|
-
#
|
14
|
-
#
|
15
|
-
#
|
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 = { '&' => '&', '>' => '>', '<' => '<', '"' => '"', "'" => ''' }
|
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 > 0 & a < 10?
|
@@ -38,7 +36,7 @@ class ERB
|
|
38
36
|
if s.html_safe?
|
39
37
|
s
|
40
38
|
else
|
41
|
-
|
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('<< Accept & Checkout')
|
52
50
|
# # => "<< Accept & 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
|
-
|
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.
|
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
|
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
|
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
|
-
|
24
|
-
gsub(/^[ \t]{#{indent}}/, '')
|
21
|
+
gsub(/^#{scan(/^[ \t]*(?=\S)/).min}/, ''.freeze)
|
25
22
|
end
|
26
23
|
end
|
@@ -1,6 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
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
|
-
#
|
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 =
|
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
|
-
#
|
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>.
|
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
|
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
|
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
|
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
|
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
|
246
|
-
if other.
|
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
|
@@ -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 # =>
|
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
|
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
|
-
|
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
|
-
|
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
|
-
#
|
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;
|
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
|
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
|
-
#
|
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) { [
|
13
|
+
str.gsub(escaped) { |match| [match[1, 2].hex].pack('C') }.force_encoding(enc)
|
16
14
|
end
|
17
15
|
end
|
18
16
|
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
|