public
Description: Ruby module exclusion functionality
Clone URL: git://github.com/yrashk/rbmodexcl.git
rbmodexcl / mrimodexcl.rb
100644 82 lines (72 sloc) 1.923 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
require 'rubygems'
require 'inline'
 
class Object
  inline(:C) do |builder|
    builder.prefix %{
static VALUE
rb_obj_dummy()
{
return Qnil;
}
}
    builder.add_to_init %{
rb_define_private_method(rb_cModule, "unextended", rb_obj_dummy, 1);
}
    builder.c %{
VALUE unextend(VALUE mod)
{
VALUE p, prev;
Check_Type(mod, T_MODULE);
if (mod == rb_mKernel)
rb_raise(rb_eArgError, "unextending Kernel is prohibited");
 
 
p = rb_singleton_class(self);
 
while (p) {
if (p == mod || RCLASS(p)->m_tbl == RCLASS(mod)->m_tbl) {
RCLASS(prev)->super = RCLASS(p)->super;
rb_clear_cache();
rb_funcall(mod, rb_intern("unextended"), 1, self);
return self;
}
prev = p;
p = RCLASS(p)->super;
}
return self;
}
}
    end
 
end
 
class Class
 
    inline(:C) do |builder|
      builder.prefix %{
static VALUE
rb_obj_dummy()
{
return Qnil;
}
}
      builder.add_to_init %{
rb_define_private_method(rb_cModule, "unincluded", rb_obj_dummy, 1);
}
      builder.c %{
VALUE uninclude(VALUE mod)
{
VALUE p, prev;
Check_Type(mod, T_MODULE);
if (mod == rb_mKernel)
rb_raise(rb_eArgError, "unincluding Kernel is prohibited");
 
p = self;
 
while (p) {
if (p == mod || RCLASS(p)->m_tbl == RCLASS(mod)->m_tbl) {
RCLASS(prev)->super = RCLASS(p)->super;
rb_clear_cache();
rb_funcall(mod, rb_intern("unincluded"), 1, self);
return self;
}
prev = p;
p = RCLASS(p)->super;
}
return self;
}
}
      end
 
end