include_complete 0.1.0-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 ADDED
@@ -0,0 +1,20 @@
1
+ 1/11/2010 *NAME CHANGE* TO include_complete, version reset to 0.1.0
2
+ * now called include_complete
3
+ 22/10/2010 version 0.2.2
4
+ * refactored compat.h, incorporated test for 1.9
5
+ * created inline static function create_class() in compat.h
6
+ 20/10/2010 version 0.2.1
7
+ * constant lookup should now work
8
+ * added real_extend and tests
9
+ 15/10/2010 version 0.1.7
10
+ * should be properly working with normal Module#include now
11
+ * no more segfaults?
12
+ * added more tests
13
+ 6/10/2010 version 0.1.3
14
+ * fixed native gem
15
+ * moved more version-dependant code to compat.h
16
+ 5/10/2010 version 0.1.2
17
+ * added 1.8 support
18
+ * added bacon tests
19
+ 4/10/10 version 0.1.0
20
+ * release! This is still beta, not 100% tested yet..but appears to work OK so far
data/README.markdown ADDED
@@ -0,0 +1,40 @@
1
+ Include Complete
2
+ ----------------
3
+
4
+ (c) John Mair (banisterfiend)
5
+ MIT license
6
+
7
+ Removes the shackles from Module#include - use Module#real_include to
8
+ bring in singleton classes from modules. No more ugly ClassMethods and
9
+ included() hook hacks.
10
+
11
+ ** This is BETA software and has not yet been thoroughly tested, use
12
+ at own risk **
13
+
14
+ install the gem: **for testing purposes only**
15
+ `gem install include_complete`
16
+
17
+ example:
18
+
19
+ module M
20
+ # class method
21
+ def self.hello
22
+ puts "hello!"
23
+ end
24
+
25
+ # instance method
26
+ def bye
27
+ puts "bye!"
28
+ end
29
+ end
30
+
31
+ class A
32
+ include_complete M
33
+ end
34
+
35
+ # invoke class method
36
+ A.hello #=> hello!
37
+
38
+ # invoke instance method
39
+ A.new.bye #=> bye!
40
+
data/Rakefile ADDED
@@ -0,0 +1,59 @@
1
+ $LOAD_PATH.unshift File.join(File.expand_path(__FILE__), '..')
2
+
3
+ direc = File.dirname(__FILE__)
4
+ dlext = Config::CONFIG['DLEXT']
5
+
6
+ require 'rake/clean'
7
+ require 'rake/gempackagetask'
8
+ require './lib/include_complete/version'
9
+
10
+ CLEAN.include("ext/**/*.#{dlext}", "ext/**/*.log", "ext/**/*.o", "ext/**/*~", "ext/**/*#*", "ext/**/*.obj", "ext/**/*.def", "ext/**/*.pdb")
11
+ CLOBBER.include("**/*.#{dlext}", "**/*~", "**/*#*", "**/*.log", "**/*.o")
12
+
13
+ def apply_spec_defaults(s)
14
+ s.name = "include_complete"
15
+ s.summary = "Fixing the limitations in traditional Module#include"
16
+ s.version = IncludeComplete::VERSION
17
+ s.date = Time.now.strftime '%Y-%m-%d'
18
+ s.author = "John Mair (banisterfiend)"
19
+ s.email = 'jrmair@gmail.com'
20
+ s.description = s.summary
21
+ s.require_path = 'lib'
22
+ s.homepage = "http://banisterfiend.wordpress.com"
23
+ s.has_rdoc = 'yard'
24
+ s.files = FileList["Rakefile", "README.markdown", "CHANGELOG",
25
+ "lib/**/*.rb", "ext/**/extconf.rb", "ext/**/*.h",
26
+ "ext/**/*.c", "test/**/*.rb"].to_a
27
+ end
28
+
29
+ task :test do
30
+ sh "bacon -k #{direc}/test/test.rb"
31
+ end
32
+
33
+ [:mingw32, :mswin32].each do |v|
34
+ namespace v do
35
+ spec = Gem::Specification.new do |s|
36
+ apply_spec_defaults(s)
37
+ s.platform = "i386-#{v}"
38
+ s.files += FileList["lib/**/*.#{dlext}"].to_a
39
+ end
40
+
41
+ Rake::GemPackageTask.new(spec) do |pkg|
42
+ pkg.need_zip = false
43
+ pkg.need_tar = false
44
+ end
45
+ end
46
+ end
47
+
48
+ namespace :ruby do
49
+ spec = Gem::Specification.new do |s|
50
+ apply_spec_defaults(s)
51
+ s.platform = Gem::Platform::RUBY
52
+ s.extensions = ["ext/include_complete/extconf.rb"]
53
+ end
54
+
55
+ Rake::GemPackageTask.new(spec) do |pkg|
56
+ pkg.need_zip = false
57
+ pkg.need_tar = false
58
+ end
59
+ end
@@ -0,0 +1,57 @@
1
+ /* contains basic macros to facilitate ruby 1.8 and ruby 1.9 compatibility */
2
+
3
+ #ifndef GUARD_COMPAT_H
4
+ #define GUARD_COMPAT_H
5
+
6
+ #include <ruby.h>
7
+
8
+ /* test for 1.9 */
9
+ #if !defined(RUBY_19) && defined(ROBJECT_EMBED_LEN_MAX)
10
+ # define RUBY_19
11
+ #endif
12
+
13
+ /* macros for backwards compatibility with 1.8 */
14
+ #ifndef RUBY_19
15
+ # define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl)
16
+ # define RCLASS_SUPER(c) (RCLASS(c)->super)
17
+ # define RCLASS_IV_TBL(c) (RCLASS(c)->iv_tbl)
18
+ # define OBJ_UNTRUSTED OBJ_TAINTED
19
+ # include "st.h"
20
+ #endif
21
+
22
+ #ifdef RUBY_19
23
+ inline static VALUE
24
+ class_alloc(VALUE flags, VALUE klass)
25
+ {
26
+ rb_classext_t *ext = ALLOC(rb_classext_t);
27
+ NEWOBJ(obj, struct RClass);
28
+ OBJSETUP(obj, klass, flags);
29
+ obj->ptr = ext;
30
+ RCLASS_IV_TBL(obj) = 0;
31
+ RCLASS_M_TBL(obj) = 0;
32
+ RCLASS_SUPER(obj) = 0;
33
+ RCLASS_IV_INDEX_TBL(obj) = 0;
34
+ return (VALUE)obj;
35
+ }
36
+ #endif
37
+
38
+ inline static VALUE
39
+ create_class(VALUE flags, VALUE klass)
40
+ {
41
+ #ifdef RUBY_19
42
+ VALUE new_klass = class_alloc(flags, klass);
43
+ #else
44
+ NEWOBJ(new_klass, struct RClass);
45
+ OBJSETUP(new_klass, klass, flags);
46
+ #endif
47
+
48
+ return (VALUE)new_klass;
49
+ }
50
+
51
+ # define FALSE 0
52
+ # define TRUE 1
53
+
54
+ /* a useful macro. cannot use ordinary CLASS_OF as it does not return an lvalue */
55
+ #define KLASS_OF(c) (RBASIC(c)->klass)
56
+
57
+ #endif
@@ -0,0 +1,6 @@
1
+ require 'mkmf'
2
+
3
+ # let's use c99
4
+ $CFLAGS += " -std=c99"
5
+
6
+ create_makefile('include_complete')
@@ -0,0 +1,11 @@
1
+ /* (c) 2010 John Mair (banisterfiend), MIT license */
2
+
3
+ void Init_patched_include(void);
4
+ void Init_include_complete_one(void);
5
+
6
+ void
7
+ Init_include_complete()
8
+ {
9
+ Init_include_complete_one();
10
+ Init_patched_include();
11
+ }
@@ -0,0 +1,151 @@
1
+ /* (c) 2010 John Mair (banisterfiend), MIT license */
2
+ /* */
3
+ /* include a module (and its singleton) into an inheritance chain */
4
+ /* only includes a single module, see include_complete.rb for multi-module version */
5
+
6
+ #include <ruby.h>
7
+ #include "compat.h"
8
+
9
+ static VALUE
10
+ class_to_s(VALUE self)
11
+ {
12
+ VALUE attached = rb_iv_get(self, "__attached__");
13
+
14
+ if (attached)
15
+ return rb_mod_name(rb_iv_get(attached, "__module__"));
16
+ else
17
+ return rb_mod_name(rb_iv_get(self, "__module__"));
18
+ }
19
+
20
+ /* totally hacked up version of include_class_new() from class.c; brings in singletons into inheritance chain */
21
+ static VALUE
22
+ include_class_new(VALUE module, VALUE super)
23
+ {
24
+ /* base case for recursion */
25
+ if (module == rb_singleton_class(rb_cModule))
26
+ return module;
27
+
28
+ if (TYPE(module) == T_ICLASS) {
29
+
30
+ /* include_complete */
31
+ if (!NIL_P(rb_iv_get(module, "__module__")))
32
+ module = rb_iv_get(module, "__module__");
33
+
34
+ /* ordinary Module#include */
35
+ else
36
+ module = KLASS_OF(module);
37
+ }
38
+
39
+ /* allocate iclass */
40
+ VALUE klass = create_class(T_ICLASS, rb_singleton_class(rb_cModule));
41
+
42
+ /* if the module hasn't yet got an ivtbl, create it */
43
+ if (!RCLASS_IV_TBL(module))
44
+ RCLASS_IV_TBL(module) = st_init_numtable();
45
+
46
+ /* we want to point to the original ivtbl for normal modules, so that we bring in constants */
47
+ RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
48
+
49
+ /* we want to point to the original module's mtbl */
50
+ RCLASS_M_TBL(klass) = RCLASS_M_TBL(module);
51
+ RCLASS_SUPER(klass) = super;
52
+
53
+ if (TYPE(module) == T_MODULE || FL_TEST(module, FL_SINGLETON))
54
+ rb_iv_set((VALUE)klass, "__module__", module);
55
+
56
+ /* create IClass for module's singleton */
57
+ /* if super is 0 then we're including into a module (not a class), so treat as special case */
58
+ VALUE meta = include_class_new(KLASS_OF(module), super ? KLASS_OF(super) : rb_cModule);
59
+
60
+ /* don't mess with (Module) */
61
+ if (meta != rb_singleton_class(rb_cModule)) {
62
+
63
+ /* set it as a singleton */
64
+ FL_SET(meta, FL_SINGLETON);
65
+
66
+ /* we want a fresh ivtbl for singleton classes (so we can redefine __attached__) */
67
+ RCLASS_IV_TBL(meta) = st_init_numtable();
68
+
69
+ /* attach singleton to module */
70
+ rb_iv_set(meta, "__attached__", (VALUE)klass);
71
+
72
+ /* attach the #to_s method to the metaclass (so #ancestors doesn't look weird) */
73
+ rb_define_singleton_method(meta, "to_s", class_to_s, 0);
74
+ }
75
+ /* assign the metaclass to module's klass */
76
+ KLASS_OF(klass) = meta;
77
+
78
+ OBJ_INFECT(klass, module);
79
+ OBJ_INFECT(klass, super);
80
+
81
+ return (VALUE)klass;
82
+ }
83
+
84
+ static VALUE
85
+ rb_include_complete_module_one(VALUE klass, VALUE module)
86
+ {
87
+ VALUE p, c;
88
+ int changed = 0;
89
+
90
+ rb_frozen_class_p(klass);
91
+ if (!OBJ_UNTRUSTED(klass)) {
92
+ rb_secure(4);
93
+ }
94
+
95
+ if (TYPE(module) != T_MODULE) {
96
+ Check_Type(module, T_MODULE);
97
+ }
98
+
99
+ OBJ_INFECT(klass, module);
100
+ c = klass;
101
+
102
+ /* ensure singleton classes exist, both for includer and includee */
103
+ rb_singleton_class(module);
104
+ rb_singleton_class(klass);
105
+
106
+ while (module) {
107
+ int superclass_seen = FALSE;
108
+
109
+ if (RCLASS_M_TBL(klass) == RCLASS_M_TBL(module))
110
+ rb_raise(rb_eArgError, "cyclic include detected");
111
+ /* ignore if the module included already in superclasses */
112
+ for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) {
113
+ switch (BUILTIN_TYPE(p)) {
114
+ case T_ICLASS:
115
+ if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) {
116
+ if (!superclass_seen) {
117
+ c = p; /* move insertion point */
118
+ }
119
+ goto skip;
120
+ }
121
+ break;
122
+ case T_CLASS:
123
+ superclass_seen = TRUE;
124
+ break;
125
+ }
126
+ }
127
+
128
+ /* we're including the module, so create the iclass */
129
+ VALUE imod = include_class_new(module, RCLASS_SUPER(c));
130
+
131
+ /* module gets included directly above c, so set the super */
132
+ RCLASS_SUPER(c) = imod;
133
+
134
+ /* also do the same for parallel inheritance chain (singleton classes) */
135
+ RCLASS_SUPER(KLASS_OF(c)) = KLASS_OF(imod);
136
+ c = imod;
137
+
138
+ if (RMODULE_M_TBL(module) && RMODULE_M_TBL(module)->num_entries)
139
+ changed = 1;
140
+ skip:
141
+ module = RCLASS_SUPER(module);
142
+ }
143
+ if (changed) rb_clear_cache();
144
+
145
+ return Qnil;
146
+ }
147
+
148
+ void
149
+ Init_include_complete_one() {
150
+ rb_define_method(rb_cModule, "include_complete_one", rb_include_complete_module_one, 1);
151
+ }
@@ -0,0 +1,109 @@
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
+ /* patched to work well with real_include */
8
+ static VALUE
9
+ include_class_new(VALUE module, VALUE super)
10
+ {
11
+ VALUE klass = create_class(T_ICLASS, rb_cClass);
12
+
13
+ if (BUILTIN_TYPE(module) == T_ICLASS) {
14
+
15
+ /***************************************************************************** */
16
+ /* This is the only change required, everything else is (pretty much) copypasta from class.c */
17
+ /* correct for real_include'd modules */
18
+ if (!NIL_P(rb_iv_get(module, "__module__")))
19
+ module = rb_iv_get(module, "__module__");
20
+ else
21
+ module = RBASIC(module)->klass;
22
+ /***************************************************************************** */
23
+
24
+ }
25
+ if (!RCLASS_IV_TBL(module)) {
26
+ RCLASS_IV_TBL(module) = st_init_numtable();
27
+ }
28
+ RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
29
+ RCLASS_M_TBL(klass) = RCLASS_M_TBL(module);
30
+ RCLASS_SUPER(klass) = super;
31
+ if (TYPE(module) == T_ICLASS) {
32
+ RBASIC(klass)->klass = RBASIC(module)->klass;
33
+ }
34
+ else {
35
+ RBASIC(klass)->klass = module;
36
+ }
37
+ OBJ_INFECT(klass, module);
38
+ OBJ_INFECT(klass, super);
39
+
40
+ return (VALUE)klass;
41
+ }
42
+
43
+ static void
44
+ rb_patched_include_module(VALUE klass, VALUE module)
45
+ {
46
+ VALUE p, c;
47
+ int changed = 0;
48
+
49
+ rb_frozen_class_p(klass);
50
+ if (!OBJ_UNTRUSTED(klass)) {
51
+ rb_secure(4);
52
+ }
53
+
54
+ if (TYPE(module) != T_MODULE) {
55
+ Check_Type(module, T_MODULE);
56
+ }
57
+
58
+ OBJ_INFECT(klass, module);
59
+ c = klass;
60
+ while (module) {
61
+ int superclass_seen = FALSE;
62
+
63
+ if (RCLASS_M_TBL(klass) == RCLASS_M_TBL(module))
64
+ rb_raise(rb_eArgError, "cyclic include detected");
65
+ /* ignore if the module included already in superclasses */
66
+ for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) {
67
+ switch (BUILTIN_TYPE(p)) {
68
+ case T_ICLASS:
69
+ if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) {
70
+ if (!superclass_seen) {
71
+ c = p; /* move insertion point */
72
+ }
73
+ goto skip;
74
+ }
75
+ break;
76
+ case T_CLASS:
77
+ superclass_seen = TRUE;
78
+ break;
79
+ }
80
+ }
81
+ c = RCLASS_SUPER(c) = include_class_new(module, RCLASS_SUPER(c));
82
+ if (RMODULE_M_TBL(module) && RMODULE_M_TBL(module)->num_entries)
83
+ changed = 1;
84
+ skip:
85
+ module = RCLASS_SUPER(module);
86
+ }
87
+ if (changed) rb_clear_cache();
88
+ }
89
+
90
+ static VALUE
91
+ rb_patched_mod_append_features(VALUE module, VALUE include)
92
+ {
93
+ switch (TYPE(include)) {
94
+ case T_CLASS:
95
+ case T_MODULE:
96
+ break;
97
+ default:
98
+ Check_Type(include, T_CLASS);
99
+ break;
100
+ }
101
+ rb_patched_include_module(include, module);
102
+
103
+ return module;
104
+ }
105
+
106
+ void
107
+ Init_patched_include() {
108
+ rb_define_method(rb_cModule, "append_features", rb_patched_mod_append_features, 1);
109
+ }
Binary file
Binary file
@@ -0,0 +1,3 @@
1
+ module IncludeComplete
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,62 @@
1
+ # (c) 2010 John Mair (banisterfiend), MIT license
2
+
3
+ direc = File.dirname(__FILE__)
4
+
5
+ begin
6
+ if RUBY_VERSION && RUBY_VERSION =~ /1.9/
7
+ require "#{direc}/1.9/include_complete"
8
+ else
9
+ require "#{direc}/1.8/include_complete"
10
+ end
11
+ rescue LoadError => e
12
+ require 'rbconfig'
13
+ dlext = Config::CONFIG['DLEXT']
14
+ require "#{direc}/include_complete.#{dlext}"
15
+ end
16
+
17
+ require "#{direc}/include_complete/version"
18
+
19
+
20
+ class Module
21
+
22
+ # include modules (and their singletons) into an
23
+ # inheritance chain
24
+ # @param [Module] mods Modules to include_complete
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
+ # include_complete M
34
+ # end
35
+ # C.hello #=> "hello"
36
+ def include_complete(*mods)
37
+ mods.each do |mod|
38
+ include_complete_one mod
39
+ end
40
+ self
41
+ end
42
+ end
43
+
44
+ class Object
45
+
46
+ # extend modules (and their singletons) into an
47
+ # inheritance chain
48
+ # @param [Module] mods Modules to extend_complete
49
+ # @return Returns the receiver
50
+ # @example
51
+ # module M
52
+ # def self.hello
53
+ # puts "hello"
54
+ # end
55
+ # end
56
+ # o = Object.new
57
+ # o.extend_complete M
58
+ # o.singleton_class.hello #=> "hello"
59
+ def extend_complete(*mods)
60
+ class << self; self; end.send(:include_complete, *mods)
61
+ end
62
+ end
@@ -0,0 +1,14 @@
1
+ require '../lib/real_include'
2
+
3
+ 5000.times {
4
+ m = Module.new
5
+ n = Module.new
6
+ k = Module.new
7
+ n.real_include m
8
+ k.real_include n
9
+
10
+ c = Class.new
11
+ c.real_include k
12
+ }
13
+
14
+ "stress test passed!".display
data/test/test.rb ADDED
@@ -0,0 +1,262 @@
1
+ direc = File.dirname(__FILE__)
2
+
3
+ require 'rubygems'
4
+ require "#{direc}/../lib/include_complete"
5
+ require 'bacon'
6
+
7
+ puts "Testing IncludeComplete version #{IncludeComplete::VERSION}..."
8
+ puts "Ruby version #{RUBY_VERSION}"
9
+
10
+ describe 'Including a module into a class using include_complete' do
11
+ before do
12
+ @m = Module.new {
13
+ def self.class_method
14
+ :class_method
15
+ end
16
+
17
+ def instance_method
18
+ :instance_method
19
+ end
20
+ }
21
+
22
+ @m::CONST = :const
23
+
24
+ @c = Class.new
25
+
26
+ @c.send(:include_complete, @m)
27
+ end
28
+
29
+ it 'should make class methods accessible to class' do
30
+ @c.class_method.should.equal :class_method
31
+ end
32
+
33
+ it 'should make instance methods accessible to instances of the class' do
34
+ obj = @c.new
35
+ obj.instance_method.should.equal :instance_method
36
+ end
37
+
38
+ it 'should make constants accessible to the class' do
39
+ lambda { @c::CONST }.should.not.raise NameError
40
+ end
41
+ end
42
+
43
+ describe 'Extending a module into a class using extend_complete' do
44
+ before do
45
+ @m = Module.new {
46
+ def self.class_method
47
+ :class_method
48
+ end
49
+
50
+ def instance_method
51
+ :instance_method
52
+ end
53
+ }
54
+
55
+ @m::CONST = :const
56
+
57
+ @c = Class.new
58
+
59
+ @c.send(:extend_complete, @m)
60
+ end
61
+
62
+ it 'should make instance methods from the module available as class methods on the class' do
63
+ @c.instance_method.should.equal :instance_method
64
+ end
65
+
66
+ it 'should make class methods from the module available as class methods on the singleton class' do
67
+ class << @c; self; end.class_method.should.equal :class_method
68
+ end
69
+ end
70
+
71
+
72
+ describe 'Including a module into a module and then into a class using include_complete' do
73
+ before do
74
+ @m1 = Module.new {
75
+ def self.class_method1
76
+ :class_method1
77
+ end
78
+
79
+ def instance_method1
80
+ :instance_method1
81
+ end
82
+ }
83
+
84
+ @m1::CONST1 = :const1
85
+
86
+ @m2 = Module.new {
87
+ def self.class_method2
88
+ :class_method2
89
+ end
90
+
91
+ def instance_method2
92
+ :instance_method2
93
+ end
94
+ }
95
+ @m2.send(:include_complete, @m1)
96
+
97
+ @m2::CONST2 = :const2
98
+
99
+ @c = Class.new
100
+
101
+ @c.send(:include_complete, @m2)
102
+ end
103
+
104
+ it 'should make class methods on m1 accessible to m2' do
105
+ @m2.class_method1.should.equal :class_method1
106
+ end
107
+
108
+ it 'should make constants on m1 and m2 accessible to class' do
109
+ lambda { @c::CONST1 == :const1 }.should.not.raise NameError
110
+ lambda { @m2::CONST1 == :const1 }.should.not.raise NameError
111
+ lambda { @c::CONST2 == :const2 }.should.not.raise NameError
112
+ end
113
+
114
+ it 'should make class methods on modules m1 and m2 accessible to class' do
115
+ @c.class_method1.should.equal :class_method1
116
+ @c.class_method2.should.equal :class_method2
117
+ end
118
+
119
+ it 'should make instance methods on modules m1 and m2 accessible to instances of class' do
120
+ obj = @c.new
121
+
122
+ obj.instance_method1.should.equal :instance_method1
123
+ obj.instance_method2.should.equal :instance_method2
124
+ end
125
+
126
+ it 'should make ancestor chain "look" accurate' do
127
+ @m1 = Module.new {
128
+ def self.class_method1
129
+ :class_method1
130
+ end
131
+
132
+ def instance_method1
133
+ :instance_method1
134
+ end
135
+ }
136
+
137
+ Object.const_set(:M1, @m1)
138
+
139
+ @m2 = Module.new {
140
+ def self.class_method2
141
+ :class_method2
142
+ end
143
+
144
+ def instance_method2
145
+ :instance_method2
146
+ end
147
+ }
148
+ Object.const_set(:M2, @m2)
149
+
150
+ @m2.send(:include_complete, @m1)
151
+
152
+ @c = Class.new
153
+
154
+ @c.send(:include_complete, @m2)
155
+
156
+ @c.ancestors[1].to_s.should.equal M2.name
157
+ @c.class_method1.should.equal :class_method1
158
+ @c.class_method2.should.equal :class_method2
159
+ end
160
+
161
+ it 'should work if real_including a module that has another module included using Module#include' do
162
+ @m1 = Module.new {
163
+ def self.class_method1
164
+ :class_method1
165
+ end
166
+
167
+ def instance_method1
168
+ :instance_method1
169
+ end
170
+ }
171
+
172
+ Object.const_set(:N1, @m1)
173
+
174
+ @m2 = Module.new {
175
+ def self.class_method2
176
+ :class_method2
177
+ end
178
+
179
+ def instance_method2
180
+ :instance_method2
181
+ end
182
+ }
183
+ Object.const_set(:N2, @m2)
184
+
185
+ @m2.send(:include, @m1)
186
+
187
+ @c = Class.new
188
+
189
+ @c.send(:include_complete, @m2)
190
+
191
+ @c.ancestors[1].to_s.should.equal N2.name
192
+ @c.ancestors[2].to_s.should.equal N1.name
193
+ @c.class_method1.should.equal :class_method1
194
+ @c.class_method2.should.equal :class_method2
195
+ end
196
+
197
+ it 'should work if Module#including a module that has another module included using include_complete' do
198
+ @m1 = Module.new {
199
+ def self.class_method1
200
+ :class_method1
201
+ end
202
+
203
+ def instance_method1
204
+ :instance_method1
205
+ end
206
+ }
207
+
208
+ Object.const_set(:K1, @m1)
209
+
210
+ @m2 = Module.new {
211
+ def self.class_method2
212
+ :class_method2
213
+ end
214
+
215
+ def instance_method2
216
+ :instance_method2
217
+ end
218
+ }
219
+ Object.const_set(:K2, @m2)
220
+
221
+ @m2.send(:include_complete, @m1)
222
+
223
+ @c = Class.new
224
+
225
+ @c.send(:include, @m2)
226
+
227
+ @c.ancestors[1].should.equal K2
228
+ @c.ancestors[2].should.equal K1
229
+ @c.new.instance_method1.should.equal :instance_method1
230
+ @c.new.instance_method2.should.equal :instance_method2
231
+ end
232
+
233
+
234
+ it 'should work with multiple modules passed to include_complete' do
235
+ @m1 = Module.new {
236
+ def self.class_method1
237
+ :class_method1
238
+ end
239
+
240
+ def instance_method1
241
+ :instance_method1
242
+ end
243
+ }
244
+
245
+ @m2 = Module.new {
246
+ def self.class_method2
247
+ :class_method2
248
+ end
249
+
250
+ def instance_method2
251
+ :instance_method2
252
+ end
253
+ }
254
+
255
+ @c = Class.new
256
+ @c.send(:include_complete, @m2, @m1)
257
+
258
+ @c.class_method1.should.equal :class_method1
259
+ @c.class_method2.should.equal :class_method2
260
+ end
261
+
262
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: include_complete
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: i386-mswin32
12
+ authors:
13
+ - John Mair (banisterfiend)
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-11-01 00:00:00 +13:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: Fixing the limitations in traditional Module#include
23
+ email: jrmair@gmail.com
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - Rakefile
32
+ - README.markdown
33
+ - CHANGELOG
34
+ - lib/include_complete/version.rb
35
+ - lib/include_complete.rb
36
+ - ext/include_complete/extconf.rb
37
+ - ext/include_complete/compat.h
38
+ - ext/include_complete/include_complete.c
39
+ - ext/include_complete/include_complete_one.c
40
+ - ext/include_complete/patched_include.c
41
+ - test/stress_test.rb
42
+ - test/test.rb
43
+ - lib/1.8/include_complete.so
44
+ - lib/1.9/include_complete.so
45
+ has_rdoc: yard
46
+ homepage: http://banisterfiend.wordpress.com
47
+ licenses: []
48
+
49
+ post_install_message:
50
+ rdoc_options: []
51
+
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 3
60
+ segments:
61
+ - 0
62
+ version: "0"
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ hash: 3
69
+ segments:
70
+ - 0
71
+ version: "0"
72
+ requirements: []
73
+
74
+ rubyforge_project:
75
+ rubygems_version: 1.3.7
76
+ signing_key:
77
+ specification_version: 3
78
+ summary: Fixing the limitations in traditional Module#include
79
+ test_files: []
80
+