superchris-rubyjs 0.8.2
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/README +131 -0
- data/Rakefile +65 -0
- data/bin/rubyjs +144 -0
- data/rubyjs.gemspec +112 -0
- data/src/rubyjs.rb +3 -0
- data/src/rubyjs/code_generator.rb +474 -0
- data/src/rubyjs/compiler.rb +2061 -0
- data/src/rubyjs/debug_name_generator.rb +95 -0
- data/src/rubyjs/encoder.rb +171 -0
- data/src/rubyjs/eval_into.rb +59 -0
- data/src/rubyjs/lib/core.rb +1016 -0
- data/src/rubyjs/lib/dom_element.rb +66 -0
- data/src/rubyjs/lib/json.rb +101 -0
- data/src/rubyjs/lib/microunit.rb +188 -0
- data/src/rubyjs/model.rb +293 -0
- data/src/rubyjs/name_generator.rb +71 -0
- data/src/rwt/AbsolutePanel.rb +161 -0
- data/src/rwt/DOM.Konqueror.rb +89 -0
- data/src/rwt/DOM.Opera.rb +65 -0
- data/src/rwt/DOM.rb +1044 -0
- data/src/rwt/Event.Opera.rb +35 -0
- data/src/rwt/Event.rb +429 -0
- data/src/rwt/HTTPRequest.IE6.rb +5 -0
- data/src/rwt/HTTPRequest.rb +74 -0
- data/src/rwt/Label.rb +164 -0
- data/src/rwt/Panel.rb +90 -0
- data/src/rwt/RootPanel.rb +16 -0
- data/src/rwt/UIObject.rb +495 -0
- data/src/rwt/Widget.rb +193 -0
- data/src/rwt/ported-from/AbsolutePanel.java +158 -0
- data/src/rwt/ported-from/DOM.java +571 -0
- data/src/rwt/ported-from/DOMImpl.java +426 -0
- data/src/rwt/ported-from/DOMImplOpera.java +82 -0
- data/src/rwt/ported-from/DOMImplStandard.java +234 -0
- data/src/rwt/ported-from/HTTPRequest.java +81 -0
- data/src/rwt/ported-from/HTTPRequestImpl.java +103 -0
- data/src/rwt/ported-from/Label.java +163 -0
- data/src/rwt/ported-from/Panel.java +99 -0
- data/src/rwt/ported-from/UIObject.java +614 -0
- data/src/rwt/ported-from/Widget.java +221 -0
- data/test/benchmark/bm_vm1_block.rb +15 -0
- data/test/benchmark/bm_vm1_const.rb +13 -0
- data/test/benchmark/bm_vm1_ensure.rb +15 -0
- data/test/benchmark/common.rb +5 -0
- data/test/benchmark/params.yaml +7 -0
- data/test/common.Browser.rb +13 -0
- data/test/common.rb +8 -0
- data/test/gen_browser_test_suite.rb +129 -0
- data/test/gen_test_suite.rb +41 -0
- data/test/run_benchs.rb +58 -0
- data/test/run_tests.rb +22 -0
- data/test/test_args.rb +24 -0
- data/test/test_array.rb +22 -0
- data/test/test_case.rb +35 -0
- data/test/test_class.rb +55 -0
- data/test/test_eql.rb +9 -0
- data/test/test_exception.rb +61 -0
- data/test/test_expr.rb +12 -0
- data/test/test_hash.rb +29 -0
- data/test/test_hot_ruby.rb +146 -0
- data/test/test_if.rb +28 -0
- data/test/test_insertion_sort.rb +25 -0
- data/test/test_inspect.rb +10 -0
- data/test/test_lebewesen.rb +39 -0
- data/test/test_massign.rb +66 -0
- data/test/test_new.rb +12 -0
- data/test/test_range.rb +70 -0
- data/test/test_regexp.rb +22 -0
- data/test/test_send.rb +65 -0
- data/test/test_simple_output.rb +5 -0
- data/test/test_splat.rb +21 -0
- data/test/test_string.rb +51 -0
- data/test/test_test.rb +17 -0
- data/test/test_yield.rb +154 -0
- data/utils/js/Makefile +9 -0
- data/utils/js/RunScript.class +0 -0
- data/utils/js/RunScript.java +73 -0
- data/utils/js/js.jar +0 -0
- data/utils/js/run.sh +3 -0
- data/utils/jsc/Makefile +7 -0
- data/utils/jsc/README +3 -0
- data/utils/jsc/RunScript.c +93 -0
- data/utils/jsc/run.sh +15 -0
- data/utils/yuicompressor/README +1 -0
- data/utils/yuicompressor/yuicompressor-2.2.5.jar +0 -0
- metadata +157 -0
data/src/rubyjs.rb
ADDED
@@ -0,0 +1,474 @@
|
|
1
|
+
#
|
2
|
+
# Generate Javascript code.
|
3
|
+
#
|
4
|
+
# Copyright (c) 2007 by Michael Neumann (mneumann@ntecs.de).
|
5
|
+
# All rights reserved.
|
6
|
+
#
|
7
|
+
|
8
|
+
require 'rubyjs/compiler'
|
9
|
+
require 'rubyjs/model'
|
10
|
+
require 'set'
|
11
|
+
|
12
|
+
RUNTIME_MM = <<EOS
|
13
|
+
//
|
14
|
+
// Generates a new method_missing function
|
15
|
+
// for the given symbol +sym+.
|
16
|
+
//
|
17
|
+
var #<globalattr:mm_fun_cache> = {};
|
18
|
+
function #<globalattr:mm_fun>(sym)
|
19
|
+
{
|
20
|
+
if (!#<globalattr:mm_fun_cache>[sym])
|
21
|
+
{
|
22
|
+
var fn = function() {
|
23
|
+
return #<globalattr:call_method_missing>(this, arguments, sym);
|
24
|
+
};
|
25
|
+
fn.#<attr:_mm> = true;
|
26
|
+
#<globalattr:mm_fun_cache>[sym] = fn;
|
27
|
+
}
|
28
|
+
|
29
|
+
return #<globalattr:mm_fun_cache>[sym];
|
30
|
+
}
|
31
|
+
|
32
|
+
function #<globalattr:call_method_missing>(obj, args, sym)
|
33
|
+
{
|
34
|
+
var i, a;
|
35
|
+
a = [];
|
36
|
+
if (args.length == 0)
|
37
|
+
a.push(#<nil>);
|
38
|
+
else
|
39
|
+
a.push(args[0]);
|
40
|
+
|
41
|
+
a.push(#<globalattr:mm>[sym] || #<nil>);
|
42
|
+
|
43
|
+
for (i=1; i<args.length; i++)
|
44
|
+
a.push(args[i]);
|
45
|
+
|
46
|
+
var m = obj.#<m:method_missing>;
|
47
|
+
|
48
|
+
if (m)
|
49
|
+
return m.apply(obj, a);
|
50
|
+
else
|
51
|
+
throw "FATAL: method_missing missing";
|
52
|
+
}
|
53
|
+
|
54
|
+
//
|
55
|
+
// assign method_missing stubs
|
56
|
+
//
|
57
|
+
function #<globalattr:mm_assign>(c)
|
58
|
+
{
|
59
|
+
var i;
|
60
|
+
|
61
|
+
for (i in #<globalattr:mm>)
|
62
|
+
{
|
63
|
+
if (c.#<attr:object_constructor>.prototype[i]===undefined)
|
64
|
+
{
|
65
|
+
c.#<attr:object_constructor>.prototype[i] = #<globalattr:mm_fun>(i);
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
69
|
+
if (c.#<attr:superclass> != #<nil>)
|
70
|
+
{
|
71
|
+
for (i in c.#<attr:superclass>)
|
72
|
+
{
|
73
|
+
if (c[i]===undefined)
|
74
|
+
{
|
75
|
+
c[i] = #<globalattr:mm_fun>(i);
|
76
|
+
}
|
77
|
+
}
|
78
|
+
}
|
79
|
+
}
|
80
|
+
EOS
|
81
|
+
|
82
|
+
RUNTIME_INIT = <<EOS
|
83
|
+
// declare nil
|
84
|
+
function NilClass() {}
|
85
|
+
|
86
|
+
// FIXME: remove
|
87
|
+
NilClass.prototype.toString = function() { return "nil"; };
|
88
|
+
#<nil> = new NilClass();
|
89
|
+
|
90
|
+
//
|
91
|
+
// define a null-function (used by HTTPRequest)
|
92
|
+
//
|
93
|
+
function #<globalattr:null_func>()
|
94
|
+
{
|
95
|
+
}
|
96
|
+
|
97
|
+
//
|
98
|
+
// r: return value
|
99
|
+
// s: scope (method scope)
|
100
|
+
//
|
101
|
+
function #<globalattr:iter_jump>(r,s)
|
102
|
+
{
|
103
|
+
this.#<attr:return_value> = r;
|
104
|
+
this.#<attr:scope> = s;
|
105
|
+
return this;
|
106
|
+
}
|
107
|
+
|
108
|
+
//
|
109
|
+
// Throw in Javascript is a statement.
|
110
|
+
//
|
111
|
+
// This function can be used to overcome
|
112
|
+
// that limitation.
|
113
|
+
//
|
114
|
+
function #<globalattr:throw_expr>(x) { throw(x); }
|
115
|
+
|
116
|
+
function #<globalattr:to_splat>(a)
|
117
|
+
{
|
118
|
+
// TODO
|
119
|
+
return a;
|
120
|
+
}
|
121
|
+
|
122
|
+
//
|
123
|
+
// helper function for multiple assignment in
|
124
|
+
// iterator parameters.
|
125
|
+
//
|
126
|
+
// undefined -> []
|
127
|
+
// 1 -> [1]
|
128
|
+
// [1] -> [[1]]
|
129
|
+
// [] -> [[]]
|
130
|
+
// [1,2] -> [1,2]
|
131
|
+
//
|
132
|
+
function #<globalattr:masgn_iter>(a)
|
133
|
+
{
|
134
|
+
if (a===undefined) return [];
|
135
|
+
if (a.constructor!=Array || a.length<2) return [a];
|
136
|
+
return a;
|
137
|
+
}
|
138
|
+
|
139
|
+
//
|
140
|
+
// Call the method in the superclass.
|
141
|
+
//
|
142
|
+
// As super is used quite rarely, we dont optimize for it.
|
143
|
+
//
|
144
|
+
// object, method, iterator, arguments
|
145
|
+
//
|
146
|
+
function #<globalattr:supercall>(o, m, i, a)
|
147
|
+
{
|
148
|
+
var r = o[m]; // method in current class
|
149
|
+
var c = o.#<attr:_class>.#<attr:superclass>;
|
150
|
+
while (r === c.#<attr:object_constructor>.prototype[m])
|
151
|
+
c = c.#<attr:superclass>;
|
152
|
+
return c.#<attr:object_constructor>.prototype[m].apply(o, [i].concat(a));
|
153
|
+
}
|
154
|
+
|
155
|
+
function #<globalattr:zsupercall>(o, m, a)
|
156
|
+
{
|
157
|
+
var r = o[m]; // method in current class
|
158
|
+
var c = o.#<attr:_class>.#<attr:superclass>;
|
159
|
+
while (r === c.#<attr:object_constructor>.prototype[m])
|
160
|
+
c = c.#<attr:superclass>;
|
161
|
+
return c.#<attr:object_constructor>.prototype[m].apply(o, a);
|
162
|
+
}
|
163
|
+
|
164
|
+
//
|
165
|
+
// Whether o.kind_of?(c)
|
166
|
+
//
|
167
|
+
function #<globalattr:kind_of>(o, c)
|
168
|
+
{
|
169
|
+
var k,i,m;
|
170
|
+
|
171
|
+
k = o.#<attr:_class>;
|
172
|
+
|
173
|
+
while (k != #<nil>)
|
174
|
+
{
|
175
|
+
if (k === c) return true;
|
176
|
+
|
177
|
+
// check included modules
|
178
|
+
m = k.#<attr:modules>;
|
179
|
+
for (i=0; i<m.length; i++)
|
180
|
+
{
|
181
|
+
if (m[i] === c) return true;
|
182
|
+
}
|
183
|
+
|
184
|
+
k = k.#<attr:superclass>;
|
185
|
+
}
|
186
|
+
|
187
|
+
return false;
|
188
|
+
}
|
189
|
+
|
190
|
+
function #<globalattr:rebuild_classes>(c)
|
191
|
+
{
|
192
|
+
for (var i=0; i<c.length; i++)
|
193
|
+
#<globalattr:rebuild_class>(c[i]);
|
194
|
+
}
|
195
|
+
|
196
|
+
function #<globalattr:rebuild_class>(c)
|
197
|
+
{
|
198
|
+
var k,i;
|
199
|
+
|
200
|
+
//
|
201
|
+
// include modules
|
202
|
+
//
|
203
|
+
// do that before, because when assigning instance methods of
|
204
|
+
// the super class, a check for === undefined prevents this method
|
205
|
+
// from being overwritten.
|
206
|
+
//
|
207
|
+
for (i=0; i<c.#<attr:modules>.length; i++)
|
208
|
+
{
|
209
|
+
for (k in c.#<attr:modules>[i].#<attr:object_constructor>.prototype)
|
210
|
+
{
|
211
|
+
if (c.#<attr:object_constructor>.prototype[k]===undefined)
|
212
|
+
{
|
213
|
+
c.#<attr:object_constructor>.prototype[k] = c.#<attr:modules>[i].#<attr:object_constructor>.prototype[k];
|
214
|
+
}
|
215
|
+
}
|
216
|
+
}
|
217
|
+
|
218
|
+
// instance methods
|
219
|
+
if (c.#<attr:superclass> != #<nil>)
|
220
|
+
{
|
221
|
+
for (k in c.#<attr:superclass>.#<attr:object_constructor>.prototype)
|
222
|
+
{
|
223
|
+
if (c.#<attr:object_constructor>.prototype[k]===undefined)
|
224
|
+
{
|
225
|
+
c.#<attr:object_constructor>.prototype[k] = c.#<attr:superclass>.#<attr:object_constructor>.prototype[k];
|
226
|
+
}
|
227
|
+
}
|
228
|
+
}
|
229
|
+
|
230
|
+
// inherit class methods from superclass
|
231
|
+
if (c.#<attr:superclass> != #<nil>)
|
232
|
+
{
|
233
|
+
for (k in c.#<attr:superclass>)
|
234
|
+
{
|
235
|
+
if (c[k]===undefined)
|
236
|
+
{
|
237
|
+
c[k] = c.#<attr:superclass>[k];
|
238
|
+
}
|
239
|
+
}
|
240
|
+
}
|
241
|
+
|
242
|
+
// set class for instanciated objects
|
243
|
+
c.#<attr:object_constructor>.prototype.#<attr:_class> = c;
|
244
|
+
}
|
245
|
+
|
246
|
+
function #<globalattr:def_class>(h)
|
247
|
+
{
|
248
|
+
var c,k,i;
|
249
|
+
c = h.#<attr:_class> || #<Class>.#<m:new>(#<nil>, h.#<attr:superclass>, h.#<attr:classname>, h.#<attr:object_constructor>);
|
250
|
+
|
251
|
+
if (h.#<attr:instance_methods>)
|
252
|
+
{
|
253
|
+
for (k in h.#<attr:instance_methods>)
|
254
|
+
{
|
255
|
+
c.#<attr:object_constructor>.prototype[k] = h.#<attr:instance_methods>[k];
|
256
|
+
}
|
257
|
+
}
|
258
|
+
|
259
|
+
if (h.#<attr:methods>)
|
260
|
+
{
|
261
|
+
for (k in h.#<attr:methods>) c[k] = h.#<attr:methods>[k];
|
262
|
+
}
|
263
|
+
|
264
|
+
if (h.#<attr:modules>)
|
265
|
+
{
|
266
|
+
for (i=0; i<h.#<attr:modules>.length; i++)
|
267
|
+
{
|
268
|
+
c.#<attr:modules>.push(h.#<attr:modules>[i]);
|
269
|
+
}
|
270
|
+
}
|
271
|
+
|
272
|
+
return c;
|
273
|
+
}
|
274
|
+
|
275
|
+
function #<globalattr:MetaClass>(#<_class>, #<superclass>, #<classname>, #<object_constructor>)
|
276
|
+
{
|
277
|
+
this.#<attr:superclass> = #<superclass>;
|
278
|
+
this.#<attr:classname> = #<classname>;
|
279
|
+
this.#<attr:object_constructor> = #<object_constructor>;
|
280
|
+
this.#<attr:modules> = [];
|
281
|
+
this.#<attr:_class> = #<_class>;
|
282
|
+
return this;
|
283
|
+
}
|
284
|
+
|
285
|
+
#<globalattr:MetaClass>.#<m:name> = function() { return "MetaClass"; };
|
286
|
+
#<globalattr:MetaClass>.#<m:class> = function() { return this; };
|
287
|
+
EOS
|
288
|
+
|
289
|
+
|
290
|
+
|
291
|
+
|
292
|
+
class CodeGenerator
|
293
|
+
def initialize
|
294
|
+
@world = Model.new
|
295
|
+
end
|
296
|
+
|
297
|
+
def def_Class
|
298
|
+
m = @world.models[RubyJS::Environment::Class]
|
299
|
+
|
300
|
+
str = ""
|
301
|
+
str << generate_class_declaration(
|
302
|
+
m,
|
303
|
+
assign=true,
|
304
|
+
_class=ipol(%[new #<globalattr:MetaClass>(#<globalattr:MetaClass>, #<nil>, "Class", #<globalattr:MetaClass>)]),
|
305
|
+
obj_cons=nil,
|
306
|
+
use_superclass=false,
|
307
|
+
use_modules=false)
|
308
|
+
|
309
|
+
str << @world.encode_globalattr('rebuild_class') + "(" + @world.encode_constant(m[:name]) + ");"
|
310
|
+
|
311
|
+
str
|
312
|
+
end
|
313
|
+
|
314
|
+
def encode(code)
|
315
|
+
return ipol(code)
|
316
|
+
end
|
317
|
+
|
318
|
+
def gen_mm_stubs
|
319
|
+
# Method name mapping
|
320
|
+
|
321
|
+
mm_stubs = ""
|
322
|
+
mm_stubs << "// method map\n"
|
323
|
+
mm_stubs << "var #<globalattr:mm> = {"
|
324
|
+
i = []
|
325
|
+
# Javascript name -> Ruby name
|
326
|
+
@world.all_method_names do |k,v|
|
327
|
+
i << "#{v.inspect}:#{k.inspect}"
|
328
|
+
end
|
329
|
+
mm_stubs << i.join(",")
|
330
|
+
mm_stubs << "};\n"
|
331
|
+
mm_stubs << "var #<globalattr:mm_reverse> = {};\n"
|
332
|
+
mm_stubs << "for (var i in #<globalattr:mm>) #<globalattr:mm_reverse>[#<globalattr:mm>[i]] = i;\n"
|
333
|
+
|
334
|
+
ipol(mm_stubs)
|
335
|
+
end
|
336
|
+
|
337
|
+
def generate
|
338
|
+
str = ""
|
339
|
+
|
340
|
+
#
|
341
|
+
# Code for Class
|
342
|
+
#
|
343
|
+
# Required at the beginning because all other classes are created as
|
344
|
+
# objects from Class using Class.new.
|
345
|
+
#
|
346
|
+
str << def_Class()
|
347
|
+
|
348
|
+
#
|
349
|
+
# Now define all other classes/modules
|
350
|
+
#
|
351
|
+
|
352
|
+
@world.iterate_all(Set.new) do |m|
|
353
|
+
|
354
|
+
#
|
355
|
+
# We have to add the modules for class Class here.
|
356
|
+
#
|
357
|
+
if m[:for] == RubyJS::Environment::Class
|
358
|
+
h = { "_class" => @world.encode_constant(m[:name]) }
|
359
|
+
b_modules(m, h)
|
360
|
+
str << b_def_class(h)
|
361
|
+
next
|
362
|
+
end
|
363
|
+
|
364
|
+
begin
|
365
|
+
obj_cons = m[:for].const_get(:OBJECT_CONSTRUCTOR__)
|
366
|
+
rescue
|
367
|
+
obj_cons = nil
|
368
|
+
end
|
369
|
+
|
370
|
+
str << generate_class_declaration(m, assign=true, _class=nil, obj_cons)
|
371
|
+
end
|
372
|
+
|
373
|
+
#
|
374
|
+
# Class is a subclass of Object
|
375
|
+
#
|
376
|
+
str << ipol(<<-EOS)
|
377
|
+
#<Class>.#<attr:superclass> = #<Object>;
|
378
|
+
EOS
|
379
|
+
|
380
|
+
#
|
381
|
+
# rebuild all classes and modules
|
382
|
+
#
|
383
|
+
klasses = []
|
384
|
+
@world.iterate_all(Set.new) do |m|
|
385
|
+
klasses << @world.encode_constant(m[:name])
|
386
|
+
end
|
387
|
+
str << ipol("var #<globalattr:klasses> = [#{klasses.join(",")}];\n" +
|
388
|
+
"#<globalattr:rebuild_classes>(#<globalattr:klasses>);\n")
|
389
|
+
|
390
|
+
unless $RUBYJS__OPTS.include?('NoMethodMissing')
|
391
|
+
str << ipol("for (var i=0; i<#<globalattr:klasses>.length; i++) #<globalattr:mm_assign>(#<globalattr:klasses>[i]);\n")
|
392
|
+
end
|
393
|
+
|
394
|
+
#
|
395
|
+
# prepend
|
396
|
+
#
|
397
|
+
|
398
|
+
str_prep = ""
|
399
|
+
|
400
|
+
# Code of runtime
|
401
|
+
str_prep << ipol(RUNTIME_INIT)
|
402
|
+
|
403
|
+
unless $RUBYJS__OPTS.include?('NoMethodMissing')
|
404
|
+
str_prep << ipol(RUNTIME_MM)
|
405
|
+
str_prep << gen_mm_stubs()
|
406
|
+
end
|
407
|
+
|
408
|
+
return str_prep + str
|
409
|
+
end
|
410
|
+
|
411
|
+
def b_methods(kind, model, h)
|
412
|
+
m = {}
|
413
|
+
model[kind].each_pair do |name, pt|
|
414
|
+
@world.with_local do
|
415
|
+
m[name] = MethodCompiler.new(@world, @world.encode_method(name)).compile_method(pt)
|
416
|
+
end
|
417
|
+
end
|
418
|
+
unless m.empty?
|
419
|
+
h[kind.to_s] = "{" + m.map {|name, fn|
|
420
|
+
if $RUBYJS__OPTS.include?('PrettyPrint')
|
421
|
+
@world.encode_method(name) + ":\n" +
|
422
|
+
%[/* #{ model[:name] }#{kind.to_s == "methods" ? "." : "#"}#{ name } */\n#{fn}\n\n]
|
423
|
+
else
|
424
|
+
@world.encode_method(name) + ": #{fn}"
|
425
|
+
end
|
426
|
+
}.join(",") + "}"
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
def b_modules(model, h)
|
431
|
+
h["modules"] = "[" + model[:modules].map {|m|
|
432
|
+
@world.encode_constant(@world.namify(m))
|
433
|
+
}.join(",") + "]"
|
434
|
+
end
|
435
|
+
|
436
|
+
def b_def_class(h)
|
437
|
+
@world.encode_globalattr('def_class') + "({" +
|
438
|
+
h.map {|k, v| @world.encode_attr(k) + ": #{v}"}.join(",") + "});"
|
439
|
+
end
|
440
|
+
|
441
|
+
def generate_class_declaration(model, assign=true, _class=nil, object_constructor=nil, use_superclass=true, use_modules=true)
|
442
|
+
h = {}
|
443
|
+
h["_class"] = _class if _class
|
444
|
+
h["object_constructor"] = object_constructor if object_constructor
|
445
|
+
|
446
|
+
b_methods(:instance_methods, model, h)
|
447
|
+
b_methods(:methods, model, h)
|
448
|
+
|
449
|
+
h["classname"] = model[:name].inspect
|
450
|
+
|
451
|
+
if model[:superclass] and use_superclass
|
452
|
+
h["superclass"] = @world.old_encode_constant(@world.namify(model[:superclass]))
|
453
|
+
else
|
454
|
+
# we need this as def_class expects a nil value if no superclass
|
455
|
+
# is given!
|
456
|
+
h["superclass"] = @world.encode_nil
|
457
|
+
end
|
458
|
+
|
459
|
+
b_modules(model, h) if use_modules
|
460
|
+
|
461
|
+
str = ""
|
462
|
+
str << @world.encode_constant(model[:name]) + " = " if assign
|
463
|
+
str << b_def_class(h)
|
464
|
+
|
465
|
+
return str
|
466
|
+
end
|
467
|
+
|
468
|
+
private
|
469
|
+
|
470
|
+
# iterpolate strings
|
471
|
+
def ipol(str)
|
472
|
+
@world.interpolate(str)
|
473
|
+
end
|
474
|
+
end
|