[ruby-trunk - Feature #8726][Open] Class#source_location

Issue #8726 has been reported by takiuchi (Genki Takiuchi).


Feature #8726: Class#source_location

Author: takiuchi (Genki Takiuchi)
Status: Open
Priority: Normal
Assignee:
Category:
Target version: current: 2.1.0

Classオブジェクトが生成された場所を返す Class#source_location メソッドの実装を希望いたします。

これによって解決される問題の例としては、Timeout::timeout が無名の例外クラスオブジェクトを raise した
場合に、どこで仕掛けられた timeout なのか、発生場所を特定できるようになります。
このようなケースでは、例外オブジェクトが保有している backtrace はtimeoutが発生した時点での
プログラム実行位置を起点としており、Timeout::timeout(…) を仕掛けた場所の情報は失われています。

Issue #8726 has been updated by takiuchi (Genki Takiuchi).

関連して、無名クラスオブジェクトのto_s の結果として、“#Class:0x007f956336abc8” のような文字列ではなく、
Class#source_location で得られる情報を付加すれば、様々な利便性の向上が望めると思います。

Feature #8726: Class#source_location

Author: takiuchi (Genki Takiuchi)
Status: Open
Priority: Normal
Assignee:
Category:
Target version: current: 2.1.0

Classオブジェクトが生成された場所を返す Class#source_location メソッドの実装を希望いたします。

これによって解決される問題の例としては、Timeout::timeout が無名の例外クラスオブジェクトを raise した
場合に、どこで仕掛けられた timeout なのか、発生場所を特定できるようになります。
このようなケースでは、例外オブジェクトが保有している backtrace はtimeoutが発生した時点での
プログラム実行位置を起点としており、Timeout::timeout(…) を仕掛けた場所の情報は失われています。

Issue #8726 has been updated by naruse (Yui NARUSE).

ユースケースがtimeoutだけなのでしたら、一般化したsource_locationではなく、
その無名クラスオブジェクトに作成時のcallerを返す特異メソッドをつけた方が早くありませんか。

Feature #8726: Class#source_location

Author: takiuchi (Genki Takiuchi)
Status: Open
Priority: Normal
Assignee:
Category:
Target version: current: 2.1.0

Classオブジェクトが生成された場所を返す Class#source_location メソッドの実装を希望いたします。

これによって解決される問題の例としては、Timeout::timeout が無名の例外クラスオブジェクトを raise した
場合に、どこで仕掛けられた timeout なのか、発生場所を特定できるようになります。
このようなケースでは、例外オブジェクトが保有している backtrace はtimeoutが発生した時点での
プログラム実行位置を起点としており、Timeout::timeout(…) を仕掛けた場所の情報は失われています。

Class$B%*%V%8%’%/%H$,@8@.$5$l$?>l=j$rJV$9(B Class#source_location
$B%a%=%C%I$N<BAu$r4uK>$$$?$7$^$9!#(B

$B$3$l$K$h$C$F2r7h$5$l$kLdBj$NNc$H$7$F$O!"(BTimeout::timeout
$B$,L5L>$NNc30%/%i%9%%V%8%’%/%H$r(B raise $B$7$?(B
$B>l9g$K!"$I$3$G;E3]$1$i$l$?(B timeout
$B$J$N$+!"H/@8>l=j$rFCDj$G$-$k$h$&$K$J$j$^$9!#(B
$B$3$N$h$&$J%1!<%9$G$O!"Nc30%
%V%8%’%/%H$,J]M-$7$F$$$k(B backtrace
$B$O(Btimeout$B$,H/@8$7$?;~E@$G$N(B
$B%W%m%0%i%`<B9T0LCV$r5/E@$H$7$F$*$j!"(BTimeout::timeout(…)
$B$r;E3]$1$?>l=j$N>pJs$O<:$o$l$F$$$^$9!#(B

$B8@$C$F$k$3$H$,:#$R$H$DM}2r$G$-$^$;$s!#(B

test.rb
$B!<!<!<!<!<!<!<!<!<!<(B
1: require “timeout”
2:
3: def foo
4: sleep 10
5: end
6:
7: Timeout.timeout(1) {
8: foo
9: }

$B$H$$$&%3!<%I$N7k2L$O(B

% ./ruby-trunk …/test.rb
…/test.rb:4:in sleep': execution expired (Timeout::Error) from ../test.rb:4:infoo’
from …/test.rb:8:in block in <main>' from ../test.rb:7:in

$B$G$"$j!"%?%$%%"%&%H$,H/@8$7$?;~E@$G$N%W%m%0%i%<B9T0LCV!J(Bfoo$BFb$N9THV9f#4!K$H(B
Timeout$B;E3]$1$?>l=j!J9THV9f(B7$B$+$i(B9$B$N%V%m%C%/!K$ON>J}6&$o$+$k$h$&$K8+$($^$9!#(B

$B$J$k$;$5$s!"$o$?$7!"$"$N%P%C%/%H%l!<%9$N@07A=hM}$,%$%^%$%AM}2r$G$-$s$N$@$,!"(B
$B$"$l$O$I$&$$$&=hM}$r0U?^$7$F$k$N!#(B

Issue #8726 has been updated by naruse (Yui NARUSE).

naruse (Yui NARUSE) wrote:

ユースケースがtimeoutだけなのでしたら、一般化したsource_locationではなく、
その無名クラスオブジェクトに作成時のcallerを返す特異メソッドをつけた方が早くありませんか。

いや、そもそもTimeout.timeoutのrescueで自身のbacktraceを除いている処理が実はいらなくて、
ちゃんと残しておくべきなのかも。

Feature #8726: Class#source_location

Author: takiuchi (Genki Takiuchi)
Status: Open
Priority: Normal
Assignee:
Category:
Target version: current: 2.1.0

Classオブジェクトが生成された場所を返す Class#source_location メソッドの実装を希望いたします。

これによって解決される問題の例としては、Timeout::timeout が無名の例外クラスオブジェクトを raise した
場合に、どこで仕掛けられた timeout なのか、発生場所を特定できるようになります。
このようなケースでは、例外オブジェクトが保有している backtrace はtimeoutが発生した時点での
プログラム実行位置を起点としており、Timeout::timeout(…) を仕掛けた場所の情報は失われています。

$B$J$k$;$5$s!"$o$?$7!"$"$N%P%C%/%H%l!<%9$N@07A=hM}$,%$%^%$%AM}2r$G$-$s$N$@$,!"(B
$B$"$l$O$I$&$$$&=hM}$r0U?^$7$F$k$N!#(B

printf$B%G%P%C%0$7$?46$8$@$H(B

  (bt = e.backtrace).reject! {|m| rej =~ m}

$B$N9T$G<h$j=|$+$l$F$k9T$O$J$$$h$&$K8+$($k!#$&!<$s!"%3!<%IMzNr$rDI$&I,MW$,$"$k$+$J$"(B

(13/08/04 6:33), KOSAKI Motohiro wrote:

$B$J$k$;$5$s!"$o$?$7!"$"$N%P%C%/%H%l!<%9$N@07A=hM}$,%$%^%$%AM}2r$G$-$s$N$@$,!"(B

$B$"$l$O$I$&$$$&=hM}$r0U?^$7$F$k$N!#(B

printf$B%G%P%C%0$7$?46$8$@$H(B

  (bt = e.backtrace).reject! {|m| rej =~ m}

$B$N9T$G<h$j=|$+$l$F$k9T$O$J$$$h$&$K8+$($k!#$&!<$s!"%3!<%IMzNr$rDI$&I,MW$,$"$k$+$J$"(B

$B$=$3$G<h$j=|$$$F$$$k$N$O!"(BThread#raise$BMQ$N%?%$%^!<%9%l%C%I$N=*N;BT$A$N9T$G$9!#(B
timeout.rb$B$+$i$N%P%C%/%H%l!<%9$r<h$j=|$$$F$$$k$N$O!"$=$N8e$N(Bwhile$B%k!<%WCf$N(Bbt.delete_at$B$G$9!#(B

Issue #8726 has been updated by ko1 (Koichi Sasada).

Category set to core

ちょっと追えていないのですが、元の提案自体は reject という感じでしょうか。

Feature #8726: Class#source_location

Author: takiuchi (Genki Takiuchi)
Status: Open
Priority: Normal
Assignee:
Category: core
Target version: current: 2.1.0

Classオブジェクトが生成された場所を返す Class#source_location メソッドの実装を希望いたします。

これによって解決される問題の例としては、Timeout::timeout が無名の例外クラスオブジェクトを raise した
場合に、どこで仕掛けられた timeout なのか、発生場所を特定できるようになります。
このようなケースでは、例外オブジェクトが保有している backtrace はtimeoutが発生した時点での
プログラム実行位置を起点としており、Timeout::timeout(…) を仕掛けた場所の情報は失われています。

2013/8/3 Nobuyoshi N. [email protected]:

$B$=$3$G<h$j=|$$$F$$$k$N$O!"(BThread#raise$BMQ$N%?%$%^!<%9%l%C%I$N=*N;BT$A$N9T$G$9!#(B

timeout.rb$B$+$i$N%P%C%/%H%l!<%9$r<h$j=|$$$F$$$k$N$O!"$=$N8e$N(Bwhile$B%k!<%WCf$N(Bbt.delete_at$B$G$9!#(B

$B$d$C$F$_$^$7$?!)(B
bt.delete_at$B$N$[$&$O0U?^DL$jF0$$$F$=$&$@$+$i%3%a%s%H$7$J$+$C$?$N$@$1$I!"$3$C$A$N(Breject$B$O(B

% ./ruby-trunk …/test.rb
/home/kosaki/local/ruby-trunk/lib/ruby/2.1.0/timeout.rb:70:in join': execution expired (Timeout::Error) from ../test.rb:7:in

$B$H!“8=:_$O;EMM$H$7$F%U%!%$%kL>9THV9f$N8e$m$K(B in `join’
$B$,$D$$$F$$$k$?$a!”(B
(J\z $B$,<YKb$7$F%^%C%A$7$F$$$^$;$s!#(B

(J\z$B$r<h$k$H0J2<$N$h$&$KJQ2=$7$3$A$i$,0U?^$7$?7k2L$G$O$J$$$+$H(B

% ./ruby-trunk …/test.rb
…/test.rb:7:in `': execution expired (Timeout::Error)

$B$A$g$C$H:G=i$N@bL@$,B-$j$J$+$C$?$+!#(B

$B$?$@!“OC$r$b$H$KLa$9$H!”$J$k$;$5$s$N!“$=$b$=$b$J$s$GL5M}$d$j@07A$7$F>pJsNLMn$H$9I,MW$”$k$N$@$H$$$&;XE&$O;j6K$^$C$H$&$J$b$N$K;W$($^$9!#(B

$BA02s$N%a!<%k$N%9%/%j%W%H$r(Bruby-1.8.7$B$G<B9T$9$k$H(B

% /usr/bin/ruby …/test.rb
/usr/lib/ruby/1.8/timeout.rb:64:in `foo’: execution expired
(Timeout::Error)
from …/test.rb:8
from …/test.rb:7

timeout.rb
$B$H$$$&J8;zNs$,8+$($F$$$k$N$G(B1.9$B$+$i$NJQ99$@$H;W$&$N$G$9$,!"(B
$B$3$&JQ$($k%a%j%C%H$,$A$HA[A|$D$+$L(B

Issue #8726 has been updated by naruse (Yui NARUSE).

ko1 (Koichi Sasada) wrote:

ちょっと追えていないのですが、元の提案自体は reject という感じでしょうか。

Class#source_location が欲しい状況って言うのはあり得るとは思いますが、
少なくとも timeout の件はユースケースとして妥当ではないように感じました。

Class#source_location 提案を粘るか、timeout 改善に切り替えるかはお任せしますが、
timeout 改善を本格的に議論するならタイトルと違うので別チケットかもしれませんね。

Feature #8726: Class#source_location

Author: takiuchi (Genki Takiuchi)
Status: Open
Priority: Normal
Assignee:
Category: core
Target version: current: 2.1.0

Classオブジェクトが生成された場所を返す Class#source_location メソッドの実装を希望いたします。

これによって解決される問題の例としては、Timeout::timeout が無名の例外クラスオブジェクトを raise した
場合に、どこで仕掛けられた timeout なのか、発生場所を特定できるようになります。
このようなケースでは、例外オブジェクトが保有している backtrace はtimeoutが発生した時点での
プログラム実行位置を起点としており、Timeout::timeout(…) を仕掛けた場所の情報は失われています。

Issue #8726 has been updated by takiuchi (Genki Takiuchi).

Timeoutのバグの本質は、timeoutブロック内で rescue Exception した場合に、timeoutの実装が
内部的に使っている Timeout::ExitException を拾ってしまうことのようです。

Timeoutの例は一例でして、Class.source_location があれば無名クラスがどこで定義されたものか
デバッグするのが容易になる、というのが趣旨でした。

Feature #8726: Class#source_location

Author: takiuchi (Genki Takiuchi)
Status: Rejected
Priority: Normal
Assignee:
Category: core
Target version: current: 2.1.0

Classオブジェクトが生成された場所を返す Class#source_location メソッドの実装を希望いたします。

これによって解決される問題の例としては、Timeout::timeout が無名の例外クラスオブジェクトを raise した
場合に、どこで仕掛けられた timeout なのか、発生場所を特定できるようになります。
このようなケースでは、例外オブジェクトが保有している backtrace はtimeoutが発生した時点での
プログラム実行位置を起点としており、Timeout::timeout(…) を仕掛けた場所の情報は失われています。

Timeoutのバグの本質は、timeoutブロック内で rescue Exception した場合に、timeoutの実装が
内部的に使っている Timeout::ExitException を拾ってしまうことのようです。

Timeoutの例は一例でして、Class.source_location があれば無名クラスがどこで定義されたものか
デバッグするのが容易になる、というのが趣旨でした。

これ、整理度合いが進化してませんよね?
Timeoutの問題ならTimeoutを直さないのはなぜなのか。Genericなデバッグメソッドを追加するなら、
それがTimeout以外の一般的な話として有用であることを示せるか。というのが論点だったはずで、
なんら追加がないように見えます。

Issue #8726 has been updated by kosaki (Motohiro KOSAKI).

Status changed from Open to Rejected

とりあえず一回Rejectするので、諦めてない人は理由を整理して再チャレンジしてください。
Timeoutが意図通り動いてない(フィルターでちゃんとフィルターされてない)は、バグだと思うのでこちらで直しておきます。
Timeoutでフィルターするのを外したらどうか、という提案は別件だと思うので必要と思う人が別チケットをオープンしてください。


Feature #8726: Class#source_location

Author: takiuchi (Genki Takiuchi)
Status: Rejected
Priority: Normal
Assignee:
Category: core
Target version: current: 2.1.0

Classオブジェクトが生成された場所を返す Class#source_location メソッドの実装を希望いたします。

これによって解決される問題の例としては、Timeout::timeout が無名の例外クラスオブジェクトを raise した
場合に、どこで仕掛けられた timeout なのか、発生場所を特定できるようになります。
このようなケースでは、例外オブジェクトが保有している backtrace はtimeoutが発生した時点での
プログラム実行位置を起点としており、Timeout::timeout(…) を仕掛けた場所の情報は失われています。

Issue #8726 has been updated by takiuchi (Genki Takiuchi).

了解です。Timeoutのバグは別なissueにしますね。

Feature #8726: Class#source_location

Author: takiuchi (Genki Takiuchi)
Status: Rejected
Priority: Normal
Assignee:
Category: core
Target version: current: 2.1.0

Classオブジェクトが生成された場所を返す Class#source_location メソッドの実装を希望いたします。

これによって解決される問題の例としては、Timeout::timeout が無名の例外クラスオブジェクトを raise した
場合に、どこで仕掛けられた timeout なのか、発生場所を特定できるようになります。
このようなケースでは、例外オブジェクトが保有している backtrace はtimeoutが発生した時点での
プログラム実行位置を起点としており、Timeout::timeout(…) を仕掛けた場所の情報は失われています。