diff options
Diffstat (limited to 'activesupport/lib/active_support/core_ext/object/duplicable.rb')
-rw-r--r-- | activesupport/lib/active_support/core_ext/object/duplicable.rb | 130 |
1 files changed, 94 insertions, 36 deletions
diff --git a/activesupport/lib/active_support/core_ext/object/duplicable.rb b/activesupport/lib/active_support/core_ext/object/duplicable.rb index befa5aee21..9bb99087bc 100644 --- a/activesupport/lib/active_support/core_ext/object/duplicable.rb +++ b/activesupport/lib/active_support/core_ext/object/duplicable.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + #-- -# Most objects are cloneable, but not all. For example you can't dup +nil+: +# Most objects are cloneable, but not all. For example you can't dup methods: # -# nil.dup # => TypeError: can't dup NilClass +# method(:puts).dup # => TypeError: allocator undefined for Method # # Classes may signal their instances are not duplicable removing +dup+/+clone+ # or raising exceptions from them. So, to dup an arbitrary object you normally @@ -19,7 +21,7 @@ class Object # Can you safely dup this object? # - # False for +nil+, +false+, +true+, symbol, number, method objects; + # False for method objects; # true otherwise. def duplicable? true @@ -27,61 +29,87 @@ class Object end class NilClass - # +nil+ is not duplicable: - # - # nil.duplicable? # => false - # nil.dup # => TypeError: can't dup NilClass - def duplicable? - false + 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 - # +false+ is not duplicable: - # - # false.duplicable? # => false - # false.dup # => TypeError: can't dup FalseClass - def duplicable? - false + 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 - # +true+ is not duplicable: - # - # true.duplicable? # => false - # true.dup # => TypeError: can't dup TrueClass - def duplicable? - false + 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 - # Symbols are not duplicable: - # - # :my_symbol.duplicable? # => false - # :my_symbol.dup # => TypeError: can't dup Symbol - def duplicable? - false + begin + :symbol.dup # Ruby 2.4.x. + "symbol_from_string".to_sym.dup # Some symbols can't `dup` in Ruby 2.4.0. + 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 - # Numbers are not duplicable: - # - # 3.duplicable? # => false - # 3.dup # => TypeError: can't dup Fixnum - def duplicable? - false + 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' +require "bigdecimal" class BigDecimal # BigDecimals are duplicable: # - # BigDecimal.new("1.2").duplicable? # => true - # BigDecimal.new("1.2").dup # => #<BigDecimal:...,'0.12E1',18(18)> + # BigDecimal("1.2").duplicable? # => true + # BigDecimal("1.2").dup # => #<BigDecimal:...,'0.12E1',18(18)> def duplicable? true end @@ -96,3 +124,33 @@ class Method false 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 + end +end |