Module: Compound::Host
- Defined in:
- lib/compound/host.rb
Overview
Include this module in a class to gain the ability to host Parts, which each embody a module, appearing to an outside object as if the modules themselves were mixed in, while maintaining separation among the modules. Refer to the README for more information
Instance Method Summary collapse
-
#compound(mod) ⇒ Object
Internalize a new Part embodying the given module.
-
#is_a?(mod) ⇒ Boolean
Pretend that the compounded modules are in the inheritance tree.
-
#kind_of?(mod) ⇒ Boolean
Pretend that the compounded modules are in the inheritance tree.
-
#method(sym) ⇒ Object
Return the Method object associated with the symbol, even if it is in one of the Parts and not the Host.
-
#method_missing(sym, *args, &block) ⇒ Object
Forward an undefined method if it is in one of the Parts.
-
#respond_to?(sym, *rest) ⇒ Boolean
Pretend to also respond_to methods in the Parts as well as the Host.
-
#uncompound(mod) ⇒ Object
Remove the Part associated with the given module.
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(sym, *args, &block) ⇒ Object
Forward an undefined method if it is in one of the Parts
37 38 39 40 41 |
# File 'lib/compound/host.rb', line 37 def method_missing sym, *args, &block component = @_compound_parts && @_compound_parts.detect { |obj| obj.respond_to? sym } component ? (component.send sym, *args, &block) : super end |
Instance Method Details
#compound(mod) ⇒ Object
Internalize a new Part embodying the given module
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/compound/host.rb', line 11 def compound mod first_time_array = nil @_compound_parts ||= (first_time_array=[]) # Pretend that the compounded modules are in the inheritance tree singleton_class.send :define_singleton_method, :ancestors do super() + first_time_array.map { |part| part.instance_variable_get(:@_compound_component_module) } end if first_time_array uncompound mod @_compound_parts.unshift ::Compound::Part.new self, mod mod.compounded(self) if mod.respond_to? :compounded return mod end |
#is_a?(mod) ⇒ Boolean
Pretend that the compounded modules are in the inheritance tree
67 68 69 70 71 |
# File 'lib/compound/host.rb', line 67 def is_a? mod super or !!(@_compound_parts && @_compound_parts.detect { |part| part.instance_variable_get(:@_compound_component_module) == mod }) end |
#kind_of?(mod) ⇒ Boolean
Pretend that the compounded modules are in the inheritance tree
60 61 62 63 64 |
# File 'lib/compound/host.rb', line 60 def kind_of? mod super or !!(@_compound_parts && @_compound_parts.detect { |part| part.instance_variable_get(:@_compound_component_module) == mod }) end |
#method(sym) ⇒ Object
Return the Method object associated with the symbol, even if it is in one of the Parts and not the Host
51 52 53 54 55 56 57 |
# File 'lib/compound/host.rb', line 51 def method sym return super if methods.include? sym component = @_compound_parts && @_compound_parts.detect { |obj| obj.respond_to? sym } component ? component.method(sym) : raise(NameError, "undefined method `#{sym}' for object `#{self}'") end |
#respond_to?(sym, *rest) ⇒ Boolean
Pretend to also respond_to methods in the Parts as well as the Host
44 45 46 47 |
# File 'lib/compound/host.rb', line 44 def respond_to? sym, *rest super || !!(@_compound_parts && @_compound_parts.detect { |obj| obj.respond_to? sym }) end |
#uncompound(mod) ⇒ Object
Remove the Part associated with the given module
29 30 31 32 33 34 |
# File 'lib/compound/host.rb', line 29 def uncompound mod (@_compound_parts && (@_compound_parts.reject! { |part| part.instance_variable_get(:@_compound_component_module) == mod } ? mod : nil)) end |