module Casting::SuperDelegate

Public Instance Methods

calling_location(call_stack) click to toggle source
# File lib/casting/super_delegate.rb, line 51
def calling_location(call_stack)
  call_stack.reject { |line|
    line.to_s.match? Regexp.union(casting_library_matcher, gem_home_matcher, debugging_matcher)
  }.first
end
casting_library_matcher() click to toggle source
# File lib/casting/super_delegate.rb, line 61
def casting_library_matcher
  Regexp.new(Dir.pwd.to_s + "/lib")
end
debugging_matcher() click to toggle source
# File lib/casting/super_delegate.rb, line 69
def debugging_matcher
  Regexp.new("internal:trace_point")
end
gem_home_matcher() click to toggle source
# File lib/casting/super_delegate.rb, line 65
def gem_home_matcher
  Regexp.new(ENV["GEM_HOME"])
end
method_delegate_skipping(meth, skipped) click to toggle source
# File lib/casting/super_delegate.rb, line 44
def method_delegate_skipping(meth, skipped)
  skipped_index = __delegates__.index(skipped)
  __delegates__[(skipped_index + 1)..__delegates__.length].find { |attendant|
    attendant_methods(attendant).include?(meth)
  }
end
name_of_calling_method(call_stack) click to toggle source
# File lib/casting/super_delegate.rb, line 57
def name_of_calling_method(call_stack)
  calling_location(call_stack).label.to_sym
end
super_delegate(mod = :none, *args, **kwargs, &block) click to toggle source

Call the method of the same name defined in the next delegate stored in your object

Because Casting creates an alternative method lookup path using a collection of delegates, you may use ‘super_delegate` to work like `super`.

If you use this feature, be sure that you have created a delegate collection which does have the method you need or you’ll see a NoMethodError.

Example:

module Greeter

def greet
  "Hello"
end

end

module FormalGreeter

include Casting::Super

def greet
  "#{super_delegate}, how do you do?"
end

end

some_object.cast_as(Greeter, FormalGreeter) some_object.greet #=> ‘Hello, how do you do?’

# File lib/casting/super_delegate.rb, line 30
def super_delegate(mod = :none, *args, **kwargs, &block)
  method_name = name_of_calling_method(caller_locations)
  owner = (mod unless mod == :none) || method_delegate(method_name)

  super_delegate_method = unbound_method_from_next_delegate(method_name, owner)
  super_delegate_method.bind_call(self, *args, **kwargs, &block)
rescue NameError
  raise NoMethodError.new("super_delegate: no delegate method `#{method_name}' for #{inspect} from #{owner}")
end
unbound_method_from_next_delegate(method_name, *skipped) click to toggle source
# File lib/casting/super_delegate.rb, line 40
def unbound_method_from_next_delegate(method_name, *skipped)
  method_delegate_skipping(method_name, *skipped).instance_method(method_name)
end