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

元ネタは
 http://www.yohasebe.com/diary/diary_search.php?id=142
なのですが、このスクリプトは、実は現在の1.8最新および1.9では
動作しません。

話を単純化して、

  def __method__
    caller.first.sub!(/^.*in `(?:.+?\#)?(.+)'$/, '\\1')
  end
  
  def foo
    p __method__
  end
  
  alias bar foo
  alias baz foo
  
  foo
  bar
  baz

というスクリプトtest.rbがあったとき、

  % ruby-1.6 -v test.rb
  ruby 1.6.8 (2003-07-27) [i586-mswin32]
  "foo"
  "foo"
  "foo"

  % ruby-1.8.1 -v test.rb
  ruby 1.8.1 (2003-12-25) [i386-mswin32]
  "foo"
  "bar"
  "baz"

  % ruby-1.8.4 -v test.rb
  ruby 1.8.4 (2005-12-25) [i386-mswin32]
  "foo"
  "bar"
  "baz"

  % ruby-1.8 -v test.rb
  ruby 1.8.4 (2006-03-23) [i386-mswin32]
  "foo"
  "foo"
  "foo"

  % ruby-1.9 -v test.rb
  ruby 1.9.0 (2006-03-26) [i386-mswin32]
  "foo"
  "foo"
  "foo"

というように、1.8系のリリース版のみ結果が異なります。
# 手元には1.8.0がなかったので試してませんが、1.8.0も他のリリ
# ース版と同様の結果になります。

alias時のcallerはどうなるべきか、という話を考え始めると、いろ
いろ難しいのですが、1.8リリース系列内での互換性を考えると、少
なくとも1.8系ではaliasされた名前が取れるべきであると思います。
また、どっちが便利か、という話になれば、aliasされた名前が取れ
た方が便利な気もします。

1.9でも、過去(2004年とか)はaliasされた名前が取れていたのです
が、1.8にせよ1.9にせよ、なぜaliasされた名前が取れるようになっ
たのか、なぜ今は取れなくされたのか、という意図はよくわかりま
せん。
というわけで、ふかーい理由がそこにあるならば諦めますが、特に
ないならご検討を願います。


おまけとして、1.8および1.9それぞれ用の修正(?)パッチをつけとき
ます。

Index: eval.c =================================================================== RCS file: /home/cvs/ruby/eval.c,v retrieving revision 1.616.2.166 diff -u -1 -p -r1.616.2.166 eval.c --- eval.c 23 Mar 2006 01:52:02 -0000 1.616.2.166 +++ eval.c 27 Mar 2006 13:05:11 -0000 @@ -6191,3 +6191,3 @@ backtrace(lev) ruby_sourcefile, ruby_sourceline, - rb_id2name(frame->orig_func)); + rb_id2name(frame->last_func)); } @@ -6216,3 +6216,3 @@ backtrace(lev) n->nd_file, nd_line(n), - rb_id2name(frame->prev->orig_func)); + rb_id2name(frame->prev->last_func)); }
Index: eval.c =================================================================== RCS file: /home/cvs/ruby/eval.c,v retrieving revision 1.890 diff -u -1 -p -r1.890 eval.c --- eval.c 23 Feb 2006 04:24:39 -0000 1.890 +++ eval.c 27 Mar 2006 13:05:21 -0000 @@ -1110,3 +1110,3 @@ error_line(struct FRAME *frame, NODE *no return rb_sprintf("%s:%d:in `%s'", file, line, - rb_id2name(frame->this_func)); + rb_id2name(frame->callee)); } @@ -1123,3 +1123,3 @@ error_line(struct FRAME *frame, NODE *no rb_class2name(oklass), - rb_id2name(frame->this_func)); + rb_id2name(frame->callee)); }
それでは。 -- U.Nakamura <usa / garbagecollect.jp>