alib 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/a.rb +12 -1
- data/{alib-0.4.0.gem → alib-0.5.0.gem} +0 -0
- data/lib/{alib-0.4.0.rb → alib-0.5.0.rb} +17 -40
- data/lib/alib-0.5.0/attributes-3.2.0.rb +54 -0
- data/lib/alib-0.5.0/attributes.rb +54 -0
- data/lib/{alib-0.4.0 → alib-0.5.0}/autohash.rb +0 -0
- data/lib/alib-0.5.0/binding_of_caller.rb +70 -0
- data/lib/{alib-0.4.0 → alib-0.5.0}/bsearch.rb +0 -0
- data/lib/alib-0.5.0/classmethods.rb +39 -0
- data/lib/{alib-0.4.0 → alib-0.5.0}/configfile.rb +0 -0
- data/lib/{alib-0.4.0 → alib-0.5.0}/find2.rb +0 -0
- data/lib/{alib-0.4.0 → alib-0.5.0}/listfile.rb +0 -0
- data/lib/{alib-0.4.0 → alib-0.5.0}/logging.rb +71 -7
- data/lib/{alib-0.4.0 → alib-0.5.0}/main.rb +416 -14
- data/lib/alib-0.5.0/main.rb.bak +1029 -0
- data/lib/alib-0.5.0/open4-0.9.1.rb +379 -0
- data/lib/alib-0.5.0/open4.rb +379 -0
- data/lib/{alib-0.4.0 → alib-0.5.0}/orderedautohash.rb +0 -0
- data/lib/{alib-0.4.0 → alib-0.5.0}/orderedhash.rb +0 -0
- data/lib/alib-0.5.0/prototype-0.3.0.rb +200 -0
- data/lib/alib-0.5.0/prototype.rb +200 -0
- data/lib/alib-0.5.0/stdext.rb +174 -0
- data/lib/{alib-0.4.0 → alib-0.5.0}/util.rb +452 -51
- data/lib/alib.rb +17 -40
- metadata +45 -32
- data/b.rb +0 -1
- data/build +0 -0
- data/install +0 -143
- data/lib/alib-0.4.0/open4.rb +0 -175
@@ -5,7 +5,8 @@
|
|
5
5
|
#
|
6
6
|
module ALib::Util
|
7
7
|
#--{{{
|
8
|
-
|
8
|
+
|
9
|
+
module Exporter
|
9
10
|
#--{{{
|
10
11
|
def export(*syms)
|
11
12
|
#--{{{
|
@@ -16,12 +17,23 @@ module ALib::Util
|
|
16
17
|
end
|
17
18
|
#--}}}
|
18
19
|
end
|
20
|
+
def self.included other
|
21
|
+
other.extend self
|
22
|
+
end
|
23
|
+
#--}}}
|
24
|
+
end
|
25
|
+
|
26
|
+
class << self
|
27
|
+
#--{{{
|
28
|
+
include Exporter
|
29
|
+
|
19
30
|
def append_features c
|
20
31
|
#--{{{
|
21
32
|
super
|
22
33
|
c.extend self
|
23
34
|
#--}}}
|
24
35
|
end
|
36
|
+
alias_method "included", "append_features"
|
25
37
|
#--}}}
|
26
38
|
end
|
27
39
|
#
|
@@ -482,9 +494,17 @@ module ALib::Util
|
|
482
494
|
def tmpnam(*argv)
|
483
495
|
#--{{{
|
484
496
|
args, opts = argv_split argv
|
485
|
-
dirname = argv.shift || getopt(%w(dir base prefix), opts, '.')
|
497
|
+
dirname = (argv.shift || getopt(%w(dir base prefix), opts, '.')).to_s
|
486
498
|
seed = getopt 'seed', opts, prognam
|
487
499
|
reap = getopt 'reap', opts, true
|
500
|
+
dot = getopt 'dot', opts, true
|
501
|
+
nodot = getopt 'nodot', opts, false
|
502
|
+
|
503
|
+
dot = false if nodot
|
504
|
+
|
505
|
+
#p 'nodot' => nodot
|
506
|
+
#p 'dot' => dot
|
507
|
+
#p dirname
|
488
508
|
|
489
509
|
dirname = File.expand_path dirname
|
490
510
|
|
@@ -493,16 +513,26 @@ module ALib::Util
|
|
493
513
|
|
494
514
|
if reap
|
495
515
|
begin
|
496
|
-
baseglob =
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
516
|
+
baseglob =
|
517
|
+
if nodot
|
518
|
+
"%s__*__*__*__%s" % [ host, seed ]
|
519
|
+
else
|
520
|
+
".%s__*__*__*__%s" % [ host, seed ]
|
521
|
+
end
|
522
|
+
host_re =
|
523
|
+
if nodot
|
524
|
+
%r/^#{ host }$/
|
525
|
+
else
|
526
|
+
%r/^\.#{ host }$/
|
527
|
+
end
|
528
|
+
g = File.join dirname, baseglob
|
529
|
+
Dir.glob(g).each do |candidate|
|
501
530
|
basename = File.basename candidate
|
502
531
|
parts = basename.split %r/__/, 5
|
503
532
|
if parts[0] =~ host_re
|
504
533
|
pid = Integer parts[1]
|
505
534
|
unless alive? pid
|
535
|
+
#STDERR.puts "FileUtils.rm_rf #{ candidate }"
|
506
536
|
FileUtils.rm_rf candidate
|
507
537
|
end
|
508
538
|
end
|
@@ -513,13 +543,23 @@ module ALib::Util
|
|
513
543
|
end
|
514
544
|
|
515
545
|
basename =
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
546
|
+
if nodot
|
547
|
+
"%s__%s__%s__%s__%s" % [
|
548
|
+
host,
|
549
|
+
Process::pid,
|
550
|
+
timestamp('nospace' => true),
|
551
|
+
rand,
|
552
|
+
seed,
|
553
|
+
]
|
554
|
+
else
|
555
|
+
".%s__%s__%s__%s__%s" % [
|
556
|
+
host,
|
557
|
+
Process::pid,
|
558
|
+
timestamp('nospace' => true),
|
559
|
+
rand,
|
560
|
+
seed,
|
561
|
+
]
|
562
|
+
end
|
523
563
|
|
524
564
|
File.join(dirname, basename)
|
525
565
|
#--}}}
|
@@ -754,7 +794,7 @@ module ALib::Util
|
|
754
794
|
#
|
755
795
|
def splitpath path
|
756
796
|
#--{{{
|
757
|
-
path =
|
797
|
+
path = path.to_s
|
758
798
|
dirname, basename = File::split path
|
759
799
|
[ dirname, (%r/^([^\.]*)(.*)$/).match(basename)[1,2] ].flatten
|
760
800
|
#--}}}
|
@@ -765,6 +805,7 @@ module ALib::Util
|
|
765
805
|
#
|
766
806
|
def unzipped path, z_pat = %r/\.(?:z|gz)$/io
|
767
807
|
#--{{{
|
808
|
+
path = path.to_s
|
768
809
|
zipped = zipped?(path, z_pat)
|
769
810
|
unless zipped
|
770
811
|
yield path
|
@@ -784,6 +825,7 @@ module ALib::Util
|
|
784
825
|
#
|
785
826
|
def zip path, z_ext = nil
|
786
827
|
#--{{{
|
828
|
+
path = path.to_s
|
787
829
|
z_ext ||= '.gz'
|
788
830
|
z_ext.gsub! %r/^\s*\.+/, '.'
|
789
831
|
spawn "gzip --suffix #{ z_ext } --force #{ path }"
|
@@ -804,6 +846,7 @@ module ALib::Util
|
|
804
846
|
#
|
805
847
|
def zipped_name path, z_ext = nil
|
806
848
|
#--{{{
|
849
|
+
path = path.to_s
|
807
850
|
z_ext ||= '.gz'
|
808
851
|
z_ext.gsub! %r/^\s*\.+/, '.'
|
809
852
|
"#{ path }#{ z_ext }"
|
@@ -815,6 +858,7 @@ module ALib::Util
|
|
815
858
|
#
|
816
859
|
def unzip path, z_pat = nil
|
817
860
|
#--{{{
|
861
|
+
path = path.to_s
|
818
862
|
z_pat ||= %r/\.(?:z|gz)$/io
|
819
863
|
spawn "gzip --force --decompress #{ path }" if zipped?(path, z_pat)
|
820
864
|
#spawn "gzip --force --decompress #{ path }"
|
@@ -834,6 +878,7 @@ module ALib::Util
|
|
834
878
|
#
|
835
879
|
def unzipped_name path, z_pat = nil
|
836
880
|
#--{{{
|
881
|
+
path = path.to_s
|
837
882
|
z_pat ||= %r/\.(?:z|gz)$/io
|
838
883
|
path.gsub z_pat, ''
|
839
884
|
#--}}}
|
@@ -844,6 +889,7 @@ module ALib::Util
|
|
844
889
|
#
|
845
890
|
def zipped? path, z_pat = %r/\.(?:z|gz)$/io
|
846
891
|
#--{{{
|
892
|
+
path = path.to_s
|
847
893
|
path =~ z_pat
|
848
894
|
#--}}}
|
849
895
|
end
|
@@ -938,12 +984,13 @@ module ALib::Util
|
|
938
984
|
loop do
|
939
985
|
changed = false
|
940
986
|
vars.each do |var, value|
|
987
|
+
var = var.to_s
|
941
988
|
var.gsub! %r/[^a-zA-Z0-9_]/, ''
|
942
989
|
[
|
943
990
|
%r/\$#{ var }\b/,
|
944
991
|
%r/\@#{ var }\b/,
|
945
|
-
%r
|
946
|
-
%r
|
992
|
+
%r/\$\{\s*#{ var }\s*\}/,
|
993
|
+
%r/\@\{\s*#{ var }\s*\}/
|
947
994
|
].each do |pat|
|
948
995
|
changed = string.gsub! pat, "#{ value }"
|
949
996
|
end
|
@@ -1008,30 +1055,46 @@ module ALib::Util
|
|
1008
1055
|
def parse_timespec spec
|
1009
1056
|
#--{{{
|
1010
1057
|
ret = nil
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1058
|
+
if((m = %r/^ (\d+(?:\.\d+)?) : (\d+(?:\.\d+)?) : (\d+(?:\.\d+)?) $/iox.match(spec.to_s)))
|
1059
|
+
m, h, m, s, ignored = m.to_a
|
1060
|
+
h, m, s = Float(h), Float(m), Float(s)
|
1061
|
+
#ret = h.hours + m.minutes + s.seconds
|
1062
|
+
ret = (h * 60 * 60) + (m * 60) + (s)
|
1063
|
+
else
|
1064
|
+
pat = %r/(\d+(?:\.\d+)?)\s*([sSmMhHdDwWyY][^\d]*)?/
|
1065
|
+
begin
|
1066
|
+
"#{ spec }".scan(pat) do |m|
|
1067
|
+
n = Float m[0]
|
1068
|
+
unit = m[1]
|
1069
|
+
if unit
|
1070
|
+
factor =
|
1071
|
+
case unit
|
1072
|
+
when %r/^m/i
|
1073
|
+
case unit
|
1074
|
+
when %r/^mo/i
|
1075
|
+
7 * (60 * 60 * 24)
|
1076
|
+
else
|
1077
|
+
60
|
1078
|
+
end
|
1079
|
+
when %r/^h/i
|
1080
|
+
60 * 60
|
1081
|
+
when %r/^d/i
|
1082
|
+
60 * 60 * 24
|
1083
|
+
when %r/^w/i
|
1084
|
+
7 * (60 * 60 * 24)
|
1085
|
+
when %r/^y/i
|
1086
|
+
365 * 7 * (60 * 60 * 24)
|
1087
|
+
else
|
1088
|
+
1
|
1089
|
+
end
|
1090
|
+
n *= factor
|
1091
|
+
end
|
1092
|
+
ret ||= 0.0
|
1093
|
+
ret += n
|
1029
1094
|
end
|
1030
|
-
|
1031
|
-
|
1095
|
+
rescue
|
1096
|
+
raise "bad time spec <#{ spec }>"
|
1032
1097
|
end
|
1033
|
-
rescue
|
1034
|
-
raise "bad time spec <#{ spec }>"
|
1035
1098
|
end
|
1036
1099
|
ret
|
1037
1100
|
#--}}}
|
@@ -1056,36 +1119,104 @@ module ALib::Util
|
|
1056
1119
|
end
|
1057
1120
|
export 'camel_case'
|
1058
1121
|
|
1059
|
-
def
|
1122
|
+
def __atomic_op op, src, dst, opts = {}
|
1060
1123
|
#--{{{
|
1061
1124
|
f, fu = File, FileUtils
|
1062
1125
|
src_dirname, src_basename = f.split src
|
1126
|
+
src_stat = File.stat src
|
1063
1127
|
|
1064
1128
|
dst = f.join dst, src_basename if test ?d, dst
|
1065
|
-
|
1066
1129
|
dst_dirname, dst_basename = f.split dst
|
1067
1130
|
|
1068
|
-
|
1131
|
+
pid = Process.pid
|
1132
|
+
tmp = f.join dst_dirname, ".#{ dst_basename }.#{ hostname }.#{ pid }.#{ rand(4242) }.alib.tmp"
|
1133
|
+
|
1134
|
+
timeout = getopt 'timeout', opts, 42
|
1135
|
+
utime = getopt 'utime', opts
|
1136
|
+
mtime = getopt 'mtime', opts
|
1137
|
+
atime = getopt 'atime', opts
|
1138
|
+
|
1139
|
+
safe_cp = lambda do |a, b|
|
1140
|
+
4.times do
|
1141
|
+
begin
|
1142
|
+
break(fu.cp_r(a, b, :preserve => true))
|
1143
|
+
rescue => e
|
1144
|
+
STDERR.puts(errmsg(e))
|
1145
|
+
uncache a rescue nil
|
1146
|
+
uncache b rescue nil
|
1147
|
+
sleep timeout
|
1148
|
+
end
|
1149
|
+
end
|
1150
|
+
end
|
1151
|
+
|
1152
|
+
safe_mv = lambda do |a, b|
|
1153
|
+
4.times do
|
1154
|
+
begin
|
1155
|
+
break(fu.mv(a, b))
|
1156
|
+
rescue => e
|
1157
|
+
STDERR.puts(errmsg(e))
|
1158
|
+
uncache a rescue nil
|
1159
|
+
uncache b rescue nil
|
1160
|
+
sleep timeout
|
1161
|
+
end
|
1162
|
+
end
|
1163
|
+
end
|
1164
|
+
|
1165
|
+
safe_rm = lambda do |a|
|
1166
|
+
4.times do
|
1167
|
+
begin
|
1168
|
+
break(fu.rm_rf(a))
|
1169
|
+
rescue => e
|
1170
|
+
STDERR.puts(errmsg(e))
|
1171
|
+
uncache a rescue nil
|
1172
|
+
sleep timeout
|
1173
|
+
end
|
1174
|
+
end
|
1175
|
+
end
|
1069
1176
|
|
1070
1177
|
begin
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1178
|
+
case op
|
1179
|
+
when 'cp'
|
1180
|
+
safe_cp[src, tmp]
|
1181
|
+
safe_mv[tmp, dst]
|
1182
|
+
when 'mv'
|
1183
|
+
safe_cp[src, tmp]
|
1184
|
+
safe_mv[tmp, dst]
|
1185
|
+
safe_rm[src]
|
1186
|
+
else
|
1187
|
+
raise ArgumentError, op.to_s
|
1079
1188
|
end
|
1080
1189
|
ensure
|
1081
|
-
|
1190
|
+
safe_rm[tmp]
|
1191
|
+
end
|
1192
|
+
|
1193
|
+
if utime or mtime or atime
|
1194
|
+
a = (atime or utime or src_stat.atime)
|
1195
|
+
m = (mtime or utime or src_stat.mtime)
|
1196
|
+
a = src_stat.atime unless Time === a
|
1197
|
+
m = src_stat.mtime unless Time === m
|
1198
|
+
ALib::Util::find(dst){|e| File.utime a, m, e}
|
1082
1199
|
end
|
1083
1200
|
|
1084
1201
|
dst
|
1085
1202
|
#--}}}
|
1086
1203
|
end
|
1204
|
+
export '__atomic_op'
|
1205
|
+
|
1206
|
+
def atomic_copy src, dst, opts = {}
|
1207
|
+
__atomic_op 'cp', src, dst, opts
|
1208
|
+
end
|
1209
|
+
alias_method "atomic_cp", "atomic_copy"
|
1210
|
+
export 'atomic_cp'
|
1087
1211
|
export 'atomic_copy'
|
1088
1212
|
|
1213
|
+
def atomic_move src, dst, opts = {}
|
1214
|
+
__atomic_op 'mv', src, dst, opts
|
1215
|
+
end
|
1216
|
+
alias_method "atomic_mv", "atomic_move"
|
1217
|
+
export 'atomic_mv'
|
1218
|
+
export 'atomic_move'
|
1219
|
+
|
1089
1220
|
def child_object
|
1090
1221
|
#--{{{
|
1091
1222
|
r, w = IO.pipe
|
@@ -1163,5 +1294,275 @@ module ALib::Util
|
|
1163
1294
|
export '#{ m }'
|
1164
1295
|
code
|
1165
1296
|
end
|
1297
|
+
|
1298
|
+
#
|
1299
|
+
# setup lspawn method/state
|
1300
|
+
#
|
1301
|
+
#--{{{
|
1302
|
+
__cmdno = 0 # static var
|
1303
|
+
|
1304
|
+
__c = Class.new{
|
1305
|
+
def initialize io, prefix
|
1306
|
+
@io, @prefix = io, prefix
|
1307
|
+
end
|
1308
|
+
def << buf
|
1309
|
+
@io << "#{ @prefix }__ "
|
1310
|
+
@io << buf
|
1311
|
+
end
|
1312
|
+
}
|
1313
|
+
|
1314
|
+
__logger = lambda{|io, prefix| __c.new io, prefix}
|
1315
|
+
|
1316
|
+
__lspawn = lambda do |cmd, *a|
|
1317
|
+
begin
|
1318
|
+
Thread.critical = true
|
1319
|
+
log = a.shift
|
1320
|
+
log = (logger rescue (@logger || Logger.new(STDERR)))
|
1321
|
+
|
1322
|
+
stdout = __logger[STDOUT, :o]
|
1323
|
+
stderr = __logger[STDERR, :e]
|
1324
|
+
|
1325
|
+
log.info{ "cmd[#{ __cmdno }] <#{ cmd }>" }
|
1326
|
+
|
1327
|
+
status = Alib::Util::spawn(cmd, 'quiet'=>true, 'raise'=>false, 'stdout'=>stdout, 'stderr'=>stderr)
|
1328
|
+
|
1329
|
+
if status and status == 0
|
1330
|
+
log.info{ "status[#{ __cmdno }] <#{ status }>" }
|
1331
|
+
else
|
1332
|
+
log.warn{ "status[#{ __cmdno }] <#{ status || 127 }>" }
|
1333
|
+
end
|
1334
|
+
|
1335
|
+
if status and status.signaled?
|
1336
|
+
if status.termsig
|
1337
|
+
log.warn{ "termsig[#{ __cmdno }] <#{ status.termsig }>" }
|
1338
|
+
end
|
1339
|
+
if status.stopsig
|
1340
|
+
log.warn{ "stopsig[#{ __cmdno }] <#{ status.stopsig }>" }
|
1341
|
+
end
|
1342
|
+
end
|
1343
|
+
|
1344
|
+
status ? status.exitstatus : 127
|
1345
|
+
ensure
|
1346
|
+
__cmdno += 1
|
1347
|
+
Thread.critical = false
|
1348
|
+
end
|
1349
|
+
end
|
1350
|
+
|
1351
|
+
define_method 'lspawn', &__lspawn
|
1352
|
+
|
1353
|
+
LSPAWN_CMDNO = [0]
|
1354
|
+
LSPAWN_LOG = Hash.new{|h,k| h[k] = alib.logging.default_logger}
|
1355
|
+
LSPAWN_IO = Class.new do
|
1356
|
+
def initialize log, prefix, io
|
1357
|
+
@log, @prefix, @io = log, prefix, io
|
1358
|
+
end
|
1359
|
+
def << buf
|
1360
|
+
@log << " #{ @prefix }__ #{ buf.chomp }\n"
|
1361
|
+
#@log << "#{ buf.chomp }\n"
|
1362
|
+
@io << buf if @io
|
1363
|
+
end
|
1364
|
+
end
|
1365
|
+
#--}}}
|
1366
|
+
|
1367
|
+
def lspawn cmd, opts = {}
|
1368
|
+
#--{{{
|
1369
|
+
begin
|
1370
|
+
Thread.critical = true
|
1371
|
+
|
1372
|
+
stdin = ALib::Util::getopt ['stdin', 'i', 'in', '0', 0], opts
|
1373
|
+
stdout = ALib::Util::getopt ['stdout', 'o', 'out', '1', 1], opts
|
1374
|
+
stderr = ALib::Util::getopt ['stderr', 'e', 'err', '2', 2], opts
|
1375
|
+
expect = ALib::Util::getopt ['expect', 'status', 'success'], opts, 0
|
1376
|
+
log = Alib::Util::getopt ['logger', 'log'], opts
|
1377
|
+
|
1378
|
+
log ||= (self.logger rescue (defined?(@logger) ? @logger : LSPAWN_LOG[0]))
|
1379
|
+
|
1380
|
+
stdout = LSPAWN_IO.new log, :o, stdout
|
1381
|
+
stderr = LSPAWN_IO.new log, :e, stderr
|
1382
|
+
|
1383
|
+
cmdno = LSPAWN_CMDNO[0]
|
1384
|
+
|
1385
|
+
log.info{ "cmd[#{ cmdno }] <#{ cmd }>" }
|
1386
|
+
|
1387
|
+
status = Alib::Util::spawn(cmd, 'quiet'=>true, 'raise'=>false, 'stdin'=>stdin, 'stdout'=>stdout, 'stderr'=>stderr)
|
1388
|
+
|
1389
|
+
exitstatus = ( (status ? (status.exitstatus || 127) : 127) rescue 127 )
|
1390
|
+
|
1391
|
+
log.send(exitstatus == 0 ? 'info' : 'warn'){ "status[#{ cmdno }] <#{ exitstatus }>" }
|
1392
|
+
|
1393
|
+
if expect
|
1394
|
+
codes = [*expect].flatten.compact.map{|code| Integer code}
|
1395
|
+
success = codes.detect{|code| exitstatus == code}
|
1396
|
+
unless success
|
1397
|
+
log.fatal{ "cmd[#{ cmdno }] failure" }
|
1398
|
+
exit exitstatus
|
1399
|
+
end
|
1400
|
+
end
|
1401
|
+
|
1402
|
+
if status and status.signaled?
|
1403
|
+
if status.termsig
|
1404
|
+
log.warn{ "termsig[#{ cmdno }] <#{ status.termsig }>" }
|
1405
|
+
end
|
1406
|
+
if status.stopsig
|
1407
|
+
log.warn{ "stopsig[#{ cmdno }] <#{ status.stopsig }>" }
|
1408
|
+
end
|
1409
|
+
end
|
1410
|
+
|
1411
|
+
exitstatus
|
1412
|
+
ensure
|
1413
|
+
LSPAWN_CMDNO[0] = LSPAWN_CMDNO[0] + 1
|
1414
|
+
Thread.critical = false
|
1415
|
+
end
|
1416
|
+
#--}}}
|
1417
|
+
end
|
1418
|
+
export 'lspawn'
|
1419
|
+
|
1420
|
+
def sweep hash
|
1421
|
+
#--{{{
|
1422
|
+
srcdir, dstdir, ignored = hash.to_a.first
|
1423
|
+
Dir.glob(File.join(srcdir, '*')) do |src|
|
1424
|
+
dirname, basename = File.split src
|
1425
|
+
dst = File.join dstdir, basename
|
1426
|
+
FileUtils.mv src, dst
|
1427
|
+
end
|
1428
|
+
#--}}}
|
1429
|
+
end
|
1430
|
+
export 'sweep'
|
1431
|
+
|
1432
|
+
|
1433
|
+
def threadify list, n = 4, &b
|
1434
|
+
#--{{{
|
1435
|
+
n = Integer n
|
1436
|
+
done = Object.new.freeze
|
1437
|
+
jobs = Queue.new
|
1438
|
+
|
1439
|
+
list.each_with_index{|elem, i| jobs.push [elem, i]}
|
1440
|
+
n.times{ jobs.push done} # mark the end
|
1441
|
+
|
1442
|
+
consumers = Array.new n
|
1443
|
+
|
1444
|
+
n.times do |i|
|
1445
|
+
consumers[i] = Thread.new do
|
1446
|
+
this = Thread.current
|
1447
|
+
this.abort_on_exception = true
|
1448
|
+
|
1449
|
+
loop{
|
1450
|
+
job = jobs.pop
|
1451
|
+
this.exit if job == done
|
1452
|
+
jobs << (job << bcall(b, job))
|
1453
|
+
}
|
1454
|
+
end
|
1455
|
+
end
|
1456
|
+
|
1457
|
+
consumers.map{|t| t.join}
|
1458
|
+
jobs.push done
|
1459
|
+
|
1460
|
+
#sleep 5
|
1461
|
+
|
1462
|
+
ret = Array.new list.size
|
1463
|
+
while((job = jobs.pop) != done)
|
1464
|
+
elem, i, value = job
|
1465
|
+
ret[i] = value
|
1466
|
+
end
|
1467
|
+
ret
|
1468
|
+
#--}}}
|
1469
|
+
end
|
1470
|
+
export 'threadify'
|
1471
|
+
|
1472
|
+
def block_argv b, argv
|
1473
|
+
#--{{{
|
1474
|
+
arity = b.arity
|
1475
|
+
if arity >= 0
|
1476
|
+
argv[0,arity]
|
1477
|
+
else
|
1478
|
+
head = []
|
1479
|
+
tail = []
|
1480
|
+
n = arity.abs - 1
|
1481
|
+
head = argv[0...n]
|
1482
|
+
tail = argv[n..-1]
|
1483
|
+
[*(head + tail)]
|
1484
|
+
end
|
1485
|
+
#--}}}
|
1486
|
+
end
|
1487
|
+
export 'block_argv'
|
1488
|
+
|
1489
|
+
def bcall b, argv
|
1490
|
+
#--{{{
|
1491
|
+
a = block_argv b, argv
|
1492
|
+
b[*a]
|
1493
|
+
#--}}}
|
1494
|
+
end
|
1495
|
+
export 'bcall'
|
1496
|
+
|
1497
|
+
#
|
1498
|
+
# casting methods
|
1499
|
+
#
|
1500
|
+
module Casting
|
1501
|
+
#--{{{
|
1502
|
+
include Exporter
|
1503
|
+
|
1504
|
+
def int_list *list
|
1505
|
+
#--{{{
|
1506
|
+
list.flatten.compact.map{|i| Util.atoi i}
|
1507
|
+
#--}}}
|
1508
|
+
end
|
1509
|
+
def float_list *list
|
1510
|
+
#--{{{
|
1511
|
+
list.flatten.compact.map{|f| Float f}
|
1512
|
+
#--}}}
|
1513
|
+
end
|
1514
|
+
def string_list *list
|
1515
|
+
#--{{{
|
1516
|
+
list.flatten.compact.map{|s| String s}
|
1517
|
+
#--}}}
|
1518
|
+
end
|
1519
|
+
def string_cast arg
|
1520
|
+
arg.to_s
|
1521
|
+
end
|
1522
|
+
def int_cast arg
|
1523
|
+
Integer arg.to_s
|
1524
|
+
end
|
1525
|
+
def float_cast arg
|
1526
|
+
Float arg
|
1527
|
+
end
|
1528
|
+
def bool_cast arg
|
1529
|
+
arg ? true : false
|
1530
|
+
end
|
1531
|
+
def bool_cast arg
|
1532
|
+
case arg
|
1533
|
+
when Numeric
|
1534
|
+
not arg.zero?
|
1535
|
+
when String
|
1536
|
+
case arg
|
1537
|
+
when %r/^(1|t|true)$/i
|
1538
|
+
true
|
1539
|
+
when %r/^(0|f|false)$/i
|
1540
|
+
false
|
1541
|
+
else
|
1542
|
+
raise ArgumentError, arg.inspect
|
1543
|
+
end
|
1544
|
+
else
|
1545
|
+
arg ? true : false
|
1546
|
+
end
|
1547
|
+
end
|
1548
|
+
def re_cast arg
|
1549
|
+
Regexp === arg ? arg : %r/#{ arg }/
|
1550
|
+
end
|
1551
|
+
def pathname_cast arg, opts = {}
|
1552
|
+
expand = opts['expand'] || opts[:expand]
|
1553
|
+
pn = (Pathname === arg ? arg : Pathname.new(arg.to_s))
|
1554
|
+
expand ? pn.expand_path : pn
|
1555
|
+
end
|
1556
|
+
|
1557
|
+
instance_methods.each{|m| export m}
|
1558
|
+
#--}}}
|
1559
|
+
end
|
1560
|
+
|
1561
|
+
# dump methods into Util
|
1562
|
+
include Casting
|
1563
|
+
Casting.instance_methods.each{|m| export m}
|
1564
|
+
|
1565
|
+
def self.casting() Casting end
|
1566
|
+
|
1166
1567
|
#--}}}
|
1167
1568
|
end # module Util
|