[ruby-list:417] Re: reexecute from rescue [ Re: about exception ]

From: matz@... (Yukihiro Matsumoto)
Date: 1996-08-14 08:32:44 UTC
List: ruby-list #417
まつもと ゆきひろです.

In message "[ruby-list:416] Re: reexecute from rescue [ Re: about exception ]"
    on 96/08/14, 石塚圭樹 <keiju@shljapan.co.jp> writes:
|
|けいじゅ@SHLジャパンです. 

|array#delete(elm)
|
|は, 無いよともいってくれませんが...

うむ,確かに.イテレータとして呼び出した時には無かった時にブ
ロックを評価するというのもひとつのアイディアですね.

|こういう時, デフォルトでは何もしないような例外があると便利ですね.

明示的に欲しいと言った時だけしか送ってくれない例外ですか? そ
れってトップレベルから現在の時点までにrescueがひとつでも指定
されているかどうかで判定するんですか? それなら大変ですけど,
実現は不可能ではないです.

でも,あまりやりたくないなあ.

|この種の例外は, 結局 resume の機能が必要になるような気がするので, 今の
|ままでは実現は不可能ですかね?

|イテレータブロックの場合は, retry と同じ動作を行なうわけですね.

あ,ちゃいます.図に書くと

  (1)
  def iter
     ...
     (2)
     yield
     (3)
     ...
  end
  (4)

  iter {
     # (A)
  }

Aの位置にbreak/next/redo/retryがあったとすると

  break		4
  next          3
  redo          2
  retry         1

の位置にジャンプすることになります.イテレータブロックの中か
ら見るとbreakとnext,redoとretryはあまり変わらない感じがあり
ますが,実際の動作は異なります.

|>  return
|>
|>    現在の関数の実行を終了する.トップレベルからはreturn出来
|>    ない(コンパイルエラーになる).lambdaの中からはreturnでき
|>    ない(実行時エラーになる).
|
|lambda の中からのreturnは, 状況によっては良いと思うのですが, 安全のた
|めにできないようになっているのですか?

安全のためというか,lamda(procオブジェクト)になった時点で現
在のコンテキストからは切り離されてしまうので,returnでどこに
戻ったら良いのか分からなくなるからです.

この辺がsmalltalkのブロックと違う所です.まあ,イテレータブ
ロックの中でreturnが呼びたければ,proc化しなければ良いことで
すし,このためにかなりパフォーマンスが上がっているはずなので,
許してください.

|>  retry

|>    イテレータの中で使われた時
|>    イテレータブロックで使われた時
|>
|>        イテレータの実行を(イテレータの引数の評価から)やり直す
|
|これってどういう意味ですか?

イテレータの中で使われるとは

  def WHILE(cond)
     yield
     retry unless cond
  end

が定義できるということです.retryでWHILEの呼出し時点まで戻る
ので,WHILEの引数がもう一度評価されます.

イテレータブロックで使われるとは

  def foo(arg)
    print arg, "\n"
    yield
  end

  i=0
  foo(i){i=12; retry if i == 0}

が

  0
  12

を出力することです.
                                まつもと ゆきひろ /:|)

In This Thread

Prev Next