Class: Module
- Defined in:
- lib/ruby_ext/multiple_inheritance.rb,
lib/ruby_ext/synchronize.rb,
lib/ruby_ext/declarative_cache.rb,
lib/ruby_ext/multiple_inheritance.rb,
lib/ruby_ext/prototype_inheritance.rb
Overview
Fix for ruby’s broken include. Included modules doesn’t propagated to it’s children.
Test case: module A; end module B
include A
end
module Plugin; end A.send(:include, Plugin)
p “Ancestors of A: ” + A.ancestors.join(‘, ’) # => “Ancestors of A: A, Plugin” p “Ancestors of B: ” + B.ancestors.join(‘, ’) # => “Ancestors of B: B, A” << NO PLUGIN!
Instance Method Summary collapse
- #cache_method(*methods) ⇒ Object
- #cache_method_with_params(*methods) ⇒ Object
- #class_methods(&block) ⇒ Object
- #class_prototype ⇒ Object
- #directly_included_by ⇒ Object
- #fixed_include(mod) ⇒ Object
- #inherit(*modules) ⇒ Object
- #synchronize_all_methods(include_super = false) ⇒ Object
- #synchronize_method(*methods) ⇒ Object
Instance Method Details
#cache_method(*methods) ⇒ Object
4 5 6 |
# File 'lib/ruby_ext/declarative_cache.rb', line 4 def cache_method *methods DeclarativeCache.cache_method self, *methods end |
#cache_method_with_params(*methods) ⇒ Object
8 9 10 |
# File 'lib/ruby_ext/declarative_cache.rb', line 8 def cache_method_with_params *methods DeclarativeCache.cache_method_with_params self, *methods end |
#class_methods(&block) ⇒ Object
51 52 53 54 55 56 57 58 |
# File 'lib/ruby_ext/multiple_inheritance.rb', line 51 def class_methods &block if block class_prototype.class_eval &block extend class_prototype else class_prototype.instance_methods end end |
#class_prototype ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/ruby_ext/multiple_inheritance.rb', line 39 def class_prototype unless @class_prototype unless const_defined? :ClassMethods class_eval "module ClassMethods; end", __FILE__, __LINE__ end @class_prototype = const_get :ClassMethods (class << self; self end).fixed_include @class_prototype end @class_prototype end |
#directly_included_by ⇒ Object
18 19 20 |
# File 'lib/ruby_ext/multiple_inheritance.rb', line 18 def directly_included_by @directly_included_by ||= Set.new end |
#fixed_include(mod) ⇒ Object
22 23 24 25 26 27 28 29 30 31 |
# File 'lib/ruby_ext/multiple_inheritance.rb', line 22 def fixed_include mod unless mod.directly_included_by.include? self mod.directly_included_by.add self end include mod directly_included_by.each do |child| child.fixed_include self end end |
#inherit(*modules) ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/ruby_ext/multiple_inheritance.rb', line 60 def inherit *modules modules.each do |mod| # Instance Methods fixed_include mod # Class Methods if self.class == Module class_prototype.fixed_include mod.class_prototype else (class << self; self end).fixed_include mod.class_prototype end # callback mod.inherited self if mod.respond_to? :inherited end end |
#synchronize_all_methods(include_super = false) ⇒ Object
20 21 22 23 |
# File 'lib/ruby_ext/synchronize.rb', line 20 def synchronize_all_methods include_super = false methods = self.instance_methods(include_super).collect{|m| m.to_sym} synchronize_method *methods end |
#synchronize_method(*methods) ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# File 'lib/ruby_ext/synchronize.rb', line 4 def synchronize_method *methods methods.each do |method| als = "sync_#{escape_method(method)}" raise "Can't synchronize the '#{method}' twice!" if instance_methods.include?(als) alias_method als, method script = "\ def #{method} *p, &b @monitor ||= Monitor.new @monitor.synchronize{#{als} *p, &b} end" class_eval script, __FILE__, __LINE__ end end |