activesupport 4.1.15 → 4.2.11.3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activesupport might be problematic. Click here for more details.

Files changed (111) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +395 -574
  3. data/README.rdoc +7 -2
  4. data/lib/active_support.rb +19 -0
  5. data/lib/active_support/backtrace_cleaner.rb +4 -4
  6. data/lib/active_support/cache.rb +17 -19
  7. data/lib/active_support/cache/file_store.rb +5 -0
  8. data/lib/active_support/cache/mem_cache_store.rb +1 -1
  9. data/lib/active_support/cache/strategy/local_cache.rb +5 -4
  10. data/lib/active_support/cache/strategy/local_cache_middleware.rb +5 -0
  11. data/lib/active_support/callbacks.rb +41 -33
  12. data/lib/active_support/concern.rb +10 -2
  13. data/lib/active_support/core_ext/array/access.rb +9 -1
  14. data/lib/active_support/core_ext/array/grouping.rb +5 -0
  15. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +2 -0
  16. data/lib/active_support/core_ext/class/delegating_attributes.rb +4 -0
  17. data/lib/active_support/core_ext/class/subclasses.rb +0 -2
  18. data/lib/active_support/core_ext/date/conversions.rb +6 -0
  19. data/lib/active_support/core_ext/date_and_time/calculations.rb +11 -0
  20. data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
  21. data/lib/active_support/core_ext/date_time.rb +1 -0
  22. data/lib/active_support/core_ext/date_time/calculations.rb +34 -4
  23. data/lib/active_support/core_ext/date_time/compatibility.rb +16 -0
  24. data/lib/active_support/core_ext/date_time/conversions.rb +2 -2
  25. data/lib/active_support/core_ext/digest/uuid.rb +51 -0
  26. data/lib/active_support/core_ext/enumerable.rb +16 -0
  27. data/lib/active_support/core_ext/file/atomic.rb +1 -1
  28. data/lib/active_support/core_ext/hash.rb +1 -0
  29. data/lib/active_support/core_ext/hash/compact.rb +20 -16
  30. data/lib/active_support/core_ext/hash/conversions.rb +3 -5
  31. data/lib/active_support/core_ext/hash/except.rb +8 -2
  32. data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -1
  33. data/lib/active_support/core_ext/hash/keys.rb +10 -6
  34. data/lib/active_support/core_ext/hash/slice.rb +8 -2
  35. data/lib/active_support/core_ext/hash/transform_values.rb +23 -0
  36. data/lib/active_support/core_ext/integer/time.rb +0 -15
  37. data/lib/active_support/core_ext/kernel.rb +3 -2
  38. data/lib/active_support/core_ext/kernel/concern.rb +10 -0
  39. data/lib/active_support/core_ext/kernel/debugger.rb +1 -1
  40. data/lib/active_support/core_ext/kernel/reporting.rb +15 -0
  41. data/lib/active_support/core_ext/load_error.rb +4 -1
  42. data/lib/active_support/core_ext/marshal.rb +8 -5
  43. data/lib/active_support/core_ext/module/aliasing.rb +2 -2
  44. data/lib/active_support/core_ext/module/delegation.rb +34 -18
  45. data/lib/active_support/core_ext/module/method_transplanting.rb +3 -1
  46. data/lib/active_support/core_ext/numeric/conversions.rb +11 -3
  47. data/lib/active_support/core_ext/numeric/time.rb +1 -34
  48. data/lib/active_support/core_ext/object.rb +1 -0
  49. data/lib/active_support/core_ext/object/blank.rb +2 -2
  50. data/lib/active_support/core_ext/object/duplicable.rb +62 -33
  51. data/lib/active_support/core_ext/object/itself.rb +15 -0
  52. data/lib/active_support/core_ext/object/json.rb +2 -2
  53. data/lib/active_support/core_ext/object/to_query.rb +2 -1
  54. data/lib/active_support/core_ext/object/try.rb +35 -13
  55. data/lib/active_support/core_ext/object/with_options.rb +30 -3
  56. data/lib/active_support/core_ext/string/access.rb +5 -5
  57. data/lib/active_support/core_ext/string/conversions.rb +1 -1
  58. data/lib/active_support/core_ext/string/filters.rb +44 -6
  59. data/lib/active_support/core_ext/string/inflections.rb +4 -1
  60. data/lib/active_support/core_ext/string/output_safety.rb +33 -14
  61. data/lib/active_support/core_ext/thread.rb +7 -0
  62. data/lib/active_support/core_ext/time.rb +1 -0
  63. data/lib/active_support/core_ext/time/calculations.rb +31 -7
  64. data/lib/active_support/core_ext/time/compatibility.rb +14 -0
  65. data/lib/active_support/core_ext/time/conversions.rb +1 -1
  66. data/lib/active_support/dependencies.rb +32 -18
  67. data/lib/active_support/dependencies/autoload.rb +1 -1
  68. data/lib/active_support/deprecation.rb +1 -1
  69. data/lib/active_support/deprecation/behaviors.rb +1 -1
  70. data/lib/active_support/duration.rb +47 -5
  71. data/lib/active_support/gem_version.rb +4 -4
  72. data/lib/active_support/hash_with_indifferent_access.rb +35 -7
  73. data/lib/active_support/i18n_railtie.rb +1 -7
  74. data/lib/active_support/inflector/inflections.rb +2 -2
  75. data/lib/active_support/inflector/methods.rb +43 -19
  76. data/lib/active_support/json/decoding.rb +1 -1
  77. data/lib/active_support/json/encoding.rb +3 -2
  78. data/lib/active_support/logger.rb +36 -0
  79. data/lib/active_support/logger_silence.rb +4 -22
  80. data/lib/active_support/logger_thread_safe_level.rb +32 -0
  81. data/lib/active_support/message_encryptor.rb +10 -2
  82. data/lib/active_support/message_verifier.rb +11 -12
  83. data/lib/active_support/multibyte/chars.rb +1 -1
  84. data/lib/active_support/multibyte/unicode.rb +5 -4
  85. data/lib/active_support/notifications.rb +8 -3
  86. data/lib/active_support/notifications/fanout.rb +12 -7
  87. data/lib/active_support/number_helper.rb +12 -13
  88. data/lib/active_support/number_helper/number_to_currency_converter.rb +1 -1
  89. data/lib/active_support/number_helper/number_to_percentage_converter.rb +1 -1
  90. data/lib/active_support/number_helper/number_to_rounded_converter.rb +1 -1
  91. data/lib/active_support/per_thread_registry.rb +5 -3
  92. data/lib/active_support/test_case.rb +46 -12
  93. data/lib/active_support/testing/assertions.rb +1 -1
  94. data/lib/active_support/testing/constant_lookup.rb +1 -5
  95. data/lib/active_support/testing/declarative.rb +1 -25
  96. data/lib/active_support/testing/isolation.rb +16 -6
  97. data/lib/active_support/testing/tagged_logging.rb +1 -1
  98. data/lib/active_support/testing/time_helpers.rb +23 -16
  99. data/lib/active_support/time.rb +0 -2
  100. data/lib/active_support/time_with_zone.rb +48 -29
  101. data/lib/active_support/values/time_zone.rb +81 -75
  102. data/lib/active_support/values/unicode_tables.dat +0 -0
  103. data/lib/active_support/xml_mini.rb +30 -15
  104. data/lib/active_support/xml_mini/libxml.rb +1 -3
  105. data/lib/active_support/xml_mini/libxmlsax.rb +1 -4
  106. data/lib/active_support/xml_mini/nokogiri.rb +1 -3
  107. data/lib/active_support/xml_mini/nokogirisax.rb +1 -3
  108. data/lib/active_support/xml_mini/rexml.rb +1 -3
  109. metadata +21 -36
  110. data/lib/active_support/core_ext/object/to_json.rb +0 -5
  111. data/lib/active_support/file_watcher.rb +0 -36
@@ -26,7 +26,7 @@ module ActiveSupport
26
26
  # scope :disabled, -> { where(disabled: true) }
27
27
  # end
28
28
  #
29
- # module ClassMethods
29
+ # class_methods do
30
30
  # ...
31
31
  # end
32
32
  # end
@@ -95,7 +95,7 @@ module ActiveSupport
95
95
  # end
96
96
  #
97
97
  # class Host
98
- # include Bar # works, Bar takes care now of its dependencies
98
+ # include Bar # It works, now Bar takes care of its dependencies
99
99
  # end
100
100
  module Concern
101
101
  class MultipleIncludedBlocks < StandardError #:nodoc:
@@ -130,5 +130,13 @@ module ActiveSupport
130
130
  super
131
131
  end
132
132
  end
133
+
134
+ def class_methods(&class_methods_module_definition)
135
+ mod = const_defined?(:ClassMethods, false) ?
136
+ const_get(:ClassMethods) :
137
+ const_set(:ClassMethods, Module.new)
138
+
139
+ mod.module_eval(&class_methods_module_definition)
140
+ end
133
141
  end
134
142
  end
@@ -5,6 +5,8 @@ class Array
5
5
  # %w( a b c d ).from(2) # => ["c", "d"]
6
6
  # %w( a b c d ).from(10) # => []
7
7
  # %w().from(0) # => []
8
+ # %w( a b c d ).from(-2) # => ["c", "d"]
9
+ # %w( a b c ).from(-10) # => []
8
10
  def from(position)
9
11
  self[position, length] || []
10
12
  end
@@ -15,8 +17,14 @@ class Array
15
17
  # %w( a b c d ).to(2) # => ["a", "b", "c"]
16
18
  # %w( a b c d ).to(10) # => ["a", "b", "c", "d"]
17
19
  # %w().to(0) # => []
20
+ # %w( a b c d ).to(-2) # => ["a", "b", "c"]
21
+ # %w( a b c ).to(-10) # => []
18
22
  def to(position)
19
- first position + 1
23
+ if position >= 0
24
+ first position + 1
25
+ else
26
+ self[0..position]
27
+ end
20
28
  end
21
29
 
22
30
  # Equal to <tt>self[1]</tt>.
@@ -18,6 +18,11 @@ class Array
18
18
  # ["3", "4"]
19
19
  # ["5"]
20
20
  def in_groups_of(number, fill_with = nil)
21
+ if number.to_i <= 0
22
+ raise ArgumentError,
23
+ "Group size must be a positive integer, was #{number.inspect}"
24
+ end
25
+
21
26
  if fill_with == false
22
27
  collection = self
23
28
  else
@@ -1,3 +1,5 @@
1
+ require 'active_support/deprecation'
2
+
1
3
  ActiveSupport::Deprecation.warn 'core_ext/big_decimal/yaml_conversions is deprecated and will be removed in the future.'
2
4
 
3
5
  require 'bigdecimal'
@@ -1,5 +1,7 @@
1
1
  require 'active_support/core_ext/kernel/singleton_class'
2
2
  require 'active_support/core_ext/module/remove_method'
3
+ require 'active_support/core_ext/module/deprecation'
4
+
3
5
 
4
6
  class Class
5
7
  def superclass_delegating_accessor(name, options = {})
@@ -21,6 +23,8 @@ class Class
21
23
  end
22
24
  end
23
25
 
26
+ deprecate superclass_delegating_accessor: :class_attribute
27
+
24
28
  private
25
29
  # Take the object being set and store it in a method. This gives us automatic
26
30
  # inheritance behavior, without having to store the object in an instance
@@ -25,8 +25,6 @@ class Class
25
25
 
26
26
  # Returns an array with the direct children of +self+.
27
27
  #
28
- # Integer.subclasses # => [Fixnum, Bignum]
29
- #
30
28
  # class Foo; end
31
29
  # class Bar < Foo; end
32
30
  # class Baz < Bar; end
@@ -35,6 +35,7 @@ class Date
35
35
  # date.to_s(:db) # => "2007-11-10"
36
36
  #
37
37
  # date.to_formatted_s(:short) # => "10 Nov"
38
+ # date.to_formatted_s(:number) # => "20071110"
38
39
  # date.to_formatted_s(:long) # => "November 10, 2007"
39
40
  # date.to_formatted_s(:long_ordinal) # => "November 10th, 2007"
40
41
  # date.to_formatted_s(:rfc822) # => "10 Nov 2007"
@@ -82,6 +83,11 @@ class Date
82
83
  ::Time.send(form, year, month, day)
83
84
  end
84
85
 
86
+ # Returns a string which represents the time in used time zone as DateTime
87
+ # defined by XML Schema:
88
+ #
89
+ # date = Date.new(2015, 05, 23) # => Sat, 23 May 2015
90
+ # date.xmlschema # => "2015-05-23T00:00:00+04:00"
85
91
  def xmlschema
86
92
  in_time_zone.xmlschema
87
93
  end
@@ -109,9 +109,20 @@ module DateAndTime
109
109
  alias :at_beginning_of_year :beginning_of_year
110
110
 
111
111
  # Returns a new date/time representing the given day in the next week.
112
+ #
113
+ # today = Date.today # => Thu, 07 May 2015
114
+ # today.next_week # => Mon, 11 May 2015
115
+ #
112
116
  # The +given_day_in_next_week+ defaults to the beginning of the week
113
117
  # which is determined by +Date.beginning_of_week+ or +config.beginning_of_week+
118
+ #
119
+ # today = Date.today # => Thu, 07 May 2015
120
+ # today.next_week(:friday) # => Fri, 15 May 2015
121
+ #
114
122
  # when set. +DateTime+ objects have their time set to 0:00.
123
+ #
124
+ # now = Time.current # => Thu, 07 May 2015 13:31:16 UTC +00:00
125
+ # now.next_week # => Mon, 11 May 2015 00:00:00 UTC +00:00
115
126
  def next_week(given_day_in_next_week = Date.beginning_of_week)
116
127
  first_hour(weeks_since(1).beginning_of_week.days_since(days_span(given_day_in_next_week)))
117
128
  end
@@ -0,0 +1,15 @@
1
+ require 'active_support/core_ext/module/attribute_accessors'
2
+ require 'active_support/core_ext/module/remove_method'
3
+
4
+ module DateAndTime
5
+ module Compatibility
6
+ # If true, +to_time+ preserves the timezone offset of receiver.
7
+ #
8
+ # NOTE: With Ruby 2.4+ the default for +to_time+ changed from
9
+ # converting to the local system time, to preserving the offset
10
+ # of the receiver. For backwards compatibility we're overriding
11
+ # this behavior, but new apps will have an initializer that sets
12
+ # this to true, because the new behavior is preferred.
13
+ mattr_accessor(:preserve_timezone, instance_writer: false) { false }
14
+ end
15
+ end
@@ -1,4 +1,5 @@
1
1
  require 'active_support/core_ext/date_time/acts_like'
2
2
  require 'active_support/core_ext/date_time/calculations'
3
+ require 'active_support/core_ext/date_time/compatibility'
3
4
  require 'active_support/core_ext/date_time/conversions'
4
5
  require 'active_support/core_ext/date_time/zones'
@@ -24,6 +24,13 @@ class DateTime
24
24
  end_of_day.to_i - to_i
25
25
  end
26
26
 
27
+ # Returns the fraction of a second as a +Rational+
28
+ #
29
+ # DateTime.new(2012, 8, 29, 0, 0, 0.5).subsec # => (1/2)
30
+ def subsec
31
+ sec_fraction
32
+ end
33
+
27
34
  # Returns a new DateTime where one or more of the elements have been changed
28
35
  # according to the +options+ parameter. The time options (<tt>:hour</tt>,
29
36
  # <tt>:min</tt>, <tt>:sec</tt>) reset cascadingly, so if only the hour is
@@ -53,6 +60,16 @@ class DateTime
53
60
  # <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>,
54
61
  # <tt>:minutes</tt>, <tt>:seconds</tt>.
55
62
  def advance(options)
63
+ unless options[:weeks].nil?
64
+ options[:weeks], partial_weeks = options[:weeks].divmod(1)
65
+ options[:days] = options.fetch(:days, 0) + 7 * partial_weeks
66
+ end
67
+
68
+ unless options[:days].nil?
69
+ options[:days], partial_days = options[:days].divmod(1)
70
+ options[:hours] = options.fetch(:hours, 0) + 24 * partial_days
71
+ end
72
+
56
73
  d = to_date.advance(options)
57
74
  datetime_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
58
75
  seconds_to_advance = \
@@ -63,7 +80,7 @@ class DateTime
63
80
  if seconds_to_advance.zero?
64
81
  datetime_advanced_by_date
65
82
  else
66
- datetime_advanced_by_date.since seconds_to_advance
83
+ datetime_advanced_by_date.since(seconds_to_advance)
67
84
  end
68
85
  end
69
86
 
@@ -129,14 +146,27 @@ class DateTime
129
146
  end
130
147
  alias :at_end_of_minute :end_of_minute
131
148
 
132
- # Adjusts DateTime to UTC by adding its offset value; offset is set to 0.
149
+ # Returns a <tt>Time</tt> instance of the simultaneous time in the system timezone.
150
+ def localtime(utc_offset = nil)
151
+ utc = new_offset(0)
152
+
153
+ Time.utc(
154
+ utc.year, utc.month, utc.day,
155
+ utc.hour, utc.min, utc.sec + utc.sec_fraction
156
+ ).getlocal(utc_offset)
157
+ end
158
+ alias_method :getlocal, :localtime
159
+
160
+ # Returns a <tt>DateTime</tt> instance of the simultaneous time in the UTC timezone.
133
161
  #
134
162
  # DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)) # => Mon, 21 Feb 2005 10:11:12 -0600
135
- # DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc # => Mon, 21 Feb 2005 16:11:12 +0000
163
+ # DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc # => Mon, 21 Feb 2005 16:11:12 UTC
136
164
  def utc
137
165
  new_offset(0)
138
166
  end
167
+ alias_method :getgm, :utc
139
168
  alias_method :getutc, :utc
169
+ alias_method :gmtime, :utc
140
170
 
141
171
  # Returns +true+ if <tt>offset == 0</tt>.
142
172
  def utc?
@@ -154,7 +184,7 @@ class DateTime
154
184
  if other.kind_of?(Infinity)
155
185
  super
156
186
  elsif other.respond_to? :to_datetime
157
- super other.to_datetime
187
+ super other.to_datetime rescue nil
158
188
  else
159
189
  nil
160
190
  end
@@ -0,0 +1,16 @@
1
+ require 'active_support/core_ext/date_and_time/compatibility'
2
+ require 'active_support/core_ext/module/remove_method'
3
+
4
+ class DateTime
5
+ include DateAndTime::Compatibility
6
+
7
+ remove_possible_method :to_time
8
+
9
+ # Either return an instance of `Time` with the same UTC offset
10
+ # as +self+ or an instance of `Time` representing the same time
11
+ # in the the local system timezone depending on the setting of
12
+ # on the setting of +ActiveSupport.to_time_preserves_timezone+.
13
+ def to_time
14
+ preserve_timezone ? getlocal(utc_offset) : getlocal
15
+ end
16
+ end
@@ -71,9 +71,9 @@ class DateTime
71
71
  civil(year, month, day, hour, min, sec, offset)
72
72
  end
73
73
 
74
- # Converts +self+ to a floating-point number of seconds since the Unix epoch.
74
+ # Converts +self+ to a floating-point number of seconds, including fractional microseconds, since the Unix epoch.
75
75
  def to_f
76
- seconds_since_unix_epoch.to_f
76
+ seconds_since_unix_epoch.to_f + sec_fraction
77
77
  end
78
78
 
79
79
  # Converts +self+ to an integer number of seconds since the Unix epoch.
@@ -0,0 +1,51 @@
1
+ require 'securerandom'
2
+
3
+ module Digest
4
+ module UUID
5
+ DNS_NAMESPACE = "k\xA7\xB8\x10\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" #:nodoc:
6
+ URL_NAMESPACE = "k\xA7\xB8\x11\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" #:nodoc:
7
+ OID_NAMESPACE = "k\xA7\xB8\x12\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" #:nodoc:
8
+ X500_NAMESPACE = "k\xA7\xB8\x14\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" #:nodoc:
9
+
10
+ # Generates a v5 non-random UUID (Universally Unique IDentifier).
11
+ #
12
+ # Using Digest::MD5 generates version 3 UUIDs; Digest::SHA1 generates version 5 UUIDs.
13
+ # uuid_from_hash always generates the same UUID for a given name and namespace combination.
14
+ #
15
+ # See RFC 4122 for details of UUID at: http://www.ietf.org/rfc/rfc4122.txt
16
+ def self.uuid_from_hash(hash_class, uuid_namespace, name)
17
+ if hash_class == Digest::MD5
18
+ version = 3
19
+ elsif hash_class == Digest::SHA1
20
+ version = 5
21
+ else
22
+ raise ArgumentError, "Expected Digest::SHA1 or Digest::MD5, got #{hash_class.name}."
23
+ end
24
+
25
+ hash = hash_class.new
26
+ hash.update(uuid_namespace)
27
+ hash.update(name)
28
+
29
+ ary = hash.digest.unpack('NnnnnN')
30
+ ary[2] = (ary[2] & 0x0FFF) | (version << 12)
31
+ ary[3] = (ary[3] & 0x3FFF) | 0x8000
32
+
33
+ "%08x-%04x-%04x-%04x-%04x%08x" % ary
34
+ end
35
+
36
+ # Convenience method for uuid_from_hash using Digest::MD5.
37
+ def self.uuid_v3(uuid_namespace, name)
38
+ self.uuid_from_hash(Digest::MD5, uuid_namespace, name)
39
+ end
40
+
41
+ # Convenience method for uuid_from_hash using Digest::SHA1.
42
+ def self.uuid_v5(uuid_namespace, name)
43
+ self.uuid_from_hash(Digest::SHA1, uuid_namespace, name)
44
+ end
45
+
46
+ # Convenience method for SecureRandom.uuid.
47
+ def self.uuid_v4
48
+ SecureRandom.uuid
49
+ end
50
+ end
51
+ end
@@ -78,3 +78,19 @@ class Range #:nodoc:
78
78
  end
79
79
  end
80
80
  end
81
+
82
+ # Array#sum was added in Ruby 2.4 but it only works with Numeric elements.
83
+ #
84
+ # We tried shimming it to attempt the fast native method, rescue TypeError,
85
+ # and fall back to the compatible implementation, but that's much slower than
86
+ # just calling the compat method in the first place.
87
+ if Array.instance_methods(false).include?(:sum) && !(%w[a].sum rescue false)
88
+ class Array
89
+ remove_method :sum
90
+
91
+ def sum(*args) #:nodoc:
92
+ # Use Enumerable#sum instead.
93
+ super
94
+ end
95
+ end
96
+ end
@@ -40,7 +40,7 @@ class File
40
40
  chown(old_stat.uid, old_stat.gid, file_name)
41
41
  # This operation will affect filesystem ACL's
42
42
  chmod(old_stat.mode, file_name)
43
- rescue Errno::EPERM
43
+ rescue Errno::EPERM, Errno::EACCES
44
44
  # Changing file ownership failed, moving on.
45
45
  end
46
46
  end
@@ -6,3 +6,4 @@ require 'active_support/core_ext/hash/indifferent_access'
6
6
  require 'active_support/core_ext/hash/keys'
7
7
  require 'active_support/core_ext/hash/reverse_merge'
8
8
  require 'active_support/core_ext/hash/slice'
9
+ require 'active_support/core_ext/hash/transform_values'
@@ -1,20 +1,24 @@
1
1
  class Hash
2
- # Returns a hash with non +nil+ values.
3
- #
4
- # hash = { a: true, b: false, c: nil}
5
- # hash.compact # => { a: true, b: false}
6
- # hash # => { a: true, b: false, c: nil}
7
- # { c: nil }.compact # => {}
8
- def compact
9
- self.select { |_, value| !value.nil? }
2
+ unless Hash.instance_methods(false).include?(:compact)
3
+ # Returns a hash with non +nil+ values.
4
+ #
5
+ # hash = { a: true, b: false, c: nil}
6
+ # hash.compact # => { a: true, b: false}
7
+ # hash # => { a: true, b: false, c: nil}
8
+ # { c: nil }.compact # => {}
9
+ def compact
10
+ self.select { |_, value| !value.nil? }
11
+ end
10
12
  end
11
-
12
- # Replaces current hash with non +nil+ values.
13
- #
14
- # hash = { a: true, b: false, c: nil}
15
- # hash.compact! # => { a: true, b: false}
16
- # hash # => { a: true, b: false}
17
- def compact!
18
- self.reject! { |_, value| value.nil? }
13
+
14
+ unless Hash.instance_methods(false).include?(:compact!)
15
+ # Replaces current hash with non +nil+ values.
16
+ #
17
+ # hash = { a: true, b: false, c: nil}
18
+ # hash.compact! # => { a: true, b: false}
19
+ # hash # => { a: true, b: false}
20
+ def compact!
21
+ self.reject! { |_, value| value.nil? }
22
+ end
19
23
  end
20
24
  end
@@ -55,8 +55,7 @@ class Hash
55
55
  #
56
56
  # XML_TYPE_NAMES = {
57
57
  # "Symbol" => "symbol",
58
- # "Fixnum" => "integer",
59
- # "Bignum" => "integer",
58
+ # "Integer" => "integer",
60
59
  # "BigDecimal" => "decimal",
61
60
  # "Float" => "float",
62
61
  # "TrueClass" => "boolean",
@@ -105,7 +104,7 @@ class Hash
105
104
  # hash = Hash.from_xml(xml)
106
105
  # # => {"hash"=>{"foo"=>1, "bar"=>2}}
107
106
  #
108
- # DisallowedType is raised if the XML contains attributes with <tt>type="yaml"</tt> or
107
+ # +DisallowedType+ is raised if the XML contains attributes with <tt>type="yaml"</tt> or
109
108
  # <tt>type="symbol"</tt>. Use <tt>Hash.from_trusted_xml</tt> to parse this XML.
110
109
  def from_xml(xml, disallowed_types = nil)
111
110
  ActiveSupport::XMLConverter.new(xml, disallowed_types).to_h
@@ -221,7 +220,7 @@ module ActiveSupport
221
220
  def garbage?(value)
222
221
  # If the type is the only element which makes it then
223
222
  # this still makes the value nil, except if type is
224
- # a XML node(where type['value'] is a Hash)
223
+ # an XML node(where type['value'] is a Hash)
225
224
  value['type'] && !value['type'].is_a?(::Hash) && value.size == 1
226
225
  end
227
226
 
@@ -241,4 +240,3 @@ module ActiveSupport
241
240
 
242
241
  end
243
242
  end
244
-
@@ -1,13 +1,19 @@
1
1
  class Hash
2
- # Returns a hash that includes everything but the given keys. This is useful for
3
- # limiting a set of parameters to everything but a few known toggles:
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}
4
6
  #
7
+ # This is useful for limiting a set of parameters to everything but a few known toggles:
5
8
  # @person.update(params[:person].except(:admin))
6
9
  def except(*keys)
7
10
  dup.except!(*keys)
8
11
  end
9
12
 
10
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 }
11
17
  def except!(*keys)
12
18
  keys.each { |key| delete(key) }
13
19
  self