Class: Module

Inherits:
Object show all
Defined in:
lib/ruby_ext/multiple_inheritance.rb,
lib/vresource/module.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

Instance Method Details

#[](resource_name) ⇒ Object



11
12
13
14
15
16
17
18
# File 'lib/vresource/module.rb', line 11

def [] resource_name
  self_ancestors_and_namespaces do |klass|
    if VResource.resource_exist? klass, resource_name
      return VResource.resource_get(klass, resource_name)
    end  
  end
  raise VResource::NotExist, "Resource '#{resource_name}' for Class '#{self.name}' doesn't exist!", caller
end

#[]=(resource_name, value) ⇒ Object



21
22
23
# File 'lib/vresource/module.rb', line 21

def []= resource_name, value
  VResource.resource_set self.name, resource_name, value
end

#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_prototypeObject



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_byObject



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

#resource_exist?(resource_name) ⇒ Boolean

TODO2 Cache it and next one

Returns:

  • (Boolean)


3
4
5
6
7
8
# File 'lib/vresource/module.rb', line 3

def resource_exist? resource_name    
  self_ancestors_and_namespaces do |klass|
    return true if VResource.resource_exist? klass, resource_name          
  end
  return false
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