vlx-multi 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/sample.rb +148 -0
- data/vlx_multi.rb +468 -0
- metadata +63 -0
data/sample.rb
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
require 'vlx_multi'
|
2
|
+
|
3
|
+
test_global = true
|
4
|
+
test_module = true
|
5
|
+
|
6
|
+
|
7
|
+
class A
|
8
|
+
end
|
9
|
+
|
10
|
+
class B < A
|
11
|
+
end
|
12
|
+
|
13
|
+
class C < A
|
14
|
+
end
|
15
|
+
|
16
|
+
class D < C
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
# test global functions reloading
|
21
|
+
|
22
|
+
if test_global == true then
|
23
|
+
|
24
|
+
# reload by regexp
|
25
|
+
vlxm(:some,"$array",/<[\w;: ]+>/) do |_1,_2|
|
26
|
+
puts 'some<$array;Regexp>' + _1.to_s + ' ' + _2.to_s
|
27
|
+
end
|
28
|
+
|
29
|
+
vlxm(:some,Object,String) do |s,s1| puts 'some<Object,String> ' + s.to_s + ' ' + s1.to_s end
|
30
|
+
|
31
|
+
vlxm(:some,String) do |s| puts 'some<String> ' + s end
|
32
|
+
|
33
|
+
vlxm(:some,String,String) do |s,s1| puts 'some<String,String> ' + s + ' ' + s1 end
|
34
|
+
|
35
|
+
vlxm(:some,Object) do |o| puts 'some<Object> ' + o.inspect end
|
36
|
+
|
37
|
+
vlxm(:some,:_1,:_2) do |_,_| puts 'some<:_1,:_2> ' end
|
38
|
+
|
39
|
+
vlxm(:some,:_1) do |_| puts 'some<:_1> ' end
|
40
|
+
|
41
|
+
vlxm(:some,'nil text',nil) do |_,_| puts 'some<nil text,nil> ' end
|
42
|
+
|
43
|
+
vlxm(:some,Symbol,Symbol) do |s,s1| puts 'some<Symbol,Symbol> ' + s.to_s + ' ' + s1.to_s end
|
44
|
+
|
45
|
+
# reload by condition: _ == 'custom def'
|
46
|
+
vlxm(:some,vlxmd("_ == 'custom def'")) do |_| puts 'some<Def>'end
|
47
|
+
|
48
|
+
vlxm(:some,A,D) { |_,_| puts '<A:D>' }
|
49
|
+
vlxm(:some,B,C) { |_,_| puts '<B:C>' }
|
50
|
+
|
51
|
+
|
52
|
+
puts 'global test begin'
|
53
|
+
begin
|
54
|
+
some('text')
|
55
|
+
some('text','text2')
|
56
|
+
some('nil text',nil)
|
57
|
+
some([55,44])
|
58
|
+
some(:_1,:_2)
|
59
|
+
some(:_1)
|
60
|
+
some(:_1,:_b)
|
61
|
+
some('$array', '<names:string; values:varaint>')
|
62
|
+
some(A.new,D.new)
|
63
|
+
some(B.new,C.new)
|
64
|
+
some(B.new,D.new)
|
65
|
+
some(D.new,D.new)
|
66
|
+
some('custom def')
|
67
|
+
rescue Exception
|
68
|
+
p $!
|
69
|
+
end
|
70
|
+
puts 'global test end'
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
# test module functions reloading
|
77
|
+
|
78
|
+
if test_module == true then
|
79
|
+
|
80
|
+
module VlxTest
|
81
|
+
module Inner
|
82
|
+
|
83
|
+
vlxm(:some,String) do |s| puts 'VlxTest::some<String> ' + s end
|
84
|
+
|
85
|
+
vlxm(:some,String,String) do |s,s1| puts 'VlxTest::some<String,String> ' + s + ' ' + s1 end
|
86
|
+
|
87
|
+
vlxm(:some,Object) do |o| puts 'VlxTest::some<Object> ' + o.to_s end
|
88
|
+
|
89
|
+
vlxm(:some,:_1,:_2) do |_,_| puts 'VlxTest::some<:_1,:_2> ' end
|
90
|
+
|
91
|
+
vlxm(:some,:_1) do |_,_| puts 'VlxTest::some<:_1> ' end
|
92
|
+
|
93
|
+
vlxm(:some,Symbol,Symbol) do |s,s1|
|
94
|
+
puts 'VlxTest::some<Symbol,Symbol> ' + s.to_s + ' ' + s1.to_s
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
puts 'module test begin'
|
99
|
+
some('text')
|
100
|
+
some('text','text2')
|
101
|
+
some(55)
|
102
|
+
some(:_1,:_2)
|
103
|
+
some(:_1)
|
104
|
+
some(:_1,:_b)
|
105
|
+
puts 'module test end'
|
106
|
+
|
107
|
+
class Test
|
108
|
+
def initialize(name)
|
109
|
+
@name = name
|
110
|
+
end
|
111
|
+
|
112
|
+
vlxm(:some,String) do |s|
|
113
|
+
puts 'VlxTest::Test::some<String> ' + s + ' ' + @name
|
114
|
+
end
|
115
|
+
|
116
|
+
vlxm(:some,String,String) do |s,s1| puts 'VlxTest::Test::some<String,String> ' + s + ' ' + s1 end
|
117
|
+
|
118
|
+
vlxm(:some,Object) do |o| puts 'VlxTest::Test::some<Object> ' + o.to_s end
|
119
|
+
|
120
|
+
vlxm(:some,:_1,:_2) do |_,_| puts 'VlxTest::Test::some<:_1,:_2> ' end
|
121
|
+
|
122
|
+
vlxm(:some,:_1) do |_|
|
123
|
+
puts 'VlxTest::Test::some<:_1> '
|
124
|
+
end
|
125
|
+
|
126
|
+
vlxm(:some,Symbol,Symbol) do |s,s1|
|
127
|
+
puts 'VlxTest::Test::some<Symbol,Symbol> ' + s.to_s + ' ' + s1.to_s
|
128
|
+
end
|
129
|
+
|
130
|
+
end # Test
|
131
|
+
|
132
|
+
end # Inner
|
133
|
+
end # VlxTest
|
134
|
+
|
135
|
+
|
136
|
+
puts 'class test begin'
|
137
|
+
c = VlxTest::Inner::Test
|
138
|
+
c.new('Test1').some('aa')
|
139
|
+
c.new('Test2').some('aa')
|
140
|
+
puts 'class test end'
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
|
145
|
+
|
146
|
+
|
147
|
+
|
148
|
+
|
data/vlx_multi.rb
ADDED
@@ -0,0 +1,468 @@
|
|
1
|
+
=begin
|
2
|
+
Multimethod call in http://rubyforge.org/projects/multimethod and http://rubyforge.org/projects/multi/
|
3
|
+
implements as several table lookups.
|
4
|
+
|
5
|
+
Vlx-multimethods generate single method definition for all overloads of one message with series of if-then-else
|
6
|
+
condition for all patterns. Overloading allowed by value, by class, by regexp, by custom condition.
|
7
|
+
|
8
|
+
=end
|
9
|
+
|
10
|
+
|
11
|
+
require 'facets/module/modspace'
|
12
|
+
require 'facets/module/basename'
|
13
|
+
require 'facets/proc/bind'
|
14
|
+
|
15
|
+
@@vlx_multi_methods_hook = self
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
module Vlx
|
20
|
+
module MultiMethods
|
21
|
+
|
22
|
+
@@debug = false
|
23
|
+
@@keys_map = {}
|
24
|
+
|
25
|
+
def self.debug?
|
26
|
+
@@debug
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.debug=(v)
|
30
|
+
@@debug = v
|
31
|
+
end
|
32
|
+
|
33
|
+
class IsValidDef
|
34
|
+
|
35
|
+
def self.s_prev(a,j,t,i)
|
36
|
+
return nil if i == 0 && j == 0
|
37
|
+
return t[i-1,1] if i > 0
|
38
|
+
p = a[j-1]
|
39
|
+
p[p.size-1,1]
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.s_next(a,j,t,i)
|
43
|
+
return nil if i == t.size - 1 && j == a.size - 1
|
44
|
+
return t[i+1,1] if i+1 < t.size
|
45
|
+
a[j+1][0,1]
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.good_char?(c)
|
49
|
+
return true if c == nil
|
50
|
+
return false if c == '_'
|
51
|
+
return false if /\d+/.match(c) != nil
|
52
|
+
return true
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.index_(a,j,i)
|
56
|
+
o = 0
|
57
|
+
k = 0
|
58
|
+
while k < j
|
59
|
+
o = o + a[k].size
|
60
|
+
k = k + 1
|
61
|
+
end
|
62
|
+
o + i
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.in_string?(s,min,count)
|
66
|
+
c1c = s[min,count].count "'"
|
67
|
+
c2c = s[min,count].count '"'
|
68
|
+
c1c % 2 != 0 || c1c % 2 != 0
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.check(t)
|
72
|
+
ur = []
|
73
|
+
r = []
|
74
|
+
t.each('_'){ |e| r << e }
|
75
|
+
#p r
|
76
|
+
i=0
|
77
|
+
while i < r.size
|
78
|
+
c = r[i]
|
79
|
+
i = i + 1
|
80
|
+
index = c.index('_')
|
81
|
+
next if index == nil
|
82
|
+
#puts 'check: ' + c
|
83
|
+
sPrev = s_prev( r, i-1, c, index )
|
84
|
+
sNext = s_next( r, i-1, c, index )
|
85
|
+
if good_char?(sPrev) && good_char?(sNext) then
|
86
|
+
i1 = index_(r,i-1,index)
|
87
|
+
if !in_string?( t, 0, i1 ) then
|
88
|
+
#puts c
|
89
|
+
ur << i1
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
ur
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
class Def
|
100
|
+
def initialize(text)
|
101
|
+
@text = text
|
102
|
+
end
|
103
|
+
|
104
|
+
attr_reader :text
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
class ArgBase
|
109
|
+
|
110
|
+
def initialize( arg )
|
111
|
+
@arg = arg
|
112
|
+
end
|
113
|
+
|
114
|
+
attr_reader :arg
|
115
|
+
end
|
116
|
+
|
117
|
+
|
118
|
+
class ArgDef < ArgBase
|
119
|
+
def text(param)
|
120
|
+
p = @arg.text.dup
|
121
|
+
offset = 0
|
122
|
+
IsValidDef.check(@arg.text).each { |index|
|
123
|
+
p[offset + index] = param
|
124
|
+
offset = offset + param.size - 1
|
125
|
+
}
|
126
|
+
#puts @arg.text + ' -> ' + p
|
127
|
+
p
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
class ArgValue < ArgBase
|
133
|
+
def text(i)
|
134
|
+
i + ' == ' + @arg.inspect
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
class ArgRegexp < ArgBase
|
140
|
+
def text(i)
|
141
|
+
i + '.class == String && ' + @arg.inspect + '.match(' + i +')'
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
|
146
|
+
class ArgClass < ArgBase
|
147
|
+
def text(i)
|
148
|
+
i + '.is_a?(' + @arg.to_s + ')'
|
149
|
+
end
|
150
|
+
|
151
|
+
def is_superclass?(p)
|
152
|
+
s = @arg
|
153
|
+
pClass = p.arg
|
154
|
+
while s != nil
|
155
|
+
return true if s == pClass
|
156
|
+
s = s.superclass
|
157
|
+
end
|
158
|
+
false
|
159
|
+
end
|
160
|
+
|
161
|
+
def compare_by_superclass(p)
|
162
|
+
return -1 if is_superclass?(p) == true
|
163
|
+
return 1 if p.is_superclass?(self) == true
|
164
|
+
0
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
|
169
|
+
class Pattern
|
170
|
+
|
171
|
+
@@blocks_map = {}
|
172
|
+
@@args = [ ArgValue, ArgRegexp, ArgDef, ArgClass ]
|
173
|
+
|
174
|
+
def self.blocks_map
|
175
|
+
@@blocks_map
|
176
|
+
end
|
177
|
+
|
178
|
+
|
179
|
+
def cond_code
|
180
|
+
r = ''
|
181
|
+
i = 0
|
182
|
+
@a.each{ |arg|
|
183
|
+
p = 'p_' + i.to_s
|
184
|
+
r = r + (i == 0 ? '' : ' and ') + arg.text( p )
|
185
|
+
i = i + 1
|
186
|
+
}
|
187
|
+
r
|
188
|
+
end
|
189
|
+
|
190
|
+
def block
|
191
|
+
@b
|
192
|
+
end
|
193
|
+
|
194
|
+
def initialize(args,block)
|
195
|
+
@a = []
|
196
|
+
args.each{|a|
|
197
|
+
aClass = a.class
|
198
|
+
if aClass == Class then
|
199
|
+
@a << ArgClass.new( a )
|
200
|
+
elsif aClass == Regexp then
|
201
|
+
@a << ArgRegexp.new( a )
|
202
|
+
elsif aClass == Def then
|
203
|
+
@a << ArgDef.new( a )
|
204
|
+
else
|
205
|
+
@a << ArgValue.new( a )
|
206
|
+
end
|
207
|
+
|
208
|
+
}
|
209
|
+
@b = block
|
210
|
+
@@blocks_map[ block.__id__ ] = block
|
211
|
+
end
|
212
|
+
|
213
|
+
def array
|
214
|
+
@a
|
215
|
+
end
|
216
|
+
|
217
|
+
@@compare_table = {}
|
218
|
+
|
219
|
+
def make_compare_(p,m,c,c2)
|
220
|
+
g = @@args.index(c)
|
221
|
+
g2 = @@args.index(c2)
|
222
|
+
Proc.new{ |a,b| [p.call(a,b) * m,g,g2] }
|
223
|
+
end
|
224
|
+
|
225
|
+
def pow(n,k)
|
226
|
+
return 1 if k == 0
|
227
|
+
return n if k == 1
|
228
|
+
return n * pow(n,k-1)
|
229
|
+
end
|
230
|
+
|
231
|
+
def priority_of(a)
|
232
|
+
return pow(100,@@args.index(a))
|
233
|
+
end
|
234
|
+
|
235
|
+
def reg_compare_(a,b,p)
|
236
|
+
aP = priority_of(a)
|
237
|
+
bP = priority_of(b)
|
238
|
+
m = 1
|
239
|
+
if aP > bP then
|
240
|
+
#t = a
|
241
|
+
#a = b
|
242
|
+
#b = t
|
243
|
+
m = -1
|
244
|
+
end
|
245
|
+
#@@compare_table[ [a,b] ] = make_compare_( p, 1, b, a )
|
246
|
+
#@@compare_table[ [b,a] ] = make_compare_( p, -1, b, a )
|
247
|
+
@@compare_table[ [a,b] ] = make_compare_( p, m, a, b )
|
248
|
+
@@compare_table[ [b,a] ] = make_compare_( p, -m, b, a )
|
249
|
+
end
|
250
|
+
|
251
|
+
def reg_compare_single_(a,p)
|
252
|
+
@@compare_table[ [a,a] ] = make_compare_( p, 1, a, a )
|
253
|
+
end
|
254
|
+
|
255
|
+
def compare_table_init
|
256
|
+
byId = Proc.new { |a,b| a.__id__ <=> b.__id__ }
|
257
|
+
cc = Proc.new { |a,b| a.compare_by_superclass(b) }
|
258
|
+
m1 = Proc.new { |a,b| -1 }
|
259
|
+
|
260
|
+
reg_compare_single_ ArgValue, byId
|
261
|
+
reg_compare_single_ ArgRegexp, byId
|
262
|
+
reg_compare_single_ ArgDef, byId
|
263
|
+
reg_compare_single_ ArgClass, cc
|
264
|
+
|
265
|
+
reg_compare_( ArgValue, ArgClass, m1 )
|
266
|
+
reg_compare_( ArgValue, ArgDef, m1 )
|
267
|
+
reg_compare_( ArgValue, ArgRegexp, m1 )
|
268
|
+
reg_compare_( ArgDef, ArgRegexp, m1 )
|
269
|
+
reg_compare_( ArgRegexp, ArgClass, m1 )
|
270
|
+
reg_compare_( ArgDef, ArgClass, m1 )
|
271
|
+
|
272
|
+
end
|
273
|
+
|
274
|
+
|
275
|
+
def compare_(a,b)
|
276
|
+
compare_table_init if @@compare_table.size == 0
|
277
|
+
return @@compare_table[ [a.class,b.class] ].call(a,b)
|
278
|
+
end
|
279
|
+
|
280
|
+
def compare(other)
|
281
|
+
return 0 if self.equal?(other)
|
282
|
+
|
283
|
+
i = 0
|
284
|
+
maxg = [-1,-1,-1]
|
285
|
+
total = Array.new(@@args.size,0)
|
286
|
+
totalOther = Array.new(@@args.size,0)
|
287
|
+
|
288
|
+
other.array.each{ |otherE|
|
289
|
+
myE = @a[i]
|
290
|
+
cr = compare_( myE, otherE )
|
291
|
+
myG = cr[1]
|
292
|
+
otherG = cr[2]
|
293
|
+
maxG = myG < otherG ? otherG : myG
|
294
|
+
total[myG] = total[myG] + 1
|
295
|
+
totalOther[otherG] = totalOther[otherG] + 1
|
296
|
+
if maxG > maxg[0] && cr[0] != 0 then
|
297
|
+
maxg[0] = maxG
|
298
|
+
maxg[1] = i
|
299
|
+
maxg[2] = cr[0]
|
300
|
+
end
|
301
|
+
i = i + 1
|
302
|
+
}
|
303
|
+
|
304
|
+
i = total.size
|
305
|
+
while i >= 0
|
306
|
+
i = i - 1
|
307
|
+
return -1 if total[i] < totalOther[i]
|
308
|
+
return 1 if total[i] > totalOther[i]
|
309
|
+
end
|
310
|
+
|
311
|
+
|
312
|
+
return -1 if maxg[2] < 0
|
313
|
+
return 1 if maxg[2] > 0
|
314
|
+
return 0
|
315
|
+
|
316
|
+
end
|
317
|
+
|
318
|
+
end
|
319
|
+
|
320
|
+
|
321
|
+
class Data
|
322
|
+
|
323
|
+
def initialize( obj, method_name )
|
324
|
+
@obj = obj
|
325
|
+
@method_name = method_name
|
326
|
+
@args = []
|
327
|
+
end
|
328
|
+
|
329
|
+
|
330
|
+
def add( args, block )
|
331
|
+
argsCount = args.size
|
332
|
+
if @args.size <= argsCount then
|
333
|
+
i = @args.size
|
334
|
+
while i <= argsCount
|
335
|
+
@args << []
|
336
|
+
i = i + 1
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
@args[ argsCount ] << Pattern.new( args, block )
|
341
|
+
gen( argsCount )
|
342
|
+
end
|
343
|
+
|
344
|
+
def print_args
|
345
|
+
@args.each { |a| p a }
|
346
|
+
end
|
347
|
+
|
348
|
+
|
349
|
+
def gen_i( argsCount, t )
|
350
|
+
args = @args[argsCount]
|
351
|
+
|
352
|
+
return if args.empty?
|
353
|
+
|
354
|
+
t << $/ << 'when ' << argsCount.to_s << $/
|
355
|
+
argsCount.times { |k|
|
356
|
+
t << 'p_' << k.to_s << ' = args[' << k.to_s << ']; '
|
357
|
+
}
|
358
|
+
|
359
|
+
t << 'vlxBlockIndex = nil '
|
360
|
+
|
361
|
+
callText = ''
|
362
|
+
argsCount.times { |i|
|
363
|
+
callText << 'p_' << i.to_s
|
364
|
+
callText << ', ' if i < argsCount - 1
|
365
|
+
}
|
366
|
+
|
367
|
+
first = true
|
368
|
+
args.each do |arg|
|
369
|
+
t << $/ << (first ? 'if ' : 'elsif ') << arg.cond_code << ' then ' << $/ <<
|
370
|
+
'vlxBlockIndex = ' << arg.block.__id__.to_s
|
371
|
+
first = false
|
372
|
+
end
|
373
|
+
t << $/ << 'end ' << $/ << 'vlxB = vlxmmBlocksMap[vlxBlockIndex]' << $/
|
374
|
+
t << 'if self.class == Module then return vlxB.call(*args) else return vlxB.bind(self)[*args] end'
|
375
|
+
|
376
|
+
end
|
377
|
+
|
378
|
+
|
379
|
+
def parents(c)
|
380
|
+
r = []
|
381
|
+
while c != nil
|
382
|
+
r << c
|
383
|
+
c = c.modspace
|
384
|
+
break if c == Object
|
385
|
+
end
|
386
|
+
r
|
387
|
+
end
|
388
|
+
|
389
|
+
def gen( argsCount )
|
390
|
+
args = @args[argsCount]
|
391
|
+
args.sort! do |x,y|
|
392
|
+
x.compare(y)
|
393
|
+
end
|
394
|
+
|
395
|
+
prefix = ''
|
396
|
+
postfix = ''
|
397
|
+
selfText = 'self.'
|
398
|
+
if @obj.__id__ == @@vlx_multi_methods_hook.__id__
|
399
|
+
;
|
400
|
+
elsif @obj.class == Class
|
401
|
+
a = parents(@obj).reverse
|
402
|
+
prefix = ''
|
403
|
+
a.each{ |e|
|
404
|
+
prefix << 'class ' if e.class == Class
|
405
|
+
prefix << 'module ' if e.class == Module
|
406
|
+
prefix << e.basename << $/
|
407
|
+
postfix << 'end '
|
408
|
+
}
|
409
|
+
|
410
|
+
selfText = ''
|
411
|
+
|
412
|
+
elsif @obj.class == Module
|
413
|
+
a = []
|
414
|
+
@obj.name.each('::') { |e|
|
415
|
+
a << e.delete('::')
|
416
|
+
}
|
417
|
+
prefix = ''
|
418
|
+
a.each { |e|
|
419
|
+
prefix << 'module ' << e.to_s << $/
|
420
|
+
postfix << 'end '
|
421
|
+
}
|
422
|
+
else
|
423
|
+
throw 'VlxMultiNethods register code generation failed ' + @obj.inspect
|
424
|
+
end
|
425
|
+
|
426
|
+
t = ''
|
427
|
+
t << prefix << $/
|
428
|
+
t << 'def ' << selfText << @method_name.to_s << '( *args )' << $/
|
429
|
+
t << 'vlxmmBlocksMap = Vlx::MultiMethods::Pattern.blocks_map' << $/
|
430
|
+
|
431
|
+
i = 0
|
432
|
+
t << 'case args.size'
|
433
|
+
@args.each { |argList|
|
434
|
+
gen_i( i, t )
|
435
|
+
i = i + 1
|
436
|
+
}
|
437
|
+
t << $/ << 'else ' << $/ << ' end' << $/
|
438
|
+
t << ' throw "unknown pattern " + args.inspect + ' << " ' for method " << @method_name.to_s << "'" << $/
|
439
|
+
t << 'end' << $/
|
440
|
+
t << postfix << $/
|
441
|
+
puts t if Vlx::MultiMethods.debug? == true
|
442
|
+
|
443
|
+
|
444
|
+
#p @@vlx_multi_methods_hook
|
445
|
+
@@vlx_multi_methods_hook.send( :eval, t, TOPLEVEL_BINDING )
|
446
|
+
|
447
|
+
end
|
448
|
+
|
449
|
+
end
|
450
|
+
|
451
|
+
def self.reg( obj, method_name, args, block )
|
452
|
+
key = [ obj, method_name ]
|
453
|
+
data = @@keys_map.fetch( key ) { d = Data.new( obj, method_name ); @@keys_map[key] = d; d }
|
454
|
+
data.add( args, block )
|
455
|
+
end
|
456
|
+
|
457
|
+
|
458
|
+
end # MultiMethods
|
459
|
+
end # Vlx
|
460
|
+
|
461
|
+
|
462
|
+
def vlxm( symbol, *args, &block )
|
463
|
+
Vlx::MultiMethods.reg( self, symbol, args, block )
|
464
|
+
end
|
465
|
+
|
466
|
+
def vlxmd(text)
|
467
|
+
Vlx::MultiMethods::Def.new(text)
|
468
|
+
end
|
metadata
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: vlx-multi
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "0.1"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kornyushenko Eugene
|
8
|
+
autorequire: vlx-multi
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-07-14 00:00:00 +04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: facets
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
description:
|
26
|
+
email: kornyushenko@gmail.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files: []
|
32
|
+
|
33
|
+
files:
|
34
|
+
- vlx_multi.rb
|
35
|
+
- sample.rb
|
36
|
+
has_rdoc: false
|
37
|
+
homepage: http://rubyforge.org/projects/vlx-multi/
|
38
|
+
post_install_message:
|
39
|
+
rdoc_options: []
|
40
|
+
|
41
|
+
require_paths:
|
42
|
+
- .
|
43
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: "0"
|
48
|
+
version:
|
49
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
version:
|
55
|
+
requirements: []
|
56
|
+
|
57
|
+
rubyforge_project: vlx-multi
|
58
|
+
rubygems_version: 1.2.0
|
59
|
+
signing_key:
|
60
|
+
specification_version: 2
|
61
|
+
summary: Multiple Dispatch/Pattern Matching for Ruby
|
62
|
+
test_files: []
|
63
|
+
|