real_include 0.1.6-i386-mingw32 → 0.1.7-i386-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +5 -1
- data/Rakefile +1 -1
- data/ext/real_include/patched_include.c +130 -0
- data/ext/real_include/real_include.c +6 -156
- data/ext/real_include/real_include_one.c +164 -0
- data/lib/1.8/real_include.so +0 -0
- data/lib/1.9/real_include.so +0 -0
- data/lib/real_include/version.rb +1 -1
- data/lib/real_include.rb +27 -0
- data/test/test.rb +137 -1
- metadata +7 -5
data/CHANGELOG
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
-
|
1
|
+
15/10/2010 version 0.1.7
|
2
|
+
* should be properly working with normal Module#include now
|
3
|
+
* no more segfaults?
|
4
|
+
* added more tests
|
5
|
+
6/10/2010 version 0.1.3
|
2
6
|
* fixed native gem
|
3
7
|
* moved more version-dependant code to compat.h
|
4
8
|
5/10/2010 version 0.1.2
|
data/Rakefile
CHANGED
@@ -23,7 +23,7 @@ specification = Gem::Specification.new do |s|
|
|
23
23
|
#s.platform = Gem::Platform::RUBY
|
24
24
|
s.platform = 'i386-mingw32'
|
25
25
|
s.homepage = "http://banisterfiend.wordpress.com"
|
26
|
-
s.has_rdoc =
|
26
|
+
s.has_rdoc = 'yard'
|
27
27
|
|
28
28
|
s.extensions = ["ext/real_include/extconf.rb"]
|
29
29
|
s.files = ["Rakefile", "README.markdown", "CHANGELOG",
|
@@ -0,0 +1,130 @@
|
|
1
|
+
/* (c) 2010 John Mair (banisterfiend), MIT license */
|
2
|
+
/* patches Module#include to work correctly with real_include */
|
3
|
+
|
4
|
+
#include <ruby.h>
|
5
|
+
#include "compat.h"
|
6
|
+
|
7
|
+
#ifdef RUBY_19
|
8
|
+
static VALUE
|
9
|
+
class_alloc(VALUE flags, VALUE klass)
|
10
|
+
{
|
11
|
+
rb_classext_t *ext = ALLOC(rb_classext_t);
|
12
|
+
NEWOBJ(obj, struct RClass);
|
13
|
+
OBJSETUP(obj, klass, flags);
|
14
|
+
obj->ptr = ext;
|
15
|
+
RCLASS_IV_TBL(obj) = 0;
|
16
|
+
RCLASS_M_TBL(obj) = 0;
|
17
|
+
RCLASS_SUPER(obj) = 0;
|
18
|
+
RCLASS_IV_INDEX_TBL(obj) = 0;
|
19
|
+
return (VALUE)obj;
|
20
|
+
}
|
21
|
+
#endif
|
22
|
+
|
23
|
+
/* patched to work well with real_include */
|
24
|
+
static VALUE
|
25
|
+
include_class_new(VALUE module, VALUE super)
|
26
|
+
{
|
27
|
+
#ifdef RUBY_19
|
28
|
+
VALUE klass = class_alloc(T_ICLASS, rb_cClass);
|
29
|
+
#else
|
30
|
+
NEWOBJ(klass, struct RClass);
|
31
|
+
OBJSETUP(klass, rb_singleton_class(rb_cModule), T_ICLASS);
|
32
|
+
#endif
|
33
|
+
|
34
|
+
if (BUILTIN_TYPE(module) == T_ICLASS) {
|
35
|
+
|
36
|
+
/***************************************************************************** */
|
37
|
+
/* This is the only change required, everything else is (pretty much) copypasta from class.c */
|
38
|
+
/* correct for real_include'd modules */
|
39
|
+
if (!NIL_P(rb_iv_get(module, "__module__")))
|
40
|
+
module = rb_iv_get(module, "__module__");
|
41
|
+
else
|
42
|
+
module = RBASIC(module)->klass;
|
43
|
+
/***************************************************************************** */
|
44
|
+
|
45
|
+
}
|
46
|
+
if (!RCLASS_IV_TBL(module)) {
|
47
|
+
RCLASS_IV_TBL(module) = st_init_numtable();
|
48
|
+
}
|
49
|
+
RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
|
50
|
+
RCLASS_M_TBL(klass) = RCLASS_M_TBL(module);
|
51
|
+
RCLASS_SUPER(klass) = super;
|
52
|
+
if (TYPE(module) == T_ICLASS) {
|
53
|
+
RBASIC(klass)->klass = RBASIC(module)->klass;
|
54
|
+
}
|
55
|
+
else {
|
56
|
+
RBASIC(klass)->klass = module;
|
57
|
+
}
|
58
|
+
OBJ_INFECT(klass, module);
|
59
|
+
OBJ_INFECT(klass, super);
|
60
|
+
|
61
|
+
return (VALUE)klass;
|
62
|
+
}
|
63
|
+
|
64
|
+
static void
|
65
|
+
rb_patched_include_module(VALUE klass, VALUE module)
|
66
|
+
{
|
67
|
+
VALUE p, c;
|
68
|
+
int changed = 0;
|
69
|
+
|
70
|
+
rb_frozen_class_p(klass);
|
71
|
+
if (!OBJ_UNTRUSTED(klass)) {
|
72
|
+
rb_secure(4);
|
73
|
+
}
|
74
|
+
|
75
|
+
if (TYPE(module) != T_MODULE) {
|
76
|
+
Check_Type(module, T_MODULE);
|
77
|
+
}
|
78
|
+
|
79
|
+
OBJ_INFECT(klass, module);
|
80
|
+
c = klass;
|
81
|
+
while (module) {
|
82
|
+
int superclass_seen = FALSE;
|
83
|
+
|
84
|
+
if (RCLASS_M_TBL(klass) == RCLASS_M_TBL(module))
|
85
|
+
rb_raise(rb_eArgError, "cyclic include detected");
|
86
|
+
/* ignore if the module included already in superclasses */
|
87
|
+
for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) {
|
88
|
+
switch (BUILTIN_TYPE(p)) {
|
89
|
+
case T_ICLASS:
|
90
|
+
if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) {
|
91
|
+
if (!superclass_seen) {
|
92
|
+
c = p; /* move insertion point */
|
93
|
+
}
|
94
|
+
goto skip;
|
95
|
+
}
|
96
|
+
break;
|
97
|
+
case T_CLASS:
|
98
|
+
superclass_seen = TRUE;
|
99
|
+
break;
|
100
|
+
}
|
101
|
+
}
|
102
|
+
c = RCLASS_SUPER(c) = include_class_new(module, RCLASS_SUPER(c));
|
103
|
+
if (RMODULE_M_TBL(module) && RMODULE_M_TBL(module)->num_entries)
|
104
|
+
changed = 1;
|
105
|
+
skip:
|
106
|
+
module = RCLASS_SUPER(module);
|
107
|
+
}
|
108
|
+
if (changed) rb_clear_cache();
|
109
|
+
}
|
110
|
+
|
111
|
+
static VALUE
|
112
|
+
rb_patched_mod_append_features(VALUE module, VALUE include)
|
113
|
+
{
|
114
|
+
switch (TYPE(include)) {
|
115
|
+
case T_CLASS:
|
116
|
+
case T_MODULE:
|
117
|
+
break;
|
118
|
+
default:
|
119
|
+
Check_Type(include, T_CLASS);
|
120
|
+
break;
|
121
|
+
}
|
122
|
+
rb_patched_include_module(include, module);
|
123
|
+
|
124
|
+
return module;
|
125
|
+
}
|
126
|
+
|
127
|
+
void
|
128
|
+
Init_patched_include() {
|
129
|
+
rb_define_method(rb_cModule, "append_features", rb_patched_mod_append_features, 1);
|
130
|
+
}
|
@@ -1,161 +1,11 @@
|
|
1
1
|
/* (c) 2010 John Mair (banisterfiend), MIT license */
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
#ifdef RUBY_19
|
7
|
-
static VALUE
|
8
|
-
class_alloc(VALUE flags, VALUE klass)
|
9
|
-
{
|
10
|
-
rb_classext_t *ext = ALLOC(rb_classext_t);
|
11
|
-
NEWOBJ(obj, struct RClass);
|
12
|
-
OBJSETUP(obj, klass, flags);
|
13
|
-
obj->ptr = ext;
|
14
|
-
RCLASS_IV_TBL(obj) = 0;
|
15
|
-
RCLASS_M_TBL(obj) = 0;
|
16
|
-
RCLASS_SUPER(obj) = 0;
|
17
|
-
RCLASS_IV_INDEX_TBL(obj) = 0;
|
18
|
-
return (VALUE)obj;
|
19
|
-
}
|
20
|
-
#endif
|
21
|
-
|
22
|
-
|
23
|
-
static VALUE
|
24
|
-
class_to_s(VALUE self)
|
25
|
-
{
|
26
|
-
VALUE attached = rb_iv_get(self, "__attached__");
|
27
|
-
|
28
|
-
if (attached)
|
29
|
-
return rb_mod_name(rb_iv_get(attached, "__module__"));
|
30
|
-
else
|
31
|
-
return rb_mod_name(rb_iv_get(self, "__module__"));
|
32
|
-
}
|
33
|
-
|
34
|
-
static VALUE
|
35
|
-
include_class_new(VALUE module, VALUE super)
|
36
|
-
{
|
37
|
-
/* base case for recursion */
|
38
|
-
if (module == rb_singleton_class(rb_cModule))
|
39
|
-
return module;
|
40
|
-
|
41
|
-
if (TYPE(module) == T_ICLASS) {
|
42
|
-
|
43
|
-
/* real_include */
|
44
|
-
if (rb_iv_get(module, "__module__"))
|
45
|
-
module = rb_iv_get(module, "__module__");
|
46
|
-
|
47
|
-
/* ordinary Module#include */
|
48
|
-
else
|
49
|
-
module = KLASS_OF(module);
|
50
|
-
}
|
51
|
-
|
52
|
-
/* allocate iclass */
|
53
|
-
#ifdef RUBY_19
|
54
|
-
VALUE klass = class_alloc(T_ICLASS, rb_singleton_class(rb_cModule));
|
55
|
-
#else
|
56
|
-
NEWOBJ(klass, struct RClass);
|
57
|
-
OBJSETUP(klass, rb_singleton_class(rb_cModule), T_ICLASS);
|
58
|
-
#endif
|
59
|
-
/* we want a fresh ivtbl */
|
60
|
-
RCLASS_IV_TBL(klass) = st_init_numtable();
|
61
|
-
|
62
|
-
/* we want to copy the mtbl */
|
63
|
-
RCLASS_M_TBL(klass) = RCLASS_M_TBL(module);
|
64
|
-
RCLASS_SUPER(klass) = super;
|
65
|
-
|
66
|
-
if (TYPE(module) == T_MODULE || FL_TEST(module, FL_SINGLETON))
|
67
|
-
rb_iv_set(klass, "__module__", module);
|
68
|
-
|
69
|
-
/* create IClass for module's singleton */
|
70
|
-
/* if super is 0 then we're including into a module (not a class), so treat as special case */
|
71
|
-
VALUE meta = include_class_new(KLASS_OF(module), super ? KLASS_OF(super) : rb_cModule);
|
72
|
-
|
73
|
-
/* don't mess with (Module) */
|
74
|
-
if (meta != rb_singleton_class(rb_cModule)) {
|
75
|
-
|
76
|
-
/* set it as a singleton */
|
77
|
-
FL_SET(meta, FL_SINGLETON);
|
78
|
-
|
79
|
-
/* attach singleton to module */
|
80
|
-
rb_iv_set(meta, "__attached__", klass);
|
81
|
-
|
82
|
-
/* attach the #to_s method to the metaclass (so #ancestors doesn't look weird) */
|
83
|
-
rb_define_singleton_method(meta, "to_s", class_to_s, 0);
|
84
|
-
}
|
85
|
-
/* assign the metaclass to module's klass */
|
86
|
-
KLASS_OF(klass) = meta;
|
87
|
-
|
88
|
-
OBJ_INFECT(klass, module);
|
89
|
-
OBJ_INFECT(klass, super);
|
90
|
-
|
91
|
-
return (VALUE)klass;
|
92
|
-
}
|
93
|
-
|
94
|
-
VALUE
|
95
|
-
rb_real_include_module(VALUE klass, VALUE module)
|
96
|
-
{
|
97
|
-
VALUE p, c;
|
98
|
-
int changed = 0;
|
99
|
-
|
100
|
-
rb_frozen_class_p(klass);
|
101
|
-
if (!OBJ_UNTRUSTED(klass)) {
|
102
|
-
rb_secure(4);
|
103
|
-
}
|
104
|
-
|
105
|
-
if (TYPE(module) != T_MODULE) {
|
106
|
-
Check_Type(module, T_MODULE);
|
107
|
-
}
|
108
|
-
|
109
|
-
OBJ_INFECT(klass, module);
|
110
|
-
c = klass;
|
111
|
-
|
112
|
-
/* ensure singleton classes exist, both for includer and includee */
|
113
|
-
rb_singleton_class(module);
|
114
|
-
rb_singleton_class(klass);
|
115
|
-
|
116
|
-
while (module) {
|
117
|
-
int superclass_seen = FALSE;
|
118
|
-
|
119
|
-
if (RCLASS_M_TBL(klass) == RCLASS_M_TBL(module))
|
120
|
-
rb_raise(rb_eArgError, "cyclic include detected");
|
121
|
-
/* ignore if the module included already in superclasses */
|
122
|
-
for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) {
|
123
|
-
switch (BUILTIN_TYPE(p)) {
|
124
|
-
case T_ICLASS:
|
125
|
-
if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) {
|
126
|
-
if (!superclass_seen) {
|
127
|
-
c = p; /* move insertion point */
|
128
|
-
}
|
129
|
-
goto skip;
|
130
|
-
}
|
131
|
-
break;
|
132
|
-
case T_CLASS:
|
133
|
-
superclass_seen = TRUE;
|
134
|
-
break;
|
135
|
-
}
|
136
|
-
}
|
137
|
-
|
138
|
-
/* we're including the module, so create the iclass */
|
139
|
-
VALUE imod = include_class_new(module, RCLASS_SUPER(c));
|
140
|
-
|
141
|
-
/* module gets included directly above c, so set the super */
|
142
|
-
RCLASS_SUPER(c) = imod;
|
143
|
-
|
144
|
-
/* also do the same for parallel inheritance chain (singleton classes) */
|
145
|
-
RCLASS_SUPER(KLASS_OF(c)) = KLASS_OF(imod);
|
146
|
-
c = imod;
|
147
|
-
|
148
|
-
if (RMODULE_M_TBL(module) && RMODULE_M_TBL(module)->num_entries)
|
149
|
-
changed = 1;
|
150
|
-
skip:
|
151
|
-
module = RCLASS_SUPER(module);
|
152
|
-
}
|
153
|
-
if (changed) rb_clear_cache();
|
154
|
-
|
155
|
-
return Qnil;
|
156
|
-
}
|
3
|
+
void Init_patched_include(void);
|
4
|
+
void Init_real_include_one(void);
|
157
5
|
|
158
6
|
void
|
159
|
-
Init_real_include()
|
160
|
-
|
7
|
+
Init_real_include()
|
8
|
+
{
|
9
|
+
Init_real_include_one();
|
10
|
+
Init_patched_include();
|
161
11
|
}
|
@@ -0,0 +1,164 @@
|
|
1
|
+
/* (c) 2010 John Mair (banisterfiend), MIT license */
|
2
|
+
/* include a module (and its singleton) into an inheritance chain */
|
3
|
+
/* only includes a single module, see real_include.rb for multi-module version */
|
4
|
+
|
5
|
+
#include <ruby.h>
|
6
|
+
#include "compat.h"
|
7
|
+
|
8
|
+
#ifdef RUBY_19
|
9
|
+
static VALUE
|
10
|
+
class_alloc(VALUE flags, VALUE klass)
|
11
|
+
{
|
12
|
+
rb_classext_t *ext = ALLOC(rb_classext_t);
|
13
|
+
NEWOBJ(obj, struct RClass);
|
14
|
+
OBJSETUP(obj, klass, flags);
|
15
|
+
obj->ptr = ext;
|
16
|
+
RCLASS_IV_TBL(obj) = 0;
|
17
|
+
RCLASS_M_TBL(obj) = 0;
|
18
|
+
RCLASS_SUPER(obj) = 0;
|
19
|
+
RCLASS_IV_INDEX_TBL(obj) = 0;
|
20
|
+
return (VALUE)obj;
|
21
|
+
}
|
22
|
+
#endif
|
23
|
+
|
24
|
+
|
25
|
+
static VALUE
|
26
|
+
class_to_s(VALUE self)
|
27
|
+
{
|
28
|
+
VALUE attached = rb_iv_get(self, "__attached__");
|
29
|
+
|
30
|
+
if (attached)
|
31
|
+
return rb_mod_name(rb_iv_get(attached, "__module__"));
|
32
|
+
else
|
33
|
+
return rb_mod_name(rb_iv_get(self, "__module__"));
|
34
|
+
}
|
35
|
+
|
36
|
+
/* totally hacked up version of include_class_new() from class.c; brings in singletons into inheritance chain */
|
37
|
+
static VALUE
|
38
|
+
include_class_new(VALUE module, VALUE super)
|
39
|
+
{
|
40
|
+
/* base case for recursion */
|
41
|
+
if (module == rb_singleton_class(rb_cModule))
|
42
|
+
return module;
|
43
|
+
|
44
|
+
if (TYPE(module) == T_ICLASS) {
|
45
|
+
|
46
|
+
/* real_include */
|
47
|
+
if (!NIL_P(rb_iv_get(module, "__module__")))
|
48
|
+
module = rb_iv_get(module, "__module__");
|
49
|
+
|
50
|
+
/* ordinary Module#include */
|
51
|
+
else
|
52
|
+
module = KLASS_OF(module);
|
53
|
+
}
|
54
|
+
|
55
|
+
/* allocate iclass */
|
56
|
+
#ifdef RUBY_19
|
57
|
+
VALUE klass = class_alloc(T_ICLASS, rb_singleton_class(rb_cModule));
|
58
|
+
#else
|
59
|
+
NEWOBJ(klass, struct RClass);
|
60
|
+
OBJSETUP(klass, rb_singleton_class(rb_cModule), T_ICLASS);
|
61
|
+
#endif
|
62
|
+
/* we want a fresh ivtbl */
|
63
|
+
RCLASS_IV_TBL(klass) = st_init_numtable();
|
64
|
+
|
65
|
+
/* we want to copy the mtbl */
|
66
|
+
RCLASS_M_TBL(klass) = RCLASS_M_TBL(module);
|
67
|
+
RCLASS_SUPER(klass) = super;
|
68
|
+
|
69
|
+
if (TYPE(module) == T_MODULE || FL_TEST(module, FL_SINGLETON))
|
70
|
+
rb_iv_set((VALUE)klass, "__module__", module);
|
71
|
+
|
72
|
+
/* create IClass for module's singleton */
|
73
|
+
/* if super is 0 then we're including into a module (not a class), so treat as special case */
|
74
|
+
VALUE meta = include_class_new(KLASS_OF(module), super ? KLASS_OF(super) : rb_cModule);
|
75
|
+
|
76
|
+
/* don't mess with (Module) */
|
77
|
+
if (meta != rb_singleton_class(rb_cModule)) {
|
78
|
+
|
79
|
+
/* set it as a singleton */
|
80
|
+
FL_SET(meta, FL_SINGLETON);
|
81
|
+
|
82
|
+
/* attach singleton to module */
|
83
|
+
rb_iv_set(meta, "__attached__", (VALUE)klass);
|
84
|
+
|
85
|
+
/* attach the #to_s method to the metaclass (so #ancestors doesn't look weird) */
|
86
|
+
rb_define_singleton_method(meta, "to_s", class_to_s, 0);
|
87
|
+
}
|
88
|
+
/* assign the metaclass to module's klass */
|
89
|
+
KLASS_OF(klass) = meta;
|
90
|
+
|
91
|
+
OBJ_INFECT(klass, module);
|
92
|
+
OBJ_INFECT(klass, super);
|
93
|
+
|
94
|
+
return (VALUE)klass;
|
95
|
+
}
|
96
|
+
|
97
|
+
static VALUE
|
98
|
+
rb_real_include_module_one(VALUE klass, VALUE module)
|
99
|
+
{
|
100
|
+
VALUE p, c;
|
101
|
+
int changed = 0;
|
102
|
+
|
103
|
+
rb_frozen_class_p(klass);
|
104
|
+
if (!OBJ_UNTRUSTED(klass)) {
|
105
|
+
rb_secure(4);
|
106
|
+
}
|
107
|
+
|
108
|
+
if (TYPE(module) != T_MODULE) {
|
109
|
+
Check_Type(module, T_MODULE);
|
110
|
+
}
|
111
|
+
|
112
|
+
OBJ_INFECT(klass, module);
|
113
|
+
c = klass;
|
114
|
+
|
115
|
+
/* ensure singleton classes exist, both for includer and includee */
|
116
|
+
rb_singleton_class(module);
|
117
|
+
rb_singleton_class(klass);
|
118
|
+
|
119
|
+
while (module) {
|
120
|
+
int superclass_seen = FALSE;
|
121
|
+
|
122
|
+
if (RCLASS_M_TBL(klass) == RCLASS_M_TBL(module))
|
123
|
+
rb_raise(rb_eArgError, "cyclic include detected");
|
124
|
+
/* ignore if the module included already in superclasses */
|
125
|
+
for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) {
|
126
|
+
switch (BUILTIN_TYPE(p)) {
|
127
|
+
case T_ICLASS:
|
128
|
+
if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) {
|
129
|
+
if (!superclass_seen) {
|
130
|
+
c = p; /* move insertion point */
|
131
|
+
}
|
132
|
+
goto skip;
|
133
|
+
}
|
134
|
+
break;
|
135
|
+
case T_CLASS:
|
136
|
+
superclass_seen = TRUE;
|
137
|
+
break;
|
138
|
+
}
|
139
|
+
}
|
140
|
+
|
141
|
+
/* we're including the module, so create the iclass */
|
142
|
+
VALUE imod = include_class_new(module, RCLASS_SUPER(c));
|
143
|
+
|
144
|
+
/* module gets included directly above c, so set the super */
|
145
|
+
RCLASS_SUPER(c) = imod;
|
146
|
+
|
147
|
+
/* also do the same for parallel inheritance chain (singleton classes) */
|
148
|
+
RCLASS_SUPER(KLASS_OF(c)) = KLASS_OF(imod);
|
149
|
+
c = imod;
|
150
|
+
|
151
|
+
if (RMODULE_M_TBL(module) && RMODULE_M_TBL(module)->num_entries)
|
152
|
+
changed = 1;
|
153
|
+
skip:
|
154
|
+
module = RCLASS_SUPER(module);
|
155
|
+
}
|
156
|
+
if (changed) rb_clear_cache();
|
157
|
+
|
158
|
+
return Qnil;
|
159
|
+
}
|
160
|
+
|
161
|
+
void
|
162
|
+
Init_real_include_one() {
|
163
|
+
rb_define_method(rb_cModule, "real_include_one", rb_real_include_module_one, 1);
|
164
|
+
}
|
data/lib/1.8/real_include.so
CHANGED
Binary file
|
data/lib/1.9/real_include.so
CHANGED
Binary file
|
data/lib/real_include/version.rb
CHANGED
data/lib/real_include.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# (c) 2010 John Mair (banisterfiend), MIT license
|
2
|
+
|
1
3
|
direc = File.dirname(__FILE__)
|
2
4
|
|
3
5
|
begin
|
@@ -13,3 +15,28 @@ rescue LoadError => e
|
|
13
15
|
end
|
14
16
|
|
15
17
|
require "#{direc}/real_include/version"
|
18
|
+
|
19
|
+
|
20
|
+
class Module
|
21
|
+
|
22
|
+
# include multiple modules (and their singletons) into an
|
23
|
+
# inheritance chain
|
24
|
+
# @param [Module] mods Modules to real_include
|
25
|
+
# @return Returns the receiver
|
26
|
+
# @example
|
27
|
+
# module M
|
28
|
+
# def self.hello
|
29
|
+
# puts "hello"
|
30
|
+
# end
|
31
|
+
# end
|
32
|
+
# class C
|
33
|
+
# real_include M
|
34
|
+
# end
|
35
|
+
# C.hello #=> "hello"
|
36
|
+
def real_include(*mods)
|
37
|
+
mods.each do |mod|
|
38
|
+
real_include_one mod
|
39
|
+
end
|
40
|
+
self
|
41
|
+
end
|
42
|
+
end
|
data/test/test.rb
CHANGED
@@ -51,7 +51,6 @@ describe 'Including a module into a module and then into a class using real_incl
|
|
51
51
|
:instance_method2
|
52
52
|
end
|
53
53
|
}
|
54
|
-
|
55
54
|
@m2.send(:real_include, @m1)
|
56
55
|
|
57
56
|
@c = Class.new
|
@@ -74,4 +73,141 @@ describe 'Including a module into a module and then into a class using real_incl
|
|
74
73
|
obj.instance_method1.should.equal :instance_method1
|
75
74
|
obj.instance_method2.should.equal :instance_method2
|
76
75
|
end
|
76
|
+
|
77
|
+
it 'should make ancestor chain "look" accurate' do
|
78
|
+
@m1 = Module.new {
|
79
|
+
def self.class_method1
|
80
|
+
:class_method1
|
81
|
+
end
|
82
|
+
|
83
|
+
def instance_method1
|
84
|
+
:instance_method1
|
85
|
+
end
|
86
|
+
}
|
87
|
+
|
88
|
+
Object.const_set(:M1, @m1)
|
89
|
+
|
90
|
+
@m2 = Module.new {
|
91
|
+
def self.class_method2
|
92
|
+
:class_method2
|
93
|
+
end
|
94
|
+
|
95
|
+
def instance_method2
|
96
|
+
:instance_method2
|
97
|
+
end
|
98
|
+
}
|
99
|
+
Object.const_set(:M2, @m2)
|
100
|
+
|
101
|
+
@m2.send(:real_include, @m1)
|
102
|
+
|
103
|
+
@c = Class.new
|
104
|
+
|
105
|
+
@c.send(:real_include, @m2)
|
106
|
+
|
107
|
+
@c.ancestors[1].to_s.should.equal M2.name
|
108
|
+
@c.class_method1.should.equal :class_method1
|
109
|
+
@c.class_method2.should.equal :class_method2
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'should work if real_including a module that has another module included using Module#include' do
|
113
|
+
@m1 = Module.new {
|
114
|
+
def self.class_method1
|
115
|
+
:class_method1
|
116
|
+
end
|
117
|
+
|
118
|
+
def instance_method1
|
119
|
+
:instance_method1
|
120
|
+
end
|
121
|
+
}
|
122
|
+
|
123
|
+
Object.const_set(:N1, @m1)
|
124
|
+
|
125
|
+
@m2 = Module.new {
|
126
|
+
def self.class_method2
|
127
|
+
:class_method2
|
128
|
+
end
|
129
|
+
|
130
|
+
def instance_method2
|
131
|
+
:instance_method2
|
132
|
+
end
|
133
|
+
}
|
134
|
+
Object.const_set(:N2, @m2)
|
135
|
+
|
136
|
+
@m2.send(:include, @m1)
|
137
|
+
|
138
|
+
@c = Class.new
|
139
|
+
|
140
|
+
@c.send(:real_include, @m2)
|
141
|
+
|
142
|
+
@c.ancestors[1].to_s.should.equal N2.name
|
143
|
+
@c.ancestors[2].to_s.should.equal N1.name
|
144
|
+
@c.class_method1.should.equal :class_method1
|
145
|
+
@c.class_method2.should.equal :class_method2
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'should work if Module#including a module that has another module included using real_include' do
|
149
|
+
@m1 = Module.new {
|
150
|
+
def self.class_method1
|
151
|
+
:class_method1
|
152
|
+
end
|
153
|
+
|
154
|
+
def instance_method1
|
155
|
+
:instance_method1
|
156
|
+
end
|
157
|
+
}
|
158
|
+
|
159
|
+
Object.const_set(:K1, @m1)
|
160
|
+
|
161
|
+
@m2 = Module.new {
|
162
|
+
def self.class_method2
|
163
|
+
:class_method2
|
164
|
+
end
|
165
|
+
|
166
|
+
def instance_method2
|
167
|
+
:instance_method2
|
168
|
+
end
|
169
|
+
}
|
170
|
+
Object.const_set(:K2, @m2)
|
171
|
+
|
172
|
+
@m2.send(:real_include, @m1)
|
173
|
+
|
174
|
+
@c = Class.new
|
175
|
+
|
176
|
+
@c.send(:include, @m2)
|
177
|
+
|
178
|
+
@c.ancestors[1].should.equal K2
|
179
|
+
@c.ancestors[2].should.equal K1
|
180
|
+
@c.new.instance_method1.should.equal :instance_method1
|
181
|
+
@c.new.instance_method2.should.equal :instance_method2
|
182
|
+
end
|
183
|
+
|
184
|
+
|
185
|
+
it 'should work with multiple modules passed to real_include' do
|
186
|
+
@m1 = Module.new {
|
187
|
+
def self.class_method1
|
188
|
+
:class_method1
|
189
|
+
end
|
190
|
+
|
191
|
+
def instance_method1
|
192
|
+
:instance_method1
|
193
|
+
end
|
194
|
+
}
|
195
|
+
|
196
|
+
@m2 = Module.new {
|
197
|
+
def self.class_method2
|
198
|
+
:class_method2
|
199
|
+
end
|
200
|
+
|
201
|
+
def instance_method2
|
202
|
+
:instance_method2
|
203
|
+
end
|
204
|
+
}
|
205
|
+
|
206
|
+
@c = Class.new
|
207
|
+
@c.send(:real_include, @m2, @m1)
|
208
|
+
|
209
|
+
@c.class_method1.should.equal :class_method1
|
210
|
+
@c.class_method2.should.equal :class_method2
|
211
|
+
end
|
212
|
+
|
77
213
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: real_include
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 7
|
10
|
+
version: 0.1.7
|
11
11
|
platform: i386-mingw32
|
12
12
|
authors:
|
13
13
|
- John Mair (banisterfiend)
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-10-
|
18
|
+
date: 2010-10-16 00:00:00 +13:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|
@@ -37,9 +37,11 @@ files:
|
|
37
37
|
- lib/1.8/real_include.so
|
38
38
|
- ext/real_include/extconf.rb
|
39
39
|
- ext/real_include/compat.h
|
40
|
+
- ext/real_include/patched_include.c
|
40
41
|
- ext/real_include/real_include.c
|
42
|
+
- ext/real_include/real_include_one.c
|
41
43
|
- test/test.rb
|
42
|
-
has_rdoc:
|
44
|
+
has_rdoc: yard
|
43
45
|
homepage: http://banisterfiend.wordpress.com
|
44
46
|
licenses: []
|
45
47
|
|