public
Description: Ruby module exclusion functionality
Clone URL: git://github.com/yrashk/rbmodexcl.git
Search Repo:
yrashk (author)
Wed Apr 30 19:27:33 -0700 2008
commit  5445dba58fd7f033ef3a2f7dc6c973f796c8f1ab
tree    ff20fe4dfbde3a8f2d67b858ed4ebca73e908bd0
parent  949eb1d42b2a2ce5ccd32c08c3e354a1ac8cfc07
rbmodexcl / rbmodexcl.rb
100644 83 lines (72 sloc) 1.884 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
83
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