remix 0.1.0-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 +2 -0
- data/README.markdown +40 -0
- data/Rakefile +37 -0
- data/ext/remix/compat.h +57 -0
- data/ext/remix/extconf.rb +3 -0
- data/ext/remix/remix.c +241 -0
- data/lib/1.8/remix.so +0 -0
- data/lib/1.9/remix.so +0 -0
- data/lib/remix/version.rb +3 -0
- data/lib/remix.rb +17 -0
- metadata +76 -0
data/CHANGELOG
ADDED
data/README.markdown
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
Remix
|
2
|
+
--------------
|
3
|
+
|
4
|
+
(c) John Mair (banisterfiend)
|
5
|
+
MIT license
|
6
|
+
|
7
|
+
Makes inheritance chains read/write
|
8
|
+
|
9
|
+
** This is BETA software and has not yet been thoroughly tested, use
|
10
|
+
at own risk **
|
11
|
+
|
12
|
+
Currently supports:
|
13
|
+
|
14
|
+
* include_at(index)
|
15
|
+
* include_before(BeforeMod, Mod)
|
16
|
+
* include_after(AfterMod, Mod)
|
17
|
+
* swap_modules(Mod1, Mod2)
|
18
|
+
* remove_module(Mod)
|
19
|
+
* ...more to come!
|
20
|
+
|
21
|
+
example:
|
22
|
+
|
23
|
+
module M end
|
24
|
+
|
25
|
+
class A; end
|
26
|
+
|
27
|
+
class B < A
|
28
|
+
include_after(A, M)
|
29
|
+
end
|
30
|
+
|
31
|
+
B.ancestors #=> [B, A, M, ...]
|
32
|
+
B.swap_modules A, M
|
33
|
+
B.ancestors #=> [B, M, A, ...]
|
34
|
+
module J end
|
35
|
+
B.include_before A, J
|
36
|
+
B.ancestors #=> [B, M, J, A, ...]
|
37
|
+
B.remove_module M
|
38
|
+
B.ancestors #=> [B, J, A, ...]
|
39
|
+
|
40
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
$LOAD_PATH.unshift File.join(File.expand_path(__FILE__), '..')
|
2
|
+
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/gempackagetask'
|
5
|
+
|
6
|
+
require 'lib/remix/version'
|
7
|
+
|
8
|
+
$dlext = Config::CONFIG['DLEXT']
|
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
|
+
specification = Gem::Specification.new do |s|
|
14
|
+
s.name = "remix"
|
15
|
+
s.summary = "Ruby modules re-mixed and remastered"
|
16
|
+
s.version = Remix::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.platform = Gem::Platform::RUBY
|
23
|
+
s.platform = 'i386-mingw32'
|
24
|
+
s.homepage = "http://banisterfiend.wordpress.com"
|
25
|
+
s.has_rdoc = 'yard'
|
26
|
+
|
27
|
+
#s.extensions = ["ext/remix/extconf.rb"]
|
28
|
+
s.files = ["Rakefile", "README.markdown", "CHANGELOG",
|
29
|
+
"lib/remix.rb", "lib/remix/version.rb"] +
|
30
|
+
["lib/1.9/remix.so", "lib/1.8/remix.so"] +
|
31
|
+
FileList["ext/**/extconf.rb", "ext/**/*.h", "ext/**/*.c"].to_a
|
32
|
+
end
|
33
|
+
|
34
|
+
Rake::GemPackageTask.new(specification) do |package|
|
35
|
+
package.need_zip = false
|
36
|
+
package.need_tar = false
|
37
|
+
end
|
data/ext/remix/compat.h
ADDED
@@ -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
|
data/ext/remix/remix.c
ADDED
@@ -0,0 +1,241 @@
|
|
1
|
+
/* object2module.c */
|
2
|
+
/* (C) John Mair 2009
|
3
|
+
* This program is distributed under the terms of the MIT License
|
4
|
+
* */
|
5
|
+
|
6
|
+
#include <ruby.h>
|
7
|
+
#include "compat.h"
|
8
|
+
|
9
|
+
/* a modified version of include_class_new from class.c */
|
10
|
+
static VALUE
|
11
|
+
j_class_new(VALUE module, VALUE sup)
|
12
|
+
{
|
13
|
+
|
14
|
+
VALUE klass = create_class(T_ICLASS, rb_cClass);
|
15
|
+
|
16
|
+
if (TYPE(module) == T_ICLASS) {
|
17
|
+
klass = module;
|
18
|
+
}
|
19
|
+
|
20
|
+
if (!RCLASS_IV_TBL(module)) {
|
21
|
+
RCLASS_IV_TBL(module) = (struct st_table *)st_init_numtable();
|
22
|
+
}
|
23
|
+
|
24
|
+
/* assign iv_tbl, m_tbl and super */
|
25
|
+
RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
|
26
|
+
|
27
|
+
if (TYPE(module) == T_ICLASS) {
|
28
|
+
if (!RTEST(rb_iv_get(module, "__module__")))
|
29
|
+
rb_iv_set(klass, "__module__", KLASS_OF(module));
|
30
|
+
}
|
31
|
+
else if (TYPE(module) == T_MODULE || TYPE(module) == T_CLASS)
|
32
|
+
rb_iv_set(klass, "__module__", module);
|
33
|
+
|
34
|
+
RCLASS_SUPER(klass) = sup;
|
35
|
+
if(TYPE(module) != T_OBJECT) {
|
36
|
+
RCLASS_M_TBL(klass) = RCLASS_M_TBL(module);
|
37
|
+
}
|
38
|
+
else {
|
39
|
+
RCLASS_M_TBL(klass) = RCLASS_M_TBL(CLASS_OF(module));
|
40
|
+
}
|
41
|
+
|
42
|
+
/* */
|
43
|
+
|
44
|
+
if (TYPE(module) == T_ICLASS) {
|
45
|
+
KLASS_OF(klass) = rb_iv_get(klass, "__module__");
|
46
|
+
}
|
47
|
+
else {
|
48
|
+
KLASS_OF(klass) = module;
|
49
|
+
}
|
50
|
+
|
51
|
+
if(TYPE(module) != T_OBJECT) {
|
52
|
+
OBJ_INFECT(klass, module);
|
53
|
+
OBJ_INFECT(klass, sup);
|
54
|
+
}
|
55
|
+
|
56
|
+
return (VALUE)klass;
|
57
|
+
}
|
58
|
+
|
59
|
+
static VALUE
|
60
|
+
set_supers(VALUE c)
|
61
|
+
{
|
62
|
+
if (RCLASS_SUPER(c) == rb_cObject || RCLASS_SUPER(c) == Qnil) {
|
63
|
+
return RCLASS_SUPER(c);
|
64
|
+
}
|
65
|
+
else {
|
66
|
+
return j_class_new(RCLASS_SUPER(c), set_supers(RCLASS_SUPER(c)));
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
VALUE
|
71
|
+
rb_prepare_for_remix(VALUE klass)
|
72
|
+
{
|
73
|
+
if (!RTEST(rb_obj_is_kind_of(klass, rb_cModule)))
|
74
|
+
rb_raise(rb_eTypeError, "Must be a Module or Class type.");
|
75
|
+
|
76
|
+
RCLASS_SUPER(klass) = set_supers(klass);
|
77
|
+
|
78
|
+
rb_clear_cache();
|
79
|
+
return klass;
|
80
|
+
}
|
81
|
+
|
82
|
+
inline static VALUE
|
83
|
+
get_source_module(VALUE mod)
|
84
|
+
{
|
85
|
+
switch (TYPE(mod)) {
|
86
|
+
case T_ICLASS:
|
87
|
+
if (RTEST(rb_iv_get(mod, "__module__")))
|
88
|
+
return rb_iv_get(mod, "__module__");
|
89
|
+
else
|
90
|
+
return KLASS_OF(mod);
|
91
|
+
break;
|
92
|
+
case T_CLASS:
|
93
|
+
case T_MODULE:
|
94
|
+
return mod;
|
95
|
+
break;
|
96
|
+
default:
|
97
|
+
rb_raise(rb_eRuntimeError, "get_source_module: mod is not a class or iclass!");
|
98
|
+
}
|
99
|
+
|
100
|
+
/* never reached */
|
101
|
+
return Qnil;
|
102
|
+
}
|
103
|
+
|
104
|
+
static VALUE
|
105
|
+
retrieve_before_mod(VALUE m, VALUE before)
|
106
|
+
{
|
107
|
+
VALUE k = get_source_module(RCLASS_SUPER(m));
|
108
|
+
while(k != before && m != Qnil && m != rb_cObject) {
|
109
|
+
m = RCLASS_SUPER(m);
|
110
|
+
k = get_source_module(RCLASS_SUPER(m));
|
111
|
+
}
|
112
|
+
if (get_source_module(RCLASS_SUPER(m)) != before)
|
113
|
+
rb_raise(rb_eRuntimeError, "'before' module not found");
|
114
|
+
|
115
|
+
return m;
|
116
|
+
}
|
117
|
+
|
118
|
+
static VALUE
|
119
|
+
retrieve_mod(VALUE m, VALUE after)
|
120
|
+
{
|
121
|
+
VALUE k = get_source_module(m);
|
122
|
+
while(k != after && m != Qnil && m != rb_cObject) {
|
123
|
+
m = RCLASS_SUPER(m);
|
124
|
+
k = get_source_module(m);
|
125
|
+
}
|
126
|
+
|
127
|
+
if (k != after)
|
128
|
+
rb_raise(rb_eRuntimeError, "'after' module not found");
|
129
|
+
|
130
|
+
return m;
|
131
|
+
}
|
132
|
+
|
133
|
+
VALUE
|
134
|
+
rb_include_after(VALUE self, VALUE after, VALUE mod)
|
135
|
+
{
|
136
|
+
rb_prepare_for_remix(self);
|
137
|
+
|
138
|
+
VALUE k, m = self;
|
139
|
+
|
140
|
+
k = get_source_module(m);
|
141
|
+
while(k != after && m != Qnil && m != rb_cObject) {
|
142
|
+
m = RCLASS_SUPER(m);
|
143
|
+
k = get_source_module(m);
|
144
|
+
}
|
145
|
+
|
146
|
+
if (k != after)
|
147
|
+
rb_raise(rb_eRuntimeError, "'after' module not found");
|
148
|
+
|
149
|
+
rb_include_module(m, mod);
|
150
|
+
|
151
|
+
return self;
|
152
|
+
}
|
153
|
+
|
154
|
+
VALUE
|
155
|
+
rb_include_before(VALUE self, VALUE before, VALUE mod)
|
156
|
+
{
|
157
|
+
rb_prepare_for_remix(self);
|
158
|
+
|
159
|
+
VALUE k, m = self;
|
160
|
+
|
161
|
+
k = get_source_module(RCLASS_SUPER(m));
|
162
|
+
while(k != before && m != Qnil && m != rb_cObject) {
|
163
|
+
m = RCLASS_SUPER(m);
|
164
|
+
k = get_source_module(RCLASS_SUPER(m));
|
165
|
+
}
|
166
|
+
|
167
|
+
if (get_source_module(RCLASS_SUPER(m)) != before)
|
168
|
+
rb_raise(rb_eRuntimeError, "'before' module not found");
|
169
|
+
|
170
|
+
rb_include_module(m, mod);
|
171
|
+
|
172
|
+
return self;
|
173
|
+
}
|
174
|
+
|
175
|
+
VALUE
|
176
|
+
rb_include_at(VALUE self, VALUE mod, VALUE rb_index)
|
177
|
+
{
|
178
|
+
rb_prepare_for_remix(self);
|
179
|
+
|
180
|
+
int index = FIX2INT(rb_index);
|
181
|
+
VALUE m = self;
|
182
|
+
|
183
|
+
int i = 0;
|
184
|
+
while(i++ < index && RCLASS_SUPER(m) != Qnil && RCLASS_SUPER(m) != rb_cObject)
|
185
|
+
m = RCLASS_SUPER(m);
|
186
|
+
|
187
|
+
rb_include_module(m, mod);
|
188
|
+
return self;
|
189
|
+
}
|
190
|
+
|
191
|
+
#define SWAP(X, Y) {(X) ^= (Y); (Y) ^= (X); (X) ^= (Y);}
|
192
|
+
|
193
|
+
VALUE
|
194
|
+
rb_swap_modules(VALUE self, VALUE mod1, VALUE mod2)
|
195
|
+
{
|
196
|
+
rb_prepare_for_remix(self);
|
197
|
+
|
198
|
+
VALUE before_mod1, before_mod2;
|
199
|
+
VALUE included_mod1, included_mod2;
|
200
|
+
|
201
|
+
if (mod1 == rb_cObject || mod2 == rb_cObject) rb_raise(rb_eRuntimeError, "can't swap Object");
|
202
|
+
|
203
|
+
included_mod1 = retrieve_mod(self, mod1);
|
204
|
+
included_mod2 = retrieve_mod(self, mod2);
|
205
|
+
before_mod1 = retrieve_before_mod(self, mod1);
|
206
|
+
before_mod2 = retrieve_before_mod(self, mod2);
|
207
|
+
|
208
|
+
SWAP(RCLASS_SUPER(before_mod1), RCLASS_SUPER(before_mod2));
|
209
|
+
SWAP(RCLASS_SUPER(included_mod1), RCLASS_SUPER(included_mod2));
|
210
|
+
|
211
|
+
rb_clear_cache();
|
212
|
+
|
213
|
+
return self;
|
214
|
+
}
|
215
|
+
|
216
|
+
VALUE
|
217
|
+
rb_remove_module(VALUE self, VALUE mod1)
|
218
|
+
{
|
219
|
+
rb_prepare_for_remix(self);
|
220
|
+
|
221
|
+
VALUE before = retrieve_before_mod(self, mod1);
|
222
|
+
VALUE included_mod = retrieve_mod(self, mod1);
|
223
|
+
|
224
|
+
if (mod1 == rb_cObject) rb_raise(rb_eRuntimeError, "can't delete Object");
|
225
|
+
RCLASS_SUPER(before) = RCLASS_SUPER(included_mod);
|
226
|
+
rb_clear_cache();
|
227
|
+
|
228
|
+
return self;
|
229
|
+
}
|
230
|
+
|
231
|
+
void
|
232
|
+
Init_remix()
|
233
|
+
{
|
234
|
+
rb_define_method(rb_cObject, "ready_remix", rb_prepare_for_remix, 0);
|
235
|
+
rb_define_method(rb_cModule, "include_at", rb_include_at, 2);
|
236
|
+
rb_define_method(rb_cModule, "include_before", rb_include_before, 2);
|
237
|
+
rb_define_method(rb_cModule, "include_after", rb_include_after, 2);
|
238
|
+
rb_define_method(rb_cModule, "swap_modules", rb_swap_modules, 2);
|
239
|
+
rb_define_method(rb_cModule, "remove_module", rb_remove_module, 1);
|
240
|
+
}
|
241
|
+
|
data/lib/1.8/remix.so
ADDED
Binary file
|
data/lib/1.9/remix.so
ADDED
Binary file
|
data/lib/remix.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
direc = File.dirname(__FILE__)
|
2
|
+
|
3
|
+
require 'rbconfig'
|
4
|
+
require "#{direc}/remix/version"
|
5
|
+
|
6
|
+
dlext = Config::CONFIG['DLEXT']
|
7
|
+
|
8
|
+
begin
|
9
|
+
if RUBY_VERSION && RUBY_VERSION =~ /1.9/
|
10
|
+
require "#{direc}/1.9/remix.#{dlext}"
|
11
|
+
else
|
12
|
+
require "#{direc}/1.8/remix.#{dlext}"
|
13
|
+
end
|
14
|
+
rescue LoadError => e
|
15
|
+
require "#{direc}/remix.#{dlext}"
|
16
|
+
end
|
17
|
+
|
metadata
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: remix
|
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-mingw32
|
12
|
+
authors:
|
13
|
+
- John Mair (banisterfiend)
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-10-25 00:00:00 +13:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: Ruby modules re-mixed and remastered
|
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/remix.rb
|
35
|
+
- lib/remix/version.rb
|
36
|
+
- lib/1.9/remix.so
|
37
|
+
- lib/1.8/remix.so
|
38
|
+
- ext/remix/extconf.rb
|
39
|
+
- ext/remix/compat.h
|
40
|
+
- ext/remix/remix.c
|
41
|
+
has_rdoc: yard
|
42
|
+
homepage: http://banisterfiend.wordpress.com
|
43
|
+
licenses: []
|
44
|
+
|
45
|
+
post_install_message:
|
46
|
+
rdoc_options: []
|
47
|
+
|
48
|
+
require_paths:
|
49
|
+
- lib
|
50
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
hash: 3
|
56
|
+
segments:
|
57
|
+
- 0
|
58
|
+
version: "0"
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
hash: 3
|
65
|
+
segments:
|
66
|
+
- 0
|
67
|
+
version: "0"
|
68
|
+
requirements: []
|
69
|
+
|
70
|
+
rubyforge_project:
|
71
|
+
rubygems_version: 1.3.7
|
72
|
+
signing_key:
|
73
|
+
specification_version: 3
|
74
|
+
summary: Ruby modules re-mixed and remastered
|
75
|
+
test_files: []
|
76
|
+
|