coderrr-mixico-inline 0.0.5 → 0.0.6
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/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
|