rubyhacks 0.1.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.
- data/.document +5 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +20 -0
- data/README.md +4 -0
- data/README.rdoc +19 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/lib/rubyhacks.rb +1257 -0
- data/rubyhacks.gemspec +60 -0
- data/test/helper.rb +18 -0
- data/test/test_rubyhacks.rb +7 -0
- metadata +127 -0
data/lib/rubyhacks.rb
ADDED
@@ -0,0 +1,1257 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'rbconfig'
|
3
|
+
require 'pp'
|
4
|
+
require 'thread'
|
5
|
+
# require 'rbgsl'
|
6
|
+
# $script_folder = File.dirname(File.expand_path(__FILE__))
|
7
|
+
# require $script_folder + "/long_regexen.rb"
|
8
|
+
$is_main = __FILE__ == $0
|
9
|
+
|
10
|
+
if RUBY_VERSION.to_f < 1.9
|
11
|
+
raise "Ruby version 1.9 or greater required (current version is #{RUBY_VERSION})"
|
12
|
+
end
|
13
|
+
#
|
14
|
+
# def pe(*args, bndng)
|
15
|
+
# args.each do |arg|
|
16
|
+
# puts arg, eval(arg, binding).inspect
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
|
20
|
+
class Object
|
21
|
+
def set(v, *args)
|
22
|
+
send(v+"=".to_sym, *args)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.find_all_methods_like(method)
|
26
|
+
method = method === Regexp ? method : Regexp.new(method)
|
27
|
+
return constants.inject({}) do |hash,ob|
|
28
|
+
ob = const_get(ob)
|
29
|
+
begin
|
30
|
+
hash[ob] = (ob.methods + ob.instance_methods).find_all{|meth| meth =~ method}
|
31
|
+
hash.delete(ob) if hash[ob].size == 0
|
32
|
+
rescue
|
33
|
+
end
|
34
|
+
hash
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
module Kernel
|
42
|
+
def eputs(*args)
|
43
|
+
#raise "here!"
|
44
|
+
$stderr.puts(*args)
|
45
|
+
end
|
46
|
+
def ep(*args)
|
47
|
+
#raise "here!"
|
48
|
+
$stderr.puts(*(args.map{|a| a.inspect}))
|
49
|
+
end
|
50
|
+
def eprint(*args)
|
51
|
+
$stderr.print(*args)
|
52
|
+
end
|
53
|
+
def self.change_environment_with_shell_script(string)
|
54
|
+
# system "echo $PATH
|
55
|
+
env = `#{string}\necho "XXXXXXZZZZZZXXXXXXX029340923"\n env`.split("XXXXXXZZZZZZXXXXXXX029340923")[-1]
|
56
|
+
new_env = {}
|
57
|
+
env.scan(/^(?<var>[a-zA-Z_][a-zA-Z_0-9]*)=(?<val>.*)/) do
|
58
|
+
# p $~
|
59
|
+
new_env[$~[:var]] = $~[:val]
|
60
|
+
end
|
61
|
+
# p new_env.keys.size - ENV.keys.size
|
62
|
+
# (ENV.keys + new_env.keys).uniq.each do |key|
|
63
|
+
# p "----|#{key}", new_env[key], ENV[key] unless new_env[key] == ENV[key]
|
64
|
+
# end
|
65
|
+
(new_env.keys - ["OLDPWD", "_", "mc", "SHLVL"]).each do |key|
|
66
|
+
ENV[key] = new_env[key]
|
67
|
+
end
|
68
|
+
# ep ENV['PATH']
|
69
|
+
|
70
|
+
# p env
|
71
|
+
# p ENV
|
72
|
+
# system "module list"
|
73
|
+
# exit
|
74
|
+
end
|
75
|
+
|
76
|
+
def forkex(string)
|
77
|
+
fork{exec string}
|
78
|
+
end
|
79
|
+
|
80
|
+
# def reraise(err)
|
81
|
+
# raise(err, err.to_s, err.backtrace)
|
82
|
+
# end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
module ObjectSpace
|
87
|
+
|
88
|
+
def self.log_state(file, &block)
|
89
|
+
File.open(file, 'w') do |file|
|
90
|
+
each_object do |obj|
|
91
|
+
if block
|
92
|
+
PP.pp(obj, file) if yield(obj)
|
93
|
+
else
|
94
|
+
PP.pp(obj, file)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
class Symbol
|
103
|
+
def +(other)
|
104
|
+
if other.class == String
|
105
|
+
self.to_s + other
|
106
|
+
elsif other.class == Symbol
|
107
|
+
(self.to_s+other.to_s).to_sym
|
108
|
+
else
|
109
|
+
raise NoMethodError
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def =~(other)
|
114
|
+
return self.to_s =~ other
|
115
|
+
end
|
116
|
+
def sign
|
117
|
+
@sign ||= 1
|
118
|
+
@sign
|
119
|
+
end
|
120
|
+
def -@
|
121
|
+
@sign ||= 1
|
122
|
+
@sign *= -1
|
123
|
+
self
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
class Class
|
128
|
+
|
129
|
+
# def new_class_method(method, &block)
|
130
|
+
# self.class.send(:define_method,method, &block)
|
131
|
+
# end
|
132
|
+
|
133
|
+
def new_class_method(method, &block)
|
134
|
+
define_singleton_method(method, &block)
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
def aliold(sym)
|
139
|
+
(eputs "Warning: This method: #{:old_+sym} already exists"; return) if instance_methods.include?(:old_+sym)
|
140
|
+
|
141
|
+
alias_method((:old_+sym),sym)
|
142
|
+
end
|
143
|
+
|
144
|
+
aliold(:class_variable_get)
|
145
|
+
def class_variable_get(var, *args)
|
146
|
+
var = var.to_s=~ /^@@/ ? var : "@@" + var.to_s
|
147
|
+
old_class_variable_get(var, *args)
|
148
|
+
end
|
149
|
+
|
150
|
+
aliold(:class_variable_set)
|
151
|
+
def class_variable_set(var,*args)
|
152
|
+
var = var.to_s=~ /^@@/ ? var : "@@" + var.to_s
|
153
|
+
old_class_variable_set(var, *args)
|
154
|
+
end
|
155
|
+
|
156
|
+
def class_accessor(*args)
|
157
|
+
args.each do |variable|
|
158
|
+
new_class_method(variable){class_variable_get(variable)}
|
159
|
+
new_class_method(variable+"=".to_sym) do |value|
|
160
|
+
class_variable_set(variable,value)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def add_a_child_class(class_name, class_definitions="")
|
166
|
+
class_eval("class #{class_name} < #{self}; end")
|
167
|
+
new_class = const_get(class_name)
|
168
|
+
new_class.class_eval(class_definitions)
|
169
|
+
new_class
|
170
|
+
end
|
171
|
+
|
172
|
+
def recursive_const_get(string)
|
173
|
+
string.split(/::/).inject(nil){|const, name| const ? const.const_get(name) : const_get(name)}
|
174
|
+
end
|
175
|
+
|
176
|
+
public :include, :attr_accessor
|
177
|
+
|
178
|
+
|
179
|
+
def instance_method?(meth)
|
180
|
+
return instance_methods.include?(meth.to_sym)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
class Object
|
185
|
+
aliold(:instance_variable_set)
|
186
|
+
def instance_variable_set(var,*args)
|
187
|
+
var = var.to_s=~ /^@/ ? var : "@" + var.to_s
|
188
|
+
old_instance_variable_set(var, *args)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
class String
|
193
|
+
alias old_plus +
|
194
|
+
def +(other)
|
195
|
+
if other.class == Symbol
|
196
|
+
old_plus(other.to_s)
|
197
|
+
else
|
198
|
+
old_plus(other)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def to_bool
|
203
|
+
if self == "true" or self == "T" or self == "TRUE"
|
204
|
+
return true
|
205
|
+
elsif self == "false" or self == "F" or self == "FALSE"
|
206
|
+
return false
|
207
|
+
else
|
208
|
+
raise ArgumentError.new("Attempt to convert string: (#{self}) to boolean failed")
|
209
|
+
end
|
210
|
+
end
|
211
|
+
alias :to_b :to_bool
|
212
|
+
|
213
|
+
def one_page_at_a_time
|
214
|
+
rows, columns = Terminal.terminal_size
|
215
|
+
i = 0
|
216
|
+
array = self.split("\n")
|
217
|
+
# puts array.size; gets;
|
218
|
+
loop do
|
219
|
+
j = 0
|
220
|
+
while j < rows - 8
|
221
|
+
line = array[i]
|
222
|
+
puts line
|
223
|
+
i+=1
|
224
|
+
break if i == array.size
|
225
|
+
j+=(line.size / columns).ceiling
|
226
|
+
# puts i,j; gets
|
227
|
+
end
|
228
|
+
break if i == array.size
|
229
|
+
puts "\nPress Enter to continue reading"
|
230
|
+
gets
|
231
|
+
3.times{print "\033[1A\033[K"}
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
def to_h
|
236
|
+
hash = eval(self)
|
237
|
+
raise ArgumentError.new("Couldn't convert #{self} to hash") unless hash.class == Hash
|
238
|
+
# puts hash; gets
|
239
|
+
return hash
|
240
|
+
end
|
241
|
+
|
242
|
+
def rewind(offset=0)
|
243
|
+
#clears a string from the terminal output and rewinds to its beginning (as long as it was the last thing sent to standard out)
|
244
|
+
# puts offset; gets
|
245
|
+
(true_lines-offset).times{print "\033[A\033[K"}
|
246
|
+
end
|
247
|
+
|
248
|
+
|
249
|
+
def true_lines
|
250
|
+
return split("\n", -1).inject(0) do |j, line|
|
251
|
+
j + (line.size / Terminal.terminal_size[1]).ceiling
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
aliold :to_f
|
256
|
+
def to_f
|
257
|
+
sub(/\.[eE]/, '.0e').old_to_f
|
258
|
+
end
|
259
|
+
|
260
|
+
def grep(pattern)
|
261
|
+
split("\n").grep(pattern).join("\n")
|
262
|
+
end
|
263
|
+
|
264
|
+
def grep_line_numbers(pattern)
|
265
|
+
ans = []
|
266
|
+
split("\n").each_with_index do |line, index|
|
267
|
+
ans.push index + 1 if line =~ pattern
|
268
|
+
end
|
269
|
+
ans
|
270
|
+
end
|
271
|
+
|
272
|
+
def print_coloured_lines(terminal_size = nil) # terminal_size = [rows, cols]
|
273
|
+
# raise CRFatal.new("terminal size must be given if this is called any where except inside a terminal (for example if you've called this as a subprocess)") unless terminal_size or $stdout.tty?
|
274
|
+
terminal_size ||= Terminal.terminal_size
|
275
|
+
#lots of gritty terminal jargon in here. Edit at your peril!
|
276
|
+
lines = self.split($/)
|
277
|
+
i = 0; j=0
|
278
|
+
lines.each do |line|
|
279
|
+
colour = j%2==0 ? j%4==0 ? "\033[0;36m" : "\033[1;32m" : "\033[1;37m"
|
280
|
+
print colour
|
281
|
+
print line.gsub(/\|/, "\033[1;37m" + '|' + colour)
|
282
|
+
print "\033[K\n"
|
283
|
+
# puts (line.size / Terminal.terminal_size[1]).class
|
284
|
+
# puts (line.size / Terminal.terminal_size[1])
|
285
|
+
|
286
|
+
i+=(line.sub(/\w*$/, '').size / terminal_size[1]).ceiling
|
287
|
+
j+=1
|
288
|
+
end
|
289
|
+
puts "\033[1;37m"
|
290
|
+
# print 'rewind size is', rewind
|
291
|
+
|
292
|
+
end
|
293
|
+
|
294
|
+
def universal_escape(name = nil)
|
295
|
+
raise ArgumentError if name unless name =~ /^[A-Za-z0-9]*$/
|
296
|
+
arr = []
|
297
|
+
self.each_codepoint{|cp| arr.push cp}
|
298
|
+
if name
|
299
|
+
return "UEBZXQF#{name}UEB#{arr.join('d')}UEEZXQF#{name}UEE"
|
300
|
+
else
|
301
|
+
return arr.join('d')
|
302
|
+
end
|
303
|
+
end
|
304
|
+
def universal_escape1
|
305
|
+
arr = []
|
306
|
+
self.each_byte{|cp| arr.push cp}
|
307
|
+
arr.join('d')
|
308
|
+
end
|
309
|
+
|
310
|
+
def universal_unescape(name = nil)
|
311
|
+
# p arrxy = self.split('d').map{
|
312
|
+
# strxy = ""
|
313
|
+
# arrxy.each{|codepointx| print codepointx.to_i.pretty_inspect, ' '; strxy << codepointx.to_i}
|
314
|
+
# return strxy
|
315
|
+
if name
|
316
|
+
return self.gsub(Regexp.new("UEBZXQF#{name}UEB([\\dd]+)UEEZXQF#{name}UEE")) do
|
317
|
+
$1.universal_unescape
|
318
|
+
end
|
319
|
+
else
|
320
|
+
raise TypeError.new("This string is not a simple escaped string: #{self}") unless self =~ /^[\dd]*$/
|
321
|
+
self.sub(/^UEB.*UEB/, '').sub(/UEE.*UEE$/, '').split('d').map{|cp| cp.to_i}.pack('U*')
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
def fortran_true?
|
326
|
+
self =~ /^(T|\.T\.|\.true\.|\.t\.)$/
|
327
|
+
end
|
328
|
+
|
329
|
+
def fortran_false?
|
330
|
+
self =~ /^(F|\.F\.|\.false\.|\.f\.)$/
|
331
|
+
end
|
332
|
+
|
333
|
+
|
334
|
+
|
335
|
+
FORTRAN_BOOLS = [".true.", ".false.", "T", "F", ".t.", ".f.", ".T.", ".F."]
|
336
|
+
|
337
|
+
def sign
|
338
|
+
@sign ||= 1
|
339
|
+
@sign
|
340
|
+
end
|
341
|
+
def -@
|
342
|
+
@sign ||= 1
|
343
|
+
@sign *= -1
|
344
|
+
self
|
345
|
+
end
|
346
|
+
def get_sign
|
347
|
+
if self[0,1] == '-'
|
348
|
+
@sign = -1
|
349
|
+
self.sub!(/^\-/, '')
|
350
|
+
end
|
351
|
+
self
|
352
|
+
end
|
353
|
+
alias :old_compare :<=>
|
354
|
+
|
355
|
+
def <=> other
|
356
|
+
begin
|
357
|
+
@sign ||= 1
|
358
|
+
if @sign == 1
|
359
|
+
return self.old_compare other
|
360
|
+
else
|
361
|
+
return other.old_compare self
|
362
|
+
end
|
363
|
+
rescue RuntimeError
|
364
|
+
return self.old_compare other
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
def esc_regex
|
369
|
+
Regexp.new(Regexp.escape(self))
|
370
|
+
end
|
371
|
+
|
372
|
+
def variable_to_class_name
|
373
|
+
self.gsub(/(?:^|_)(\w)/){"#$1".capitalize}
|
374
|
+
end
|
375
|
+
|
376
|
+
def delete_substrings(*strings)
|
377
|
+
new_string = self
|
378
|
+
strings.each do |str|
|
379
|
+
new_string = new_string.sub(Regexp.new_escaped(str), '')
|
380
|
+
end
|
381
|
+
new_string
|
382
|
+
end
|
383
|
+
alias :delsubstr :delete_substrings
|
384
|
+
end
|
385
|
+
|
386
|
+
class TrueClass
|
387
|
+
def to_s
|
388
|
+
return "true"
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
392
|
+
class FalseClass
|
393
|
+
def to_s
|
394
|
+
return "false"
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
|
399
|
+
|
400
|
+
|
401
|
+
|
402
|
+
|
403
|
+
class Hash
|
404
|
+
def +(other)
|
405
|
+
temp = {}
|
406
|
+
raise TypeError unless other.class == Hash
|
407
|
+
self.each do |key, value|
|
408
|
+
raise "Non unique key set for Hash + Hash" unless other[key].class == NilClass
|
409
|
+
temp[key] = value
|
410
|
+
end
|
411
|
+
other.each do |key, value|
|
412
|
+
raise "Non unique key set for Hash + Hash" unless self[key].class == NilClass
|
413
|
+
temp[key] = value
|
414
|
+
end
|
415
|
+
return temp
|
416
|
+
end
|
417
|
+
|
418
|
+
|
419
|
+
def random_value
|
420
|
+
self[random_key]
|
421
|
+
end
|
422
|
+
|
423
|
+
def random_key
|
424
|
+
keys.random
|
425
|
+
end
|
426
|
+
|
427
|
+
def random
|
428
|
+
key = random_key
|
429
|
+
return {key => self[key]}
|
430
|
+
end
|
431
|
+
def modify(hash, excludes=[])
|
432
|
+
hash.each do |key, value|
|
433
|
+
# p key
|
434
|
+
begin
|
435
|
+
self[key] = value.dup unless excludes.include? key
|
436
|
+
rescue TypeError #immediate values cannot be dup'd
|
437
|
+
self[key] = value unless excludes.include? key
|
438
|
+
end
|
439
|
+
end
|
440
|
+
self
|
441
|
+
end
|
442
|
+
alias :absorb :modify
|
443
|
+
|
444
|
+
def expand_bools
|
445
|
+
self[:true].each do |key|
|
446
|
+
self[key] = true
|
447
|
+
end
|
448
|
+
self[:false].each do |key|
|
449
|
+
self[key] = false
|
450
|
+
end
|
451
|
+
self
|
452
|
+
end
|
453
|
+
end
|
454
|
+
|
455
|
+
class Array
|
456
|
+
def random
|
457
|
+
self[rand(size)]
|
458
|
+
end
|
459
|
+
|
460
|
+
def slice_with_stride(stride, offset, slice_size = 1)
|
461
|
+
raise ArgumentError.new("slice_size cannot be bigger than stride - offset") if slice_size > stride - offset
|
462
|
+
i = 0; new_arr = []
|
463
|
+
loop do
|
464
|
+
for j in 0...slice_size
|
465
|
+
new_arr.push self[i + offset + j]
|
466
|
+
end
|
467
|
+
i += stride
|
468
|
+
break if i >= size
|
469
|
+
end
|
470
|
+
return new_arr
|
471
|
+
end
|
472
|
+
|
473
|
+
def pieces(no_pieces)
|
474
|
+
ans = []
|
475
|
+
piece_sizes = []
|
476
|
+
|
477
|
+
for i in 0...no_pieces
|
478
|
+
ans.push []; piece_sizes[i] = 0
|
479
|
+
end
|
480
|
+
for j in 0...size
|
481
|
+
piece_sizes[j % no_pieces] += 1
|
482
|
+
end
|
483
|
+
# p ans, piece_sizes
|
484
|
+
accum = 0
|
485
|
+
piece_sizes.each_with_index do |piece_size, piece|
|
486
|
+
ans[piece] = self.slice(accum...accum + piece_size)
|
487
|
+
accum += piece_size
|
488
|
+
end
|
489
|
+
return ans
|
490
|
+
end
|
491
|
+
|
492
|
+
def sum
|
493
|
+
return inject{|old, new| old + new}
|
494
|
+
end
|
495
|
+
def product
|
496
|
+
return inject{|old, new| old * new}
|
497
|
+
end
|
498
|
+
|
499
|
+
def nuniq
|
500
|
+
arr = dup
|
501
|
+
i=0;
|
502
|
+
while i < arr.size
|
503
|
+
j=i+1
|
504
|
+
while j < arr.size
|
505
|
+
# p arr[i], arr[j]
|
506
|
+
arr.delete_at(j) if (arr[j].to_f <=> arr[i].to_f) == 0
|
507
|
+
j+=1
|
508
|
+
end
|
509
|
+
i+=1
|
510
|
+
end
|
511
|
+
arr
|
512
|
+
end
|
513
|
+
|
514
|
+
|
515
|
+
|
516
|
+
end
|
517
|
+
|
518
|
+
|
519
|
+
|
520
|
+
|
521
|
+
class Module
|
522
|
+
def aliold(sym)
|
523
|
+
alias_method((:old_+sym),sym)
|
524
|
+
end
|
525
|
+
end
|
526
|
+
|
527
|
+
class Fixnum
|
528
|
+
def ceiling
|
529
|
+
return floor + 1
|
530
|
+
end
|
531
|
+
end
|
532
|
+
|
533
|
+
module Terminal
|
534
|
+
|
535
|
+
case Config::CONFIG['host']
|
536
|
+
when /i386-apple-darwin/
|
537
|
+
TIOCGWINSZ = 0x40087468
|
538
|
+
OTHER_TIOCGWINSZ = 0x5413
|
539
|
+
else
|
540
|
+
TIOCGWINSZ = 0x5413
|
541
|
+
OTHER_TIOCGWINSZ = 0x40087468
|
542
|
+
end
|
543
|
+
|
544
|
+
class TerminalError < StandardError
|
545
|
+
end
|
546
|
+
|
547
|
+
def self.terminal_size
|
548
|
+
return [ENV['ROWS'].to_i, ENV['COLS'].to_i] if ENV['ROWS'] and ENV['COLS']
|
549
|
+
raise TerminalError.new("Tried to determine terminal size but this process is not being run from within a terminal (may be a sub process or called within another script). Set ENV['ROWS'] ($ROWS in shell) and ENV['COLS'] ($COLS in shell) to avoid this warning") unless STDOUT.tty?
|
550
|
+
system_code = TIOCGWINSZ
|
551
|
+
begin
|
552
|
+
rows, cols = 25, 80
|
553
|
+
buf = [0, 0, 0, 0].pack("SSSS")
|
554
|
+
if STDOUT.ioctl(system_code, buf) >= 0 then
|
555
|
+
rows, cols, row_pixels, row_pixels, col_pixels =
|
556
|
+
buf.unpack("SSSS")[0..1]
|
557
|
+
end
|
558
|
+
return [rows, cols]
|
559
|
+
rescue
|
560
|
+
puts "Warning: TIOCGWINSZ switched in Terminal.terminal_size"
|
561
|
+
system_code = OTHER_TIOCGWINSZ
|
562
|
+
retry
|
563
|
+
end
|
564
|
+
end
|
565
|
+
|
566
|
+
def self.rewind(nlines)
|
567
|
+
print "\033[#{nlines}A"
|
568
|
+
end
|
569
|
+
|
570
|
+
def self.erewind(nlines)
|
571
|
+
eprint "\033[#{nlines}A"
|
572
|
+
end
|
573
|
+
|
574
|
+
|
575
|
+
def self.reset
|
576
|
+
print "\033[0;00m"
|
577
|
+
end
|
578
|
+
|
579
|
+
def self.default_colour
|
580
|
+
"\033[00m"
|
581
|
+
end
|
582
|
+
|
583
|
+
RESET = "\033[0;00m"
|
584
|
+
CLEAR_LINE = "\033[K"
|
585
|
+
CYAN = "\033[2;36m"
|
586
|
+
LIGHT_GREEN= "\033[1;32m"
|
587
|
+
WHITE = "\033[1;37m"
|
588
|
+
RED = "\033[1;31m"
|
589
|
+
BACKGROUND_BLACK = "\033[40m"
|
590
|
+
end
|
591
|
+
|
592
|
+
class Regexp
|
593
|
+
def verbatim
|
594
|
+
self.inspect.sub(/\A\//,'').sub(/\/[mix]*\Z/,'')
|
595
|
+
end
|
596
|
+
def self.properly_nested(left_delim, right_delim, start_anywhere=true, ext = "")
|
597
|
+
raise ArgumentError.new("Left and right delimiters (#{left_delim.inspect}, #{right_delim.inspect}) cannot be the same") if left_delim == right_delim
|
598
|
+
|
599
|
+
nodelim = "(?<nodelim#{ext}>\\\\\\\\|\\\\\\#{left_delim}|\\\\\\#{right_delim}|[^#{left_delim}#{right_delim}\\\\]|\\\\[^#{left_delim}#{right_delim}\\\\])"
|
600
|
+
|
601
|
+
new("#{start_anywhere ? "(?<before#{ext}>#{nodelim}*?)" : ""}(?<group#{ext}>\\#{left_delim}#{start_anywhere ? "\\g<nodelim#{ext}>" : nodelim}*?(?:\\g<group#{ext}>\\g<nodelim#{ext}>*?)*\\#{right_delim})")
|
602
|
+
end
|
603
|
+
def self.quoted_string
|
604
|
+
/"(?:\\\\|\\"|[^"\\]|\\[^"\\])*"|'(?:\\\\|\\'|[^'\\]|\\[^'\\])*'/
|
605
|
+
end
|
606
|
+
def self.whole_string(regex)
|
607
|
+
new("\\A#{regex.to_s}\\Z")
|
608
|
+
end
|
609
|
+
def self.new_escaped(*args)
|
610
|
+
new(escape(*args))
|
611
|
+
end
|
612
|
+
end
|
613
|
+
|
614
|
+
class FloatHash < Hash
|
615
|
+
|
616
|
+
def self.from_hash(hash)
|
617
|
+
fh = new
|
618
|
+
hash.each{|k,v| fh[k]=v}
|
619
|
+
fh
|
620
|
+
end
|
621
|
+
|
622
|
+
aliold :inspect
|
623
|
+
def inspect
|
624
|
+
"FloatHash.from_hash(#{old_inspect})"
|
625
|
+
end
|
626
|
+
aliold :pretty_inspect
|
627
|
+
def pretty_inspect
|
628
|
+
"FloatHash.from_hash(#{old_pretty_inspect})"
|
629
|
+
end
|
630
|
+
|
631
|
+
def []=(key, var)
|
632
|
+
# super(key.to_f, var)
|
633
|
+
# raise TypeError unless key.kind
|
634
|
+
old_key = self.find{|k, v| (k-key.to_f).abs < Float::EPSILON}
|
635
|
+
if old_key
|
636
|
+
super(old_key[0].to_f, var)
|
637
|
+
else
|
638
|
+
super(key.to_f, var)
|
639
|
+
end
|
640
|
+
end
|
641
|
+
|
642
|
+
def [](key)
|
643
|
+
# # # super(key.to_f)
|
644
|
+
# raise TypeError unless key.class == Float
|
645
|
+
old_key = self.find{|k, v| (k-key.to_f).abs < Float::EPSILON}
|
646
|
+
if old_key
|
647
|
+
return super(old_key[0])
|
648
|
+
else
|
649
|
+
return nil
|
650
|
+
end
|
651
|
+
end
|
652
|
+
|
653
|
+
|
654
|
+
|
655
|
+
# def to_s
|
656
|
+
# return self.inject(""){ |str, (key,val)|
|
657
|
+
# str+ sprintf("[%f, %s],", key, val.to_s)}.chop
|
658
|
+
# end
|
659
|
+
end
|
660
|
+
|
661
|
+
class String
|
662
|
+
def to_f_wsp
|
663
|
+
self.sub(/^\s*\-\s*/, '-').to_f
|
664
|
+
end
|
665
|
+
end
|
666
|
+
|
667
|
+
class Numeric
|
668
|
+
def to_mathematica_format
|
669
|
+
return "0.0" if self.to_f == 0.0
|
670
|
+
l = Math.log10(self.to_f.abs).floor
|
671
|
+
return "#{self.to_f / 10.0**(l.to_f)}*10^(#{l})"
|
672
|
+
end
|
673
|
+
end
|
674
|
+
|
675
|
+
class Dir
|
676
|
+
class << self
|
677
|
+
aliold(:entries)
|
678
|
+
def entries(dir=pwd,opts={})
|
679
|
+
old_entries(dir,opts)
|
680
|
+
end
|
681
|
+
end
|
682
|
+
end
|
683
|
+
|
684
|
+
module Log
|
685
|
+
|
686
|
+
@@log_file = 'log.txt'
|
687
|
+
|
688
|
+
def self.log_file
|
689
|
+
@@log_file
|
690
|
+
end
|
691
|
+
|
692
|
+
def self.log_file=(file)
|
693
|
+
@@log_file=file
|
694
|
+
end
|
695
|
+
|
696
|
+
def self.clean_up
|
697
|
+
return unless @@log_file
|
698
|
+
File.delete @@log_file if FileTest.exist? @@log_file
|
699
|
+
end
|
700
|
+
|
701
|
+
def Log.log(*messages)
|
702
|
+
# p 'wanting to log', @@log_file
|
703
|
+
return nil unless @@log_file
|
704
|
+
# return
|
705
|
+
# return unless @@log_file
|
706
|
+
# puts 'logging'
|
707
|
+
messages.each do |message|
|
708
|
+
File.open(@@log_file, 'a'){|file| file.puts message}
|
709
|
+
end
|
710
|
+
end
|
711
|
+
|
712
|
+
def log(*messages)
|
713
|
+
return nil unless @@log_file
|
714
|
+
Log.log(*messages)
|
715
|
+
end
|
716
|
+
|
717
|
+
def Log.logf(func_name)
|
718
|
+
log("Function: " + func_name + ": " + self.to_s)
|
719
|
+
end
|
720
|
+
|
721
|
+
def logf(func_name)
|
722
|
+
# p func_name
|
723
|
+
# p "Function: " + func_name.to_s + ": " + self.class.to_s
|
724
|
+
message = "Function: " + func_name.to_s + ": " + self.class.to_s
|
725
|
+
# p message.class
|
726
|
+
log(message)
|
727
|
+
end
|
728
|
+
|
729
|
+
def logfc(func_name)
|
730
|
+
# p func_name
|
731
|
+
# p "Function: " + func_name.to_s + ": " + self.class.to_s
|
732
|
+
message = "Function: " + func_name.to_s + ": complete :" + self.class.to_s
|
733
|
+
# p message.class
|
734
|
+
log(message)
|
735
|
+
end
|
736
|
+
|
737
|
+
def Log.logi(*messages)
|
738
|
+
return nil unless @@log_file
|
739
|
+
messages.each do |message|
|
740
|
+
File.open(@@log_file, 'a'){|file| file.puts message.inspect}
|
741
|
+
end
|
742
|
+
end
|
743
|
+
|
744
|
+
def logi(*messages)
|
745
|
+
return nil unless @@log_file
|
746
|
+
messages.each do |message|
|
747
|
+
File.open(@@log_file, 'a'){|file| file.puts message.inspect}
|
748
|
+
end
|
749
|
+
end
|
750
|
+
|
751
|
+
def logt
|
752
|
+
log("Traceback \n" + caller.join("\n"))
|
753
|
+
end
|
754
|
+
|
755
|
+
def Log.logt
|
756
|
+
log("Traceback \n" + caller.join("\n"))
|
757
|
+
end
|
758
|
+
|
759
|
+
def logd
|
760
|
+
log("Current Directory: " + Dir.pwd)
|
761
|
+
end
|
762
|
+
|
763
|
+
end
|
764
|
+
|
765
|
+
|
766
|
+
class Dir
|
767
|
+
|
768
|
+
def self.recursive_entries(dirct=Dir.pwd, hidden = false, toplevel=true)
|
769
|
+
found = []
|
770
|
+
# ep Dir.pwd
|
771
|
+
# ep Dir.entries.find_all{|file| File.directory? file}
|
772
|
+
chdir(dirct) do
|
773
|
+
# ep 'b'
|
774
|
+
entries(dirct).each do |file|
|
775
|
+
# ep 'c'
|
776
|
+
next if file =~ /^\./ and not hidden
|
777
|
+
found.push file
|
778
|
+
# ep file
|
779
|
+
next if [".", ".."].include? file
|
780
|
+
if FileTest.directory?(file)
|
781
|
+
# ep file, Dir.pwd, File.expand_path(file)
|
782
|
+
more = recursive_entries(File.expand_path(file), hidden, false)
|
783
|
+
found = found + more
|
784
|
+
end
|
785
|
+
end
|
786
|
+
end
|
787
|
+
return toplevel ? found.map{|f| dirct + '/' + f} : found.map{|f| File.basename(dirct) + '/' + f}
|
788
|
+
end
|
789
|
+
end
|
790
|
+
|
791
|
+
module FileUtils
|
792
|
+
|
793
|
+
# def self.tail(file_name, lines = 10, sep = $/)
|
794
|
+
# file = File.open(file_name, 'r')
|
795
|
+
# string = ""
|
796
|
+
# pos = -1
|
797
|
+
# n = 0
|
798
|
+
# size = file.stat.size
|
799
|
+
# # return string if size == 0
|
800
|
+
# while size > 0
|
801
|
+
# file.sysseek(pos, IO::SEEK_END)
|
802
|
+
# char = file.sysread(1)
|
803
|
+
# n+= 1 if char == sep
|
804
|
+
# break if n == lines + 1
|
805
|
+
# string = char + string
|
806
|
+
# break if pos == - size
|
807
|
+
# pos -= 1
|
808
|
+
# end
|
809
|
+
# file.close
|
810
|
+
# return string
|
811
|
+
# end
|
812
|
+
|
813
|
+
def self.tail(file_name, lines = 10, sep = $/)
|
814
|
+
if lines > 49 and sep == "\n" # The command line utility will be much faster
|
815
|
+
begin
|
816
|
+
return `tail -n #{lines} #{file_name}`
|
817
|
+
rescue => err #in case the command tail can't be found
|
818
|
+
# puts err
|
819
|
+
end
|
820
|
+
end
|
821
|
+
file = File.open(file_name, 'r')
|
822
|
+
string = ""
|
823
|
+
pos = -1
|
824
|
+
n = 0
|
825
|
+
size = file.stat.size
|
826
|
+
while size > 0
|
827
|
+
file.sysseek(size + pos)
|
828
|
+
char = file.sysread(1)
|
829
|
+
n+= 1 if char == sep and not pos == -1
|
830
|
+
break if n == lines
|
831
|
+
string = char + string
|
832
|
+
break if pos == - size
|
833
|
+
pos -= 1
|
834
|
+
end
|
835
|
+
file.close
|
836
|
+
return string
|
837
|
+
end
|
838
|
+
|
839
|
+
# def self.tail(file_name, lines = 10, sep = $/)
|
840
|
+
# file = File.open(file_name, 'r')
|
841
|
+
# string = ""
|
842
|
+
# pos = -1
|
843
|
+
# buffer_pos = 0
|
844
|
+
# n = 0
|
845
|
+
# size = file.stat.size
|
846
|
+
# # return string if size == 0
|
847
|
+
# buffer = ""
|
848
|
+
# # buffer_size = 0
|
849
|
+
# while size > 0
|
850
|
+
# if -pos > -buffer_pos
|
851
|
+
# incr = [size + buffer_pos, 1000].min
|
852
|
+
# buffer_pos -= incr
|
853
|
+
# file.sysseek(size + buffer_pos)
|
854
|
+
# buffer = file.sysread(incr) + buffer
|
855
|
+
# end
|
856
|
+
# char = buffer[pos, 1]
|
857
|
+
# n+= 1 if char == sep
|
858
|
+
# break if n == lines + 1
|
859
|
+
# string = char + string
|
860
|
+
# break if pos == - size
|
861
|
+
# pos -= 1
|
862
|
+
# end
|
863
|
+
# file.close
|
864
|
+
# return string
|
865
|
+
# end
|
866
|
+
|
867
|
+
end
|
868
|
+
|
869
|
+
class Class
|
870
|
+
def phoenix(file_name, &block)
|
871
|
+
if FileTest.exist? file_name
|
872
|
+
obj = eval(File.read(file_name), binding, file_name)
|
873
|
+
raise "Corrupt File: #{file_name}" unless obj.class == self
|
874
|
+
else
|
875
|
+
obj = new
|
876
|
+
obj.phoenix(file_name)
|
877
|
+
end
|
878
|
+
if block
|
879
|
+
yield(obj)
|
880
|
+
obj.phoenix(file_name)
|
881
|
+
else
|
882
|
+
return obj
|
883
|
+
end
|
884
|
+
end
|
885
|
+
end
|
886
|
+
|
887
|
+
class Object
|
888
|
+
def phoenix(file_name)
|
889
|
+
File.open(file_name, 'w'){|file| file.puts "# coding: utf-8"; file.puts self.pretty_inspect}
|
890
|
+
end
|
891
|
+
end
|
892
|
+
|
893
|
+
|
894
|
+
class Complex
|
895
|
+
# aliold :inspect
|
896
|
+
def inspect
|
897
|
+
return %[Complex(#{real},#{imag})]
|
898
|
+
end
|
899
|
+
end
|
900
|
+
|
901
|
+
class Integer
|
902
|
+
def to_sym
|
903
|
+
to_s.to_sym
|
904
|
+
end
|
905
|
+
end
|
906
|
+
|
907
|
+
module Math
|
908
|
+
def self.heaviside(num)
|
909
|
+
return 1.0 if num >= 0.0
|
910
|
+
return 0.0
|
911
|
+
end
|
912
|
+
end
|
913
|
+
|
914
|
+
module GoTo
|
915
|
+
STACK = []
|
916
|
+
|
917
|
+
|
918
|
+
class Label
|
919
|
+
attr_accessor :name;
|
920
|
+
attr_accessor :block;
|
921
|
+
|
922
|
+
def initialize(name, block);
|
923
|
+
@name = name
|
924
|
+
@block = block
|
925
|
+
end
|
926
|
+
|
927
|
+
def ==(sym)
|
928
|
+
@name == sym
|
929
|
+
end
|
930
|
+
end
|
931
|
+
|
932
|
+
class Goto < Exception;
|
933
|
+
attr_accessor :label
|
934
|
+
def initialize(label); @label = label; end
|
935
|
+
end
|
936
|
+
|
937
|
+
def label_goto(sym, &block)
|
938
|
+
STACK.last << Label.new(sym, block)
|
939
|
+
end
|
940
|
+
|
941
|
+
def frame_start_goto
|
942
|
+
STACK << []
|
943
|
+
end
|
944
|
+
|
945
|
+
def frame_end_goto
|
946
|
+
frame = STACK.pop
|
947
|
+
idx = 0
|
948
|
+
|
949
|
+
begin
|
950
|
+
for i in (idx...frame.size)
|
951
|
+
frame[i].block.call if frame[i].block
|
952
|
+
end
|
953
|
+
rescue Goto => g
|
954
|
+
idx = frame.index(g.label)
|
955
|
+
retry
|
956
|
+
end
|
957
|
+
end
|
958
|
+
|
959
|
+
def goto(label)
|
960
|
+
raise Goto.new(label)
|
961
|
+
end
|
962
|
+
|
963
|
+
end
|
964
|
+
|
965
|
+
if $is_main #testing and debugging
|
966
|
+
class Trial
|
967
|
+
class_accessor(:box)
|
968
|
+
attr_accessor :sweet
|
969
|
+
|
970
|
+
def initialize
|
971
|
+
@sweet = true
|
972
|
+
end
|
973
|
+
|
974
|
+
@@box = "chocs"
|
975
|
+
|
976
|
+
end
|
977
|
+
|
978
|
+
class Other
|
979
|
+
@@box = "to"
|
980
|
+
end
|
981
|
+
|
982
|
+
@bt = "hello"
|
983
|
+
|
984
|
+
p ({:a => :b} + {:c => :d})
|
985
|
+
puts Trial.class_variable_get(:box)
|
986
|
+
puts Trial.box
|
987
|
+
begin; puts Other.box; rescue; puts "That method should fail"; end
|
988
|
+
# puts Other.top
|
989
|
+
puts instance_variable_get("@bt")
|
990
|
+
puts Object.find_all_methods_like("alias_method")
|
991
|
+
# puts Object.find_all_methods_like("singleton_method")
|
992
|
+
|
993
|
+
# puts Kernel.global_variables.inspect
|
994
|
+
# puts Kernel.class_variable_get("$is_main")
|
995
|
+
|
996
|
+
@forks=[]
|
997
|
+
FileUtils.makedirs("temp")
|
998
|
+
5.times do |i|
|
999
|
+
@forks[i] = i.to_f
|
1000
|
+
puts @forks[i].object_id
|
1001
|
+
fork do
|
1002
|
+
100000.times{ @forks[i] *= 1.00001}
|
1003
|
+
File.open("temp/#{i}.msl", 'w'){|file| file.puts Marshal.dump(@forks[i])}
|
1004
|
+
end
|
1005
|
+
|
1006
|
+
end
|
1007
|
+
# Thread.list.each{|thr| thr.join unless thr==Thread.main}
|
1008
|
+
Process.waitall
|
1009
|
+
5.times{ |i| @forks[i] = Marshal.load(File.read("temp/#{i}.msl"))}
|
1010
|
+
p @forks
|
1011
|
+
a = Trial.new
|
1012
|
+
puts Marshal.dump(a)
|
1013
|
+
a.define_singleton_method(:alone){puts "I am a singleton"}
|
1014
|
+
begin
|
1015
|
+
puts Marshal.dump(a)
|
1016
|
+
rescue
|
1017
|
+
puts "You can't dump a singleton"
|
1018
|
+
end
|
1019
|
+
|
1020
|
+
|
1021
|
+
d = Trial.add_a_child_class("TrialChild", <<EOF
|
1022
|
+
|
1023
|
+
def hello
|
1024
|
+
puts "hello i am a TrialChild"
|
1025
|
+
end
|
1026
|
+
|
1027
|
+
EOF
|
1028
|
+
)
|
1029
|
+
|
1030
|
+
|
1031
|
+
ch = d.new
|
1032
|
+
ch.hello
|
1033
|
+
che = Trial::TrialChild.new
|
1034
|
+
che.hello
|
1035
|
+
puts che.sweet
|
1036
|
+
puts Trial.constants[0].class
|
1037
|
+
|
1038
|
+
module TrialMod
|
1039
|
+
def TrialMod.append_features(the_class)
|
1040
|
+
puts the_class.box
|
1041
|
+
def the_class.bricks
|
1042
|
+
puts "Build a wall"
|
1043
|
+
@@box = "bricks"
|
1044
|
+
end
|
1045
|
+
@@wall = "long"
|
1046
|
+
the_class.class_accessor(:mortar, :wall, :elephant)
|
1047
|
+
the_class.mortar = "cement"
|
1048
|
+
the_class.elephant = "wall-smasher"
|
1049
|
+
super
|
1050
|
+
end
|
1051
|
+
|
1052
|
+
|
1053
|
+
|
1054
|
+
def check_sweet
|
1055
|
+
@sweet = "bricks aren't sweet"
|
1056
|
+
puts @sweet
|
1057
|
+
end
|
1058
|
+
end
|
1059
|
+
|
1060
|
+
Trial.include(TrialMod)
|
1061
|
+
|
1062
|
+
Trial.bricks
|
1063
|
+
|
1064
|
+
puts Trial.mortar
|
1065
|
+
puts Trial.wall
|
1066
|
+
puts Trial.elephant
|
1067
|
+
|
1068
|
+
class DoubleJeopardy
|
1069
|
+
class_accessor(:box)
|
1070
|
+
@@box = "trunk"
|
1071
|
+
end
|
1072
|
+
|
1073
|
+
DoubleJeopardy.include(TrialMod)
|
1074
|
+
puts DoubleJeopardy.elephant
|
1075
|
+
DoubleJeopardy.elephant = "big grey"
|
1076
|
+
puts Trial.elephant
|
1077
|
+
puts Trial.box
|
1078
|
+
|
1079
|
+
a.check_sweet
|
1080
|
+
|
1081
|
+
puts :NotStarted =~ /N/
|
1082
|
+
|
1083
|
+
puts /a
|
1084
|
+
b/x.inspect.sub(/\A\//,'').sub(/\/[mix]\Z/,'')
|
1085
|
+
|
1086
|
+
puts /(?: \/ #comment
|
1087
|
+
)/x.verbatim
|
1088
|
+
|
1089
|
+
|
1090
|
+
# require 'pp'
|
1091
|
+
p Config::CONFIG['host']
|
1092
|
+
|
1093
|
+
puts Terminal.terminal_size
|
1094
|
+
|
1095
|
+
puts /(?<a>a)(?:\g<a>)/.match('aa')
|
1096
|
+
|
1097
|
+
puts "1.e-02".to_f
|
1098
|
+
|
1099
|
+
puts [].push(1).inspect
|
1100
|
+
|
1101
|
+
puts Float::EPSILON
|
1102
|
+
|
1103
|
+
puts "12.".to_f
|
1104
|
+
|
1105
|
+
puts "abc\nefg".grep(/a/)
|
1106
|
+
|
1107
|
+
begin
|
1108
|
+
raise '1'
|
1109
|
+
rescue
|
1110
|
+
begin
|
1111
|
+
raise '2'
|
1112
|
+
rescue
|
1113
|
+
puts "well that worked!"
|
1114
|
+
end
|
1115
|
+
end
|
1116
|
+
hash = {:a => :b, :c => :d}
|
1117
|
+
puts hash.find{|key, value| value == :d}.class
|
1118
|
+
|
1119
|
+
puts 0.23.class
|
1120
|
+
|
1121
|
+
a = FloatHash.new
|
1122
|
+
|
1123
|
+
a[0.123e06] = "right"
|
1124
|
+
a[0.12300001e06] = "wrong"
|
1125
|
+
puts a[0.1230000e06]
|
1126
|
+
a[0.231] = 0.789
|
1127
|
+
puts a.key(0.78900)
|
1128
|
+
# pp Object.objects
|
1129
|
+
|
1130
|
+
pp Object.find_all_methods_like "objects"
|
1131
|
+
|
1132
|
+
ObjectSpace.each_object do |obj|
|
1133
|
+
# pp obj
|
1134
|
+
end
|
1135
|
+
|
1136
|
+
puts ObjectSpace.class
|
1137
|
+
|
1138
|
+
puts ch.inspect
|
1139
|
+
|
1140
|
+
puts 1.class
|
1141
|
+
puts "12".to_i.class
|
1142
|
+
|
1143
|
+
qfr = Trial.add_a_child_class("TrialBaby", "")
|
1144
|
+
# qfr.box = "BigBigBox"
|
1145
|
+
puts Trial.box
|
1146
|
+
puts qfr.box
|
1147
|
+
|
1148
|
+
class Vartest
|
1149
|
+
# class_accessor :toy
|
1150
|
+
attr_accessor :marbles
|
1151
|
+
class Kid < Vartest
|
1152
|
+
class_accessor :toy
|
1153
|
+
@@toy = :balloon
|
1154
|
+
end
|
1155
|
+
class Kad < Vartest
|
1156
|
+
class_accessor :toy
|
1157
|
+
@@toy = :train
|
1158
|
+
end
|
1159
|
+
add_a_child_class("Boy", "class_accessor :toy; @@toy=:sword")
|
1160
|
+
add_a_child_class("Girl", "class_accessor :toy; @@toy=:boat")
|
1161
|
+
|
1162
|
+
def initialize
|
1163
|
+
@marbles = [:blue, :red, :green]
|
1164
|
+
end
|
1165
|
+
|
1166
|
+
def arrange_marbles(&block)
|
1167
|
+
yield(@marbles)
|
1168
|
+
end
|
1169
|
+
|
1170
|
+
def squeak
|
1171
|
+
puts 'Squeak!'
|
1172
|
+
end
|
1173
|
+
|
1174
|
+
end
|
1175
|
+
# Vartest.toy = :doll
|
1176
|
+
|
1177
|
+
puts Vartest::Kid.toy
|
1178
|
+
puts Vartest::Kad.toy
|
1179
|
+
puts Vartest::Boy.toy
|
1180
|
+
puts Vartest::Girl.toy
|
1181
|
+
|
1182
|
+
puts hash.size
|
1183
|
+
puts hash[hash.keys[rand(hash.size)]]
|
1184
|
+
puts hash.random
|
1185
|
+
|
1186
|
+
puts TrueClass.ancestors
|
1187
|
+
|
1188
|
+
p "asb".scan(/(d)?(s)(b)/)
|
1189
|
+
|
1190
|
+
p :gs2 =~ /\A[a-z_][a-z_\d]*\Z/
|
1191
|
+
|
1192
|
+
while true
|
1193
|
+
puts "swimming is good"
|
1194
|
+
break if true
|
1195
|
+
puts "not!"
|
1196
|
+
end
|
1197
|
+
|
1198
|
+
tim = Vartest.new
|
1199
|
+
|
1200
|
+
puts tim.marbles
|
1201
|
+
|
1202
|
+
|
1203
|
+
|
1204
|
+
tim.arrange_marbles do |marbles|
|
1205
|
+
marbles.sort!
|
1206
|
+
tim.squeak
|
1207
|
+
puts qfr.box
|
1208
|
+
end
|
1209
|
+
|
1210
|
+
puts tim.marbles
|
1211
|
+
|
1212
|
+
i = 0
|
1213
|
+
catch(:dd) do
|
1214
|
+
for i in 0..10
|
1215
|
+
throw(:dd) if i==2
|
1216
|
+
end
|
1217
|
+
end
|
1218
|
+
|
1219
|
+
puts i
|
1220
|
+
|
1221
|
+
puts (0...0).to_a.join(" ").inspect
|
1222
|
+
puts [:a, :b].slice(0...0).inspect
|
1223
|
+
|
1224
|
+
puts tim.class.ancestors.inspect
|
1225
|
+
|
1226
|
+
@mutex = Mutex.new
|
1227
|
+
|
1228
|
+
t2 = Thread.new do
|
1229
|
+
i = 0;
|
1230
|
+
loop do
|
1231
|
+
@mutex.synchronize{i+=1; puts "sleeping", i; sleep 0.2}; break if i==2;
|
1232
|
+
end
|
1233
|
+
sleep 0.1; puts "woken up"
|
1234
|
+
end
|
1235
|
+
|
1236
|
+
for i in 1..3
|
1237
|
+
@mutex.synchronize do
|
1238
|
+
puts 'waiting for the lazy thread'
|
1239
|
+
end
|
1240
|
+
sleep rand(0) / 10.0
|
1241
|
+
end
|
1242
|
+
puts 'thread has woken up'
|
1243
|
+
|
1244
|
+
t2.join
|
1245
|
+
|
1246
|
+
hash = {z: :b, y: :a}
|
1247
|
+
p hash.sort{|(k1,v1), (k2, v2)| k1<=>k2}
|
1248
|
+
|
1249
|
+
gs = GSL::Vector.alloc((0..10).to_a)
|
1250
|
+
puts gs.subvector(3, 5)
|
1251
|
+
g2 = GSL::Vector.alloc((1..11).to_a)
|
1252
|
+
m = GSL::Matrix.alloc(gs, g2)
|
1253
|
+
m.fprintf($stdout, "%e\t%e\t%e\t")
|
1254
|
+
m.transpose.to_a.each{|row| puts row.join("\t")}
|
1255
|
+
|
1256
|
+
p [2,3,4,5,3].pieces(4)
|
1257
|
+
end
|