[Feature #3627] catch$B$N%V%m%C%/$r:F<B9T$9$k%a%=%C%I(B

Feature #3627: catche$B$N%V%m%C%/$r:F<B9T$9$k%a%=%C%Ie(B
http://redmine.ruby-lang.org/issues/show/3627

e$B5/I<<Te(B: Makoto K.
e$B%9%F!<%?%9e(B: Open, e$BM%@hEYe(B: Low
e$B%+%F%4%je(B: core, Target version: 2.0

catche$B$He(Bthrowe$B$G!"%M%9%H$rHt$S1[$($?e(Bbreake$B$N$h$&$J$3$H$,$G$-$k$o$1$G$9$,!“F1MM$N%M%9%H$rHt$S1[$($?e(Bnexte$B$N$h$&$J$b$N!”$r8=:_$Ne(Brubye$B$G$d$k$N$O>/!9LLE]$G$9!#e(B
retrye$B$rMxMQ$7$F!"e(B

tag = Class.new Exception
begin
e$B!!e(B…
e$B!!e(Braise tag
e$B!!e(B…
rescue tag
e$B!!e(Bretry
end

e$B$H$$$&<j$b$J$$$G$O$“$j$^$;$s$,L5M}LpM}$C$]$$$G$9!#e(B
throwe$B$N$+$o$j$K!”$J$K$+JL$N%a%=%C%I!Je(Brewinde$B$H$$$&L>A0$O$I$&$G$7$g$&!)!K$r<B9T$9$k$H!“e(Bcatche$B$N%V%m%C%/$,:F<B9T$5$l$k!”$H$$$&$N$O$I$&$G$7$g$&$+!)e(B

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:41892] [Feature #3627]
catche$B$N%V%m%C%/$r:F<B9T$9$k%a%=%C%Ie(B”
on Thu, 29 Jul 2010 17:33:11 +0900, Makoto K.
[email protected] writes:

|throwe$B$N$+$o$j$K!"$J$K$+JL$N%a%=%C%I!Je(Brewinde$B$H$$$&L>A0$O$I$&$G$7$g$&!)!K$r<B9T$9$k$H!“e(Bcatche$B$N%V%m%C%/$,:F<B9T$5$l$k!”$H$$$&$N$O$I$&$G$7$g$&$+!)e(B

e$B4pK\E*$J%“%$%G%#%”$rH]Dj$9$k$o$1$G$O$"$j$^$;$s$,!"e(B

  • catche$B%V%m%C%/$N:F<B9T$,I,MW$J%f!<%9%1!<%9$,<($5$l$F$$$J$$e(B
  • rewinde$B$H$$$&L>A0$O$$$m$$$m$J$H$3$m$G;H$o$l$F$$$k$N$GK>$^e(B
    e$B$7$/$J$$e(B

e$B$N$G!"8=;~E@$G$O;?@.$7$^$;$s!#e(B

e$B$-$7$b$H$G$9e(B

|throwe$B$N$+$o$j$K!"$J$K$+JL$N%a%=%C%I!Je(Brewinde$B$H$$$&L>A0$O$I$&$G$7$g$&!)!K$r<B9T$9$k$H!“e(Bcatche$B$N%V%m%C%/$,:F<B9T$5$l$k!”$H$$$&$N$O$I$&$G$7$g$&$+!)e(B

e$B4pK\E*$J%"%$%G%#%"$rH]Dj$9$k$o$1$G$O$"$j$^$;$s$,!"e(B

  • catche$B%V%m%C%/$N:F<B9T$,I,MW$J%f!<%9%1!<%9$,<($5$l$F$$$J$$e(B
  • rewinde$B$H$$$&L>A0$O$$$m$$$m$J$H$3$m$G;H$o$l$F$$$k$N$GK>$^e(B
    e$B$7$/$J$$e(B

e$B$N$G!"8=;~E@$G$O;?@.$7$^$;$s!#e(B

e$B%f!<%9%1!<%9$G$9$,!"e(BThe Art of Multiprocessor Programming
e$B$N!"e(B
e$B%m%C%/%U%j!<%9%-%C%W%j%9%H$Ne(B find e$B%a%=%C%I!Je(BFig.
14.13e$B!K$re(B Ruby e$B$G=q$$$?e(B
e$B$b$N$r<($7$^$9!#!Je(Bbegin e$B$He(B rescue e$B$He(B retry
e$B$GF1Ey$N$b$N$r<BAu$7$F$$$^$9!#e(B
e$B85$Ne(B Java e$B%3!<%I$G$O%i%Y%kIU$-$Ne(B continue e$B$G$7$?!Ke(B

def find key, before_list, after_list
    retry_tag = Class.new Exception
    begin
        pp = nil
        p = @head
        @level_max.downto(0){|level|
            pp = p.links[level].get_link
            loop {
                ppp, mark = pp.links[level].get
                while mark do
                    snip = p.links[level].compare_and_set pp, ppp, 

false, false
unless snip then
raise retry_tag
end
pp = ppp
ppp, mark = pp.links[level].get
end
if pp.key.send(@cmp_op, key) == -1 then
p = pp
pp = ppp
else
break
end
}
before_list[level] = p
after_list[level] = pp
}
if pp.key.send(@cmp_op, key) == 0 then
pp
else
nil
end
rescue retry_tag
retry
end
end
private :find

e$B$^$?!"$7$P$i$/9M$($F$_$?$N$G$9$,!“e(BCe$B8@8l$Ge(B do { continue; }
while (0); e$B$,e(B
e$B%k!<%W$K$J$i$J$$$3$H$r9M$($k$H!”%G%U%)%k%H$G$Oe(B1e$B2s$-$j$N<B9T$,4|BT$5$l$F$$$ke(B
catch e$B$H$NAH$_9g$o$;$O$"$^$jNI$/$J$$$h$&$K;W$($F$-$^$7$?!#e(B

loop e$B$N%V%m%C%/$,0z?t$r<h$k$h$&$K$7$F!"e(B
loop {|tag|
e$B!!e(B…
e$B!!e(Bcontinue tag
e$B!!e(B…
}

e$B$H$$$&$+$?$A$G$O$I$&$G$7$g$&$+!)e(B

e$B$"$H!"L>A0$G$9$,!"e(Bcontinue e$B$NB>$Ke(B loop e$B$HBP$K$J$k$N$Ge(B
pool …e$B$H$$$&$N$Oe(B
e$B%@%a$G$9$MB?J,!#e(B

e$B$-$7$b$H$G$9e(B

e$B$3$s$J$N$G$O$I$&$G$7$g$&$+!#e(B

e$B$"$j$,$H$&$4$6$$$^$9!#e(B
while e$B$Ge(B catch
e$B$r0O$s$@$i!"$H$$$&%"%$%G%#%"$Oe(B%rubye$B$G$$$?$@$$$F$$$?$N$G$9$,!"e(B
e$B$&$^$/Cj>]2=$G$-$k$N$G$9$M!#e(B

e$B$J$+$@$G$9!#e(B

At Sat, 31 Jul 2010 19:06:51 +0900,
KISHIMOTO, Makoto wrote in [ruby-dev:41906]:

loop e$B$N%V%m%C%/$,0z?t$r<h$k$h$&$K$7$F!"e(B
loop {|tag|
e$B!!e(B…
e$B!!e(Bcontinue tag
e$B!!e(B…
}

e$B$H$$$&$+$?$A$G$O$I$&$G$7$g$&$+!)e(B

e$B$3$s$J$N$G$O$I$&$G$7$g$&$+!#e(B

class Loop
def loop
begin
t, val = catch(self) {
yield self
false
}
end while t
val
end
def next(*values)
Kernel.throw(self, [true, values])
end
def break(*values)
Kernel.throw(self, [false, values])
end
def self.loop(&block)
new.loop(&block)
end
end

i = 0
Loop.loop do |tag|
p(i += 1)
tag.next if i < 3
p “end”
tag.break
end

e$B%A%1%C%He(B #3627 e$B$,99?7$5$l$^$7$?!#e(B (by Shyouhei U.)

e$B%9%F!<%?%9e(B Opene$B$+$ie(BRejectede$B$KJQ99e(B

e$BDs0F;vBV$Oe(Brejecte$B$7$^$9$N$G$b$7?7$7$$%“%$%G%#%”$,$G$-$?$i$^$?EPO?$7$F$/$@$5$$!#e(B

http://redmine.ruby-lang.org/issues/show/3627