mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00
70 lines
1.8 KiB
Ruby
70 lines
1.8 KiB
Ruby
# typed: strict
|
|
# frozen_string_literal: true
|
|
|
|
# Most objects are cloneable, but not all. For example you can't dup methods:
|
|
#
|
|
# ```ruby
|
|
# 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
|
|
# use an optimistic approach and are ready to catch an exception, say:
|
|
#
|
|
# ```ruby
|
|
# arbitrary_object.dup rescue object
|
|
# ```
|
|
#
|
|
# Rails dups objects in a few critical spots where they are not that arbitrary.
|
|
# That `rescue` is very expensive (like 40 times slower than a predicate) and it
|
|
# is often triggered.
|
|
#
|
|
# That's why we hardcode the following cases and check duplicable? instead of
|
|
# using that rescue idiom.
|
|
# rubocop:disable Layout/EmptyLines
|
|
|
|
|
|
# rubocop:enable Layout/EmptyLines
|
|
class Object
|
|
# Can you safely dup this object?
|
|
#
|
|
# False for method objects;
|
|
# true otherwise.
|
|
sig { returns(T::Boolean) }
|
|
def duplicable? = true
|
|
end
|
|
|
|
class Method
|
|
# Methods are not duplicable:
|
|
#
|
|
# ```ruby
|
|
# method(:puts).duplicable? # => false
|
|
# method(:puts).dup # => TypeError: allocator undefined for Method
|
|
# ```
|
|
sig { returns(FalseClass) }
|
|
def duplicable? = false
|
|
end
|
|
|
|
class UnboundMethod
|
|
# Unbound methods are not duplicable:
|
|
#
|
|
# ```ruby
|
|
# method(:puts).unbind.duplicable? # => false
|
|
# method(:puts).unbind.dup # => TypeError: allocator undefined for UnboundMethod
|
|
# ```
|
|
sig { returns(FalseClass) }
|
|
def duplicable? = false
|
|
end
|
|
|
|
require "singleton"
|
|
|
|
module Singleton
|
|
# Singleton instances are not duplicable:
|
|
#
|
|
# ```ruby
|
|
# Class.new.include(Singleton).instance.dup # TypeError (can't dup instance of singleton
|
|
# ```
|
|
sig { returns(FalseClass) }
|
|
def duplicable? = false
|
|
end
|