[#21225] Re: [ruby-cvs] ruby: * enum.c (inject_i): use rb_yield_values. — "U.Nakamura" <usa@...>

こんにちは、なかむら(う)です。

14 messages 2003/08/22
[#21227] Re: [ruby-cvs] ruby: * enum.c (inject_i): use rb_yield_values. — nobu.nakada@... 2003/08/22

なかだです。

[#21228] Re: [ruby-cvs] ruby: * enum.c (inject_i): use rb_yield_values. — matz@... (Yukihiro Matsumoto) 2003/08/22

まつもと ゆきひろです

[#21281] 大量メモリ消費攻撃に対する対応 — Hidetoshi NAGAI <nagai@...>

永井@知能.九工大です.

16 messages 2003/08/29
[#21285] Re: 大量メモリ消費攻撃に対する対応 — matz@... (Yukihiro Matsumoto) 2003/08/29

まつもと ゆきひろです

[#21288] Re: 大量メモリ消費攻撃に対する対応 — Hidetoshi NAGAI <nagai@...> 2003/08/29

永井@知能.九工大です.

[#21306] Re: 大量メモリ消費攻撃に対する対応 — matz@... (Yukihiro Matsumoto) 2003/09/03

まつもと ゆきひろです

[ruby-dev:21256] Re: [ruby-cvs] ruby: * enum.c (inject_i):userb_yield_values.

From: Koji Arai <JCA02266@...>
Date: 2003-08-24 21:51:19 UTC
List: ruby-dev #21256
新井です。

In message "[ruby-dev:21253] Re: [ruby-cvs] ruby: * enum.c (inject_i):userb_yield_values."
  on Sun, 24 Aug 2003 02:21:15 +0900,
  matz@ruby-lang.org (Yukihiro Matsumoto) wrote:
> まつもと ゆきひろです

> |簡単に言うとscanがブロックに何を渡すべきかです。
> |私の意見は
> |
> |  * 1個の配列([$1,$2..])
> |  * マッチした括弧の数だけの値(*[$1,$2..])
> |
> |のいずれかが望ましいのではないか、です。1.8では上記の二つは
> |違う意味を持っています。
> |
> |今、CVSでは後者になっています。
> 
> しかし、考えてみるとscanは
> 
>   * 括弧がある時には配列
>   * 括弧がない時には文字列
> 
> を渡すと言う仕様になっているので、やはり前者の方が望ましいよ
> うですね。この修正は元に戻します。この修正の発想の元はscanf
> だったのですが、括弧がない場合に相当するものがないscanfとは
> 違う発想が必要でした。
> 
> scanfの方はscanに合わせたいそうですので、結局1.8.0の仕様があ
> るべき仕様という結論になりそうです。難しいものだな。

うむむ。CVS「後者」版を試してみましたが、これは悩ましいです
ね。いずれにしても非互換になるわけだ。

"a".scan(/(.)/) {|*a| p a}

=> ruby 1.6.8 (2003-08-03) [i586-linux]
   ["a"]
=> ruby 1.8.0 (2003-08-04) [i586-linux]		<- 前者の非互換
   [["a"]]
=> ruby 1.8.0 (2003-08-24) [i586-linux]
   ["a"]


"a".scan(/(.)/) {|a| p a}
=> ruby 1.6.8 (2003-08-03) [i586-linux]
   ["a"]
=> ruby 1.8.0 (2003-08-04) [i586-linux]
   ["a"]
=> ruby 1.8.0 (2003-08-24) [i586-linux]
   "a"						<- 後者の非互換

この非互換への対処がいずれにしても必要になるわけですが、イテ
レータの実装側は複数のパラメータを渡す可能性のあるイテレータ
を実装する場合、二つの選択肢があります。

(1) yield ary
(2) yield *ary   (あるいは yield a,b,...)

(1) は、ブロックを書く側がパラメータを ary の要素数あるいは
一変数(var)で受けなければならないという制約があります。そう
しないと(*var で受けると)ary が一要素のとき var は配列にな
りません(配列の配列になります)。

(2) は、ブロックを書く側がパラメータを ary の要素数あるいは
*var で受けなければならないという制約があります。そうしない
と(var で受けると)ary が一要素のとき var は配列になりません。

なんと、イテレータ利用者にとってはどちらもあまり変わらないの
ですね。イテレータのあるべき仕様(配列を渡すか多値を渡すか)に
よってどちらが自然かを選ばなくてはいけません。

考えられる判断材料をいろいろと検討したのですが、決定的な一般
則を思い付くことができませんでした。

で、私見ですがなんとなく scan の場合は (2)の方が驚きがすくな
い気はします。ブロック利用者は一つの配列が欲しいのではなく、
複数の部分配列が欲しい(多値が基本)だと思うのです。
多値が基本で単値(配列)が欲しい場合は *var で受けなさいという
のは 1.6 から変わらない考え方だと思うからですが。

# 多値が基本かどうかは怪しいですが。

が、これはかなり感覚的な(しかも即席な)意見ですのであまりアテ
になりませんねえ。

# 実は、どちらも変わらないというのが真実なのではなかろうかと
# 思っているのですが、scanf の際に [["a"]] という結果は驚き
# が大きかったのは事実でして・・・

ところで上記とは逆に元に戻すこと自体は賛成です。中途半端な変
更は混乱を来すので。もう少し様子を見た方が良いでしょうね。

--
新井康司 (Koji Arai)

In This Thread

Prev Next