def detach(p1, from:, between: nil, and: nil)
      p2 = from
      sender = between
      # use binding#local_variable_get because 'and:' keyword argument clashes
      # with the language reserved keyword.
      receiver = binding.local_variable_get(:and)

      raise ArgumentError.new("'between:' keyword was omitted, 'p1' should be a Port.") if sender.nil? && !p1.is_a?(Port)
      raise ArgumentError.new("'and:' keyword was omitted, 'from:' should be a Port") if receiver.nil? && !p2.is_a?(Port)

      a = if p1.is_a?(Port) then p1.host
      elsif sender.is_a?(Coupleable) then sender
      elsif sender == @name then self
      else fetch_child(sender); end

      b = if p2.is_a?(Port) then p2.host
      elsif receiver.is_a?(Coupleable) then receiver
      elsif receiver == @name then self
      else fetch_child(receiver); end

      if has_child?(a) && has_child?(b) # IC
        _internal_couplings[p1].delete(p2) != nil
      elsif a == self && has_child?(b)  # EIC
        _input_couplings[p1].delete(p2) != nil
      elsif has_child?(a) && b == self  # EOC
        _output_couplings[p1].delete(p2) != nil
      else
        false
      end
    end
def detach(p1, from:, between: nil, and: nil)
      p2 = from
      sender = between
      # use binding#local_variable_get because 'and:' keyword argument clashes
      # with the language reserved keyword.
      receiver = binding.local_variable_get(:and)

      raise ArgumentError.new("'between:' keyword was omitted, 'p1' should be a Port.") if sender.nil? && !p1.is_a?(Port)
      raise ArgumentError.new("'and:' keyword was omitted, 'from:' should be a Port") if receiver.nil? && !p2.is_a?(Port)

      a = if p1.is_a?(Port) then p1.host
      elsif sender.is_a?(Coupleable) then sender
      elsif sender == @name then self
      else fetch_child(sender); end

      b = if p2.is_a?(Port) then p2.host
      elsif receiver.is_a?(Coupleable) then receiver
      elsif receiver == @name then self
      else fetch_child(receiver); end

      if has_child?(a) && has_child?(b) # IC
        _internal_couplings[p1].delete(p2) != nil
      elsif a == self && has_child?(b)  # EIC
        _input_couplings[p1].delete(p2) != nil
      elsif has_child?(a) && b == self  # EOC
        _output_couplings[p1].delete(p2) != nil
      else
        false
      end
    end
Deletes a coupling between given ports and components from *self*.

 @overload detach(p1, from:)
   @param p1 [Port] the source port of the coupling
   @param from [Port] the destination port of the coupling

 @overload detach(p1, from:, between:, and:)
   @param p1 [Port,Symbol,String] the source port of the coupling
   @param from [Port,Symbol,String] the destination port of the coupling
   @param between [Coupleable,Symbol,String] the sender of the coupling
   @param and [Coupleable,Symbol,String] the receiver of the coupling

 @return [true,false] if successful

 @example Detach two ports from each other
   detach component1.output_port(:out) from: component2.input_port(:in) #IC
   detach self.input_port(:in) from: child.input_port(:in) # EIC
   detach child.output_port(:out) from: self.output_port(:out) # EOC
 @example Detach specified ports and components from each other
   detach :out, from: :in, between: :component1, and: :component2
   detach :in, from: :in, between: self, and: child