Sha256: 4aa427d5bdab5f0793892ec2d91051b71cc0455ac938b7651da38c7896200d89

Contents?: true

Size: 1.82 KB

Versions: 3

Compression:

Stored size: 1.82 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.new(delegated_method_name, self)
    end

    def cast(delegated_method_name, attendant, *args, &block)
      validate_attendant(attendant)
      delegation(delegated_method_name).to(attendant).with(*args, &block).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

3 entries across 3 versions & 1 rubygems

Version Path
casting-0.7.2 lib/casting/client.rb
casting-0.7.1 lib/casting/client.rb
casting-0.7.0 lib/casting/client.rb