activesupport 4.2.11.3 → 5.0.7.2
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 +678 -348
- 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/strategy/local_cache_middleware.rb +4 -4
- data/lib/active_support/cache.rb +71 -87
- data/lib/active_support/callbacks.rb +109 -113
- data/lib/active_support/concern.rb +1 -1
- data/lib/active_support/concurrency/latch.rb +11 -12
- data/lib/active_support/concurrency/share_lock.rb +226 -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 -2
- 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 +7 -6
- data/lib/active_support/core_ext/date.rb +1 -1
- data/lib/active_support/core_ext/date_and_time/calculations.rb +100 -27
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +0 -1
- 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 +14 -8
- data/lib/active_support/core_ext/date_time/conversions.rb +2 -0
- data/lib/active_support/core_ext/date_time.rb +1 -1
- data/lib/active_support/core_ext/enumerable.rb +75 -25
- data/lib/active_support/core_ext/file/atomic.rb +30 -25
- data/lib/active_support/core_ext/hash/conversions.rb +22 -2
- 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 +25 -21
- 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 +2 -2
- 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 -84
- data/lib/active_support/core_ext/kernel.rb +0 -1
- data/lib/active_support/core_ext/load_error.rb +5 -2
- data/lib/active_support/core_ext/marshal.rb +7 -9
- 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 +11 -20
- data/lib/active_support/core_ext/module/deprecation.rb +2 -2
- data/lib/active_support/core_ext/module/introspection.rb +8 -2
- data/lib/active_support/core_ext/module/method_transplanting.rb +3 -13
- 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 +78 -77
- data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
- data/lib/active_support/core_ext/numeric/time.rb +26 -6
- data/lib/active_support/core_ext/numeric.rb +1 -0
- data/lib/active_support/core_ext/object/blank.rb +15 -3
- data/lib/active_support/core_ext/object/deep_dup.rb +10 -3
- data/lib/active_support/core_ext/object/duplicable.rb +7 -12
- 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 +67 -21
- 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/behavior.rb +1 -1
- data/lib/active_support/core_ext/string/conversions.rb +3 -2
- data/lib/active_support/core_ext/string/filters.rb +1 -2
- 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 +12 -14
- 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 +18 -9
- 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 +0 -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 +55 -0
- data/lib/active_support/dependencies.rb +88 -95
- data/lib/active_support/deprecation/behaviors.rb +15 -1
- data/lib/active_support/deprecation/instance_delegator.rb +13 -0
- 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 +90 -15
- data/lib/active_support/evented_file_update_checker.rb +199 -0
- data/lib/active_support/execution_wrapper.rb +126 -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 +5 -5
- data/lib/active_support/gzip.rb +1 -1
- data/lib/active_support/hash_with_indifferent_access.rb +40 -11
- 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 +1 -51
- data/lib/active_support/key_generator.rb +7 -9
- data/lib/active_support/lazy_load_hooks.rb +46 -18
- 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 +3 -4
- data/lib/active_support/logger_silence.rb +2 -1
- data/lib/active_support/logger_thread_safe_level.rb +2 -3
- data/lib/active_support/message_encryptor.rb +7 -7
- data/lib/active_support/message_verifier.rb +70 -8
- data/lib/active_support/multibyte/chars.rb +12 -3
- data/lib/active_support/multibyte/unicode.rb +44 -21
- data/lib/active_support/notifications/fanout.rb +5 -5
- 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 +3 -0
- 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 +101 -47
- data/lib/active_support/string_inquirer.rb +1 -1
- data/lib/active_support/subscriber.rb +5 -10
- data/lib/active_support/tagged_logging.rb +8 -7
- data/lib/active_support/test_case.rb +17 -29
- data/lib/active_support/testing/assertions.rb +15 -13
- 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 +3 -1
- data/lib/active_support/time_with_zone.rb +123 -33
- data/lib/active_support/values/time_zone.rb +101 -47
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/xml_mini/jdom.rb +1 -1
- data/lib/active_support/xml_mini/libxml.rb +2 -2
- data/lib/active_support/xml_mini/nokogiri.rb +2 -2
- data/lib/active_support.rb +11 -6
- metadata +36 -17
- data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
- 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
@@ -1,27 +1,50 @@
|
|
1
1
|
module Enumerable
|
2
|
-
#
|
2
|
+
# Enumerable#sum was added in Ruby 2.4 but it only works with Numeric elements
|
3
|
+
# when we omit an identity.
|
3
4
|
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
5
|
+
# We tried shimming it to attempt the fast native method, rescue TypeError,
|
6
|
+
# and fall back to the compatible implementation, but that's much slower than
|
7
|
+
# just calling the compat method in the first place.
|
8
|
+
if Enumerable.instance_methods(false).include?(:sum) && !((?a..?b).sum rescue false)
|
9
|
+
# We can't use Refinements here because Refinements with Module which will be prepended
|
10
|
+
# doesn't work well https://bugs.ruby-lang.org/issues/13446
|
11
|
+
alias :_original_sum_with_required_identity :sum
|
12
|
+
private :_original_sum_with_required_identity
|
13
|
+
# Calculates a sum from the elements.
|
14
|
+
#
|
15
|
+
# payments.sum { |p| p.price * p.tax_rate }
|
16
|
+
# payments.sum(&:price)
|
17
|
+
#
|
18
|
+
# The latter is a shortcut for:
|
19
|
+
#
|
20
|
+
# payments.inject(0) { |sum, p| sum + p.price }
|
21
|
+
#
|
22
|
+
# It can also calculate the sum without the use of a block.
|
23
|
+
#
|
24
|
+
# [5, 15, 10].sum # => 30
|
25
|
+
# ['foo', 'bar'].sum # => "foobar"
|
26
|
+
# [[1, 2], [3, 1, 5]].sum # => [1, 2, 3, 1, 5]
|
27
|
+
#
|
28
|
+
# The default sum of an empty list is zero. You can override this default:
|
29
|
+
#
|
30
|
+
# [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)
|
31
|
+
def sum(identity = nil, &block)
|
32
|
+
if identity
|
33
|
+
_original_sum_with_required_identity(identity, &block)
|
34
|
+
elsif block_given?
|
35
|
+
map(&block).sum(identity)
|
36
|
+
else
|
37
|
+
inject(:+) || 0
|
38
|
+
end
|
39
|
+
end
|
40
|
+
else
|
41
|
+
def sum(identity = nil, &block)
|
42
|
+
if block_given?
|
43
|
+
map(&block).sum(identity)
|
44
|
+
else
|
45
|
+
sum = identity ? inject(identity, :+) : inject(:+)
|
46
|
+
sum || identity || 0
|
47
|
+
end
|
25
48
|
end
|
26
49
|
end
|
27
50
|
|
@@ -60,20 +83,47 @@ module Enumerable
|
|
60
83
|
def exclude?(object)
|
61
84
|
!include?(object)
|
62
85
|
end
|
86
|
+
|
87
|
+
# Returns a copy of the enumerable without the specified elements.
|
88
|
+
#
|
89
|
+
# ["David", "Rafael", "Aaron", "Todd"].without "Aaron", "Todd"
|
90
|
+
# => ["David", "Rafael"]
|
91
|
+
#
|
92
|
+
# {foo: 1, bar: 2, baz: 3}.without :bar
|
93
|
+
# => {foo: 1, baz: 3}
|
94
|
+
def without(*elements)
|
95
|
+
reject { |element| elements.include?(element) }
|
96
|
+
end
|
97
|
+
|
98
|
+
# Convert an enumerable to an array based on the given key.
|
99
|
+
#
|
100
|
+
# [{ name: "David" }, { name: "Rafael" }, { name: "Aaron" }].pluck(:name)
|
101
|
+
# => ["David", "Rafael", "Aaron"]
|
102
|
+
#
|
103
|
+
# [{ id: 1, name: "David" }, { id: 2, name: "Rafael" }].pluck(:id, :name)
|
104
|
+
# => [[1, "David"], [2, "Rafael"]]
|
105
|
+
def pluck(*keys)
|
106
|
+
if keys.many?
|
107
|
+
map { |element| keys.map { |key| element[key] } }
|
108
|
+
else
|
109
|
+
map { |element| element[keys.first] }
|
110
|
+
end
|
111
|
+
end
|
63
112
|
end
|
64
113
|
|
65
114
|
class Range #:nodoc:
|
66
115
|
# Optimize range sum to use arithmetic progression if a block is not given and
|
67
116
|
# we have a range of numeric values.
|
68
|
-
def sum(identity =
|
117
|
+
def sum(identity = nil)
|
69
118
|
if block_given? || !(first.is_a?(Integer) && last.is_a?(Integer))
|
70
119
|
super
|
71
120
|
else
|
72
121
|
actual_last = exclude_end? ? (last - 1) : last
|
73
122
|
if actual_last >= first
|
74
|
-
|
123
|
+
sum = identity || 0
|
124
|
+
sum + (actual_last - first + 1) * (actual_last + first) / 2
|
75
125
|
else
|
76
|
-
identity
|
126
|
+
identity || 0
|
77
127
|
end
|
78
128
|
end
|
79
129
|
end
|
@@ -8,40 +8,45 @@ class File
|
|
8
8
|
# file.write('hello')
|
9
9
|
# end
|
10
10
|
#
|
11
|
-
#
|
12
|
-
#
|
11
|
+
# This method needs to create a temporary file. By default it will create it
|
12
|
+
# in the same directory as the destination file. If you don't like this
|
13
|
+
# behavior you can provide a different directory but it must be on the
|
14
|
+
# same physical filesystem as the file you're trying to write.
|
13
15
|
#
|
14
16
|
# File.atomic_write('/data/something.important', '/data/tmp') do |file|
|
15
17
|
# file.write('hello')
|
16
18
|
# end
|
17
|
-
def self.atomic_write(file_name, temp_dir =
|
19
|
+
def self.atomic_write(file_name, temp_dir = dirname(file_name))
|
18
20
|
require 'tempfile' unless defined?(Tempfile)
|
19
|
-
require 'fileutils' unless defined?(FileUtils)
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
Tempfile.open(".#{basename(file_name)}", temp_dir) do |temp_file|
|
23
|
+
temp_file.binmode
|
24
|
+
return_val = yield temp_file
|
25
|
+
temp_file.close
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
27
|
+
old_stat = if exist?(file_name)
|
28
|
+
# Get original file permissions
|
29
|
+
stat(file_name)
|
30
|
+
elsif temp_dir != dirname(file_name)
|
31
|
+
# If not possible, probe which are the default permissions in the
|
32
|
+
# destination directory.
|
33
|
+
probe_stat_in(dirname(file_name))
|
34
|
+
end
|
34
35
|
|
35
|
-
|
36
|
-
|
36
|
+
if old_stat
|
37
|
+
# Set correct permissions on new file
|
38
|
+
begin
|
39
|
+
chown(old_stat.uid, old_stat.gid, temp_file.path)
|
40
|
+
# This operation will affect filesystem ACL's
|
41
|
+
chmod(old_stat.mode, temp_file.path)
|
42
|
+
rescue Errno::EPERM, Errno::EACCES
|
43
|
+
# Changing file ownership failed, moving on.
|
44
|
+
end
|
45
|
+
end
|
37
46
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
# This operation will affect filesystem ACL's
|
42
|
-
chmod(old_stat.mode, file_name)
|
43
|
-
rescue Errno::EPERM, Errno::EACCES
|
44
|
-
# Changing file ownership failed, moving on.
|
47
|
+
# Overwrite original file with temp file
|
48
|
+
rename(temp_file.path, file_name)
|
49
|
+
return_val
|
45
50
|
end
|
46
51
|
end
|
47
52
|
|
@@ -31,7 +31,7 @@ class Hash
|
|
31
31
|
# with +key+ as <tt>:root</tt>, and +key+ singularized as second argument. The
|
32
32
|
# callable can add nodes by using <tt>options[:builder]</tt>.
|
33
33
|
#
|
34
|
-
#
|
34
|
+
# {foo: lambda { |options, key| options[:builder].b(key) }}.to_xml
|
35
35
|
# # => "<b>foo</b>"
|
36
36
|
#
|
37
37
|
# * If +value+ responds to +to_xml+ the method is invoked with +key+ as <tt>:root</tt>.
|
@@ -105,7 +105,25 @@ class Hash
|
|
105
105
|
# # => {"hash"=>{"foo"=>1, "bar"=>2}}
|
106
106
|
#
|
107
107
|
# +DisallowedType+ is raised if the XML contains attributes with <tt>type="yaml"</tt> or
|
108
|
-
# <tt>type="symbol"</tt>. Use <tt>Hash.from_trusted_xml</tt> to
|
108
|
+
# <tt>type="symbol"</tt>. Use <tt>Hash.from_trusted_xml</tt> to
|
109
|
+
# parse this XML.
|
110
|
+
#
|
111
|
+
# Custom +disallowed_types+ can also be passed in the form of an
|
112
|
+
# array.
|
113
|
+
#
|
114
|
+
# xml = <<-XML
|
115
|
+
# <?xml version="1.0" encoding="UTF-8"?>
|
116
|
+
# <hash>
|
117
|
+
# <foo type="integer">1</foo>
|
118
|
+
# <bar type="string">"David"</bar>
|
119
|
+
# </hash>
|
120
|
+
# XML
|
121
|
+
#
|
122
|
+
# hash = Hash.from_xml(xml, ['integer'])
|
123
|
+
# # => ActiveSupport::XMLConverter::DisallowedType: Disallowed type attribute: "integer"
|
124
|
+
#
|
125
|
+
# Note that passing custom disallowed types will override the default types,
|
126
|
+
# which are Symbol and YAML.
|
109
127
|
def from_xml(xml, disallowed_types = nil)
|
110
128
|
ActiveSupport::XMLConverter.new(xml, disallowed_types).to_h
|
111
129
|
end
|
@@ -119,6 +137,8 @@ end
|
|
119
137
|
|
120
138
|
module ActiveSupport
|
121
139
|
class XMLConverter # :nodoc:
|
140
|
+
# Raised if the XML contains attributes with type="yaml" or
|
141
|
+
# type="symbol". Read Hash#from_xml for more details.
|
122
142
|
class DisallowedType < StandardError
|
123
143
|
def initialize(type)
|
124
144
|
super "Disallowed type attribute: #{type.inspect}"
|
@@ -4,7 +4,7 @@ class Hash
|
|
4
4
|
# h1 = { a: true, b: { c: [1, 2, 3] } }
|
5
5
|
# h2 = { a: false, b: { x: [3, 4, 5] } }
|
6
6
|
#
|
7
|
-
# h1.deep_merge(h2)
|
7
|
+
# h1.deep_merge(h2) # => { a: false, b: { c: [1, 2, 3], x: [3, 4, 5] } }
|
8
8
|
#
|
9
9
|
# Like with Hash#merge in the standard library, a block can be provided
|
10
10
|
# to merge values:
|
@@ -1,8 +1,9 @@
|
|
1
1
|
class Hash
|
2
|
-
# Returns a hash that includes everything
|
3
|
-
# hash = { a: true, b: false, c: nil}
|
4
|
-
# hash.except(:c)
|
5
|
-
# hash # => {
|
2
|
+
# Returns a hash that includes everything except given keys.
|
3
|
+
# hash = { a: true, b: false, c: nil }
|
4
|
+
# hash.except(:c) # => { a: true, b: false }
|
5
|
+
# hash.except(:a, :b) # => { c: nil }
|
6
|
+
# hash # => { a: true, b: false, c: nil }
|
6
7
|
#
|
7
8
|
# This is useful for limiting a set of parameters to everything but a few known toggles:
|
8
9
|
# @person.update(params[:person].except(:admin))
|
@@ -10,10 +11,10 @@ class Hash
|
|
10
11
|
dup.except!(*keys)
|
11
12
|
end
|
12
13
|
|
13
|
-
#
|
14
|
-
# hash = { a: true, b: false, c: nil}
|
15
|
-
# hash.except!(:c) # => { a: true, b: false}
|
16
|
-
# hash
|
14
|
+
# Removes the given keys from hash and returns it.
|
15
|
+
# hash = { a: true, b: false, c: nil }
|
16
|
+
# hash.except!(:c) # => { a: true, b: false }
|
17
|
+
# hash # => { a: true, b: false }
|
17
18
|
def except!(*keys)
|
18
19
|
keys.each { |key| delete(key) }
|
19
20
|
self
|
@@ -6,7 +6,7 @@ class Hash
|
|
6
6
|
#
|
7
7
|
# { a: 1 }.with_indifferent_access['a'] # => 1
|
8
8
|
def with_indifferent_access
|
9
|
-
ActiveSupport::HashWithIndifferentAccess.
|
9
|
+
ActiveSupport::HashWithIndifferentAccess.new(self)
|
10
10
|
end
|
11
11
|
|
12
12
|
# Called when object is nested under an object that receives
|
@@ -1,28 +1,32 @@
|
|
1
1
|
class Hash
|
2
|
-
# Returns a new hash with all keys converted using the block operation.
|
2
|
+
# Returns a new hash with all keys converted using the +block+ operation.
|
3
3
|
#
|
4
4
|
# hash = { name: 'Rob', age: '28' }
|
5
5
|
#
|
6
|
-
# hash.transform_keys{ |key| key.to_s.upcase }
|
7
|
-
#
|
6
|
+
# hash.transform_keys { |key| key.to_s.upcase } # => {"NAME"=>"Rob", "AGE"=>"28"}
|
7
|
+
#
|
8
|
+
# If you do not provide a +block+, it will return an Enumerator
|
9
|
+
# for chaining with other methods:
|
10
|
+
#
|
11
|
+
# hash.transform_keys.with_index { |k, i| [k, i].join } # => {"name0"=>"Rob", "age1"=>"28"}
|
8
12
|
def transform_keys
|
9
|
-
return enum_for(:transform_keys) unless block_given?
|
10
|
-
result =
|
13
|
+
return enum_for(:transform_keys) { size } unless block_given?
|
14
|
+
result = {}
|
11
15
|
each_key do |key|
|
12
16
|
result[yield(key)] = self[key]
|
13
17
|
end
|
14
18
|
result
|
15
|
-
end
|
19
|
+
end unless method_defined? :transform_keys
|
16
20
|
|
17
|
-
# Destructively
|
18
|
-
# Same as transform_keys but modifies +self+.
|
21
|
+
# Destructively converts all keys using the +block+ operations.
|
22
|
+
# Same as +transform_keys+ but modifies +self+.
|
19
23
|
def transform_keys!
|
20
|
-
return enum_for(:transform_keys!) unless block_given?
|
24
|
+
return enum_for(:transform_keys!) { size } unless block_given?
|
21
25
|
keys.each do |key|
|
22
26
|
self[yield(key)] = delete(key)
|
23
27
|
end
|
24
28
|
self
|
25
|
-
end
|
29
|
+
end unless method_defined? :transform_keys!
|
26
30
|
|
27
31
|
# Returns a new hash with all keys converted to strings.
|
28
32
|
#
|
@@ -31,13 +35,13 @@ class Hash
|
|
31
35
|
# hash.stringify_keys
|
32
36
|
# # => {"name"=>"Rob", "age"=>"28"}
|
33
37
|
def stringify_keys
|
34
|
-
transform_keys
|
38
|
+
transform_keys(&:to_s)
|
35
39
|
end
|
36
40
|
|
37
|
-
# Destructively
|
41
|
+
# Destructively converts all keys to strings. Same as
|
38
42
|
# +stringify_keys+, but modifies +self+.
|
39
43
|
def stringify_keys!
|
40
|
-
transform_keys!
|
44
|
+
transform_keys!(&:to_s)
|
41
45
|
end
|
42
46
|
|
43
47
|
# Returns a new hash with all keys converted to symbols, as long as
|
@@ -52,15 +56,15 @@ class Hash
|
|
52
56
|
end
|
53
57
|
alias_method :to_options, :symbolize_keys
|
54
58
|
|
55
|
-
# Destructively
|
59
|
+
# Destructively converts all keys to symbols, as long as they respond
|
56
60
|
# to +to_sym+. Same as +symbolize_keys+, but modifies +self+.
|
57
61
|
def symbolize_keys!
|
58
62
|
transform_keys!{ |key| key.to_sym rescue key }
|
59
63
|
end
|
60
64
|
alias_method :to_options!, :symbolize_keys!
|
61
65
|
|
62
|
-
#
|
63
|
-
# ArgumentError on a mismatch.
|
66
|
+
# Validates all keys in a hash match <tt>*valid_keys</tt>, raising
|
67
|
+
# +ArgumentError+ on a mismatch.
|
64
68
|
#
|
65
69
|
# Note that keys are treated differently than HashWithIndifferentAccess,
|
66
70
|
# meaning that string and symbol keys will not match.
|
@@ -89,7 +93,7 @@ class Hash
|
|
89
93
|
_deep_transform_keys_in_object(self, &block)
|
90
94
|
end
|
91
95
|
|
92
|
-
# Destructively
|
96
|
+
# Destructively converts all keys by using the block operation.
|
93
97
|
# This includes the keys from the root hash and from all
|
94
98
|
# nested hashes and arrays.
|
95
99
|
def deep_transform_keys!(&block)
|
@@ -105,14 +109,14 @@ class Hash
|
|
105
109
|
# hash.deep_stringify_keys
|
106
110
|
# # => {"person"=>{"name"=>"Rob", "age"=>"28"}}
|
107
111
|
def deep_stringify_keys
|
108
|
-
deep_transform_keys
|
112
|
+
deep_transform_keys(&:to_s)
|
109
113
|
end
|
110
114
|
|
111
|
-
# Destructively
|
115
|
+
# Destructively converts all keys to strings.
|
112
116
|
# This includes the keys from the root hash and from all
|
113
117
|
# nested hashes and arrays.
|
114
118
|
def deep_stringify_keys!
|
115
|
-
deep_transform_keys!
|
119
|
+
deep_transform_keys!(&:to_s)
|
116
120
|
end
|
117
121
|
|
118
122
|
# Returns a new hash with all keys converted to symbols, as long as
|
@@ -127,7 +131,7 @@ class Hash
|
|
127
131
|
deep_transform_keys{ |key| key.to_sym rescue key }
|
128
132
|
end
|
129
133
|
|
130
|
-
# Destructively
|
134
|
+
# Destructively converts all keys to symbols, as long as they respond
|
131
135
|
# to +to_sym+. This includes the keys from the root hash and from all
|
132
136
|
# nested hashes and arrays.
|
133
137
|
def deep_symbolize_keys!
|
@@ -2,10 +2,15 @@ class Hash
|
|
2
2
|
# Returns a new hash with the results of running +block+ once for every value.
|
3
3
|
# The keys are unchanged.
|
4
4
|
#
|
5
|
-
# { a: 1, b: 2, c: 3 }.transform_values { |x| x * 2 }
|
6
|
-
#
|
5
|
+
# { a: 1, b: 2, c: 3 }.transform_values { |x| x * 2 } # => { a: 2, b: 4, c: 6 }
|
6
|
+
#
|
7
|
+
# If you do not provide a +block+, it will return an Enumerator
|
8
|
+
# for chaining with other methods:
|
9
|
+
#
|
10
|
+
# { a: 1, b: 2 }.transform_values.with_index { |v, i| [v, i].join.to_i } # => { a: 10, b: 21 }
|
7
11
|
def transform_values
|
8
|
-
return enum_for(:transform_values) unless block_given?
|
12
|
+
return enum_for(:transform_values) { size } unless block_given?
|
13
|
+
return {} if empty?
|
9
14
|
result = self.class.new
|
10
15
|
each do |key, value|
|
11
16
|
result[key] = yield(value)
|
@@ -13,9 +18,10 @@ class Hash
|
|
13
18
|
result
|
14
19
|
end unless method_defined? :transform_values
|
15
20
|
|
16
|
-
#
|
21
|
+
# Destructively converts all values using the +block+ operations.
|
22
|
+
# Same as +transform_values+ but modifies +self+.
|
17
23
|
def transform_values!
|
18
|
-
return enum_for(:transform_values!) unless block_given?
|
24
|
+
return enum_for(:transform_values!) { size } unless block_given?
|
19
25
|
each do |key, value|
|
20
26
|
self[key] = yield(value)
|
21
27
|
end
|
@@ -18,12 +18,12 @@ class Integer
|
|
18
18
|
# # equivalent to Time.now.advance(months: 4, years: 5)
|
19
19
|
# (4.months + 5.years).from_now
|
20
20
|
def months
|
21
|
-
ActiveSupport::Duration.
|
21
|
+
ActiveSupport::Duration.months(self)
|
22
22
|
end
|
23
23
|
alias :month :months
|
24
24
|
|
25
25
|
def years
|
26
|
-
ActiveSupport::Duration.
|
26
|
+
ActiveSupport::Duration.years(self)
|
27
27
|
end
|
28
28
|
alias :year :years
|
29
29
|
end
|
@@ -1,10 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
def debugger
|
5
|
-
message = "\n***** Debugger requested, but was not available (ensure the debugger gem is listed in Gemfile/installed as gem): Start server with --debugger to enable *****\n"
|
6
|
-
defined?(Rails.logger) ? Rails.logger.info(message) : $stderr.puts(message)
|
7
|
-
end
|
8
|
-
alias breakpoint debugger unless respond_to?(:breakpoint)
|
9
|
-
end
|
10
|
-
end
|
1
|
+
require 'active_support/deprecation'
|
2
|
+
|
3
|
+
ActiveSupport::Deprecation.warn("This file is deprecated and will be removed in Rails 5.1 with no replacement.")
|
@@ -1,8 +1,6 @@
|
|
1
|
-
require 'rbconfig'
|
2
|
-
require 'tempfile'
|
3
|
-
require 'active_support/deprecation'
|
4
|
-
|
5
1
|
module Kernel
|
2
|
+
module_function
|
3
|
+
|
6
4
|
# Sets $VERBOSE to nil for the duration of the block and back to its original
|
7
5
|
# value afterwards.
|
8
6
|
#
|
@@ -30,34 +28,6 @@ module Kernel
|
|
30
28
|
$VERBOSE = old_verbose
|
31
29
|
end
|
32
30
|
|
33
|
-
# For compatibility
|
34
|
-
def silence_stderr #:nodoc:
|
35
|
-
ActiveSupport::Deprecation.warn(
|
36
|
-
"`#silence_stderr` is deprecated and will be removed in the next release."
|
37
|
-
) #not thread-safe
|
38
|
-
silence_stream(STDERR) { yield }
|
39
|
-
end
|
40
|
-
|
41
|
-
# Deprecated : this method is not thread safe
|
42
|
-
# Silences any stream for the duration of the block.
|
43
|
-
#
|
44
|
-
# silence_stream(STDOUT) do
|
45
|
-
# puts 'This will never be seen'
|
46
|
-
# end
|
47
|
-
#
|
48
|
-
# puts 'But this will'
|
49
|
-
#
|
50
|
-
# This method is not thread-safe.
|
51
|
-
def silence_stream(stream)
|
52
|
-
old_stream = stream.dup
|
53
|
-
stream.reopen(RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ ? 'NUL:' : '/dev/null')
|
54
|
-
stream.sync = true
|
55
|
-
yield
|
56
|
-
ensure
|
57
|
-
stream.reopen(old_stream)
|
58
|
-
old_stream.close
|
59
|
-
end
|
60
|
-
|
61
31
|
# Blocks and ignores any exception passed as argument if raised within the block.
|
62
32
|
#
|
63
33
|
# suppress(ZeroDivisionError) do
|
@@ -70,56 +40,4 @@ module Kernel
|
|
70
40
|
yield
|
71
41
|
rescue *exception_classes
|
72
42
|
end
|
73
|
-
|
74
|
-
# Captures the given stream and returns it:
|
75
|
-
#
|
76
|
-
# stream = capture(:stdout) { puts 'notice' }
|
77
|
-
# stream # => "notice\n"
|
78
|
-
#
|
79
|
-
# stream = capture(:stderr) { warn 'error' }
|
80
|
-
# stream # => "error\n"
|
81
|
-
#
|
82
|
-
# even for subprocesses:
|
83
|
-
#
|
84
|
-
# stream = capture(:stdout) { system('echo notice') }
|
85
|
-
# stream # => "notice\n"
|
86
|
-
#
|
87
|
-
# stream = capture(:stderr) { system('echo error 1>&2') }
|
88
|
-
# stream # => "error\n"
|
89
|
-
def capture(stream)
|
90
|
-
ActiveSupport::Deprecation.warn(
|
91
|
-
"`#capture(stream)` is deprecated and will be removed in the next release."
|
92
|
-
) #not thread-safe
|
93
|
-
stream = stream.to_s
|
94
|
-
captured_stream = Tempfile.new(stream)
|
95
|
-
stream_io = eval("$#{stream}")
|
96
|
-
origin_stream = stream_io.dup
|
97
|
-
stream_io.reopen(captured_stream)
|
98
|
-
|
99
|
-
yield
|
100
|
-
|
101
|
-
stream_io.rewind
|
102
|
-
return captured_stream.read
|
103
|
-
ensure
|
104
|
-
captured_stream.close
|
105
|
-
captured_stream.unlink
|
106
|
-
stream_io.reopen(origin_stream)
|
107
|
-
end
|
108
|
-
alias :silence :capture
|
109
|
-
|
110
|
-
# Silences both STDOUT and STDERR, even for subprocesses.
|
111
|
-
#
|
112
|
-
# quietly { system 'bundle install' }
|
113
|
-
#
|
114
|
-
# This method is not thread-safe.
|
115
|
-
def quietly
|
116
|
-
ActiveSupport::Deprecation.warn(
|
117
|
-
"`#quietly` is deprecated and will be removed in the next release."
|
118
|
-
) #not thread-safe
|
119
|
-
silence_stream(STDOUT) do
|
120
|
-
silence_stream(STDERR) do
|
121
|
-
yield
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
43
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'active_support/core_ext/kernel/agnostics'
|
2
2
|
require 'active_support/core_ext/kernel/concern'
|
3
|
-
require 'active_support/core_ext/kernel/debugger' if RUBY_VERSION < '2.0.0'
|
4
3
|
require 'active_support/core_ext/kernel/reporting'
|
5
4
|
require 'active_support/core_ext/kernel/singleton_class'
|
@@ -1,3 +1,6 @@
|
|
1
|
+
require "active_support/deprecation"
|
2
|
+
require "active_support/deprecation/proxy_wrappers"
|
3
|
+
|
1
4
|
class LoadError
|
2
5
|
REGEXPS = [
|
3
6
|
/^no such file to load -- (.+)$/i,
|
@@ -21,8 +24,8 @@ class LoadError
|
|
21
24
|
# Returns true if the given path name (except perhaps for the ".rb"
|
22
25
|
# extension) is the missing file which caused the exception to be raised.
|
23
26
|
def is_missing?(location)
|
24
|
-
location.sub(/\.rb$/, '') == path.sub(/\.rb$/, '')
|
27
|
+
location.sub(/\.rb$/, ''.freeze) == path.sub(/\.rb$/, ''.freeze)
|
25
28
|
end
|
26
29
|
end
|
27
30
|
|
28
|
-
MissingSourceFile = LoadError
|
31
|
+
MissingSourceFile = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('MissingSourceFile', 'LoadError')
|
@@ -1,11 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
def load_with_autoloading(source, proc = nil)
|
6
|
-
load_without_autoloading(source, proc)
|
1
|
+
module ActiveSupport
|
2
|
+
module MarshalWithAutoloading # :nodoc:
|
3
|
+
def load(source, proc = nil)
|
4
|
+
super(source, proc)
|
7
5
|
rescue ArgumentError, NameError => exc
|
8
|
-
if exc.message.match(%r|undefined class/module (.+?)(
|
6
|
+
if exc.message.match(%r|undefined class/module (.+?)(?:::)?\z|)
|
9
7
|
# try loading the class/module
|
10
8
|
loaded = $1.constantize
|
11
9
|
|
@@ -18,7 +16,7 @@ module Marshal
|
|
18
16
|
raise exc
|
19
17
|
end
|
20
18
|
end
|
21
|
-
|
22
|
-
alias_method_chain :load, :autoloading
|
23
19
|
end
|
24
20
|
end
|
21
|
+
|
22
|
+
Marshal.singleton_class.prepend(ActiveSupport::MarshalWithAutoloading)
|
@@ -1,4 +1,7 @@
|
|
1
1
|
class Module
|
2
|
+
# NOTE: This method is deprecated. Please use <tt>Module#prepend</tt> that
|
3
|
+
# comes with Ruby 2.0 or newer instead.
|
4
|
+
#
|
2
5
|
# Encapsulates the common pattern of:
|
3
6
|
#
|
4
7
|
# alias_method :foo_without_feature, :foo
|
@@ -21,6 +24,8 @@ class Module
|
|
21
24
|
#
|
22
25
|
# so you can safely chain foo, foo?, foo! and/or foo= with the same feature.
|
23
26
|
def alias_method_chain(target, feature)
|
27
|
+
ActiveSupport::Deprecation.warn("alias_method_chain is deprecated. Please, use Module#prepend instead. From module, you can access the original method using super.")
|
28
|
+
|
24
29
|
# Strip out punctuation on predicates, bang or writer methods since
|
25
30
|
# e.g. target?_without_feature is not a valid method name.
|
26
31
|
aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
|
@@ -43,7 +48,7 @@ class Module
|
|
43
48
|
end
|
44
49
|
|
45
50
|
# Allows you to make aliases for attributes, which includes
|
46
|
-
# getter, setter, and
|
51
|
+
# getter, setter, and a predicate.
|
47
52
|
#
|
48
53
|
# class Content < ActiveRecord::Base
|
49
54
|
# # has a title attribute
|