# frozen_string_literal: true
class Object
# Provides a way to check whether some class acts like some other class based on the existence of
# an appropriately-named marker method.
#
# A class that provides the same interface as SomeClass may define a marker method named
# acts_like_some_class? to signal its compatibility to callers of
# acts_like?(:some_class).
#
# For example, Active Support extends Date to define an acts_like_date? method,
# and extends Time to define acts_like_time?. As a result, developers can call
# x.acts_like?(:time) and x.acts_like?(:date) to test duck-type compatibility,
# and classes that are able to act like Time can also define an acts_like_time?
# method to interoperate.
#
# Note that the marker method is only expected to exist. It isn't called, so its body or return
# value are irrelevant.
#
# ==== Example: A class that provides the same interface as String
#
# This class may define:
#
# class Stringish
# def acts_like_string?
# end
# end
#
# Then client code can query for duck-type-safeness this way:
#
# Stringish.new.acts_like?(:string) # => true
#
def acts_like?(duck)
case duck
when :time
respond_to? :acts_like_time?
when :date
respond_to? :acts_like_date?
when :string
respond_to? :acts_like_string?
else
respond_to? :"acts_like_#{duck}?"
end
end
end