Module: Contrast::Utils::DuckUtils

Defined in:
lib/contrast/utils/duck_utils.rb

Overview

Utility methods for identifying instances that can be used interchangeably

Class Method Summary collapse

Class Method Details

.closable_io?(object) ⇒ Boolean

Most things that are closable IO’s will in fact be of the IO type. That being said, some will also be extensions of DelegateClass with IO type, like Tempfile. We need to handle both cases.

Parameters:

Returns:

  • (Boolean)


29
30
31
32
33
# File 'lib/contrast/utils/duck_utils.rb', line 29

def closable_io? object
  return false unless Contrast::Utils::IOUtil.io?(object)

  quacks_to?(object, :closed?)
end

.empty_duck?(object) ⇒ Boolean

Every duck quacks to nil, we need to check if it is empty? Utils method to check for blank ( nil or empty object ).

Parameters:

  • object (Object)

    to test.

Returns:

  • (Boolean)


72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/contrast/utils/duck_utils.rb', line 72

def empty_duck? object
  # If not quacking to empty it is True/False class, Integer, Regexp or Time instance.
  return false if object.instance_of?(TrueClass) || object.instance_of?(FalseClass)

  if object.cs__respond_to?(:empty?)
    return true if object.empty?
  elsif object.nil?
    return true
  end

  false
end

.iterable_enumerable?(object) ⇒ Boolean

Determine if the given Object is a concrete implementation of Enumerable known to be safe to call #each on.

Parameters:

Returns:

  • (Boolean)


53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/contrast/utils/duck_utils.rb', line 53

def iterable_enumerable? object
  # do iterate on things believed to safely implement #each. We're
  # purposefully skipping Hash and Hash-like things here as
  # #iterable_hash? should handle those.
  return true if object.cs__is_a?(Array)
  return true if object.cs__is_a?(Enumerator)
  return true if object.cs__is_a?(Hash)
  return true if object.cs__is_a?(Range)
  return true if object.cs__is_a?(Set)

  # otherwise, don't risk it
  false
end

.iterable_hash?(object) ⇒ Boolean

Determine if the given Object is a Hash, or similar enough to a hash for us to iterate on it using the #each_pair method

Parameters:

Returns:

  • (Boolean)


40
41
42
43
44
45
46
# File 'lib/contrast/utils/duck_utils.rb', line 40

def iterable_hash? object
  # do iterate on things believed to safely implement #each_pair
  return true if object.cs__is_a?(Hash)

  # otherwise, don't risk it
  false
end

.quacks_to?(object, method) ⇒ Boolean

Determine if the given object, or the object to which it delegates, responds to the given method.

Parameters:

  • object (Object)
  • method (Symbol)

Returns:

  • (Boolean)


15
16
17
18
19
20
21
# File 'lib/contrast/utils/duck_utils.rb', line 15

def quacks_to? object, method
  object.cs__respond_to?(method)
  return true if object.cs__respond_to?(method)
  return false unless object.is_a?(Delegator)

  object.cs__delegator_respond_to?(method)
end