tins 0.13.2 → 1.0.0
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Rakefile +1 -13
- data/VERSION +1 -1
- data/examples/add_one.png +0 -0
- data/examples/add_one.stm +13 -0
- data/examples/bb3.png +0 -0
- data/examples/bb3.stm +26 -0
- data/examples/bb3_19.stm +26 -0
- data/examples/concatenate_compare.mtm +31 -0
- data/examples/concatenate_compare.png +0 -0
- data/examples/concatenate_compare_19.mtm +31 -0
- data/examples/length_difference.mtm +17 -0
- data/examples/length_difference.png +0 -0
- data/examples/length_difference_19.mtm +17 -0
- data/examples/let.rb +62 -0
- data/examples/mail.rb +73 -0
- data/examples/minsky.rb +145 -0
- data/examples/multiply.reg +42 -0
- data/examples/null_pattern.rb +52 -0
- data/examples/ones_difference-mtm.png +0 -0
- data/examples/ones_difference-stm.png +0 -0
- data/examples/ones_difference.mtm +12 -0
- data/examples/ones_difference.stm +25 -0
- data/examples/ones_difference_19.mtm +12 -0
- data/examples/ones_difference_19.stm +25 -0
- data/examples/prefix-equals-suffix-reversed-with-infix.png +0 -0
- data/examples/prefix-equals-suffix-reversed-with-infix.stm +38 -0
- data/examples/prefix-equals-suffix-reversed-with-infix_19.stm +38 -0
- data/examples/recipe.rb +81 -0
- data/examples/recipe2.rb +82 -0
- data/examples/recipe_common.rb +97 -0
- data/examples/subtract.reg +9 -0
- data/examples/turing-graph.rb +17 -0
- data/examples/turing.rb +310 -0
- data/lib/dslkit.rb +2 -0
- data/lib/dslkit/polite.rb +1 -0
- data/lib/dslkit/rude.rb +1 -0
- data/lib/tins.rb +1 -0
- data/lib/tins/dslkit.rb +662 -0
- data/lib/tins/thread_local.rb +52 -0
- data/lib/tins/version.rb +1 -1
- data/lib/tins/xt.rb +1 -0
- data/lib/tins/xt/dslkit.rb +23 -0
- data/tests/concern_test.rb +24 -25
- data/tests/dslkit_test.rb +308 -0
- data/tests/dynamic_scope_test.rb +31 -0
- data/tests/from_module_test.rb +61 -0
- data/tests/scope_test.rb +31 -0
- data/tests/test_helper.rb +0 -1
- data/tins.gemspec +10 -10
- metadata +68 -17
@@ -0,0 +1,52 @@
|
|
1
|
+
module Tins
|
2
|
+
module ThreadLocal
|
3
|
+
@@mutex = Mutex.new
|
4
|
+
|
5
|
+
@@cleanup = lambda do |my_object_id|
|
6
|
+
my_id = "__thread_local_#{my_object_id}__"
|
7
|
+
@@mutex.synchronize do
|
8
|
+
for t in Thread.list
|
9
|
+
t[my_id] = nil if t[my_id]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Define a thread local variable named _name_ in this module/class. If the
|
15
|
+
# value _value_ is given, it is used to initialize the variable.
|
16
|
+
def thread_local(name, default_value = nil)
|
17
|
+
is_a?(Module) or raise TypeError, "receiver has to be a Module"
|
18
|
+
|
19
|
+
name = name.to_s
|
20
|
+
my_id = "__thread_local_#{__id__}__"
|
21
|
+
|
22
|
+
ObjectSpace.define_finalizer(self, @@cleanup)
|
23
|
+
|
24
|
+
define_method(name) do
|
25
|
+
Thread.current[my_id] ||= {}
|
26
|
+
Thread.current[my_id][name]
|
27
|
+
end
|
28
|
+
|
29
|
+
define_method("#{name}=") do |value|
|
30
|
+
Thread.current[my_id] ||= {}
|
31
|
+
Thread.current[my_id][name] = value
|
32
|
+
end
|
33
|
+
|
34
|
+
if default_value
|
35
|
+
Thread.current[my_id] = {}
|
36
|
+
Thread.current[my_id][name] = default_value
|
37
|
+
end
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
# Define a thread local variable for the current instance with name _name_.
|
42
|
+
# If the value _value_ is given, it is used to initialize the variable.
|
43
|
+
def instance_thread_local(name, value = nil)
|
44
|
+
sc = class << self
|
45
|
+
extend Tins::ThreadLocal
|
46
|
+
self
|
47
|
+
end
|
48
|
+
sc.thread_local name, value
|
49
|
+
self
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/tins/version.rb
CHANGED
data/lib/tins/xt.rb
CHANGED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'tins'
|
2
|
+
|
3
|
+
module Tins
|
4
|
+
class ::Module
|
5
|
+
include Tins::Constant
|
6
|
+
include Tins::DSLAccessor
|
7
|
+
include Tins::ClassMethod
|
8
|
+
include Tins::Delegate
|
9
|
+
include Tins::ParameterizedModule
|
10
|
+
include Tins::FromModule
|
11
|
+
end
|
12
|
+
|
13
|
+
class ::Object
|
14
|
+
include Tins::ThreadLocal
|
15
|
+
include Tins::ThreadGlobal
|
16
|
+
include Tins::InstanceExec
|
17
|
+
include Tins::Interpreter
|
18
|
+
include Tins::Deflect
|
19
|
+
include Tins::ThreadLocal
|
20
|
+
include Tins::Eigenclass
|
21
|
+
include Tins::BlockSelf
|
22
|
+
end
|
23
|
+
end
|
data/tests/concern_test.rb
CHANGED
@@ -1,36 +1,35 @@
|
|
1
1
|
require 'test_helper'
|
2
|
-
require 'tins
|
2
|
+
require 'tins'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
extend ::Tins::Concern[:complain => true]
|
4
|
+
class ConcernTest < Test::Unit::TestCase
|
5
|
+
module AC
|
6
|
+
extend Tins::Concern
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
end
|
8
|
+
included do
|
9
|
+
$included = self
|
10
|
+
end
|
13
11
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end
|
18
|
-
end
|
12
|
+
def foo
|
13
|
+
:foo
|
14
|
+
end
|
19
15
|
|
20
|
-
|
21
|
-
|
16
|
+
module ClassMethods
|
17
|
+
def bar
|
18
|
+
:bar
|
22
19
|
end
|
23
20
|
end
|
21
|
+
end
|
24
22
|
|
25
|
-
|
26
|
-
include ConcernTroll
|
27
|
-
end
|
23
|
+
$included = nil
|
28
24
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
25
|
+
class A
|
26
|
+
include AC
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_concern
|
30
|
+
a = A.new
|
31
|
+
assert_equal A, $included
|
32
|
+
assert_equal :foo, a.foo
|
33
|
+
assert_equal :bar, A.bar
|
35
34
|
end
|
36
35
|
end
|
@@ -0,0 +1,308 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'tins'
|
3
|
+
|
4
|
+
class TL
|
5
|
+
def initialize
|
6
|
+
make_baz
|
7
|
+
end
|
8
|
+
|
9
|
+
extend Tins::ThreadLocal
|
10
|
+
thread_local :foo
|
11
|
+
|
12
|
+
include Tins::ThreadLocal
|
13
|
+
def make_baz
|
14
|
+
instance_thread_local :baz
|
15
|
+
end
|
16
|
+
|
17
|
+
extend Tins::ThreadGlobal
|
18
|
+
thread_global :bar
|
19
|
+
end
|
20
|
+
|
21
|
+
class IE
|
22
|
+
include Tins::InstanceExec
|
23
|
+
|
24
|
+
def initialize(&block)
|
25
|
+
@block = block
|
26
|
+
end
|
27
|
+
|
28
|
+
def exec
|
29
|
+
instance_exec(&@block)
|
30
|
+
end
|
31
|
+
|
32
|
+
def foo
|
33
|
+
:foo
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class C
|
38
|
+
extend Tins::Constant
|
39
|
+
|
40
|
+
constant :foo
|
41
|
+
|
42
|
+
constant :bar, :baz
|
43
|
+
end
|
44
|
+
|
45
|
+
class DA
|
46
|
+
extend Tins::DSLAccessor
|
47
|
+
|
48
|
+
dsl_accessor :foo
|
49
|
+
|
50
|
+
dsl_accessor :bar, :bar
|
51
|
+
|
52
|
+
dsl_accessor :baz do :baz end
|
53
|
+
|
54
|
+
dsl_accessor :quux, :qu, :ux
|
55
|
+
|
56
|
+
dsl_reader :on, true
|
57
|
+
|
58
|
+
dsl_reader :off, false
|
59
|
+
|
60
|
+
dsl_reader :states do
|
61
|
+
[ on, off ]
|
62
|
+
end
|
63
|
+
|
64
|
+
dsl_reader :abc, *%w[a b c]
|
65
|
+
end
|
66
|
+
|
67
|
+
class I
|
68
|
+
include Tins::Interpreter
|
69
|
+
|
70
|
+
def foo
|
71
|
+
:foo
|
72
|
+
end
|
73
|
+
|
74
|
+
def y
|
75
|
+
2
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
class S
|
80
|
+
include Tins::InstanceExec
|
81
|
+
include Tins::SymbolMaker
|
82
|
+
end
|
83
|
+
|
84
|
+
module K
|
85
|
+
extend Tins::ConstantMaker
|
86
|
+
end
|
87
|
+
|
88
|
+
module D
|
89
|
+
extend Tins::Deflect
|
90
|
+
end
|
91
|
+
|
92
|
+
class D2
|
93
|
+
extend Tins::Delegate
|
94
|
+
|
95
|
+
def initialize
|
96
|
+
@ary = [ 1, 2, 3 ]
|
97
|
+
end
|
98
|
+
attr_reader :ary
|
99
|
+
|
100
|
+
delegate :my_size1, :@ary, :size
|
101
|
+
delegate :my_size2, :ary, :size
|
102
|
+
delegate :size, :ary
|
103
|
+
delegate :length, :ary
|
104
|
+
end
|
105
|
+
|
106
|
+
class D3 < Tins::MethodMissingDelegator::DelegatorClass
|
107
|
+
end
|
108
|
+
|
109
|
+
require 'test/unit'
|
110
|
+
require 'tempfile'
|
111
|
+
|
112
|
+
class PoliteTest < Test::Unit::TestCase
|
113
|
+
def setup
|
114
|
+
@tl = TL.new
|
115
|
+
@tl2 = TL.new
|
116
|
+
@ie = IE.new { foo }
|
117
|
+
@c = C.new
|
118
|
+
@da = DA.new
|
119
|
+
@i = I.new
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_version
|
123
|
+
assert_equal Tins::VERSION_ARRAY * '.', Tins::VERSION
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_thread_local
|
127
|
+
assert_nil @tl.foo
|
128
|
+
@tl.foo = 1
|
129
|
+
assert_equal 1, @tl.foo
|
130
|
+
new_foo = nil
|
131
|
+
thread = Thread.new do
|
132
|
+
@tl.foo = 2
|
133
|
+
new_foo = @tl.foo
|
134
|
+
end
|
135
|
+
thread.join
|
136
|
+
assert_equal 2, new_foo
|
137
|
+
assert_equal 1, @tl.foo
|
138
|
+
assert_equal @tl.baz, @tl2.baz
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_instance_thread_local
|
142
|
+
assert_nil @tl.baz
|
143
|
+
@tl.baz = 1
|
144
|
+
assert_equal 1, @tl.baz
|
145
|
+
new_foo = nil
|
146
|
+
thread = Thread.new do
|
147
|
+
@tl.baz = 2
|
148
|
+
new_foo = @tl.baz
|
149
|
+
end
|
150
|
+
thread.join
|
151
|
+
assert_equal 2, new_foo
|
152
|
+
assert_equal 1, @tl.baz
|
153
|
+
assert_not_equal @tl.baz, @tl2.baz
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_thread_global
|
157
|
+
assert_nil @tl.bar
|
158
|
+
@tl.bar = 1
|
159
|
+
assert_equal 1, @tl.bar
|
160
|
+
new_bar = nil
|
161
|
+
thread = Thread.new do
|
162
|
+
@tl.bar = 2
|
163
|
+
new_bar = @tl.bar
|
164
|
+
end
|
165
|
+
thread.join
|
166
|
+
assert_equal 2, new_bar
|
167
|
+
assert_equal 2, @tl.bar
|
168
|
+
end
|
169
|
+
|
170
|
+
def test_instance_exec
|
171
|
+
assert_equal :foo, @ie.foo
|
172
|
+
assert_equal :foo, @ie.exec
|
173
|
+
@ie.freeze
|
174
|
+
assert_equal :foo, @ie.foo
|
175
|
+
assert_equal :foo, @ie.exec
|
176
|
+
end
|
177
|
+
|
178
|
+
def test_constant
|
179
|
+
assert_equal :foo, @c.foo
|
180
|
+
assert_equal :baz, @c.bar
|
181
|
+
end
|
182
|
+
|
183
|
+
def test_dsl_accessor
|
184
|
+
assert_nil @da.foo
|
185
|
+
assert_equal :bar, @da.bar
|
186
|
+
assert_equal :baz, @da.baz
|
187
|
+
assert_equal [:qu, :ux], @da.quux
|
188
|
+
@da.foo 1
|
189
|
+
@da.bar 2
|
190
|
+
@da.baz 3
|
191
|
+
assert_equal 1, @da.foo
|
192
|
+
assert_equal 2, @da.bar
|
193
|
+
assert_equal 3, @da.baz
|
194
|
+
end
|
195
|
+
|
196
|
+
def test_dsl_reader
|
197
|
+
assert_equal true, @da.on
|
198
|
+
assert_equal false, @da.off
|
199
|
+
assert_raises(ArgumentError) do
|
200
|
+
@da.on false
|
201
|
+
end
|
202
|
+
assert_equal [ @da.on, @da.off ], @da.states
|
203
|
+
assert_equal %w[a b c], @da.abc
|
204
|
+
@da.abc << 'd'
|
205
|
+
assert_equal %w[a b c d], @da.abc
|
206
|
+
@da.instance_variable_set :@abc, %w[a b c]
|
207
|
+
assert_equal %w[a b c], @da.abc
|
208
|
+
end
|
209
|
+
|
210
|
+
def test_dsl_accessor_multiple
|
211
|
+
assert_nil @da.foo
|
212
|
+
assert_equal :bar, @da.bar
|
213
|
+
@da.foo 1, 2
|
214
|
+
@da.bar [1, 2]
|
215
|
+
assert_equal [1, 2], @da.foo
|
216
|
+
assert_equal [1, 2], @da.bar
|
217
|
+
@da.bar [1, 2, *@da.bar]
|
218
|
+
assert_equal [1, 2] * 2, @da.bar
|
219
|
+
end
|
220
|
+
|
221
|
+
def test_interpreter
|
222
|
+
assert_equal :foo, @i.interpret('foo')
|
223
|
+
temp = Tempfile.new('foo')
|
224
|
+
temp.write 'foo'
|
225
|
+
temp.rewind
|
226
|
+
assert_equal :foo, @i.interpret(temp)
|
227
|
+
end
|
228
|
+
|
229
|
+
def test_interpreter_with_args
|
230
|
+
assert_equal 3, @i.interpret('|x| x + y', 1)
|
231
|
+
temp = Tempfile.new('foo')
|
232
|
+
temp.write '|x| x + y'
|
233
|
+
temp.rewind
|
234
|
+
assert_equal 3, @i.interpret(temp, 1)
|
235
|
+
end
|
236
|
+
|
237
|
+
def test_symbol_maker
|
238
|
+
s = S.new
|
239
|
+
assert_equal(:foo, s.instance_exec { foo })
|
240
|
+
assert_raises(NoMethodError) { s.instance_exec { foo 1 }}
|
241
|
+
end
|
242
|
+
|
243
|
+
def test_constant_maker
|
244
|
+
assert_equal(:FOO, K::FOO)
|
245
|
+
end
|
246
|
+
|
247
|
+
def test_deflect_block
|
248
|
+
assert_raises(NoMethodError) { 1.foo }
|
249
|
+
assert !D.deflect?(Integer, :foo)
|
250
|
+
D.deflect(Integer, :foo, Tins::Deflect::Deflector.new { :foo }) do
|
251
|
+
assert_equal :foo, 1.foo
|
252
|
+
assert D.deflect?(Integer, :foo)
|
253
|
+
end
|
254
|
+
assert !D.deflect?(Integer, :foo)
|
255
|
+
assert_raises(NoMethodError) { 1.foo }
|
256
|
+
end
|
257
|
+
|
258
|
+
def test_deflect
|
259
|
+
assert_raises(NoMethodError) { 1.foo }
|
260
|
+
assert !D.deflect?(Integer, :foo)
|
261
|
+
D.deflect_start(Integer, :foo, Tins::Deflect::Deflector.new { :foo })
|
262
|
+
assert_equal :foo, 1.foo
|
263
|
+
assert D.deflect?(Integer, :foo)
|
264
|
+
t = Thread.new do
|
265
|
+
assert !D.deflect?(Integer, :foo)
|
266
|
+
assert_raises(NoMethodError) { 1.foo }
|
267
|
+
end
|
268
|
+
t.join
|
269
|
+
D.deflect_stop(Integer, :foo)
|
270
|
+
assert !D.deflect?(Integer, :foo)
|
271
|
+
assert_raises(NoMethodError) { 1.foo }
|
272
|
+
end
|
273
|
+
|
274
|
+
def test_deflect_method_missing
|
275
|
+
assert_raises(NoMethodError) { 1.foo }
|
276
|
+
assert !D.deflect?(Integer, :method_missing)
|
277
|
+
D.deflect_start(Integer, :method_missing, Tins::Deflect::Deflector.new { :foo })
|
278
|
+
assert_equal :foo, 1.foo
|
279
|
+
assert D.deflect?(Integer, :method_missing)
|
280
|
+
t = Thread.new do
|
281
|
+
assert !D.deflect?(Integer, :method_missing)
|
282
|
+
assert_raises(NoMethodError) { 1.foo }
|
283
|
+
end
|
284
|
+
t.join
|
285
|
+
D.deflect_stop(Integer, :method_missing)
|
286
|
+
assert !D.deflect?(Integer, :method_missing)
|
287
|
+
assert_raises(NoMethodError) { 1.foo }
|
288
|
+
end
|
289
|
+
|
290
|
+
def test_delegate
|
291
|
+
d = D2.new
|
292
|
+
assert_equal 3, d.my_size1
|
293
|
+
assert_equal 3, d.my_size2
|
294
|
+
assert_equal 3, d.size
|
295
|
+
assert_equal 3, d.length
|
296
|
+
end
|
297
|
+
|
298
|
+
def test_delegate_d3
|
299
|
+
d = D3.new []
|
300
|
+
assert_equal 0, d.size
|
301
|
+
d.push 1
|
302
|
+
assert_equal [1], d.map { |x| x }
|
303
|
+
d.push 2
|
304
|
+
assert_equal [1, 2], d.map { |x| x }
|
305
|
+
d.push 3
|
306
|
+
assert_equal [1, 2, 3], d.map { |x| x }
|
307
|
+
end
|
308
|
+
end
|