Module: Plumb::Equality

Defined in:
lib/plumb/composable.rb

Overview

Override #=== and #== for Composable instances. but only when included in classes, not extended.

Instance Method Summary collapse

Instance Method Details

#<(other) ⇒ Object

Strict subtype / supertype.



151
# File 'lib/plumb/composable.rb', line 151

def <(other) = (self <= other) && !(self >= other)

#<=(other) ⇒ Boolean

Subtype/subset operator. a <= b is true when every value described by self is also described by other (other may be a raw Ruby class or value; it is normalized). Delegates to the generic Plumb::Subtyping engine.

Parameters:

Returns:

  • (Boolean)


140
141
142
# File 'lib/plumb/composable.rb', line 140

def <=(other)
  Plumb::Subtyping.subtype?(self, other)
end

#==(other) ⇒ Boolean

Compares nodes by exact class and children. Use instance_of?, not is_a?: a subclass may change behavior without changing #children, making parent/subclass equality asymmetric. Subtyping and optimization short-circuit on ==, so that asymmetry could discard the narrower node before its behavioral guards run.

Parameters:

  • other (Object)

Returns:

  • (Boolean)


131
132
133
# File 'lib/plumb/composable.rb', line 131

def ==(other)
  other.instance_of?(self.class) && other.respond_to?(:children) && other.children == children
end

#===(other) ⇒ Boolean

#=== equality. So that Plumb steps can be used in case statements and pattern matching.

Parameters:

  • other (Object)

Returns:

  • (Boolean)


116
117
118
119
120
121
122
123
# File 'lib/plumb/composable.rb', line 116

def ===(other)
  case other
  when Composable
    other == self
  else
    resolve(other).valid?
  end
end

#>(other) ⇒ Object



152
# File 'lib/plumb/composable.rb', line 152

def >(other) = (self >= other) && !(self <= other)

#>=(other) ⇒ Object

self is a supertype of other: every value of other is a value of self.



146
147
148
# File 'lib/plumb/composable.rb', line 146

def >=(other)
  Plumb::Subtyping.subtype?(Composable.wrap(other), self)
end

#subtype_of?(other) ⇒ Boolean

Leaf hook for Plumb::Subtyping.subtype?, called once the algebra (Intersection/Or/top, and the #subtype_identity projection that replaces a converting node with what it produces) has been peeled away. It must NOT delegate back to #<= (that would recurse); it recurses only through Plumb::Subtyping.subtype?.

Default behaviour:

1. reflexive structural equality;
2. atomic leaves (a single raw matcher/value) compared via Ruby
 semantics (Plumb::Subtyping.atomic_subtype?);
3. covariant containers — same class with pairwise-subtype children,
 which covers Array/Tuple/HashMap/Stream and any custom container that
 exposes #children, for free.

Override for bespoke leaf relations (see HashClass width/depth subtyping).

Parameters:

Returns:

  • (Boolean)


171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/plumb/composable.rb', line 171

def subtype_of?(other)
  return true if self == other

  if Plumb::Subtyping.atomic?(self) && Plumb::Subtyping.atomic?(other)
    # #children contains only the matcher, but a refinement also describes its
    # base. Check both or an unrelated atomic value may pass on matcher overlap
    # alone (for example, Value[5.0] against Integer[1..5]).
    if other.respond_to?(:base) && other.base && !Plumb::Subtyping.subtype?(self, other.base)
      return false
    end

    return Plumb::Subtyping.atomic_subtype?(children.first, other.children.first)
  end

  return false unless other.instance_of?(self.class)
  return false if children.empty? || children.size != other.children.size

  children.zip(other.children).all? { |c, o| Plumb::Subtyping.subtype?(c, o) }
end

#supertype_of?(other) ⇒ Boolean

Mirror of #subtype_of?, for relations the supertype owns and the subtype can't know about (eg. Interface duck-typing: any type is a subtype of an Interface whose methods its values support). Consulted by Plumb::Subtyping.subtype? only after #subtype_of? declines. Default: no — only the subtype side decides. Recurse via Plumb::Subtyping.subtype?, never #<=. Override for bespoke supertype behaviour (see InterfaceClass).

Parameters:

Returns:

  • (Boolean)


199
# File 'lib/plumb/composable.rb', line 199

def supertype_of?(other) = false