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

From: keiju@...
Date: 1996-08-20 04:09:32 UTC
List: ruby-list #420
けいじゅ@SHLジャパンです. 

何か届いていないみたいなので, 再送します. 

In [ruby-list :00417 ] the message: "[ruby-list:417] Re: reexecute
from rescue [ Re: about exception ] ", on Aug/14 17:32(JST)
matz@caelum.co.jp (Yukihiro Matsumoto) writes:

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

例外を使わないで, 例えば以下のように定義するのはできるのですか?

array.delete(elm)
array.delete(elm) {
  ...
}

つまり, イテレータブロックがオプションになっているのですが...
array#sortができているのだからできるのでしょうね.  

ここで質問, このようなメソッドはどのように定義すれば良いのでしょうか? 

あと, 別件なのですが, 渡されたイテレータブロックをprocにすることはでき
ないのでしょうか? やりたいことは, イテレータブロックとして渡されたもの
を(procとして?)インスタンス変数に保持したいのですが??

>明示的に欲しいと言った時だけしか送ってくれない例外ですか?

私が考えていたのは, 今の例外は捕捉されないと結局exitしますよね. そうで
はなくて, 捕捉されなければそのまま処理を継続するようなものです.

シグナルの無視と同じだと思って下さい.

> それってトップレベルから現在の時点までにrescueがひとつでも指定されて
>いるかどうかで判定するんですか? それなら大変ですけど,実現は不可能で
>はないです.

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

例外を発行する側から, 今rescueがあるか調べる機能があればいいのかなあ..

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

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

逆にいえば, returnがしたければ, イテレータブロックが使えるように工夫し
ろということですね. わかりました.

>|>  retry
>イテレータの中で使われるとは
>
>  def WHILE(cond)
>     yield
>     retry unless cond
>  end
>
>が定義できるということです.retryでWHILEの呼出し時点まで戻る
>ので,WHILEの引数がもう一度評価されます.

なるほど, それが retry では, (1)から再実行されるということですね. 

>イテレータブロックで使われるとは
>  def foo(arg)
>    print arg, "\n"
>    yield
>  end
>  i=0
>  foo(i){i=12; retry if i == 0}
>が
>  0
>  12
>を出力することです.

バグってます. どうせ例を出すのなら,

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

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

が良いでしょう(^^;;

__
..........................................石塚 圭樹@SHLジャパン(株)...
------------->アドレス変わりました!! e-mail: keiju@shljapan.co.jp <----

In This Thread

Prev Next