Module: Casting::SuperDelegate
- Defined in:
- lib/casting/super_delegate.rb
Instance Method Summary collapse
- #casting_library_matcher ⇒ Object
- #method_delegate_skipping(meth, skipped) ⇒ Object
- #name_of_calling_method(call_stack) ⇒ Object
-
#super_delegate(*args, &block) ⇒ Object
Call the method of the same name defined in the next delegate stored in your object.
- #unbound_method_from_next_delegate(method_name, *skipped) ⇒ Object
Instance Method Details
#casting_library_matcher ⇒ Object
64 65 66 |
# File 'lib/casting/super_delegate.rb', line 64 def casting_library_matcher Regexp.new(Dir.pwd.to_s + '/lib') end |
#method_delegate_skipping(meth, skipped) ⇒ Object
50 51 52 53 54 55 56 |
# File 'lib/casting/super_delegate.rb', line 50 def method_delegate_skipping(meth, skipped) skipped_index = __delegates__.index(skipped) __delegates__.find{|attendant| attendant_methods(attendant).include?(meth) && skipped_index < __delegates__.index(attendant) } end |
#name_of_calling_method(call_stack) ⇒ Object
58 59 60 61 62 |
# File 'lib/casting/super_delegate.rb', line 58 def name_of_calling_method(call_stack) call_stack.reject{|line| line.to_s =~ casting_library_matcher }.first.split('`').last.sub("'","").to_sym end |
#super_delegate(*args, &block) ⇒ Object
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?’
31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/casting/super_delegate.rb', line 31 def super_delegate(*args, &block) method_name = name_of_calling_method(caller) owner = args.first || method_delegate(method_name) super_delegate_method = unbound_method_from_next_delegate(method_name, owner) if super_delegate_method.arity == 0 super_delegate_method.bind(self).call else super_delegate_method.bind(self).call(*args, &block) end rescue NameError raise NoMethodError.new("super_delegate: no delegate method `#{method_name}' for #{self.inspect} from #{owner}") end |
#unbound_method_from_next_delegate(method_name, *skipped) ⇒ Object
46 47 48 |
# File 'lib/casting/super_delegate.rb', line 46 def unbound_method_from_next_delegate(method_name, *skipped) method_delegate_skipping(method_name, *skipped).instance_method(method_name) end |