[#18651] Enumerable#zip — matz@... (Yukihiro Matsumoto)

まつもと ゆきひろです

77 messages 2002/11/05
[#18659] Re: Enumerable#zip — Shin-ichiro HARA <sinara@...> 2002/11/06

原です。

[#18669] Re: Enumerable#zip — matz@... (Yukihiro Matsumoto) 2002/11/06

まつもと ゆきひろです

[#18675] Re: Enumerable#zip — Shin-ichiro HARA <sinara@...> 2002/11/07

原です。

[#18684] Re: Enumerable#zip — matz@... (Yukihiro Matsumoto) 2002/11/07

まつもと ゆきひろです

[#18690] Re: Enumerable#zip — Shin-ichiro HARA <sinara@...> 2002/11/08

原です。

[#18692] Re: Enumerable#zip — Tanaka Akira <akr@...17n.org> 2002/11/08

In article <4.3.2-J.20021108124934.033a2eb0@blade.nagaokaut.ac.jp>,

[#18696] Re: Enumerable#zip — Shin-ichiro HARA <sinara@...> 2002/11/08

原です。

[#18713] Re: Enumerable#zip — matz@... (Yukihiro Matsumoto) 2002/11/09

まつもと ゆきひろです

[#18719] Re: Enumerable#zip — Tanaka Akira <akr@...17n.org> 2002/11/09

In article <1036742681.769607.13070.nullmailer@picachu.netlab.jp>,

[#18721] Re: Enumerable#zip — matz@... (Yukihiro Matsumoto) 2002/11/09

まつもと ゆきひろです

[#18723] Re: Enumerable#zip — Tanaka Akira <akr@...17n.org> 2002/11/09

In article <1036847474.074389.7942.nullmailer@picachu.netlab.jp>,

[#18735] Re: Enumerable#zip — Shin-ichiro HARA <sinara@...> 2002/11/11

原です。

[#18746] Re: Enumerable#zip — matz@... (Yukihiro Matsumoto) 2002/11/11

まつもと ゆきひろです

[#18749] Re: Enumerable#zip — Shin-ichiro HARA <sinara@...> 2002/11/12

原です。

[#18766] Re: Enumerable#zip — matz@... (Yukihiro Matsumoto) 2002/11/13

まつもと ゆきひろです

[#18800] Re: Enumerable#zip — Shin-ichiro HARA <sinara@...> 2002/11/15

原です。

[#18801] Re: Enumerable#zip — matz@... (Yukihiro Matsumoto) 2002/11/15

まつもと ゆきひろです

[#18804] Re: Enumerable#zip — Shin-ichiro HARA <sinara@...> 2002/11/15

原です。

[#18805] Re: Enumerable#zip — matz@... (Yukihiro Matsumoto) 2002/11/15

まつもと ゆきひろです

[#18728] Re: Enumerable#zip — Daisuke Aoki <dai@...> 2002/11/09

青木@横浜です。基本的にROM な人間なんですがなんとなく書いてみました。

[#18774] Re: Enumerable#zip — Daisuke Aoki <dai@...> 2002/11/13

青木@横浜です。

[#18799] Re: Enumerable#zip — Shin-ichiro HARA <sinara@...> 2002/11/15

原です。

[#18802] Re: Enumerable#zip — Tanaka Akira <akr@...17n.org> 2002/11/15

In article <5.1.1.8.2.20021115145423.03541008@blade.nagaokaut.ac.jp>,

[#18803] Re: Enumerable#zip — matz@... (Yukihiro Matsumoto) 2002/11/15

まつもと ゆきひろです

[#18806] Re: Enumerable#zip — Tanaka Akira <akr@...17n.org> 2002/11/15

In article <1037348006.479453.32695.nullmailer@picachu.netlab.jp>,

[#18808] Re: Enumerable#zip — matz@... (Yukihiro Matsumoto) 2002/11/15

まつもと ゆきひろです

[#18823] Re: Enumerable#zip — Shugo Maeda <shugo@...> 2002/11/18

前田です。

[#18833] Re: Enumerable#zip — Tanaka Akira <akr@...17n.org> 2002/11/18

In article <8765uv4fu7.wl@studly.priv.netlab.jp>,

[#18835] Re: Enumerable#zip — Shugo Maeda <shugo@...> 2002/11/18

前田です。

[#18845] Re: Enumerable#zip — Tanaka Akira <akr@...17n.org> 2002/11/19

In article <874raf6xuc.wl@studly.priv.netlab.jp>,

[#18870] Re: Enumerable#zip — Shugo Maeda <shugo@...> 2002/11/21

前田です。

[#18873] Re: Enumerable#zip — Tanaka Akira <akr@...17n.org> 2002/11/21

In article <87fztv5zir.wl@studly.priv.netlab.jp>,

[#18754] Different caller(0) in trace_func when NameError from toplevel between 1.6 and 1.7 — "NAKAMURA, Hiroshi" <nahi@...>

なひです。

27 messages 2002/11/12
[#18755] Re: Different caller(0) in trace_func when NameError from toplevel between 1.6 and 1.7 — nobu.nakada@... 2002/11/12

なかだです。

[#18776] Re: Different caller(0) in trace_func when NameError from toplevel between 1.6 and 1.7 — "NAKAMURA, Hiroshi" <nakahiro@...> 2002/11/14

なひです。

[#18777] Re: Different caller(0) in trace_func when NameError from toplevel between 1.6 and 1.7 — "NAKAMURA, Hiroshi" <nakahiro@...> 2002/11/14

なひです。ひええすいません、タブが落ちちゃった。

[#18789] Re: Different caller(0) in trace_func when NameError from toplevel between 1.6 and 1.7 — "NAKAMURA, Hiroshi" <nahi@...> 2002/11/14

なひです。

[#18795] Re: Different caller(0) in trace_func when NameError from toplevel between 1.6 and 1.7 — nobu.nakada@... 2002/11/15

なかだです。

[#18820] deprecated method( Re: Different caller(0) in trace_func when NameError from toplevel between 1.6 and 1.7) — nobu.nakada@... 2002/11/18

なかだです。

[#18821] Re: deprecated method( Re: Different caller(0) in trace_func when NameError from toplevel between 1.6 and 1.7) — matz@... (Yukihiro Matsumoto) 2002/11/18

まつもと ゆきひろです

[#18825] Re: deprecated method( Re: Different caller(0) in trace_func when NameError from toplevel between 1.6 and 1.7) — nobu.nakada@... 2002/11/18

なかだです。

[#18861] class variables — matz@... (Yukihiro Matsumoto)

まつもと ゆきひろです

31 messages 2002/11/20
[#18913] Re: class variables — "K.Kosako" <kosako@...> 2002/11/22

Yukihiro Matsumotoさんの

[#18895] [patch] install bat file on Windows — "U.Nakamura" <usa@...>

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

14 messages 2002/11/22
[#18900] Re: [patch] install bat file on Windows — "Akinori MUSHA" <knu@...> 2002/11/22

At Fri, 22 Nov 2002 11:09:19 +0900,

[#18903] Re: [patch] install bat file on Windows — "U.Nakamura" <usa@...> 2002/11/22

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

[#18966] [ONIGURUMA] \S doesn't match multibyte char (Re: [ruby-list:36618] Re: 全角文字に挟まれた半角スペースを削除するには?) — nobu.nakada@...

なかだです。

13 messages 2002/11/28

[ruby-dev:18818] CFD: adding "condition", "block-call/return", and "load-call/return" trace-events

From: "NAKAMURA, Hiroshi" <nahi@...>
Date: 2002-11-17 13:41:26 UTC
List: ruby-dev #18818
なひです。

1.7のほうのeval.cに、いくつかtraceイベント発生用の
コードを修正/変更したいです。複数の項目があります。
追加すべきものかどうかという議論に加え、実装が
正しいのかどうかの議論/チェックもお願いしたいです。
特に6、7が怪しい。^^;

0. call_trace_funcでklassがfalseになることがありますが、
  これをidに揃えてnilに。[ruby-dev:18789]の件です。

1. ifの先頭で発生する"line"イベント
  (なひが以前追加をお願いしたもの)を、"condition"
  イベントに変更する。"line"イベントはNODE_NEWLINEのみが
  使うようにしたほうが自然。

2. whenの行で上げている"line"イベント(なひが以前、
  1と一緒にお願いしたもの)は、何もしてないところで
  あげてしまいました。取り下げます。ごめんなさい。
  削除してください。

3. caseの行で上げている"line"イベント(これも1,2と一緒に
  お願いしたもの)を、1に揃えて"condition"イベントに。

4. whileおよびuntilの条件判断のところで、
  1,3に揃えて"condition"イベントを通知するように。

5. rescue節でのhandle_rescueの前で"condition"イベントを
  通知するように。これが1〜4で言うところの"condition"と
  同じ扱いとすべきかどうかは微妙です。「例外のタイプチェック
  をする」という点で"condition"として提案してみました。

  さらに、実際にrescueすると決めた場合に上げる、
  "rescue"イベントを新設。

6. blockの呼び出し直前および直後に通知する、
  "block-call"および"block-return"イベントを新設。

7. ファイルの読み込み直前および直後に通知する、
  "load-call"および"load-return"イベントを新設。


□"condition"について

"condition"イベントのセマンティクスは、ある条件判断が
実施されたかどうかを知らせるために、条件判断をチェックする
直前に通知する、というものです。直前に通知するのは
"line"や"call"など他のイベントと同様です。

本来ならば、ある条件判断の結果、true/falseのどちら
サイドへ分岐したかを通知できるとより面白いことが
し易くなります。が、[ruby-dev:18762]に書いたように、
今はいいと思います。

条件判断を実施された(される)かどうかが通知されると、
カバレジツールやトレーサはそこのカバレジを取れるようになり、
デバガはそこのブレークポイントを打てるようになります。


□"rescue"について

以下のpatchを当てると、

1: begin
2:   raise
3: rescue NameError => ne
4:   raise ChainedError.new(ne)
5: rescue RuntimeError => re
6: end


のようなコードで、3および5行目で"condition"が通知されます。
が、実際にどこでrescueされたかを明示的にするために、
5行目で"rescue"を通知します。

ただし、「RuntimeErrorがどこでraiseされたかどうかを知りたい」
人は居ても(現状のraiseイベント)、
「RuntimeErrorがrescueされた場所を知りたい」という人は
少ないかもしれません。


□"block-call"/"block-return"について

現在、yieldやproc#callによるブロックの呼び出しは、
明示的なメソッド呼び出しと異なり、呼び出し/復帰イベントが
通知されません。このため、

1: def foo
2:   yield 1
3: end
4: foo do |i|
5:   i
6: end

のようなコードでは、2行目のyieldにより、4行目に実行行が
遷移しているように見えるにも関わらず、なにも通知されません
(次の5行目のNODE_NEWLINEで"line"が通知される)。
patchをあてると、yieldの"call"イベントに続き、
4行目で"block-call"イベント、5行目で"block-return"イベントを
発生するようになります。

問題になるのは、このイベントはRubyのソース上のそこらじゅうで
通知されるため、速度パフォーマンスへの悪影響が避けられない点です。
100.times do |i|
  i
end
なんてので、合計200イベント増えることになります。なひは許容
範囲と思ってますが。。。(traceしたらどうせ遅い)


□"load-call"/"load-return"について

これはrequireおよびloadによるRubyソースファイルの読み込みの
前後で通知します。具体的な用途としては、デバガにおいて
ファイル読み込みをスタックとして扱い、「require "foo"」の
次の行へ遷移しやすくすることを考えています(現在、
require行でnextコマンドを叩くと、requireするファイルの
先頭行で止まります。)

requireとloadのc-callを特別扱いするなど、デバガ側の工夫で
なんとかすることも可能ではあります。例えば[ruby-talk:53424]
で書いたような方法です。ですが、ファイル読み込みによる
ソースファイル間の依存関係を把握するツールを書いたり
(現状でいくらでも実現方法はありますが)、ついでに追加しておくと
いろいろ便利なこともあるかな、と思って提案してみました。^^;


本文以上です。

Index: eval.c
===================================================================
RCS file: /src/ruby/eval.c,v
retrieving revision 1.353
diff -u -w -2 -p -r1.353 eval.c
--- eval.c      14 Nov 2002 13:51:18 -0000      1.353
+++ eval.c      17 Nov 2002 12:46:51 -0000
@@ -2116,4 +2116,7 @@ call_trace_func(event, node, self, id, k
        }
     }
+    else {
+       klass = Qnil;
+    }
     PUSH_TAG(PROT_NONE);
     if ((state = EXEC_TAG()) == 0) {
@@ -2324,5 +2327,5 @@ rb_eval(self, n)
       case NODE_IF:
        if (trace_func) {
-           call_trace_func("line", node, self,
+           call_trace_func("condition", node, self,
                            ruby_frame->last_func,
                            ruby_frame->last_class);
@@ -2343,9 +2346,4 @@ rb_eval(self, n)
            tag = node->nd_head;
            while (tag) {
-               if (trace_func) {
-                   call_trace_func("line", tag, self,
-                                   ruby_frame->last_func,
-                                   ruby_frame->last_class);
-               }
                if (nd_type(tag->nd_head) == NODE_WHEN) {
                    VALUE v = rb_eval(self, tag->nd_head->nd_head);
@@ -2387,5 +2385,5 @@ rb_eval(self, n)
                while (tag) {
                    if (trace_func) {
-                       call_trace_func("line", tag, self,
+                       call_trace_func("condition", tag, self,
                                        ruby_frame->last_func,
                                        ruby_frame->last_class);
@@ -2421,4 +2419,9 @@ rb_eval(self, n)
        switch (state = EXEC_TAG()) {
          case 0:
+           if (trace_func && node->nd_state) {
+               call_trace_func("condition", node->nd_cond, self,
+                               ruby_frame->last_func,
+                               ruby_frame->last_class);
+           }
            if (node->nd_state && !RTEST(rb_eval(self, node->nd_cond)))
                goto while_out;
@@ -2428,4 +2431,9 @@ rb_eval(self, n)
              while_next:
                ;
+               if (trace_func) {
+                   call_trace_func("condition", node->nd_cond, self,
+                                   ruby_frame->last_func,
+                                   ruby_frame->last_class);
+               }
            } while (RTEST(rb_eval(self, node->nd_cond)));
            break;
@@ -2453,4 +2461,9 @@ rb_eval(self, n)
        switch (state = EXEC_TAG()) {
          case 0:
+           if (trace_func && node->nd_state) {
+               call_trace_func("condition", node->nd_cond, self,
+                               ruby_frame->last_func,
+                               ruby_frame->last_class);
+           }
            if (node->nd_state && RTEST(rb_eval(self, node->nd_cond)))
                goto until_out;
@@ -2460,4 +2473,9 @@ rb_eval(self, n)
              until_next:
                ;
+               if (trace_func) {
+                   call_trace_func("condition", node->nd_cond, self,
+                                   ruby_frame->last_func,
+                                   ruby_frame->last_class);
+               }
            } while (!RTEST(rb_eval(self, node->nd_cond)));
            break;
@@ -2602,6 +2620,16 @@ rb_eval(self, n)

                while (resq) {
+                   if (trace_func) {
+                       call_trace_func("condition", resq, self,
+                                       ruby_frame->last_func,
+                                       ruby_frame->last_class);
+                   }
                    ruby_current_node = resq;
                    if (handle_rescue(self, resq)) {
+                       if (trace_func) {
+                           call_trace_func("rescue", resq, self,
+                                           ruby_frame->last_func,
+                                           ruby_frame->last_class);
+                       }
                        state = 0;
                        PUSH_TAG(PROT_NONE);
@@ -3872,4 +3900,7 @@ rb_yield_0(val, self, klass, pcall)
     if ((state = EXEC_TAG()) == 0) {
       redo:
+       if (trace_func && node) {
+           call_trace_func("block-call", ruby_frame->node, self, 0, 0);
+       }
        if (!node) {
            result = Qnil;
@@ -3881,4 +3912,7 @@ rb_yield_0(val, self, klass, pcall)
            result = rb_eval(self, node);
        }
+       if (trace_func && node) {
+           call_trace_func("block-return", ruby_last_node, self, 0, 0);
+       }
     }
     else {
@@ -5396,4 +5430,8 @@ rb_load(fname, wrap)
     fname = tmp;

+    if (trace_func) {
+       call_trace_func("load-call", ruby_current_node, self,
+                       ruby_frame->last_func, ruby_frame->last_class);
+    }
     ruby_errinfo = Qnil;       /* ensure */
     PUSH_VARS();
@@ -5451,4 +5489,8 @@ rb_load(fname, wrap)
     POP_VARS();
     ruby_wrapper = wrapper;
+    if (trace_func) {
+       call_trace_func("load-return", ruby_current_node, self,
+                       ruby_frame->last_func, ruby_frame->last_class);
+    }
     if (ruby_nerrs > 0) {
        ruby_nerrs = 0;



In This Thread

Prev Next