module Forwardable::Extended

def self.extended(klass)

def self.extended(klass)
  instance_methods.each do |method|
    klass.private_class_method(
      method
    )
  end
end

def def_delegator(accessor, method, alias_ = method, **kwd)

def def_delegator(accessor, method, alias_ = method, **kwd)
  kwd, alias_ = alias_, method if alias_.is_a?(Hash) && !kwd.any?
  if alias_.is_a?(Hash) || !kwd.any?
    Forwardable.instance_method(:def_delegator).bind(self) \
      .call(accessor, method, alias_)
  elsif !kwd[:type]
    def_modern_delegator(
      accessor, method, alias_, **kwd
    )
  else
    raise ArgumentError, "Alias not supported." if alias_ != method
    send("def_#{kwd[:type]}_delegator", accessor, method, **kwd.tap do |obj|
      obj.delete(:type)
    end)
  end
end

def def_delegators(accessor, *methods)

def def_delegators(accessor, *methods)
  kwd = methods.shift if methods.first.is_a?(Hash)
  kwd = methods.pop   if methods. last.is_a?(Hash)
  kwd = {} unless kwd
  methods.each do |method|
    def_delegator accessor, method, **kwd
  end
end

def def_hash_delegator(hash, method, key: method, **kwd)

def def_hash_delegator(hash, method, key: method, **kwd)
  prefix, suffix, wrap = prepare_delegate(**kwd)
  if suffix
    method = method.to_s.gsub(
      /\?$/, ""
    )
  end
  class_eval delegate_debug(<<-STR), __FILE__, __LINE__ - 9
    def #{method}#{suffix}(*args)
      #{wrap}(
        #{prefix}#{hash}[#{key.inspect}]
      )
    rescue Exception
      if !Forwardable.debug && $@ && $@.respond_to?(:delete_if)
        $@.delete_if do |source|
          source =~ %r"#{Regexp.escape(__FILE__)}"o
        end
      end
      raise
    end
  STR
end

def def_ivar_delegator(ivar, alias_ = ivar, **kwd)

def def_ivar_delegator(ivar, alias_ = ivar, **kwd)
  prefix, suffix, wrap = prepare_delegate(**kwd)
  if suffix
    alias_ = alias_.to_s.gsub(
      /\?$/, ""
    )
  end
  class_eval delegate_debug(<<-STR), __FILE__, __LINE__ - 9
    def #{alias_.to_s.gsub(/\A@/, "")}#{suffix}
      #{wrap}(
        #{prefix}#{ivar}
      )
    rescue Exception
      if !Forwardable.debug && $@ && $@.respond_to?(:delete_if)
        $@.delete_if do |source|
          source =~ %r"#{Regexp.escape(__FILE__)}"o
        end
      end
      raise
    end
  STR
end

def def_modern_delegator(accessor, method, alias_ = method, args: \

def def_modern_delegator(accessor, method, alias_ = method, args: \
    { :before => [], :after => [] }, **kwd)
  prefix, suffix, wrap = prepare_delegate(**kwd)
  args = { :before => args } unless args.is_a?(Hash)
  b = [args[:before]].flatten.compact.map(&:to_s).join(", ")
  a = [args[ :after]].flatten.compact.map(&:to_s).join(", ")
  b = b + ", " unless args[:before].nil? || args[:before].empty?
  a = ", " + a unless args[ :after].nil? || args[ :after].empty?
  alias_ = alias_.to_s.gsub(/\?$/, "") if suffix
  class_eval delegate_debug(<<-STR), __FILE__, __LINE__ - 10
    def #{alias_}#{suffix}(*args, &block)
      #{wrap}(#{prefix}#{accessor}.send(
        #{method.inspect}, #{b}*args#{a}, &block
      ))
    rescue Exception
      if !Forwardable.debug && $@ && $@.respond_to?(:delete_if)
        $@.delete_if do |source|
          source =~ %r"#{Regexp.escape(__FILE__)}"o
        end
      end
      raise
    end
  STR
end

def delegate_debug(str)

def delegate_debug(str)
  if Forwardable.debug && !Forwardable.debug.is_a?(TrueClass)
    then Forwardable.debug.debug(
      str
    )
  elsif Forwardable.debug
    $stdout.puts(
      "\n# ------\n\n", str
    )
  end
  str
end

def prepare_delegate(wrap: nil, bool: false)

def prepare_delegate(wrap: nil, bool: false)
  prefix = (bool == :reverse ? "!!!" : "!!") if bool
  wrap   = "self.class.new" if wrap.is_a?(TrueClass)
  suffix = "?" if bool
  return [
    prefix, suffix, wrap
  ]
end

def rb_delegate(method, to: nil, alias_of: method, **kwd)

def rb_delegate(method, to: nil, alias_of: method, **kwd)
  raise ArgumentError, "to must be provided" unless to
  def_delegator(
    to, alias_of, method, **kwd
  )
end