diff options
Diffstat (limited to 'activesupport/lib/active_support/core_ext')
11 files changed, 108 insertions, 162 deletions
diff --git a/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb b/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb index e2e11545e2..c7a2378e41 100644 --- a/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb @@ -20,21 +20,11 @@ module DateAndTime advance(days: -1) end - # Returns a new date/time the specified number of days ago. - def prev_day(days = 1) - advance(days: -days) - end - # Returns a new date/time representing tomorrow. def tomorrow advance(days: 1) end - # Returns a new date/time the specified number of days in the future. - def next_day(days = 1) - advance(days: days) - end - # Returns true if the date/time is today. def today? to_date == ::Date.current @@ -198,21 +188,11 @@ module DateAndTime end end - # Returns a new date/time the specified number of months in the future. - def next_month(months = 1) - advance(months: months) - end - # Short-hand for months_since(3) def next_quarter months_since(3) end - # Returns a new date/time the specified number of years in the future. - def next_year(years = 1) - advance(years: years) - end - # Returns a new date/time representing the given day in the previous week. # Week is assumed to start on +start_day+, default is # +Date.beginning_of_week+ or +config.beginning_of_week+ when set. @@ -233,11 +213,6 @@ module DateAndTime end alias_method :last_weekday, :prev_weekday - # Returns a new date/time the specified number of months ago. - def prev_month(months = 1) - advance(months: -months) - end - # Short-hand for months_ago(1). def last_month months_ago(1) @@ -249,11 +224,6 @@ module DateAndTime end alias_method :last_quarter, :prev_quarter - # Returns a new date/time the specified number of years ago. - def prev_year(years = 1) - advance(years: -years) - end - # Short-hand for years_ago(1). def last_year years_ago(1) diff --git a/activesupport/lib/active_support/core_ext/date_and_time/zones.rb b/activesupport/lib/active_support/core_ext/date_and_time/zones.rb index 894fd9b76d..fb6a27cb27 100644 --- a/activesupport/lib/active_support/core_ext/date_and_time/zones.rb +++ b/activesupport/lib/active_support/core_ext/date_and_time/zones.rb @@ -29,7 +29,6 @@ module DateAndTime end private - def time_with_zone(time, zone) if time ActiveSupport::TimeWithZone.new(time.utc? ? time : time.getutc, zone) diff --git a/activesupport/lib/active_support/core_ext/date_time/conversions.rb b/activesupport/lib/active_support/core_ext/date_time/conversions.rb index 29725c89f7..231bf870a2 100644 --- a/activesupport/lib/active_support/core_ext/date_time/conversions.rb +++ b/activesupport/lib/active_support/core_ext/date_time/conversions.rb @@ -96,7 +96,6 @@ class DateTime end private - def offset_in_seconds (offset * 86400).to_i end diff --git a/activesupport/lib/active_support/core_ext/digest.rb b/activesupport/lib/active_support/core_ext/digest.rb new file mode 100644 index 0000000000..ce1427e13a --- /dev/null +++ b/activesupport/lib/active_support/core_ext/digest.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +require "active_support/core_ext/digest/uuid" diff --git a/activesupport/lib/active_support/core_ext/enumerable.rb b/activesupport/lib/active_support/core_ext/enumerable.rb index 4675c41936..728d332306 100644 --- a/activesupport/lib/active_support/core_ext/enumerable.rb +++ b/activesupport/lib/active_support/core_ext/enumerable.rb @@ -148,6 +148,41 @@ module Enumerable map { |element| element[keys.first] } end end + + # Returns a new +Array+ without the blank items. + # Uses Object#blank? for determining if an item is blank. + # + # [1, "", nil, 2, " ", [], {}, false, true].compact_blank + # # => [1, 2, true] + # + # Set.new([nil, "", 1, 2]) + # # => [2, 1] (or [1, 2]) + # + # When called on a +Hash+, returns a new +Hash+ without the blank values. + # + # { a: "", b: 1, c: nil, d: [], e: false, f: true }.compact_blank + # #=> { b: 1, f: true } + def compact_blank + reject(&:blank?) + end +end + +class Hash + # Hash#reject has its own definition, so this needs one too. + def compact_blank #:nodoc: + reject { |_k, v| v.blank? } + end + + # Removes all blank values from the +Hash+ in place and returns self. + # Uses Object#blank? for determining if a value is blank. + # + # h = { a: "", b: 1, c: nil, d: [], e: false, f: true } + # h.compact_blank! + # # => { b: 1, f: true } + def compact_blank! + # use delete_if rather than reject! because it always returns self even if nothing changed + delete_if { |_k, v| v.blank? } + end end class Range #:nodoc: @@ -185,4 +220,15 @@ class Array #:nodoc: super end end + + # Removes all blank elements from the +Array+ in place and returns self. + # Uses Object#blank? for determining if an item is blank. + # + # a = [1, "", nil, 2, " ", [], {}, false, true] + # a.compact_blank! + # # => [1, 2, true] + def compact_blank! + # use delete_if rather than reject! because it always returns self even if nothing changed + delete_if(&:blank?) + end end diff --git a/activesupport/lib/active_support/core_ext/hash/deep_transform_values.rb b/activesupport/lib/active_support/core_ext/hash/deep_transform_values.rb index 720a1f67c8..18acb1e70c 100644 --- a/activesupport/lib/active_support/core_ext/hash/deep_transform_values.rb +++ b/activesupport/lib/active_support/core_ext/hash/deep_transform_values.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true class Hash - # Returns a new hash with all keys converted by the block operation. - # This includes the keys from the root hash and from all + # Returns a new hash with all values converted by the block operation. + # This includes the values from the root hash and from all # nested hashes and arrays. # # hash = { person: { name: 'Rob', age: '28' } } diff --git a/activesupport/lib/active_support/core_ext/module/delegation.rb b/activesupport/lib/active_support/core_ext/module/delegation.rb index 9fe7f8fe01..14d7f0c484 100644 --- a/activesupport/lib/active_support/core_ext/module/delegation.rb +++ b/activesupport/lib/active_support/core_ext/module/delegation.rb @@ -205,18 +205,18 @@ class Module if allow_nil method_def = [ "def #{method_prefix}#{method}(#{definition})", - "_ = #{to}", - "if !_.nil? || nil.respond_to?(:#{method})", - " _.#{method}(#{definition})", - "end", - "end" + " _ = #{to}", + " if !_.nil? || nil.respond_to?(:#{method})", + " _.#{method}(#{definition})", + " end", + "end" ].join ";" else exception = %(raise DelegationError, "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}") method_def = [ "def #{method_prefix}#{method}(#{definition})", - " _ = #{to}", + " _ = #{to}", " _.#{method}(#{definition})", "rescue NoMethodError => e", " if _.nil? && e.name == :#{method}", @@ -274,8 +274,14 @@ class Module # variables, methods, constants, etc. # # The delegated method must be public on the target, otherwise it will - # raise +NoMethodError+. - def delegate_missing_to(target) + # raise +DelegationError+. If you wish to instead return +nil+, + # use the <tt>:allow_nil</tt> option. + # + # The <tt>marshal_dump</tt> and <tt>_dump</tt> methods are exempt from + # delegation due to possible interference when calling + # <tt>Marshal.dump(object)</tt>, should the delegation target method + # of <tt>object</tt> add or remove instance variables. + def delegate_missing_to(target, allow_nil: nil) target = target.to_s target = "self.#{target}" if DELEGATION_RESERVED_METHOD_NAMES.include?(target) @@ -284,6 +290,7 @@ class Module # It may look like an oversight, but we deliberately do not pass # +include_private+, because they do not get delegated. + return false if name == :marshal_dump || name == :_dump #{target}.respond_to?(name) || super end @@ -295,7 +302,11 @@ class Module super rescue NoMethodError if #{target}.nil? - raise DelegationError, "\#{method} delegated to #{target}, but #{target} is nil" + if #{allow_nil == true} + nil + else + raise DelegationError, "\#{method} delegated to #{target}, but #{target} is nil" + end else raise end diff --git a/activesupport/lib/active_support/core_ext/object/duplicable.rb b/activesupport/lib/active_support/core_ext/object/duplicable.rb index c78ee6bbfc..3ebcdca02b 100644 --- a/activesupport/lib/active_support/core_ext/object/duplicable.rb +++ b/activesupport/lib/active_support/core_ext/object/duplicable.rb @@ -28,96 +28,6 @@ class Object end end -class NilClass - begin - nil.dup - rescue TypeError - - # +nil+ is not duplicable: - # - # nil.duplicable? # => false - # nil.dup # => TypeError: can't dup NilClass - def duplicable? - false - end - end -end - -class FalseClass - begin - false.dup - rescue TypeError - - # +false+ is not duplicable: - # - # false.duplicable? # => false - # false.dup # => TypeError: can't dup FalseClass - def duplicable? - false - end - end -end - -class TrueClass - begin - true.dup - rescue TypeError - - # +true+ is not duplicable: - # - # true.duplicable? # => false - # true.dup # => TypeError: can't dup TrueClass - def duplicable? - false - end - end -end - -class Symbol - begin - :symbol.dup - - # Some symbols couldn't be duped in Ruby 2.4.0 only, due to a bug. - # This feature check catches any regression. - "symbol_from_string".to_sym.dup - rescue TypeError - - # Symbols are not duplicable: - # - # :my_symbol.duplicable? # => false - # :my_symbol.dup # => TypeError: can't dup Symbol - def duplicable? - false - end - end -end - -class Numeric - begin - 1.dup - rescue TypeError - - # Numbers are not duplicable: - # - # 3.duplicable? # => false - # 3.dup # => TypeError: can't dup Integer - def duplicable? - false - end - end -end - -require "bigdecimal" -class BigDecimal - # BigDecimals are duplicable: - # - # BigDecimal("1.2").duplicable? # => true - # BigDecimal("1.2").dup # => #<BigDecimal:...,'0.12E1',18(18)> - def duplicable? - true - end -end - class Method # Methods are not duplicable: # @@ -128,32 +38,12 @@ class Method end end -class Complex - begin - Complex(1).dup - rescue TypeError - - # Complexes are not duplicable: - # - # Complex(1).duplicable? # => false - # Complex(1).dup # => TypeError: can't copy Complex - def duplicable? - false - end - end -end - -class Rational - begin - Rational(1).dup - rescue TypeError - - # Rationals are not duplicable: - # - # Rational(1).duplicable? # => false - # Rational(1).dup # => TypeError: can't copy Rational - def duplicable? - false - end +class UnboundMethod + # Unbound methods are not duplicable: + # + # method(:puts).unbind.duplicable? # => false + # method(:puts).unbind.dup # => TypeError: allocator undefined for UnboundMethod + def duplicable? + false end end diff --git a/activesupport/lib/active_support/core_ext/range/each.rb b/activesupport/lib/active_support/core_ext/range/each.rb index 2f22cd0e92..2d86997edf 100644 --- a/activesupport/lib/active_support/core_ext/range/each.rb +++ b/activesupport/lib/active_support/core_ext/range/each.rb @@ -15,7 +15,6 @@ module ActiveSupport end private - def ensure_iteration_allowed raise TypeError, "can't iterate from #{first.class}" if first.is_a?(TimeWithZone) end diff --git a/activesupport/lib/active_support/core_ext/string/output_safety.rb b/activesupport/lib/active_support/core_ext/string/output_safety.rb index 645b1fea17..f48ea56326 100644 --- a/activesupport/lib/active_support/core_ext/string/output_safety.rb +++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb @@ -291,7 +291,6 @@ module ActiveSupport #:nodoc: end private - def html_escape_interpolated_argument(arg) (!html_safe? || arg.html_safe?) ? arg : CGI.escapeHTML(arg.to_s) end diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb index f09a6271ad..eed34965e3 100644 --- a/activesupport/lib/active_support/core_ext/time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/time/calculations.rb @@ -311,4 +311,34 @@ class Time end alias_method :eql_without_coercion, :eql? alias_method :eql?, :eql_with_coercion + + # Returns a new time the specified number of days ago. + def prev_day(days = 1) + advance(days: -days) + end + + # Returns a new time the specified number of days in the future. + def next_day(days = 1) + advance(days: days) + end + + # Returns a new time the specified number of months ago. + def prev_month(months = 1) + advance(months: -months) + end + + # Returns a new time the specified number of months in the future. + def next_month(months = 1) + advance(months: months) + end + + # Returns a new time the specified number of years ago. + def prev_year(years = 1) + advance(years: -years) + end + + # Returns a new time the specified number of years in the future. + def next_year(years = 1) + advance(years: years) + end end |