coderrr-mixico-inline 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/mixico.rb +71 -2
- data/mixico-inline.gemspec +2 -2
- data/test/mixico_test.rb +77 -0
- metadata +2 -2
data/lib/mixico.rb
CHANGED
@@ -3,7 +3,7 @@ require 'inline'
|
|
3
3
|
|
4
4
|
class Module
|
5
5
|
inline do |builder|
|
6
|
-
builder.c %
|
6
|
+
builder.c %{
|
7
7
|
static VALUE
|
8
8
|
disable_mixin(VALUE super)
|
9
9
|
{
|
@@ -25,7 +25,7 @@ class Module
|
|
25
25
|
}
|
26
26
|
}
|
27
27
|
|
28
|
-
builder.c %
|
28
|
+
builder.c %{
|
29
29
|
static VALUE
|
30
30
|
enable_mixin(VALUE mixin)
|
31
31
|
{
|
@@ -48,6 +48,58 @@ class Module
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
+
class Object
|
52
|
+
inline do |builder|
|
53
|
+
builder.prefix %{
|
54
|
+
#define KLASS_OF(o) RCLASS(RBASIC(o)->klass)
|
55
|
+
}
|
56
|
+
|
57
|
+
builder.c %{
|
58
|
+
void redirect_tbls(VALUE obj) {
|
59
|
+
unsigned long orig_iv_tbl, orig_m_tbl;
|
60
|
+
orig_iv_tbl = (unsigned long)ROBJECT(self)->iv_tbl;
|
61
|
+
orig_m_tbl = (unsigned long)KLASS_OF(self)->m_tbl;
|
62
|
+
ROBJECT(self)->iv_tbl = ROBJECT(obj)->iv_tbl;
|
63
|
+
KLASS_OF(self)->m_tbl = KLASS_OF(obj)->m_tbl;
|
64
|
+
rb_iv_set(self, "__orig_m_tbl__", orig_m_tbl);
|
65
|
+
rb_iv_set(self, "__orig_iv_tbl__", orig_iv_tbl);
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
69
|
+
# restore needed, or else GC will crash
|
70
|
+
builder.c %{
|
71
|
+
void restore_tbls() {
|
72
|
+
KLASS_OF(self)->m_tbl = (struct st_table *)rb_iv_get(self, "__orig_m_tbl__");
|
73
|
+
KLASS_OF(self)->iv_tbl = (struct st_table *)rb_iv_get(self, "__orig_iv_tbl__");
|
74
|
+
}
|
75
|
+
}
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
class Class
|
80
|
+
inline do |builder|
|
81
|
+
builder.c %{
|
82
|
+
void redirect_tbls(VALUE class) {
|
83
|
+
unsigned long orig_iv_tbl, orig_m_tbl;
|
84
|
+
orig_iv_tbl = (unsigned long)RCLASS(self)->iv_tbl;
|
85
|
+
orig_m_tbl = (unsigned long)RCLASS(self)->m_tbl;
|
86
|
+
RCLASS(self)->iv_tbl = RCLASS(class)->iv_tbl;
|
87
|
+
RCLASS(self)->m_tbl = RCLASS(class)->m_tbl;
|
88
|
+
rb_iv_set(self, "__orig_iv_tbl__", orig_iv_tbl);
|
89
|
+
rb_iv_set(self, "__orig_m_tbl__", orig_m_tbl);
|
90
|
+
}
|
91
|
+
}
|
92
|
+
|
93
|
+
# restore needed, or else GC will crash
|
94
|
+
builder.c %{
|
95
|
+
void restore_tbls() {
|
96
|
+
RCLASS(self)->m_tbl = rb_iv_get(self, "__orig_m_tbl__");
|
97
|
+
RCLASS(self)->iv_tbl = rb_iv_get(self, "__orig_iv_tbl__");
|
98
|
+
}
|
99
|
+
}
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
51
103
|
class Proc
|
52
104
|
def mixin mod
|
53
105
|
context.extend mod
|
@@ -71,6 +123,23 @@ class Module
|
|
71
123
|
blk.mixout mod
|
72
124
|
end
|
73
125
|
end
|
126
|
+
|
127
|
+
def safe_mix_eval mod, &blk
|
128
|
+
duped_context = blk.context.dup
|
129
|
+
# make sure the singleton class is in existence
|
130
|
+
class << duped_context; self; end
|
131
|
+
|
132
|
+
duped_context.redirect_tbls(blk.context)
|
133
|
+
|
134
|
+
duped_context.extend mod
|
135
|
+
begin
|
136
|
+
m = duped_context.is_a?(Module) ? :class_eval : :instance_eval
|
137
|
+
duped_context.send(m, &blk)
|
138
|
+
ensure
|
139
|
+
duped_context.restore_tbls
|
140
|
+
(class << duped_context; self; end).disable_mixin mod
|
141
|
+
end
|
142
|
+
end
|
74
143
|
|
75
144
|
alias_method :mix_exec, :mix_eval
|
76
145
|
end
|
data/mixico-inline.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "mixico-inline"
|
3
|
-
s.version = "0.0.
|
4
|
-
s.summary = "1.8.6 compatible version of why's mixico"
|
3
|
+
s.version = "0.0.6"
|
4
|
+
s.summary = "1.8.6 compatible version of why's mixico + thread safety"
|
5
5
|
s.email = "coderrr.contact@gmail.com"
|
6
6
|
s.homepage = "http://github.com/coderrr/mixico-inline"
|
7
7
|
s.description = "see http://github.com/why/mixico"
|
data/test/mixico_test.rb
CHANGED
@@ -32,4 +32,81 @@ class MixicoTest < Test::Unit::TestCase
|
|
32
32
|
@p.mixout @m
|
33
33
|
assert_raises(NameError) { @p.call }
|
34
34
|
end
|
35
|
+
|
36
|
+
def test_mix_eval_modify_ivar
|
37
|
+
@x = 5
|
38
|
+
b = lambda do
|
39
|
+
assert_equal 5, @x
|
40
|
+
@x = 6
|
41
|
+
end
|
42
|
+
Module.mix_eval @m, &b
|
43
|
+
assert_equal 6, @x
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_safe_mix_eval_modify_ivar
|
47
|
+
b = lambda do
|
48
|
+
assert_equal 5, @x
|
49
|
+
@x = 6
|
50
|
+
end
|
51
|
+
@x = 5
|
52
|
+
Module.safe_mix_eval @m, &b
|
53
|
+
assert_equal 6, @x
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_mix_eval_add_method
|
57
|
+
k = Class.new
|
58
|
+
k.class_eval do
|
59
|
+
b = lambda do
|
60
|
+
def x; :x; end
|
61
|
+
end
|
62
|
+
|
63
|
+
Module.mix_eval Module.new, &b
|
64
|
+
end
|
65
|
+
assert_equal :x, k.new.x
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_mix_eval_add_singleton_method
|
69
|
+
o = Object.new
|
70
|
+
o.instance_eval do
|
71
|
+
Module.mix_eval Module.new do
|
72
|
+
def x; :x; end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
assert_equal :x, o.x
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_safe_mix_eval_add_method
|
79
|
+
k = Class.new
|
80
|
+
k.class_eval do
|
81
|
+
Module.safe_mix_eval Module.new do
|
82
|
+
def x; :x; end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
assert_equal :x, k.new.x
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_safe_mix_eval_add_singleton_method
|
89
|
+
o = Object.new
|
90
|
+
o.instance_eval do
|
91
|
+
Module.safe_mix_eval Module.new do
|
92
|
+
def x; :x; end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
assert_equal :x, o.x
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_FIX_THIS_safe_mix_eval_add_singleton_method_in_class
|
99
|
+
k = Class.new
|
100
|
+
k.class_eval do
|
101
|
+
Module.safe_mix_eval Module.new do
|
102
|
+
class << self
|
103
|
+
def x; :x; end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# FIX THIS, THIS SHOULD NOT HAPPEN
|
109
|
+
assert_raises(NoMethodError) { k.x }
|
110
|
+
# assert_equal :x, k.x
|
111
|
+
end
|
35
112
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: coderrr-mixico-inline
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- why
|
@@ -60,6 +60,6 @@ rubyforge_project:
|
|
60
60
|
rubygems_version: 1.2.0
|
61
61
|
signing_key:
|
62
62
|
specification_version: 2
|
63
|
-
summary: 1.8.6 compatible version of why's mixico
|
63
|
+
summary: 1.8.6 compatible version of why's mixico + thread safety
|
64
64
|
test_files:
|
65
65
|
- test/mixico_test.rb
|