remix 0.2.5-i386-mswin32 → 0.3.0-i386-mswin32
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +16 -21
- data/ext/remix/remix.c +36 -7
- data/lib/1.8/remix.so +0 -0
- data/lib/1.9/remix.so +0 -0
- data/lib/remix/c_docs.rb +3 -3
- data/lib/remix/version.rb +2 -1
- data/lib/remix.rb +20 -11
- data/test/test.rb +29 -1
- metadata +4 -4
data/README.markdown
CHANGED
@@ -22,15 +22,8 @@ example: include_at_top():
|
|
22
22
|
Using `include_at_top` we can include a module at the top of a chain
|
23
23
|
rather than at the bottom (the default).
|
24
24
|
|
25
|
-
# ... modules A, B, C, and J defined above...
|
26
|
-
|
27
|
-
module M
|
28
|
-
include A, B, C
|
29
|
-
end
|
30
|
-
|
31
25
|
M.ancestors #=> [M, A, B, C]
|
32
26
|
|
33
|
-
# Now let's insert a module between A and B
|
34
27
|
M.include_at_top J
|
35
28
|
|
36
29
|
# Modified ancestor chain
|
@@ -43,21 +36,16 @@ Like the Mixico library Remix allows you to unextend
|
|
43
36
|
(or uninclude) modules from inheritance chains; but also extends this
|
44
37
|
functionality by (optionally) removing nested modules too:
|
45
38
|
|
46
|
-
|
47
|
-
# ...modules A, B defined above...
|
48
|
-
|
49
|
-
module C
|
50
|
-
include A, B
|
51
|
-
end
|
39
|
+
C.ancestors #=> [C, A, B]
|
52
40
|
|
53
|
-
|
54
|
-
|
55
|
-
|
41
|
+
o = Object.new
|
42
|
+
o.extend C
|
43
|
+
o.singleton_class.ancestors #=> [C, A, B, Object, ...]
|
56
44
|
|
57
45
|
# remove entire nested module C by passing true as second parameter
|
58
|
-
|
46
|
+
o.unextend C, true
|
59
47
|
|
60
|
-
|
48
|
+
o.singleton_class.ancestors #=> [Object, ...]
|
61
49
|
|
62
50
|
Special features
|
63
51
|
------------------
|
@@ -102,7 +90,7 @@ Full list of functions
|
|
102
90
|
|
103
91
|
**include-based functions:**
|
104
92
|
|
105
|
-
* include_at(index)
|
93
|
+
* include_at(index, mod)
|
106
94
|
* include_at_top(mod)
|
107
95
|
* include_before(before_mod, mod)
|
108
96
|
* include_after(after_mod, mod)
|
@@ -114,15 +102,15 @@ Full list of functions
|
|
114
102
|
|
115
103
|
**extend-based functions:**
|
116
104
|
|
117
|
-
* extend_at(index)
|
105
|
+
* extend_at(index, mod)
|
118
106
|
* extend_at_top(mod)
|
119
107
|
* extend_before(before_mod, mod)
|
120
108
|
* extend_after(after_mod, mod)
|
121
109
|
* swap_extended_modules(mod1, mod2)
|
122
|
-
* replace_module(mod1, mod2)
|
123
110
|
* unextend(mod, recurse=false)
|
124
111
|
* extended_module_move_up(mod)
|
125
112
|
* extended_module_move_down(mod)
|
113
|
+
* replace_extended_module(mod1, mod2)
|
126
114
|
|
127
115
|
Limitations
|
128
116
|
------------
|
@@ -131,6 +119,11 @@ Remix does not currently reorder the singleton classes of superclasses
|
|
131
119
|
to reflect the new position of the class. This functionality is coming
|
132
120
|
soon.
|
133
121
|
|
122
|
+
Special Thanks
|
123
|
+
---------------
|
124
|
+
|
125
|
+
[Asher](http://github.com/asher-)
|
126
|
+
|
134
127
|
Contact
|
135
128
|
-------
|
136
129
|
|
@@ -140,3 +133,5 @@ Dedication
|
|
140
133
|
----------
|
141
134
|
|
142
135
|
For Rue (1977-)
|
136
|
+
|
137
|
+
|
data/ext/remix/remix.c
CHANGED
@@ -8,6 +8,12 @@
|
|
8
8
|
|
9
9
|
VALUE rb_swap_modules(VALUE self, VALUE mod1, VALUE mod2);
|
10
10
|
|
11
|
+
#define Enforce_Classmod(klass) \
|
12
|
+
do { \
|
13
|
+
if (!RTEST(rb_obj_is_kind_of(klass, rb_cModule))) \
|
14
|
+
rb_raise(rb_eTypeError, "Must be a Module or Class type."); \
|
15
|
+
} while(0)
|
16
|
+
|
11
17
|
/* a modified version of include_class_new from class.c */
|
12
18
|
static VALUE
|
13
19
|
j_class_new(VALUE module, VALUE sup)
|
@@ -15,7 +21,7 @@ j_class_new(VALUE module, VALUE sup)
|
|
15
21
|
VALUE klass = create_class(T_ICLASS, rb_cClass);
|
16
22
|
|
17
23
|
if (TYPE(module) == T_ICLASS) {
|
18
|
-
klass = module;
|
24
|
+
// klass = module;
|
19
25
|
}
|
20
26
|
|
21
27
|
if (!RCLASS_IV_TBL(module)) {
|
@@ -69,11 +75,16 @@ set_supers(VALUE c)
|
|
69
75
|
VALUE
|
70
76
|
rb_prepare_for_remix(VALUE klass)
|
71
77
|
{
|
72
|
-
|
73
|
-
rb_raise(rb_eTypeError, "Must be a Module or Class type.");
|
78
|
+
Enforce_Classmod(klass);
|
74
79
|
|
80
|
+
/* class chain is already prepared for remixing */
|
81
|
+
if (RTEST(rb_iv_get(klass, "__remix_ready__")))
|
82
|
+
return klass;
|
83
|
+
|
75
84
|
RCLASS_SUPER(klass) = set_supers(klass);
|
76
85
|
|
86
|
+
rb_iv_set(klass, "__remix_ready__", Qtrue);
|
87
|
+
|
77
88
|
rb_clear_cache();
|
78
89
|
return klass;
|
79
90
|
}
|
@@ -260,6 +271,26 @@ remove_nested_module(VALUE included_mod, VALUE module)
|
|
260
271
|
RCLASS_SUPER(included_mod) = RCLASS_SUPER(RCLASS_SUPER(included_mod));
|
261
272
|
}
|
262
273
|
}
|
274
|
+
|
275
|
+
static VALUE
|
276
|
+
rb_classmod_include_p(VALUE mod, VALUE mod2)
|
277
|
+
{
|
278
|
+
VALUE p;
|
279
|
+
|
280
|
+
Enforce_Classmod(mod2);
|
281
|
+
|
282
|
+
for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
|
283
|
+
if (BUILTIN_TYPE(p) == T_ICLASS) {
|
284
|
+
if (RTEST(rb_iv_get(p, "__module__"))) {
|
285
|
+
if (rb_iv_get(p, "__module__") == mod2) return Qtrue;
|
286
|
+
}
|
287
|
+
|
288
|
+
if (RBASIC(p)->klass == mod2) return Qtrue;
|
289
|
+
}
|
290
|
+
}
|
291
|
+
return Qfalse;
|
292
|
+
}
|
293
|
+
|
263
294
|
|
264
295
|
VALUE
|
265
296
|
rb_uninclude(int argc, VALUE * argv, VALUE self)
|
@@ -269,7 +300,7 @@ rb_uninclude(int argc, VALUE * argv, VALUE self)
|
|
269
300
|
VALUE mod1, recurse = Qfalse;
|
270
301
|
rb_scan_args(argc, argv, "11", &mod1, &recurse);
|
271
302
|
|
272
|
-
if (!RTEST(
|
303
|
+
if (!RTEST(rb_classmod_include_p(self, mod1)))
|
273
304
|
rb_raise(rb_eArgError, "Module not found");
|
274
305
|
|
275
306
|
VALUE before = retrieve_before_mod(self, mod1);
|
@@ -292,7 +323,7 @@ rb_replace_module(VALUE self, VALUE mod1, VALUE mod2)
|
|
292
323
|
{
|
293
324
|
rb_prepare_for_remix(self);
|
294
325
|
|
295
|
-
if (
|
326
|
+
if (rb_classmod_include_p(self, mod2))
|
296
327
|
return rb_swap_modules(self, mod1, mod2);
|
297
328
|
|
298
329
|
VALUE before = retrieve_before_mod(self, mod1);
|
@@ -322,7 +353,5 @@ Init_remix()
|
|
322
353
|
rb_define_method(mModuleExtensions, "uninclude", rb_uninclude, -1);
|
323
354
|
rb_define_alias(mModuleExtensions, "remove_module", "uninclude");
|
324
355
|
rb_define_method(mModuleExtensions, "replace_module", rb_replace_module, 2);
|
325
|
-
|
326
|
-
rb_include_module(rb_cModule, mModuleExtensions);
|
327
356
|
}
|
328
357
|
|
data/lib/1.8/remix.so
CHANGED
Binary file
|
data/lib/1.9/remix.so
CHANGED
Binary file
|
data/lib/remix/c_docs.rb
CHANGED
@@ -49,7 +49,7 @@ module Remix
|
|
49
49
|
|
50
50
|
# Moves a module up one position in the ancestor chain.
|
51
51
|
# Module must already be in ancestor chain.
|
52
|
-
# @param [Module]
|
52
|
+
# @param [Module] mod The module to move up
|
53
53
|
# @return [Module] The receiver
|
54
54
|
# @example
|
55
55
|
# M.ancestors #=> [M, A, B]
|
@@ -59,7 +59,7 @@ module Remix
|
|
59
59
|
|
60
60
|
# Moves a module down one position in the ancestor chain.
|
61
61
|
# Module must already be in ancestor chain.
|
62
|
-
# @param [Module]
|
62
|
+
# @param [Module] mod The module to move down
|
63
63
|
# @return [Module] The receiver
|
64
64
|
# @example
|
65
65
|
# M.ancestors #=> [M, A, B]
|
@@ -72,7 +72,7 @@ module Remix
|
|
72
72
|
# @param [Module] mod The module to uninclude
|
73
73
|
# @param [Boolean] recurse Set to true to remove nested modules
|
74
74
|
# @return [Module] The receiver
|
75
|
-
# @example
|
75
|
+
# @example Without recursion
|
76
76
|
# module C
|
77
77
|
# include A, B
|
78
78
|
# end
|
data/lib/remix/version.rb
CHANGED
data/lib/remix.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
# remix.rb
|
2
|
+
# (C) John Mair (banisterfiend); MIT license
|
3
|
+
|
1
4
|
direc = File.dirname(__FILE__)
|
2
5
|
|
3
6
|
require 'rbconfig'
|
@@ -17,7 +20,8 @@ rescue LoadError => e
|
|
17
20
|
end
|
18
21
|
|
19
22
|
module Kernel
|
20
|
-
#
|
23
|
+
# define a `singleton_class` method for the 1.8 kids
|
24
|
+
# @return [Class] The singleton class of the receiver
|
21
25
|
def singleton_class
|
22
26
|
class << self; self; end
|
23
27
|
end if !respond_to?(:singleton_class)
|
@@ -26,64 +30,69 @@ end
|
|
26
30
|
module Remix::ObjectExtensions
|
27
31
|
|
28
32
|
# Like `include_at()` but for the singleton class
|
29
|
-
# @see
|
33
|
+
# @see Remix::ModuleExtensions#include_at
|
30
34
|
def extend_at(index, mod)
|
31
35
|
singleton_class.include_at(index, mod)
|
32
36
|
end
|
33
37
|
|
34
38
|
# Like `include_below()` but for the singleton class
|
35
|
-
# @see
|
39
|
+
# @see Remix::ModuleExtensions#include_below
|
36
40
|
def extend_below(mod1, mod2)
|
37
41
|
singleton_class.include_below(mod1, mod2)
|
38
42
|
end
|
39
43
|
alias_method :extend_before, :extend_below
|
40
44
|
|
41
45
|
# Like `include_above()` but for the singleton class
|
42
|
-
# @see
|
46
|
+
# @see Remix::ModuleExtensions#include_above
|
43
47
|
def extend_above(mod1, mod2)
|
44
48
|
singleton_class.include_above(mod1, mod2)
|
45
49
|
end
|
46
50
|
alias_method :extend_after, :extend_above
|
47
51
|
|
48
52
|
# Like `uninclude()` but for the singleton class
|
49
|
-
# @see
|
53
|
+
# @see Remix::ModuleExtensions#uninclude
|
50
54
|
def unextend(mod, recurse = false)
|
51
55
|
singleton_class.uninclude(mod, recurse)
|
52
56
|
end
|
53
57
|
alias_method :remove_extended_module, :unextend
|
54
58
|
|
55
59
|
# Like `include_at_top()` but for the singleton class
|
56
|
-
# @see
|
60
|
+
# @see Remix::ModuleExtensions#include_at_top
|
57
61
|
def extend_at_top(mod)
|
58
62
|
singleton_class.include_at_top(mod)
|
59
63
|
end
|
60
64
|
|
61
65
|
# Like `swap_modules()` but for the singleton class
|
62
|
-
# @see
|
66
|
+
# @see Remix::ModuleExtensions#swap_modules
|
63
67
|
def swap_extended_modules(mod1, mod2)
|
64
68
|
singleton_class.swap_modules(mod1, mod2)
|
65
69
|
end
|
66
70
|
|
67
71
|
# Like `module_move_up()` but for the singleton class
|
68
|
-
# @see
|
72
|
+
# @see Remix::ModuleExtensions#module_move_up
|
69
73
|
def extended_module_move_up(mod)
|
70
74
|
singleton_class.module_move_up(mod)
|
71
75
|
end
|
72
76
|
|
73
77
|
# Like `module_move_down()` but for the singleton class
|
74
|
-
# @see
|
78
|
+
# @see Remix::ModuleExtensions#module_move_down
|
75
79
|
def extended_module_move_down(mod)
|
76
80
|
singleton_class.module_move_down(mod)
|
77
81
|
end
|
78
82
|
|
79
83
|
# Like `replace_module()` but for the singleton class
|
80
|
-
# @see
|
84
|
+
# @see Remix::ModuleExtensions#replace_module_down
|
81
85
|
def replace_extended_module(mod1, mod2)
|
82
86
|
singleton_class.replace_module(mod1, mod2)
|
83
87
|
end
|
84
88
|
end
|
85
89
|
|
86
|
-
|
90
|
+
# bring extend-based methods into Object
|
87
91
|
class Object
|
88
92
|
include Remix::ObjectExtensions
|
89
93
|
end
|
94
|
+
|
95
|
+
# bring include-based methods into Module
|
96
|
+
class Module
|
97
|
+
include Remix::ModuleExtensions
|
98
|
+
end
|
data/test/test.rb
CHANGED
@@ -17,6 +17,10 @@ describe 'Test basic remix functionality' do
|
|
17
17
|
|
18
18
|
M.include A, B
|
19
19
|
M.extend A, B
|
20
|
+
|
21
|
+
C1 = Class.new
|
22
|
+
C2 = Class.new(C1)
|
23
|
+
C2.include A
|
20
24
|
end
|
21
25
|
|
22
26
|
after do
|
@@ -25,6 +29,8 @@ describe 'Test basic remix functionality' do
|
|
25
29
|
Object.remove_const(:C)
|
26
30
|
Object.remove_const(:M)
|
27
31
|
Object.remove_const(:J)
|
32
|
+
Object.remove_const(:C1)
|
33
|
+
Object.remove_const(:C2)
|
28
34
|
end
|
29
35
|
|
30
36
|
describe 'extend-based methods' do
|
@@ -52,7 +58,23 @@ describe 'Test basic remix functionality' do
|
|
52
58
|
M.singleton_class.ancestors[0..3].should == [J, C, A, B]
|
53
59
|
M.unextend C, true
|
54
60
|
M.singleton_class.ancestors[0..1].should == [J, Module]
|
55
|
-
end
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should unextend the class of the object' do
|
64
|
+
o = C2.new
|
65
|
+
o.singleton_class.ancestors.first.should == C2
|
66
|
+
o.unextend(C2)
|
67
|
+
o.singleton_class.ancestors.first.should == A
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe 'replace_extended_module' do
|
72
|
+
it 'should replace the class of the object with a module' do
|
73
|
+
o = C2.new
|
74
|
+
o.singleton_class.ancestors.first.should == C2
|
75
|
+
o.replace_extended_module C2, J
|
76
|
+
o.singleton_class.ancestors.first.should == J
|
77
|
+
end
|
56
78
|
end
|
57
79
|
end
|
58
80
|
|
@@ -131,6 +153,12 @@ describe 'Test basic remix functionality' do
|
|
131
153
|
M.replace_module B, C
|
132
154
|
M.ancestors[1..2].should == [A, C]
|
133
155
|
end
|
156
|
+
|
157
|
+
it 'should replace a class with a module' do
|
158
|
+
C2.ancestors[0..2].should == [C2, A, C1]
|
159
|
+
C2.replace_module C1, B
|
160
|
+
C2.ancestors[0..2].should == [C2, A, B]
|
161
|
+
end
|
134
162
|
end
|
135
163
|
|
136
164
|
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 3
|
8
|
+
- 0
|
9
|
+
version: 0.3.0
|
10
10
|
platform: i386-mswin32
|
11
11
|
authors:
|
12
12
|
- John Mair (banisterfiend)
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-10-
|
17
|
+
date: 2010-10-29 00:00:00 +13:00
|
18
18
|
default_executable:
|
19
19
|
dependencies: []
|
20
20
|
|