remix 0.2.5-i386-mswin32 → 0.3.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/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
|
|