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.

Files changed (182) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +678 -348
  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/strategy/local_cache_middleware.rb +4 -4
  14. data/lib/active_support/cache.rb +71 -87
  15. data/lib/active_support/callbacks.rb +109 -113
  16. data/lib/active_support/concern.rb +1 -1
  17. data/lib/active_support/concurrency/latch.rb +11 -12
  18. data/lib/active_support/concurrency/share_lock.rb +226 -0
  19. data/lib/active_support/configurable.rb +1 -0
  20. data/lib/active_support/core_ext/array/access.rb +27 -1
  21. data/lib/active_support/core_ext/array/conversions.rb +6 -4
  22. data/lib/active_support/core_ext/array/grouping.rb +9 -18
  23. data/lib/active_support/core_ext/array/inquiry.rb +17 -0
  24. data/lib/active_support/core_ext/array/wrap.rb +5 -4
  25. data/lib/active_support/core_ext/array.rb +1 -0
  26. data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -10
  27. data/lib/active_support/core_ext/class/attribute.rb +10 -9
  28. data/lib/active_support/core_ext/class/subclasses.rb +3 -2
  29. data/lib/active_support/core_ext/class.rb +0 -1
  30. data/lib/active_support/core_ext/date/blank.rb +12 -0
  31. data/lib/active_support/core_ext/date/calculations.rb +1 -1
  32. data/lib/active_support/core_ext/date/conversions.rb +7 -6
  33. data/lib/active_support/core_ext/date.rb +1 -1
  34. data/lib/active_support/core_ext/date_and_time/calculations.rb +100 -27
  35. data/lib/active_support/core_ext/date_and_time/compatibility.rb +0 -1
  36. data/lib/active_support/core_ext/date_and_time/zones.rb +3 -4
  37. data/lib/active_support/core_ext/date_time/blank.rb +12 -0
  38. data/lib/active_support/core_ext/date_time/calculations.rb +14 -8
  39. data/lib/active_support/core_ext/date_time/conversions.rb +2 -0
  40. data/lib/active_support/core_ext/date_time.rb +1 -1
  41. data/lib/active_support/core_ext/enumerable.rb +75 -25
  42. data/lib/active_support/core_ext/file/atomic.rb +30 -25
  43. data/lib/active_support/core_ext/hash/conversions.rb +22 -2
  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 +25 -21
  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 +2 -2
  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 -84
  54. data/lib/active_support/core_ext/kernel.rb +0 -1
  55. data/lib/active_support/core_ext/load_error.rb +5 -2
  56. data/lib/active_support/core_ext/marshal.rb +7 -9
  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 +11 -20
  64. data/lib/active_support/core_ext/module/deprecation.rb +2 -2
  65. data/lib/active_support/core_ext/module/introspection.rb +8 -2
  66. data/lib/active_support/core_ext/module/method_transplanting.rb +3 -13
  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 +78 -77
  73. data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
  74. data/lib/active_support/core_ext/numeric/time.rb +26 -6
  75. data/lib/active_support/core_ext/numeric.rb +1 -0
  76. data/lib/active_support/core_ext/object/blank.rb +15 -3
  77. data/lib/active_support/core_ext/object/deep_dup.rb +10 -3
  78. data/lib/active_support/core_ext/object/duplicable.rb +7 -12
  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 +67 -21
  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/behavior.rb +1 -1
  91. data/lib/active_support/core_ext/string/conversions.rb +3 -2
  92. data/lib/active_support/core_ext/string/filters.rb +1 -2
  93. data/lib/active_support/core_ext/string/inflections.rb +32 -5
  94. data/lib/active_support/core_ext/string/multibyte.rb +11 -7
  95. data/lib/active_support/core_ext/string/output_safety.rb +12 -14
  96. data/lib/active_support/core_ext/string/strip.rb +3 -6
  97. data/lib/active_support/core_ext/struct.rb +3 -6
  98. data/lib/active_support/core_ext/time/calculations.rb +18 -9
  99. data/lib/active_support/core_ext/time/conversions.rb +4 -2
  100. data/lib/active_support/core_ext/time/marshal.rb +2 -29
  101. data/lib/active_support/core_ext/time/zones.rb +36 -4
  102. data/lib/active_support/core_ext/time.rb +0 -1
  103. data/lib/active_support/core_ext/uri.rb +1 -3
  104. data/lib/active_support/core_ext.rb +2 -1
  105. data/lib/active_support/dependencies/interlock.rb +55 -0
  106. data/lib/active_support/dependencies.rb +88 -95
  107. data/lib/active_support/deprecation/behaviors.rb +15 -1
  108. data/lib/active_support/deprecation/instance_delegator.rb +13 -0
  109. data/lib/active_support/deprecation/method_wrappers.rb +42 -16
  110. data/lib/active_support/deprecation/proxy_wrappers.rb +47 -24
  111. data/lib/active_support/deprecation/reporting.rb +23 -5
  112. data/lib/active_support/deprecation.rb +1 -1
  113. data/lib/active_support/duration/iso8601_parser.rb +122 -0
  114. data/lib/active_support/duration/iso8601_serializer.rb +51 -0
  115. data/lib/active_support/duration.rb +90 -15
  116. data/lib/active_support/evented_file_update_checker.rb +199 -0
  117. data/lib/active_support/execution_wrapper.rb +126 -0
  118. data/lib/active_support/executor.rb +6 -0
  119. data/lib/active_support/file_update_checker.rb +23 -3
  120. data/lib/active_support/gem_version.rb +5 -5
  121. data/lib/active_support/gzip.rb +1 -1
  122. data/lib/active_support/hash_with_indifferent_access.rb +40 -11
  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 +1 -51
  129. data/lib/active_support/key_generator.rb +7 -9
  130. data/lib/active_support/lazy_load_hooks.rb +46 -18
  131. data/lib/active_support/locale/en.yml +2 -0
  132. data/lib/active_support/log_subscriber/test_helper.rb +3 -3
  133. data/lib/active_support/log_subscriber.rb +1 -1
  134. data/lib/active_support/logger.rb +3 -4
  135. data/lib/active_support/logger_silence.rb +2 -1
  136. data/lib/active_support/logger_thread_safe_level.rb +2 -3
  137. data/lib/active_support/message_encryptor.rb +7 -7
  138. data/lib/active_support/message_verifier.rb +70 -8
  139. data/lib/active_support/multibyte/chars.rb +12 -3
  140. data/lib/active_support/multibyte/unicode.rb +44 -21
  141. data/lib/active_support/notifications/fanout.rb +5 -5
  142. data/lib/active_support/notifications/instrumenter.rb +20 -2
  143. data/lib/active_support/notifications.rb +2 -2
  144. data/lib/active_support/number_helper/number_to_currency_converter.rb +7 -9
  145. data/lib/active_support/number_helper/number_to_delimited_converter.rb +8 -3
  146. data/lib/active_support/number_helper/number_to_human_converter.rb +6 -4
  147. data/lib/active_support/number_helper/number_to_human_size_converter.rb +6 -2
  148. data/lib/active_support/number_helper/number_to_percentage_converter.rb +1 -1
  149. data/lib/active_support/number_helper/number_to_phone_converter.rb +11 -2
  150. data/lib/active_support/number_helper/number_to_rounded_converter.rb +30 -25
  151. data/lib/active_support/number_helper.rb +90 -67
  152. data/lib/active_support/ordered_hash.rb +1 -1
  153. data/lib/active_support/ordered_options.rb +15 -1
  154. data/lib/active_support/per_thread_registry.rb +3 -0
  155. data/lib/active_support/rails.rb +2 -2
  156. data/lib/active_support/railtie.rb +6 -1
  157. data/lib/active_support/reloader.rb +129 -0
  158. data/lib/active_support/rescuable.rb +101 -47
  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 +8 -7
  162. data/lib/active_support/test_case.rb +17 -29
  163. data/lib/active_support/testing/assertions.rb +15 -13
  164. data/lib/active_support/testing/deprecation.rb +9 -8
  165. data/lib/active_support/testing/file_fixtures.rb +34 -0
  166. data/lib/active_support/testing/isolation.rb +22 -8
  167. data/lib/active_support/testing/method_call_assertions.rb +41 -0
  168. data/lib/active_support/testing/stream.rb +42 -0
  169. data/lib/active_support/testing/time_helpers.rb +3 -1
  170. data/lib/active_support/time_with_zone.rb +123 -33
  171. data/lib/active_support/values/time_zone.rb +101 -47
  172. data/lib/active_support/values/unicode_tables.dat +0 -0
  173. data/lib/active_support/xml_mini/jdom.rb +1 -1
  174. data/lib/active_support/xml_mini/libxml.rb +2 -2
  175. data/lib/active_support/xml_mini/nokogiri.rb +2 -2
  176. data/lib/active_support.rb +11 -6
  177. metadata +36 -17
  178. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
  179. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
  180. data/lib/active_support/core_ext/date_time/zones.rb +0 -6
  181. data/lib/active_support/core_ext/object/itself.rb +0 -15
  182. data/lib/active_support/core_ext/thread.rb +0 -86
@@ -1,27 +1,50 @@
1
1
  module Enumerable
2
- # Calculates a sum from the elements.
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
- # payments.sum { |p| p.price * p.tax_rate }
5
- # payments.sum(&:price)
6
- #
7
- # The latter is a shortcut for:
8
- #
9
- # payments.inject(0) { |sum, p| sum + p.price }
10
- #
11
- # It can also calculate the sum without the use of a block.
12
- #
13
- # [5, 15, 10].sum # => 30
14
- # ['foo', 'bar'].sum # => "foobar"
15
- # [[1, 2], [3, 1, 5]].sum => [1, 2, 3, 1, 5]
16
- #
17
- # The default sum of an empty list is zero. You can override this default:
18
- #
19
- # [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)
20
- def sum(identity = 0, &block)
21
- if block_given?
22
- map(&block).sum(identity)
23
- else
24
- inject { |sum, element| sum + element } || identity
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 = 0)
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
- (actual_last - first + 1) * (actual_last + first) / 2
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
- # If your temp directory is not on the same filesystem as the file you're
12
- # trying to write, you can provide a different temporary directory.
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 = Dir.tmpdir)
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
- temp_file = Tempfile.new(basename(file_name), temp_dir)
22
- temp_file.binmode
23
- yield temp_file
24
- temp_file.close
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
- if File.exist?(file_name)
27
- # Get original file permissions
28
- old_stat = stat(file_name)
29
- else
30
- # If not possible, probe which are the default permissions in the
31
- # destination directory.
32
- old_stat = probe_stat_in(dirname(file_name))
33
- end
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
- # Overwrite original file with temp file
36
- FileUtils.mv(temp_file.path, file_name)
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
- # Set correct permissions on new file
39
- begin
40
- chown(old_stat.uid, old_stat.gid, file_name)
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
- # 'foo'.to_xml(lambda { |options, key| options[:builder].b(key) })
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 parse this XML.
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) #=> { a: false, b: { c: [1, 2, 3], x: [3, 4, 5] } }
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 but the given keys.
3
- # hash = { a: true, b: false, c: nil}
4
- # hash.except(:c) # => { a: true, b: false}
5
- # hash # => { a: true, b: false, c: nil}
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
- # Replaces the hash without the given keys.
14
- # hash = { a: true, b: false, c: nil}
15
- # hash.except!(:c) # => { a: true, b: false}
16
- # hash # => { a: true, b: false }
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.new_from_hash_copying_default(self)
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
- # # => {"NAME"=>"Rob", "AGE"=>"28"}
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 = self.class.new
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 convert all keys using the block operations.
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{ |key| key.to_s }
38
+ transform_keys(&:to_s)
35
39
  end
36
40
 
37
- # Destructively convert all keys to strings. Same as
41
+ # Destructively converts all keys to strings. Same as
38
42
  # +stringify_keys+, but modifies +self+.
39
43
  def stringify_keys!
40
- transform_keys!{ |key| key.to_s }
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 convert all keys to symbols, as long as they respond
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
- # Validate all keys in a hash match <tt>*valid_keys</tt>, raising
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 convert all keys by using the block operation.
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{ |key| key.to_s }
112
+ deep_transform_keys(&:to_s)
109
113
  end
110
114
 
111
- # Destructively convert all keys to strings.
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!{ |key| key.to_s }
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 convert all keys to symbols, as long as they respond
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!
@@ -1,5 +1,5 @@
1
1
  class Hash
2
- # Slice a hash to include only the given keys. Returns a hash containing
2
+ # Slices a hash to include only the given keys. Returns a hash containing
3
3
  # the given keys.
4
4
  #
5
5
  # { a: 1, b: 2, c: 3, d: 4 }.slice(:a, :b)
@@ -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
- # # => { a: 2, b: 4, c: 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
- # Destructive +transform_values+
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.new(self * 30.days, [[:months, self]])
21
+ ActiveSupport::Duration.months(self)
22
22
  end
23
23
  alias :month :months
24
24
 
25
25
  def years
26
- ActiveSupport::Duration.new(self * 365.25.days, [[:years, self]])
26
+ ActiveSupport::Duration.years(self)
27
27
  end
28
28
  alias :year :years
29
29
  end
@@ -1,6 +1,8 @@
1
1
  require 'active_support/core_ext/module/concerning'
2
2
 
3
3
  module Kernel
4
+ module_function
5
+
4
6
  # A shortcut to define a toplevel concern, not within a module.
5
7
  #
6
8
  # See Module::Concerning for more.
@@ -1,10 +1,3 @@
1
- module Kernel
2
- unless respond_to?(:debugger)
3
- # Starts a debugging session if the +debugger+ gem has been loaded (call rails server --debugger to do load it).
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
- require 'active_support/core_ext/module/aliasing'
2
-
3
- module Marshal
4
- class << self
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 (.+?)(::)?\z|)
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 query methods.
51
+ # getter, setter, and a predicate.
47
52
  #
48
53
  # class Content < ActiveRecord::Base
49
54
  # # has a title attribute