Sha256: aa52c2baa0bd526ac2175bdfbb9b5aa8258409cd57a0a1a9d1f3367ed41a9604

Contents?: true

Size: 1.8 KB

Versions: 2

Compression:

Stored size: 1.8 KB

Contents

require 'casting/delegation'
require 'casting/missing_method_client'
require 'casting/missing_method_client_class'

module Casting
  module Client

    def self.included(base)
      def base.delegate_missing_methods(*which)
        Casting::Client.set_delegation_strategy(self, *which.reverse)
      end

      unless base.method_defined?('delegate')
        add_delegate_method_to(base)
      end
    end

    def self.extended(base)
      unless base.respond_to?('delegate')
        add_delegate_method_to(base.singleton_class)
      end
    end

    def delegation(delegated_method_name)
      Casting::Delegation.prepare(delegated_method_name, self)
    end

    def cast(delegated_method_name, attendant, ...)
      validate_attendant(attendant)
      delegation(delegated_method_name).to(attendant).call(...)
    end

    def delegate_missing_methods(*which)
      Casting::Client.set_delegation_strategy(self.singleton_class, *which.reverse)
    end

    private

    def validate_attendant(attendant)
      if attendant == self
        raise Casting::InvalidAttendant.new('client can not delegate to itself')
      end
    end

    def self.set_delegation_strategy(base, *which)
      which = [:instance] if which.empty?
      which.map!{|selection|
        selection == :instance && selection = self.method(:set_method_missing_client)
        selection == :class && selection = self.method(:set_method_missing_client_class)
        selection
      }.map{|meth| meth.call(base) }
    end

    def self.add_delegate_method_to(base)
      base.class_eval{ alias_method :delegate, :cast }
    end

    def self.set_method_missing_client(base)
      base.send(:include, ::Casting::MissingMethodClient)
    end

    def self.set_method_missing_client_class(base)
      base.send(:extend, ::Casting::MissingMethodClientClass)
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
casting-1.0.1 lib/casting/client.rb
casting-1.0.0 lib/casting/client.rb