[Bug #1198] corrupted iteratoin during "enum_for :inject"


#1

Bug #1198: corrupted iteratoin during “enum_for :inject”
http://redmine.ruby-lang.org/issues/show/1198

e$B5/I<<Te(B: Shyouhei U.
e$B%9%F!<%?%9e(B: Open, e$BM%@hEYe(B: Normal
e$B%+%F%4%je(B: core
ruby -v: ruby 1.9.2dev (2009-02-24 trunk 22589) [x86_64-linux]

e$B0J2<$N$h$&$K!"e(B1.8e$B$He(B1.9e$B$Ge(Benum_for(:inject)e$B$7$?$H$-$N?6$kIq$$$,0c$&$h$&$G$9!#e(B

zsh % ruby -ve ‘[:x].enum_for(:inject, :y).with_index {|*a| p a }’
ruby 1.8.7p5000 (2009-02-24 revision 22586) [x86_64-linux]
[[:y, :x], 0]

zsh % ruby -ve ‘[:x].enum_for(:inject, :y).with_index {|*a| p a }’
ruby 1.9.2dev (2009-02-24 trunk 22589) [x86_64-linux]
[:y, 0]


#2

e$B%A%1%C%He(B #1198 e$B$,99?7$5$l$^$7$?!#e(B (by Akinori MUSHA)

e$B%U%!%$%ke(B with_index-compat.patch e$BDI2Ce(B

e$B?6$kIq$$$,0c$&$N$Oe(B (each_)with_index e$B$NJ}$G$9!#e(B
1.9e$B$G$O!"%$%F%l!<%?4X?t$NBh0l0z?t$K$O:G=i$N0z?t$@$1$,EO$k$h$&$K$J$j!“e(B
e$BB?CM$r<h$j$?$1$l$PBh;0Bh;M0z?t$Ge(Bargc/argve$B$r8+$kI,MW$,$”$j$^$9!#e(B
e$B$3$NJQ99$KBP1~$9$kJQ99$,;$5$l$F$$$J$$$?$a!"$=$N$h$&$J5sF0$K$J$C$F$$$^$9!#e(B

e$BC1$Ke(B1.8e$B$HF1$8$h$&$K?6$kIq$o$;$k$?$a$K$OE:IU$N%Q%C%A$G$$$$$O$:$G$9!#e(B

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


#3

e$B%A%1%C%He(B #1198 e$B$,99?7$5$l$^$7$?!#e(B (by Akinori MUSHA)

e$B%U%!%$%ke(B with_index-incompat.patch e$BDI2Ce(B

e$B$?$@!"$3$N>l9gJ,$1$Oe(B1.9e$B$G@0M}$7$?C1CM!&B?CM$N07$$$N0l4S@-$rJx$9$3$H$K$b$J$k$N$Ge(B
e$B$b$&>/$79M$($?J}$,$$$$$H;W$$$^$9!#e(B

with_index-compat.patch e$B$NDL$j!"e(B1.8e$B$G$O!"e(B

  • yield() e$B$5$l$?$ie(B yield(nil, idx) e$B$9$ke(B
  • yield(single) e$B$5$l$?$ie(B yield(single, idx) e$B$9$ke(B
  • yield(*multiple) e$B$5$l$?$ie(B yield(multiple, idx) e$B$9$ke(B

e$B$H$$$&$$$S$D$J;EMM$G!“C1CM$+B?CM$+$rCN$C$F$$$J$$$H@5$7$$%3!<%I$,=q$1$J$$>l9g$,$”$j$^$9!#e(B

1.9e$B$G$Oe(B { |*args, idx| … } e$B$H<u$1<h$jJ}$,$G$-$k$N$G!"C1$Ke(B

  • yield(*any) e$B$5$l$?$ie(B yield(*any, idx) e$B$9$ke(B

e$B$H$$$&$9$C$-$j$7$?;EMM$KJQ99$9$k$H$$$&A*Br;h$b==J,$K9M$($i$l$^$9!#e(B

e$B8_49@-$,:GBg$N>c32$G$9$1$I$M!D!#e(B

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


#4

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

In message “Re: [ruby-dev:38076] [Bug #1198] corrupted iteratoin during
“enum_for :inject””
on Tue, 24 Feb 2009 19:29:44 +0900, Akinori MUSHA
removed_email_address@domain.invalid writes:

|e$B?6$kIq$$$,0c$&$N$Oe(B (each_)with_index e$B$NJ}$G$9!#e(B
|1.9e$B$G$O!"%$%F%l!<%?4X?t$NBh0l0z?t$K$O:G=i$N0z?t$@$1$,EO$k$h$&$K$J$j!“e(B
|e$BB?CM$r<h$j$?$1$l$PBh;0Bh;M0z?t$Ge(Bargc/argve$B$r8+$kI,MW$,$”$j$^$9!#e(B
|e$B$3$NJQ99$KBP1~$9$kJQ99$,;$5$l$F$$$J$$$?$a!"$=$N$h$&$J5sF0$K$J$C$F$$$^$9!#e(B
|
|e$BC1$Ke(B1.8e$B$HF1$8$h$&$K?6$kIq$o$;$k$?$a$K$OE:IU$N%Q%C%A$G$$$$$O$:$G$9!#e(B

e$B%3%_%C%H$7$F$/$@$5$$!#e(B


#5

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

In message “Re: [ruby-dev:38078] [Bug #1198] corrupted iteratoin during
“enum_for :inject””
on Tue, 24 Feb 2009 19:53:59 +0900, Akinori MUSHA
removed_email_address@domain.invalid writes:

|e$B%U%!%$%ke(B with_index-incompat.patch e$BDI2Ce(B
|
|e$B$?$@!"$3$N>l9gJ,$1$Oe(B1.9e$B$G@0M}$7$?C1CM!&B?CM$N07$$$N0l4S@-$rJx$9$3$H$K$b$J$k$N$Ge(B
|e$B$b$&>/$79M$($?J}$,$$$$$H;W$$$^$9!#e(B

e$B$&!<$`!#e(B

|1.9e$B$G$Oe(B { |*args, idx| … } e$B$H<u$1<h$jJ}$,$G$-$k$N$G!"C1$Ke(B
|
|- yield(*any) e$B$5$l$?$ie(B yield(any, idx) e$B$9$ke(B
|
|e$B$H$$$&$9$C$-$j$7$?;EMM$KJQ99$9$k$H$$$&A
Br;h$b==J,$K9M$($i$l$^$9!#e(B

e$B$J$k$[$I!#e(B

|e$B8_49@-$,:GBg$N>c32$G$9$1$I$M!D!#e(B

e$B$^$:8=:_$Ne(B1.9.1e$B$N5sF0$OL@$i$+$K%P%0$J$N$G=$@5$9$kI,MW$,$"$ke(B
e$B$H;W$$$^$9!#$=$l$r$I$NJ}8~$KD>$9$+$G$9$,!"$3$3$OHs8_49$G$b$9$Ce(B
e$B$-$j$7$?=$@5$NJ}$,K>$^$7$$$N$G$O$J$$$G$7$g$&$+!#e(B

e$BIp<T$5$s$,%3%_%C%H$5$l$^$9$+!)e(B

                            e$B$^$D$b$He(B e$B$f$-$R$me(B /:|)

#6

e$B%A%1%C%He(B #1198 e$B$,99?7$5$l$^$7$?!#e(B (by Akinori MUSHA)

e$B%9%F!<%?%9e(B Opene$B$+$ie(BClosede$B$KJQ99e(B
e$B?JD=e(B % 0e$B$+$ie(B100e$B$KJQ99e(B

Applied in changeset r22992.

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


#7

At Fri, 13 Mar 2009 19:47:54 +0900,
matz wrote:

|1.9では { |*args, idx| … } と受け取り方ができるので、単に
と思います。それをどの方向に直すかですが、ここは非互換でもすっ
きりした修正の方が望ましいのではないでしょうか。

 Enumerator#each_with_index については明らかなバグと言える挙動
だったのですが、 Enumerable#each_with_index は1.8と同じ仕様で
動いていたことがわかりました。

% ruby-1.9.1 -e ‘Enumerator.new{|y| y.yield(); y.yield(1); y.yield(1,2)
}.to_a.each_with_index {|*x| p x}’
[nil, 0]
[1, 1]
[[1, 2], 2]

この両者で挙動が食い違うわけにもいかないので、少なくとも1.9系列は
1.8仕様で行くしかなさそうです。

 ただし、 with_index のみ変えるというのはありかもしれません。
いや、そんな違いはわかりにくいからなしかな…。