real_include 0.1.6-i386-mswin32 → 0.1.7-i386-mswin32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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.rb +27 -0
- data/lib/real_include/version.rb +1 -1
- 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-mswin32'
|
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.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/lib/real_include/version.rb
CHANGED
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-mswin32
|
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
|
|