remix 0.2.0-i386-mingw32 → 0.2.5-i386-mingw32
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 +7 -0
- data/README.markdown +123 -35
- data/Rakefile +3 -3
- data/ext/remix/remix.c +60 -16
- data/lib/1.8/remix.so +0 -0
- data/lib/1.9/remix.so +0 -0
- data/lib/remix.rb +72 -0
- data/lib/remix/c_docs.rb +114 -0
- data/lib/remix/version.rb +1 -1
- data/test/test.rb +137 -0
- metadata +10 -11
data/CHANGELOG
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
27/10/2010 version 0.2.5
|
2
|
+
* added tests
|
3
|
+
* reversed order of arguments for #include_at
|
4
|
+
* made it so first index of #include_at is 1 (not 0, since 0 is host module)
|
5
|
+
* added extend-based methods
|
6
|
+
* reordered modules (Remix::ObjectExtenstions and Remix::ModuleExtensions)
|
7
|
+
* added recursive uninclude
|
1
8
|
26/10/2010 version 0.2.0
|
2
9
|
* added include_at_top, replace_module, module_move_up, etc
|
3
10
|
25/10/2010 version 0.1.0
|
data/README.markdown
CHANGED
@@ -1,54 +1,142 @@
|
|
1
1
|
Remix
|
2
|
-
|
2
|
+
=======
|
3
3
|
|
4
|
-
(
|
5
|
-
MIT license
|
4
|
+
(C) John Mair (banisterfiend) 2010
|
6
5
|
|
7
|
-
|
6
|
+
_Ruby modules remixed and remastered_
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
install the gem: **for testing purposes only**
|
13
|
-
`gem install remix`
|
8
|
+
Remix is a library to give you total control over class and module ancestor
|
9
|
+
chains.
|
14
10
|
|
15
|
-
|
11
|
+
Using Remix you can add a module at any point in the chain,
|
12
|
+
remove modules, replace modules, move modules around and otherwise
|
13
|
+
'remix' your modules.
|
16
14
|
|
17
|
-
*
|
18
|
-
*
|
19
|
-
*
|
20
|
-
* include_after(AfterMod, Mod)
|
21
|
-
* swap_modules(Mod1, Mod2)
|
22
|
-
* remove_module(Mod)
|
23
|
-
* module_move_up(Mod)
|
24
|
-
* module_move_down(Mod)
|
25
|
-
* replace_module(Mod1, Mod2)
|
26
|
-
* ...more to come!
|
15
|
+
* Install the [gem](https://rubygems.org/gems/remix): `gem install remix`
|
16
|
+
* Read the [documentation](http://rdoc.info/github/banister/remix/master/file/README.markdown)
|
17
|
+
* See the [source code](http://github.com/banister/remix)
|
27
18
|
|
28
|
-
example:
|
19
|
+
example: include_at_top():
|
20
|
+
--------------------------
|
29
21
|
|
30
|
-
|
22
|
+
Using `include_at_top` we can include a module at the top of a chain
|
23
|
+
rather than at the bottom (the default).
|
24
|
+
|
25
|
+
# ... modules A, B, C, and J defined above...
|
26
|
+
|
27
|
+
module M
|
28
|
+
include A, B, C
|
29
|
+
end
|
30
|
+
|
31
|
+
M.ancestors #=> [M, A, B, C]
|
32
|
+
|
33
|
+
# Now let's insert a module between A and B
|
34
|
+
M.include_at_top J
|
35
|
+
|
36
|
+
# Modified ancestor chain
|
37
|
+
M.ancestors #=> [M, A, B, C, J]
|
38
|
+
|
39
|
+
example: unextend()
|
40
|
+
--------------------
|
41
|
+
|
42
|
+
Like the Mixico library Remix allows you to unextend
|
43
|
+
(or uninclude) modules from inheritance chains; but also extends this
|
44
|
+
functionality by (optionally) removing nested modules too:
|
45
|
+
|
46
|
+
|
47
|
+
# ...modules A, B defined above...
|
48
|
+
|
49
|
+
module C
|
50
|
+
include A, B
|
51
|
+
end
|
52
|
+
|
53
|
+
D = Object.new
|
54
|
+
D.extend C
|
55
|
+
D.singleton_class.ancestors #=> [C, A, B, Object, ...]
|
56
|
+
|
57
|
+
# remove entire nested module C by passing true as second parameter
|
58
|
+
D.unextend C, true
|
59
|
+
|
60
|
+
D.singleton_class.ancestors #=> [Object, ...]
|
61
|
+
|
62
|
+
Special features
|
63
|
+
------------------
|
31
64
|
|
32
|
-
|
65
|
+
Remix is intelligent enough to manipulate classes as well as
|
66
|
+
modules:
|
33
67
|
|
34
|
-
class
|
35
|
-
|
68
|
+
class D < C
|
69
|
+
include M
|
36
70
|
end
|
71
|
+
|
72
|
+
D.ancestors #=> [D, M, C]
|
73
|
+
|
74
|
+
D.swap_modules C, M
|
75
|
+
|
76
|
+
D.ancestors #=> [D, C, M]
|
77
|
+
|
78
|
+
It does this by first converting all superclasses to Included Modules
|
79
|
+
before remixing takes place.
|
37
80
|
|
38
|
-
|
81
|
+
How it works
|
82
|
+
--------------
|
39
83
|
|
40
|
-
|
84
|
+
Remix is a C-based extension that directly manipulates the superclass
|
85
|
+
pointers of Included Modules.
|
41
86
|
|
42
|
-
|
87
|
+
Companion Libraries
|
88
|
+
--------------------
|
43
89
|
|
44
|
-
|
90
|
+
Remix is one of a series of experimental libraries that mess with
|
91
|
+
the internals of Ruby to bring new and interesting functionality to
|
92
|
+
the language, see also:
|
45
93
|
|
46
|
-
|
94
|
+
* [Real Include](http://github.com/banister/real_include) - Brings in
|
95
|
+
module singleton classes during an include. No more ugly ClassMethods and included() hook hacks.
|
96
|
+
* [Object2module](http://github.com/banister/object2module) - Convert Classes and Objects to Modules so they can be extended/included
|
97
|
+
* [Prepend](http://github.com/banister/prepend) - Prepends modules in front of a class; so method lookup starts with the module
|
98
|
+
* [GenEval](http://github.com/banister/gen_eval) - A strange new breed of instance_eval
|
47
99
|
|
48
|
-
|
100
|
+
Full list of functions
|
101
|
+
----------------------
|
49
102
|
|
50
|
-
|
103
|
+
**include-based functions:**
|
51
104
|
|
52
|
-
|
53
|
-
|
54
|
-
|
105
|
+
* include_at(index)
|
106
|
+
* include_at_top(mod)
|
107
|
+
* include_before(before_mod, mod)
|
108
|
+
* include_after(after_mod, mod)
|
109
|
+
* swap_modules(mod1, mod2)
|
110
|
+
* uninclude(mod, recurse=fale)
|
111
|
+
* module_move_up(mod)
|
112
|
+
* module_move_down(mod)
|
113
|
+
* replace_module(mod1, mod2)
|
114
|
+
|
115
|
+
**extend-based functions:**
|
116
|
+
|
117
|
+
* extend_at(index)
|
118
|
+
* extend_at_top(mod)
|
119
|
+
* extend_before(before_mod, mod)
|
120
|
+
* extend_after(after_mod, mod)
|
121
|
+
* swap_extended_modules(mod1, mod2)
|
122
|
+
* replace_module(mod1, mod2)
|
123
|
+
* unextend(mod, recurse=false)
|
124
|
+
* extended_module_move_up(mod)
|
125
|
+
* extended_module_move_down(mod)
|
126
|
+
|
127
|
+
Limitations
|
128
|
+
------------
|
129
|
+
|
130
|
+
Remix does not currently reorder the singleton classes of superclasses
|
131
|
+
to reflect the new position of the class. This functionality is coming
|
132
|
+
soon.
|
133
|
+
|
134
|
+
Contact
|
135
|
+
-------
|
136
|
+
|
137
|
+
Problems or questions contact me at [github](http://github.com/banister)
|
138
|
+
|
139
|
+
Dedication
|
140
|
+
----------
|
141
|
+
|
142
|
+
For Rue (1977-)
|
data/Rakefile
CHANGED
@@ -25,10 +25,10 @@ specification = Gem::Specification.new do |s|
|
|
25
25
|
s.has_rdoc = 'yard'
|
26
26
|
|
27
27
|
#s.extensions = ["ext/remix/extconf.rb"]
|
28
|
-
s.files =
|
29
|
-
"lib/remix.rb", "lib/remix/version.rb"] +
|
28
|
+
s.files =
|
30
29
|
["lib/1.9/remix.so", "lib/1.8/remix.so"] +
|
31
|
-
|
30
|
+
FileList["ext/**/extconf.rb", "ext/**/*.h", "ext/**/*.c", "lib/**/*.rb", "test/*.rb",
|
31
|
+
"CHANGELOG", "README.markdown", "Rakefile"].to_a
|
32
32
|
end
|
33
33
|
|
34
34
|
Rake::GemPackageTask.new(specification) do |package|
|
data/ext/remix/remix.c
CHANGED
@@ -106,6 +106,9 @@ get_source_module(VALUE mod)
|
|
106
106
|
static VALUE
|
107
107
|
retrieve_before_mod(VALUE m, VALUE before)
|
108
108
|
{
|
109
|
+
if (!RTEST(rb_obj_is_kind_of(before, rb_cModule)) && TYPE(before) != T_FALSE)
|
110
|
+
rb_raise(rb_eTypeError, "Must be a Module or Class type.");
|
111
|
+
|
109
112
|
VALUE k = get_source_module(RCLASS_SUPER(m));
|
110
113
|
while(k != before && m != 0 && m != rb_cObject) {
|
111
114
|
m = RCLASS_SUPER(m);
|
@@ -120,6 +123,9 @@ retrieve_before_mod(VALUE m, VALUE before)
|
|
120
123
|
static VALUE
|
121
124
|
retrieve_mod(VALUE m, VALUE after)
|
122
125
|
{
|
126
|
+
if (!RTEST(rb_obj_is_kind_of(after, rb_cModule)) && TYPE(after) != T_FALSE)
|
127
|
+
rb_raise(rb_eTypeError, "Must be a Module or Class type.");
|
128
|
+
|
123
129
|
VALUE k = get_source_module(m);
|
124
130
|
while(k != after && m != 0 && m != rb_cObject) {
|
125
131
|
m = RCLASS_SUPER(m);
|
@@ -191,19 +197,25 @@ VALUE
|
|
191
197
|
rb_include_before(VALUE self, VALUE before, VALUE mod)
|
192
198
|
{
|
193
199
|
rb_prepare_for_remix(self);
|
200
|
+
|
201
|
+
if (before == self)
|
202
|
+
rb_raise(rb_eRuntimeError, "Prepend not supported yet!");
|
203
|
+
|
194
204
|
rb_include_module(retrieve_before_mod(self, before), mod);
|
195
205
|
return self;
|
196
206
|
}
|
197
207
|
|
198
208
|
VALUE
|
199
|
-
rb_include_at(VALUE self, VALUE
|
209
|
+
rb_include_at(VALUE self, VALUE rb_index, VALUE mod)
|
200
210
|
{
|
201
211
|
rb_prepare_for_remix(self);
|
212
|
+
|
213
|
+
Check_Type(rb_index, T_FIXNUM);
|
202
214
|
|
203
215
|
int index = FIX2INT(rb_index);
|
204
216
|
VALUE m = self;
|
205
217
|
|
206
|
-
int i =
|
218
|
+
int i = 1;
|
207
219
|
while(i++ < index && RCLASS_SUPER(m) != 0 && RCLASS_SUPER(m) != rb_cObject)
|
208
220
|
m = RCLASS_SUPER(m);
|
209
221
|
|
@@ -236,16 +248,40 @@ rb_swap_modules(VALUE self, VALUE mod1, VALUE mod2)
|
|
236
248
|
return self;
|
237
249
|
}
|
238
250
|
|
251
|
+
static void
|
252
|
+
remove_nested_module(VALUE included_mod, VALUE module)
|
253
|
+
{
|
254
|
+
VALUE source_mod = get_source_module(RCLASS_SUPER(included_mod));
|
255
|
+
|
256
|
+
if (source_mod == rb_cObject || source_mod == Qfalse)
|
257
|
+
return;
|
258
|
+
else if (source_mod == get_source_module(RCLASS_SUPER(module))) {
|
259
|
+
remove_nested_module(RCLASS_SUPER(included_mod), RCLASS_SUPER(module));
|
260
|
+
RCLASS_SUPER(included_mod) = RCLASS_SUPER(RCLASS_SUPER(included_mod));
|
261
|
+
}
|
262
|
+
}
|
263
|
+
|
239
264
|
VALUE
|
240
|
-
|
265
|
+
rb_uninclude(int argc, VALUE * argv, VALUE self)
|
241
266
|
{
|
242
267
|
rb_prepare_for_remix(self);
|
243
268
|
|
269
|
+
VALUE mod1, recurse = Qfalse;
|
270
|
+
rb_scan_args(argc, argv, "11", &mod1, &recurse);
|
271
|
+
|
272
|
+
if (!RTEST(rb_mod_include_p(self, mod1)))
|
273
|
+
rb_raise(rb_eArgError, "Module not found");
|
274
|
+
|
244
275
|
VALUE before = retrieve_before_mod(self, mod1);
|
245
276
|
VALUE included_mod = retrieve_mod(self, mod1);
|
246
277
|
|
247
278
|
if (mod1 == rb_cObject) rb_raise(rb_eRuntimeError, "can't delete Object");
|
279
|
+
|
280
|
+
if (RTEST(recurse))
|
281
|
+
remove_nested_module(included_mod, mod1);
|
282
|
+
|
248
283
|
RCLASS_SUPER(before) = RCLASS_SUPER(included_mod);
|
284
|
+
|
249
285
|
rb_clear_cache();
|
250
286
|
|
251
287
|
return self;
|
@@ -260,7 +296,7 @@ rb_replace_module(VALUE self, VALUE mod1, VALUE mod2)
|
|
260
296
|
return rb_swap_modules(self, mod1, mod2);
|
261
297
|
|
262
298
|
VALUE before = retrieve_before_mod(self, mod1);
|
263
|
-
|
299
|
+
rb_uninclude(1, &mod1, self);
|
264
300
|
rb_include_module(before, mod2);
|
265
301
|
return self;
|
266
302
|
}
|
@@ -268,17 +304,25 @@ rb_replace_module(VALUE self, VALUE mod1, VALUE mod2)
|
|
268
304
|
void
|
269
305
|
Init_remix()
|
270
306
|
{
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
rb_define_method(
|
276
|
-
rb_define_method(
|
277
|
-
|
278
|
-
rb_define_method(
|
279
|
-
|
280
|
-
|
281
|
-
rb_define_method(
|
282
|
-
|
307
|
+
VALUE mRemix = rb_define_module("Remix");
|
308
|
+
VALUE mModuleExtensions = rb_define_module_under(mRemix, "ModuleExtensions");
|
309
|
+
|
310
|
+
rb_define_method(mModuleExtensions, "ready_remix", rb_prepare_for_remix, 0);
|
311
|
+
rb_define_method(mModuleExtensions, "module_move_up", rb_module_move_up, 1);
|
312
|
+
rb_define_method(mModuleExtensions, "module_move_down", rb_module_move_down, 1);
|
313
|
+
|
314
|
+
rb_define_method(mModuleExtensions, "include_at", rb_include_at, 2);
|
315
|
+
rb_define_method(mModuleExtensions, "include_below", rb_include_before, 2);
|
316
|
+
rb_define_alias(mModuleExtensions, "include_before", "include_below");
|
317
|
+
rb_define_method(mModuleExtensions, "include_above", rb_include_after, 2);
|
318
|
+
rb_define_alias(mModuleExtensions, "include_after", "include_above");
|
319
|
+
rb_define_method(mModuleExtensions, "include_at_top", rb_include_at_top, 1);
|
320
|
+
|
321
|
+
rb_define_method(mModuleExtensions, "swap_modules", rb_swap_modules, 2);
|
322
|
+
rb_define_method(mModuleExtensions, "uninclude", rb_uninclude, -1);
|
323
|
+
rb_define_alias(mModuleExtensions, "remove_module", "uninclude");
|
324
|
+
rb_define_method(mModuleExtensions, "replace_module", rb_replace_module, 2);
|
325
|
+
|
326
|
+
rb_include_module(rb_cModule, mModuleExtensions);
|
283
327
|
}
|
284
328
|
|
data/lib/1.8/remix.so
CHANGED
Binary file
|
data/lib/1.9/remix.so
CHANGED
Binary file
|
data/lib/remix.rb
CHANGED
@@ -2,6 +2,7 @@ direc = File.dirname(__FILE__)
|
|
2
2
|
|
3
3
|
require 'rbconfig'
|
4
4
|
require "#{direc}/remix/version"
|
5
|
+
require "#{direc}/remix/c_docs"
|
5
6
|
|
6
7
|
dlext = Config::CONFIG['DLEXT']
|
7
8
|
|
@@ -15,3 +16,74 @@ rescue LoadError => e
|
|
15
16
|
require "#{direc}/remix.#{dlext}"
|
16
17
|
end
|
17
18
|
|
19
|
+
module Kernel
|
20
|
+
# :nodoc:
|
21
|
+
def singleton_class
|
22
|
+
class << self; self; end
|
23
|
+
end if !respond_to?(:singleton_class)
|
24
|
+
end
|
25
|
+
|
26
|
+
module Remix::ObjectExtensions
|
27
|
+
|
28
|
+
# Like `include_at()` but for the singleton class
|
29
|
+
# @see Module#include_at
|
30
|
+
def extend_at(index, mod)
|
31
|
+
singleton_class.include_at(index, mod)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Like `include_below()` but for the singleton class
|
35
|
+
# @see Module#include_below
|
36
|
+
def extend_below(mod1, mod2)
|
37
|
+
singleton_class.include_below(mod1, mod2)
|
38
|
+
end
|
39
|
+
alias_method :extend_before, :extend_below
|
40
|
+
|
41
|
+
# Like `include_above()` but for the singleton class
|
42
|
+
# @see Module#include_above
|
43
|
+
def extend_above(mod1, mod2)
|
44
|
+
singleton_class.include_above(mod1, mod2)
|
45
|
+
end
|
46
|
+
alias_method :extend_after, :extend_above
|
47
|
+
|
48
|
+
# Like `uninclude()` but for the singleton class
|
49
|
+
# @see Module#uninclude
|
50
|
+
def unextend(mod, recurse = false)
|
51
|
+
singleton_class.uninclude(mod, recurse)
|
52
|
+
end
|
53
|
+
alias_method :remove_extended_module, :unextend
|
54
|
+
|
55
|
+
# Like `include_at_top()` but for the singleton class
|
56
|
+
# @see Module#include_at_top
|
57
|
+
def extend_at_top(mod)
|
58
|
+
singleton_class.include_at_top(mod)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Like `swap_modules()` but for the singleton class
|
62
|
+
# @see Module#swap_modules
|
63
|
+
def swap_extended_modules(mod1, mod2)
|
64
|
+
singleton_class.swap_modules(mod1, mod2)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Like `module_move_up()` but for the singleton class
|
68
|
+
# @see Module#module_move_up
|
69
|
+
def extended_module_move_up(mod)
|
70
|
+
singleton_class.module_move_up(mod)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Like `module_move_down()` but for the singleton class
|
74
|
+
# @see Module#module_move_down
|
75
|
+
def extended_module_move_down(mod)
|
76
|
+
singleton_class.module_move_down(mod)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Like `replace_module()` but for the singleton class
|
80
|
+
# @see Module#replace_module_down
|
81
|
+
def replace_extended_module(mod1, mod2)
|
82
|
+
singleton_class.replace_module(mod1, mod2)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
class Object
|
88
|
+
include Remix::ObjectExtensions
|
89
|
+
end
|
data/lib/remix/c_docs.rb
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
module Remix
|
2
|
+
module ModuleExtensions
|
3
|
+
# Includes a module at a particular index in the ancestor
|
4
|
+
# chain.
|
5
|
+
#
|
6
|
+
# @param [Fixnum] index The index where the module will be included
|
7
|
+
# (must be > 1.)
|
8
|
+
# @param [Module] mod The module to include
|
9
|
+
# @return [Module] The receiver
|
10
|
+
# @example
|
11
|
+
# module M end
|
12
|
+
# module N end
|
13
|
+
# module O end
|
14
|
+
# module P
|
15
|
+
# include M, N
|
16
|
+
# end
|
17
|
+
# P.include_at 2, O
|
18
|
+
# P.ancestors #=> [P, M, O, N]
|
19
|
+
def include_at(index, mod) end
|
20
|
+
|
21
|
+
# Includes a module below a specific module in the ancestor chain.
|
22
|
+
# @param [Module] mod1 Module with position
|
23
|
+
# @param [Module] mod2 Module that will be included
|
24
|
+
# @return [Module] The receiver
|
25
|
+
# @example
|
26
|
+
# M.ancestors #=> [M, A, B]
|
27
|
+
# M.include_below B, J
|
28
|
+
# M.ancestors #=> [M, A, J, B]
|
29
|
+
def include_below(mod1, mod2) end
|
30
|
+
|
31
|
+
# Includes a module above a specific module in the ancestor chain.
|
32
|
+
# @param [Module] mod1 Module with position
|
33
|
+
# @param [Module] mod2 Module that will be included
|
34
|
+
# @return [Module] The receiver
|
35
|
+
# @example
|
36
|
+
# M.ancestors #=> [M, A, B]
|
37
|
+
# M.include_above B, J
|
38
|
+
# M.ancestors #=> [M, A, B, J]
|
39
|
+
def include_above(mod1, mod) end
|
40
|
+
|
41
|
+
# Includes a module at top of ancestor chain
|
42
|
+
# @param [Module] mod Module that will be included
|
43
|
+
# @return [Module] The receiver
|
44
|
+
# @example
|
45
|
+
# M.ancestors #=> [M, A, B]
|
46
|
+
# M.include_at_top J
|
47
|
+
# M.ancestors #=> [M, A, B, J]
|
48
|
+
def include_at_top(mod) end
|
49
|
+
|
50
|
+
# Moves a module up one position in the ancestor chain.
|
51
|
+
# Module must already be in ancestor chain.
|
52
|
+
# @param [Module] Module to move up
|
53
|
+
# @return [Module] The receiver
|
54
|
+
# @example
|
55
|
+
# M.ancestors #=> [M, A, B]
|
56
|
+
# M.module_move_up A
|
57
|
+
# M.ancestors #=> [M, B, A]
|
58
|
+
def module_move_up(mod) end
|
59
|
+
|
60
|
+
# Moves a module down one position in the ancestor chain.
|
61
|
+
# Module must already be in ancestor chain.
|
62
|
+
# @param [Module] Module to move down
|
63
|
+
# @return [Module] The receiver
|
64
|
+
# @example
|
65
|
+
# M.ancestors #=> [M, A, B]
|
66
|
+
# M.module_move_down B
|
67
|
+
# M.ancestors #=> [M, B, A]
|
68
|
+
def module_move_down(mod) end
|
69
|
+
|
70
|
+
# Unincludes a module from an ancestor chain with optional recursion
|
71
|
+
# for nested modules.
|
72
|
+
# @param [Module] mod The module to uninclude
|
73
|
+
# @param [Boolean] recurse Set to true to remove nested modules
|
74
|
+
# @return [Module] The receiver
|
75
|
+
# @example
|
76
|
+
# module C
|
77
|
+
# include A, B
|
78
|
+
# end
|
79
|
+
# M.ancestors #=> [M, C, A, B]
|
80
|
+
# M.uninclude C
|
81
|
+
# M.ancestors #=> [M, A, B]
|
82
|
+
# @example With recursion
|
83
|
+
# module C
|
84
|
+
# include A, B
|
85
|
+
# end
|
86
|
+
# M.ancestors #=> [M, C, A, B]
|
87
|
+
# M.uninclude C, true
|
88
|
+
# M.ancestors #=> [M]
|
89
|
+
def uninclude(mod, recurse = false) end
|
90
|
+
|
91
|
+
# Swaps the position of two modules that already exist in an
|
92
|
+
# ancestor chain.
|
93
|
+
# @param [Module] mod1 Module to swap
|
94
|
+
# @param [Module] mod2 Module to swap
|
95
|
+
# @return [Module] The receiver
|
96
|
+
# @example
|
97
|
+
# M.ancestors #=> [M, A, B, C, D]
|
98
|
+
# M.swap_modules A, D
|
99
|
+
# M.ancestors #=> [M, D, B, C, A]
|
100
|
+
def swap_modules(mod1, mod2) end
|
101
|
+
|
102
|
+
# Replaces a module with another module that is not already in the
|
103
|
+
# ancestor chain.
|
104
|
+
# @param [Module] mod1 The module to be replaced
|
105
|
+
# @param [Module] mod2 The module that will replace
|
106
|
+
# @return [Module] The receiver
|
107
|
+
# @example
|
108
|
+
# J = Module.new
|
109
|
+
# M.ancestors #=> [M, A, B]
|
110
|
+
# M.replace_module B, J
|
111
|
+
# M.ancestors #=> [M, A, J]
|
112
|
+
def replace_module(mod1, mod2) end
|
113
|
+
end
|
114
|
+
end
|
data/lib/remix/version.rb
CHANGED
data/test/test.rb
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require '../lib/remix'
|
3
|
+
require 'bacon'
|
4
|
+
|
5
|
+
class Module
|
6
|
+
public :include, :remove_const
|
7
|
+
end
|
8
|
+
|
9
|
+
describe 'Test basic remix functionality' do
|
10
|
+
before do
|
11
|
+
A = Module.new
|
12
|
+
B = Module.new
|
13
|
+
C = Module.new
|
14
|
+
J = Module.new
|
15
|
+
|
16
|
+
M = Module.new
|
17
|
+
|
18
|
+
M.include A, B
|
19
|
+
M.extend A, B
|
20
|
+
end
|
21
|
+
|
22
|
+
after do
|
23
|
+
Object.remove_const(:A)
|
24
|
+
Object.remove_const(:B)
|
25
|
+
Object.remove_const(:C)
|
26
|
+
Object.remove_const(:M)
|
27
|
+
Object.remove_const(:J)
|
28
|
+
end
|
29
|
+
|
30
|
+
describe 'extend-based methods' do
|
31
|
+
describe 'extend_after' do
|
32
|
+
it 'should insert module into correct position in singleton class' do
|
33
|
+
M.extend_above B, J
|
34
|
+
M.singleton_class.ancestors
|
35
|
+
M.singleton_class.ancestors[0..2].should == [A, B, J]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'unextend' do
|
40
|
+
it 'should unextend the module' do
|
41
|
+
C.include A, B
|
42
|
+
M.extend C
|
43
|
+
M.singleton_class.ancestors[0..2].should == [C, A, B]
|
44
|
+
M.unextend C
|
45
|
+
M.singleton_class.ancestors[0..1].should == [A, B]
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should unextend the nested module' do
|
49
|
+
C.include A, B
|
50
|
+
M.extend C
|
51
|
+
M.extend J
|
52
|
+
M.singleton_class.ancestors[0..3].should == [J, C, A, B]
|
53
|
+
M.unextend C, true
|
54
|
+
M.singleton_class.ancestors[0..1].should == [J, Module]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe 'include-based methods' do
|
60
|
+
describe 'include_after' do
|
61
|
+
it 'should insert module into correct position' do
|
62
|
+
M.include_after A, C
|
63
|
+
M.ancestors[2].should == C
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe 'include_before' do
|
68
|
+
it 'should insert module into correct position' do
|
69
|
+
M.include_before B, C
|
70
|
+
M.ancestors[2].should == C
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe 'include_at_top' do
|
75
|
+
it 'should insert module at top of chain' do
|
76
|
+
M.include_at_top C
|
77
|
+
M.ancestors.last.should == C
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe 'swap_modules' do
|
82
|
+
it 'should interchange modules' do
|
83
|
+
M.ancestors[1..2].should == [A, B]
|
84
|
+
M.swap_modules A, B
|
85
|
+
M.ancestors[1..2].should == [B, A]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe 'module_move_up' do
|
90
|
+
it 'should move module up the chain' do
|
91
|
+
M.ancestors[1..2].should == [A, B]
|
92
|
+
M.module_move_up A
|
93
|
+
M.ancestors[1..2].should == [B, A]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe 'module_move_down' do
|
98
|
+
it 'should move module down the chain' do
|
99
|
+
M.ancestors[1..2].should == [A, B]
|
100
|
+
M.module_move_down B
|
101
|
+
M.ancestors[1..2].should == [B, A]
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe 'include_at' do
|
106
|
+
it 'should include module at specified index' do
|
107
|
+
M.include_at(1, C)
|
108
|
+
M.ancestors[1].should == C
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe 'remove_module' do
|
113
|
+
it 'should remove the module' do
|
114
|
+
M.ancestors[1..2].should == [A, B]
|
115
|
+
M.remove_module A
|
116
|
+
M.ancestors[1..2].should == [B]
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'should remove recursively if second parameter is true' do
|
120
|
+
klass = Module.new
|
121
|
+
klass.include J, M, C
|
122
|
+
klass.ancestors[1..-1].should == [J, M, A, B, C]
|
123
|
+
klass.remove_module M, true
|
124
|
+
klass.ancestors[1..-1].should == [J, C]
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe 'replace_module' do
|
129
|
+
it 'should replace the module with another' do
|
130
|
+
M.ancestors[1..2].should == [A, B]
|
131
|
+
M.replace_module B, C
|
132
|
+
M.ancestors[1..2].should == [A, C]
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: remix
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: 23
|
5
4
|
prerelease: false
|
6
5
|
segments:
|
7
6
|
- 0
|
8
7
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
8
|
+
- 5
|
9
|
+
version: 0.2.5
|
11
10
|
platform: i386-mingw32
|
12
11
|
authors:
|
13
12
|
- John Mair (banisterfiend)
|
@@ -15,7 +14,7 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date: 2010-10-
|
17
|
+
date: 2010-10-27 00:00:00 +13:00
|
19
18
|
default_executable:
|
20
19
|
dependencies: []
|
21
20
|
|
@@ -28,16 +27,18 @@ extensions: []
|
|
28
27
|
extra_rdoc_files: []
|
29
28
|
|
30
29
|
files:
|
31
|
-
- Rakefile
|
32
|
-
- README.markdown
|
33
|
-
- CHANGELOG
|
34
|
-
- lib/remix.rb
|
35
|
-
- lib/remix/version.rb
|
36
30
|
- lib/1.9/remix.so
|
37
31
|
- lib/1.8/remix.so
|
38
32
|
- ext/remix/extconf.rb
|
39
33
|
- ext/remix/compat.h
|
40
34
|
- ext/remix/remix.c
|
35
|
+
- lib/remix/c_docs.rb
|
36
|
+
- lib/remix/version.rb
|
37
|
+
- lib/remix.rb
|
38
|
+
- test/test.rb
|
39
|
+
- CHANGELOG
|
40
|
+
- README.markdown
|
41
|
+
- Rakefile
|
41
42
|
has_rdoc: yard
|
42
43
|
homepage: http://banisterfiend.wordpress.com
|
43
44
|
licenses: []
|
@@ -52,7 +53,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
52
53
|
requirements:
|
53
54
|
- - ">="
|
54
55
|
- !ruby/object:Gem::Version
|
55
|
-
hash: 3
|
56
56
|
segments:
|
57
57
|
- 0
|
58
58
|
version: "0"
|
@@ -61,7 +61,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
61
61
|
requirements:
|
62
62
|
- - ">="
|
63
63
|
- !ruby/object:Gem::Version
|
64
|
-
hash: 3
|
65
64
|
segments:
|
66
65
|
- 0
|
67
66
|
version: "0"
|