From: matz / netlab.co.jp (Yukihiro Matsumoto)
Subject: [ruby-dev:2739] Re: return value of iterator File.open and Dir.open
Date: Mon, 25 May 1998 13:04:53 +0900

> In message "[ruby-dev:2729] Re: return value of iterator File.open and Dir.open"
>     on 98/05/23, Inaba Hiroto <inaba / st.rim.or.jp> writes:

> |既存のiteratorとしても非iteratorとしても使えるbuiltin methodで、返り値
> |が違うものとしてEnumerable#grepとString#scanがあります。
> 
> なるほど,非常に説得力がありました.採用しましょう.^^;;;

:->

> |Enumerable#grep	grepの結果の配列		self
> |String#scan	マッチした配列(の配列)		nil 
> |
> |2つともiteratorの場合に返された値を積極的に使う事はあまり意図されては
> |いないようですが。
> 
> ところで,「意味のない場合の戻り値」はnilとselfの場合の両方
> があって統一されてませんですね.これは統一した方が良いのでしょ
> うか?

もし統一することにするならselfがいいような気がします。でも、「統一すべ
き」かどうかは、わかりません。

> |・instance_evalやmodule_evalと同じように、evalもイテレータとして使える
> |といいですね。前に提案した、ブロックを1回だけ実行するイテレータとして。
> 
> ええと,「ブロックを1回だけ実行するイテレータ」で良いのでし
> たら簡単ですが,それで良いんでしょうか.というのも文字列で与
> えるevalと「1回だけ実行するイテレータ」とでは初出のローカル
> 変数の挙動がかなり違うんですが.
> 
>   * 通常のeval - ローカル変数が定義され,スコープに追加され
>     る.次回のevalで参照できる
> 
>   * イテレータ - そのブロック内で初出のローカル変数はそのブ
>     ロックを抜けた時点で消え失せる

うーん、以下のような事ですね。

% ruby -le '
  eval "a = 123"
  eval "p a"'
123

これが以下だと

% ruby -le '
eval "a = 123"
p a'
-e:3: undefined local variable or method `a' for #<Object:0x808d110> (NameError)

とエラー(コンパイル時なんでしょうか?)になってしまう...  はい、違う事
はわかりました。とりあえず今は提案をひいて、ちょっと考えてみます。

> |・Array#deleteやHash#deleteにブロックを与えると削除しようとしたものが
> |なかった時ブロックを実行してます。今はnilを返してますが、この場合もイ
> |テレータの返り値をブロックの返す値にしても良いと思います。昔からある機
> |能だとしたら、非互換になるのでまずいかもしれませんが。
> 
> これはそうしようかなあ,と思います.反対の方は居ます?
> # みんな使ってなかったに違いない.

えっと、簡単に受け入れられるとは思ってなくて、書かなかったのですが、取
りいれてもらえるのなら、一応、書くだけ書いておこうと思います。

今、Hashの[]メソッドに別名として(例えば)fetchを使えるようにし、このメ
ソッドがイテレータとしてブロックを受け取れるようにし、これがHashの要素
がなかった時に実行されその値が返るとすると、豊福さんが書いておられたハッ
シュキーがなかった時のデフォルトが少し簡単に書けます。

#このやり方を豊福さんたちが好まれるかどうかわかりませんが。
--
			   稲葉 浩人 (inaba / st.rim.or.jp)