From: matz@... (Yukihiro Matsumoto) Date: 1997-07-04T23:50:29+09:00 Subject: [ruby-list:3282] exceptions (Re: Ver 1.1 [Re: Matrix]) まつもと ゆきひろです In message "[ruby-list:3280] Re: Ver 1.1 [Re: Matrix]" on 97/07/04, 石塚圭樹 writes: |けいじゅ@今はフリー(^^;;;です. |マクロは, 関数呼出側のコンテキストで処理を進めるところに意味があると思 |うのですが, マクロではなくてもいいのでそういう機能をrubyで付加すること |はできないですかねえ? つまり, 呼出側のbindingを呼び出され側で参照する |ことができると色々便利なのですが... そうすると, マクロはなくても同等な |機能を通常の関数で実現できる(苦労のレベルは別として)と思うのですが, い |かがでしょう? わたしはC Hackerですから,Cのマクロで考えると,マクロの使い 道としては (a) 定数定義 (b) インライン関数の代わり (c) 引数に対する副作用のある関数定義 (d) 制御構造の拡張 があるように感じます.で,aについてはrubyには専用の定数があ りますから,それを使ってもらうことにしましょう.bはrubyのよ うなインタプリタ言語でインラインまでして高速化することが意味 があるようには思えませんから,普通のメソッドを使ってください, ということにしましょう.cは多重代入による複数の戻り値で我慢 してもらうしかないですね. 問題はdですが,これはいくつかのパターンに分類できると思うの ですが,個人的な印象ではほとんどの場合は,イテレータで解消で きるものが多いのではないかと思います.イテレータによって自分 のコンテキストを他の関数に渡せますから,そのことによって制御 構造の拡張が可能になるのではないかと思います. そうでない場合のほとんど(Cなら#や##を使う場面)はevalを使うこ とでなんとかなると思います. で,石塚さんの提案はtclのupvar相当のものをrubyに,ということ でした.便利であろうことは確かなのですが,若干抵抗があります. * これがあると任意のメソッドを呼び出すことでローカル変数の 値が変わってしまうことがありえる * 「普通の言語」にはそんな機能はない * 現在のインタプリタの実装ではupvarを実装するのはちょっと 大変(呼び出し元のコンテキストへのポインタを保存していな いので) もちろん,前二つはいいわけで,一番問題なのは最後なんですけど ^^;;; というわけですぐに採用というわけにはいかないのですが,次の方 法が使えるのではないかと思います. 1. 問題のメソッドをイテレータとして呼び出してもらう 2. Proc.newを使ってイテレータブロックをProc化する 3. Procはbindingとしても使えるのでそれをeval()の第2引数に する いかがでしょう? イテレータブロックは空でも構いません. |ついでに要望を: |メタプログラミング(rubyのクラスやメソッドを定義するようなプログラム)を |サポートしてくれる機能をもっと充実してくれるとありがたいなぁと最近思う |ようになってきました. 前にもそういう話が出てそのままになっていますよね.メタプログ ラミング系が弱いのはPythonと比べた弱点と言っても良いと思いま すが,なかなかよいインタフェースが思い付かないまま現状に至っ ています.pythonのように__dict__とかで現在のネームスペースを 直接見せられるような単純な実装になっていないんですよね. そういうものを作ることに反対しているわけではないので,また提 案してみてください. |ところで, $@ が設定された状態で, 引数付きfailを行った場合, $@に今回の |例外と位置が追加されるのですか? それとも最計算される? 引数つきfailを使うと$!, $@の値は再設定されます.$!,$@の値を 操作したい場合には必ず引数なしで呼んでください. まつもと ゆきひろ /:|)