In article [email protected],
Tanaka A. [email protected] writes:
e$B7OE}E*$KD4$Y$k5$$K$J$C$F!"%9%/%j%W%H$r=q$$$FD4$Y$F8+$^$7$?!#e(B
e$B$3$N%9%/%j%W%H$,4V0c$C$F$$$?$N$GD>$7$F!"$$$m$$$m$H9M$($F$_$^$7$?!#e(B
% ~/ruby/19/ruby/ruby block-wrapper.rb
…
{|*v|yield(*v)}: 1259/43956 2.86422786422786%
{|v|yield(v)}: 11945/43956 27.1749021749022%
{|*v|b.call(*v)}: 2463/43956 5.6033306033306%
{|v|b.call(v)}: 36199/43956 82.3528073528073%
{|*v|b.yield(*v)}: 1589/43956 3.61497861497861%
{|v|b.yield(v)}: 11910/43956 27.0952770952771%
% ~/ruby/18/ruby/ruby block-wrapper.rb
…
{|*v|yield(*v)}: 2332/29304 7.95795795795796%
{|v|yield(v)}: 7092/29304 24.2014742014742%
{|*v|b.call(*v)}: 2260/29304 7.71225771225771%
{|v|b.call(v)}: 14470/29304 49.3789243789244%
1.8 e$B$Ne(B {|*v|yield(*v)} e$B$GLse(B8% e$B$@$C$?<:GTN($,e(B 1.9
e$B$Ne(B
{|*v|yield(*v)} e$B$GLse(B3% e$B$K2<$,$C$F$$$k$N$G!"?t$H$7$F$O8:$C$Fe(B
e$B$$$^$9!#e(B
e$B$?$@!"e(Bpp.rb e$B$N<:GT$N$h$&$K!"8D!9$NNc$K$D$$$F$O0JA0$Oe(B wrapper
e$B$K$J$C$F$$$?$b$N$,e(B wrapper e$B$K$J$i$J$/$J$C$F$7$^$C$?$b$N$b$"e(B
e$B$j$^$9$+$i!"C1=c$K2~A1$H$O$$$($^$;$s!#e(B
e$B$H$$$&$+!"<:GT$7$?Nc$rHf$Y$F$_$k$H!“e(B1.9 e$B$G$N<:GT$O$9$Y$F<u$1e(B
e$BB&$N%V%m%C%/$,e(B {|v| … } e$B$H$$$&$R$H$D$NJQ?t$N%1!<%9$G$”$k$Ne(B
e$B$KBP$7!“e(B1.8 e$B$G$N<:GT$OA4$F$=$&$G$J$$e(B ({|| … }
e$B$HJQ?t$,$R$He(B
e$B$D$b$J$$$+e(B {|v1, v2| … } e$B$J$IJQ?t$,e(B 2e$B$D0J>e$”$ke(B)
e$B%1!<%9$Ge(B
e$B$9!#e(Bwrapper e$B$N4QE@$+$i8+$k$H!“2~A1$H$$$&$h$j$O!”$&$^$/$$$+$Je(B
e$B$$;E3]$1$+$i$d$C$Q$j$&$^$/$$$+$J$$B>$N;E3]$1$KJQ$o$C$?$H$$$&e(B
e$B0u>]$G$9!#e(B
e$B$=$7$F!“e(B1.9 e$B$Ge(B {|*v|yield(v)} e$B$H$$$&e(B wrapper
e$B$,$&$^$/$$$+$Je(B
e$B$$Nc$rD4$Y$F$$k$H!"$[$H$s$I$Oe(B b.call e$B$G%V%m%C%/$r8F$s$@>l9ge(B
e$B$G$9!#9M$($F$$k$H!“$3$l$Oe(B yield e$B$He(B call
e$B$N0c$$$r;H$C$F9)IWe(B
e$B$7$h$&$H$$$&J}?K$+$iG<F@$G$-$^$9!#e(Byield e$B$He(B call
e$B$O0c$&$N$G$9e(B
e$B$+$i!”$=$l$i$r6hJL$;$:$Ke(B yield e$B$GCf7Q$9$l$P$$+$7$J$3$H$K$Je(B
e$B$k$N$OA[A|$KFq$/$”$j$^$;$s!#e(B
e$B$^$?!“e(B{|*v|b.call(*v)} e$B$re(B wrapper
e$B$H$7$F;H$&$H!”$&$^$/$$$+$Je(B
e$B$$%1!<%9$O$9$Y$F$,e(B yield e$B$+e(B b.yield
e$B$G%V%m%C%/$r8F$s$@>l9g$Ge(B
e$B$9!#$3$l$bF1MM$K7o$NJ}?K$+$iG<F@$G$-$^$9!#e(B
e$B$3$3$G!"6=L#?<$$$N$O!“e(B{|*v|yield(*v)} e$B$N>l9g$K$O<:GT$Ne(B
e$B!V$[$H$s$I!W$,e(B b.call e$B$K4X$9$k$b$N$G$”$k$N$KBP$7!"e(B
{|*v|b.call(*v)} e$B$N>l9g$K$O<:GT$N!V$9$Y$F!W$,e(B yield e$B$He(B
b.yield e$B$K4X$9$k$b$N$@$H$$$&0c$$$G$9!#e(B
e$B$3$3$G5?Ld$,$"$k$N$G$9$,!"e(Byield e$B$re(B e$B8=:_$Ne(B 1.9 e$B$Ne(B
b.call e$B$NF0e(B
e$B:n$K$7$F$7$^$o$J$$$N$O$J$s$G$G$7$g$&e(B?
e$B$b$7$=$&$J$C$F$/$l$l$P!"8=:_$Ne(B ({|*v|b.call(*v)} e$B$G$N<:GT$Ne(B
e$B860x$Ne(B) yield/b.yield e$B$O$J$/$J$C$F!"40A4$KF0$/e(B wrapper
e$B$,<Be(B
e$B8=$G$-$k$N$G$9$,!#e(B
ARGS = [
#nil,
“”,
“v1”,
“v1,v2”,
“*v1”,
“v1,*v2”,
“v1,v2,*v3”,
#“v1,*v2,v3”,
#“*v1,v2”,
#“*v1,v2,v3”
]
YIELDS = %W[
yield
b.yield
b.call
]
VALUES = [
0,
[],
[0],
[[]],
[[0]],
[[[]]],
[0,0],
[0,[]],
[[],0],
[[],[]]
]
WRAPBLOCKS = [
“{|*v|yield(*v)}”,
“{|v|yield(v)}”,
“{|*v|b.call(*v)}”,
“{|v|b.call(v)}”,
“{|*v|b.yield(*v)}”,
“{|v|b.yield(v)}”,
]
unless lambda{}.respond_to? :yield
YIELDS.delete(“b.yield”)
WRAPBLOCKS.reject! {|b| /b.yield/ =~ b }
end
def calleeNN(vv) YIELD(ARGS) end
def callerNN(callee_name, *vs) send(callee_name, *vs) {|ARGS| …
} end
def callerNN(callee_name, *vs) send(callee_name, *vs, &lambda
{|ARGS| … }) end
def wrapperNN(callee_name, *vs) send(callee_name, *vs) WRAPBLOCK
end
CALLEE = []
def define_callee
name = “callee00”
ARGS.each {|as|
next if !as
vars = as.scan(/v\d/)
varsb = (vars+[‘&b’]).join(‘,’)
YIELDS.each {|y|
name.succ!
n = name.dup
eval “def #{n}(#{varsb}) #{y}(#{as}) end”
CALLEE << [n, [vars.length, “#{y}(#{as})”]]
}
}
end
define_callee
CALLER = []
def define_caller
name = “caller00”
ARGS.each {|as|
vars = as ? as.scan(/v\d/) : []
as = as ? “|#{as}|” : ‘’
name.succ!
n = name.dup
eval “def #{n}(callee_name, *vs) send(callee_name, *vs) {#{as}
[#{vars.join(‘,’)}] } end”
CALLER << [n, “{#{as}}”]
}
ARGS.each {|as|
vars = as ? as.scan(/v\d/) : []
as = as ? “|#{as}|” : ‘’
name.succ!
n = name.dup
eval “def #{n}(callee_name, *vs) send(callee_name, *vs, &lambda
{#{as} [#{vars.join(‘,’)}] }) end”
CALLER << [n, “&{#{as}}”]
}
end
define_caller
WRAPPER = []
def define_wrapper
name = “wrapper00”
WRAPBLOCKS.each {|w|
name.succ!
n = name.dup
w2 = w.sub(/|.*|/) { $& + “$wrapper_value = v;” }
eval “def #{n}(callee_name, *vs, &b) send(callee_name, *vs)
#{w2} end”
WRAPPER << [n, w]
}
end
define_wrapper
def perm(vs, n)
if n == 0
yield []
else
perm(vs, n-1) {|vv|
vs.each {|v| yield vv + [v] }
}
end
end
$VERBOSE = nil
def check(callee_name, callee_desc, wrapper_name, wrapper_desc,
caller_name, caller_desc, vs)
r1 = (send(caller_name, callee_name, *vs) rescue $!)
r2 = (send(caller_name, wrapper_name, callee_name, *vs) rescue $!)
wv = $wrapper_value
success = r1 == r2 || (r1.kind_of?(Exception) &&
r2.kind_of?(Exception) && r1.class == r2.class && r1.message ==
r2.message)
print(success ? “succ\t” : “fail\t”)
vs2 = vs.dup
cd = callee_desc.gsub(/v\d/) { vs2.shift.inspect }.gsub(/ /, ‘’)
wd = (wrapper_desc + ‘/’ + wv.inspect).gsub(/ /, ‘’)
r1 = r1.inspect.gsub(/ /, r1.kind_of?(Exception) ? ‘’ : ‘’)
r2 = r2.inspect.gsub(/ /, r2.kind_of?(Exception) ? '’ : ‘’)
print cd, “\t”
print wd, “\t”
print caller_desc, “\t”
print r1, “\t”
print r2, “\n”
success
end
count = {}
error = {}
WRAPPER.each {|wrapper_name, wrapper_desc|
count[wrapper_desc] = 0
error[wrapper_desc] = 0
CALLEE.each {|callee_name, (callee_arity, callee_desc)|
perm(VALUES, callee_arity) {|vs|
CALLER.each {|caller_name, caller_desc|
count[wrapper_desc] += 1
success = check(callee_name, callee_desc, wrapper_name,
wrapper_desc, caller_name, caller_desc, vs)
error[wrapper_desc] += 1 if !success
}
}
}
puts
}
WRAPPER.each {|wrapper_name, wrapper_desc|
c = count[wrapper_desc]
e = error[wrapper_desc]
puts “#{wrapper_desc}:\t#{e}/#{c}\t#{e*100.0/c}%”
}