[#37959] [Bug:trunk] I can modify literals — Yusuke ENDOH <mame@...>

遠藤です。

13 messages 2009/02/10

[#38005] Is URI.decode() broken? — MOROHASHI Kyosuke <moronatural@...>

もろはしです。いつもお世話になっております。

39 messages 2009/02/14
[#38006] Re: Is URI.decode() broken? — Nobuyoshi Nakada <nobu@...> 2009/02/14

なかだです。

[#38009] Re: Is URI.decode() broken? — "NARUSE, Yui" <naruse@...> 2009/02/14

成瀬です、

[#38016] Re: Is URI.decode() broken? — Fujioka <fuj@...> 2009/02/15

xibbarこと藤岡です。

[#38017] Re: Is URI.decode() broken? — "NARUSE, Yui" <naruse@...> 2009/02/15

成瀬です。

[#38040] Re: Is URI.decode() broken? — akira yamada / やまだあきら <akira@...> 2009/02/17

NARUSE, Yui さんは書きました:

[#38124] Re: Is URI.decode() broken? — "NARUSE, Yui" <naruse@...> 2009/03/03

成瀬です。

[#39214] Re: Is URI.decode() broken? — akira yamada / やまだあきら <akira@...> 2009/09/02

(2009年03月03日 22:45), NARUSE, Yui さんは書きました:

[#39218] Re: Is URI.decode() broken? — "NARUSE, Yui" <naruse@...> 2009/09/02

成瀬です。

[#39236] Re: Is URI.decode() broken? — Tanaka Akira <akr@...> 2009/09/05

In article <4A9E44DD.6050706@airemix.jp>,

[#39242] Re: Is URI.decode() broken? — KOSAKI Motohiro <kosaki.motohiro@...> 2009/09/07

小崎@思いつきを適当に書いてみるテスト

[#39246] Re: Is URI.decode() broken? — Tanaka Akira <akr@...> 2009/09/07

In article <20090907091830.2C7A.A69D9226@jp.fujitsu.com>,

[#38096] 多重代入やメソッド引数の展開でto_aが呼ばれます — nagachika <nagachika00@...>

nagachika と申します。

10 messages 2009/02/26

[#38098] ブロック引数と括弧・引数なしsuper — Shugo Maeda <shugo@...>

前田です。

12 messages 2009/02/27

[ruby-dev:37982] Re: proposal: Module#method_adding

From: SASADA Koichi <ko1@...>
Date: 2009-02-12 20:52:57 UTC
List: ruby-dev #37982
 ささだです.

SASADA Koichi wrote::
>  今,asakusa.rb で酒を飲んでたんですが,Module#method_adding とか,そう
> いうメソッドというのはどうでしょうか. メソッドが定義される直前に呼ばれ
> るメソッドです.
> 
> やりたいこと:
>  例えば,foo というメソッドのオーバーライドをしたときに,old_foo のよう
> な古いメソッドの alias を自動的に作るにはどうすれば,という話になりまし
> た.Module#method_added を使うとどうだろう,と思ったのですが,これはすで
> にメソッドを上書きした後でよばれるようです.
> 
>  ということで,メソッドを定義する直前にフックするためのメソッドとして
> Module#method_adding というのを新設するのはどうだろう,という案がでまし
> た.すでに,そういうことをする方法があればいいんですが,なければ,一つ検
> 討ご検討いただけないでしょうか.
> 

 なんとなく実装してみました.ちなみに,method_added の rdoc がなかった
ので,singleton_method_added をコピーして適当に書きました.

 気づいた点は2点.

* ...ed 系のフックメソッドに,...ing 系を付け加えたくなってくる
  結構きりがない.hook 関数全般を set_trace_func みたいにまとめる?

* singleton_*ed があるメソッドは *ed の rdoc がない.


Index: object.c
===================================================================
--- object.c	(リビジョン 22272)
+++ object.c	(作業コピー)
@@ -523,6 +523,91 @@ rb_obj_tap(VALUE obj)
  */

 /*
+ * Document-method: method_adding
+ *
+ *  call-seq:
+ *     method_adding(symbol)
+ *
+ *  Invoked as a callback whenever a method (except singleton method)
+ *  is adding to the class.
+ *  This method is called before method adding process.
+ *
+ *     module Chatty
+ *       def Chatty.method_adding(id)
+ *         puts "adding: #{id}, respond_to?: #{method_defined? id}"
+ *       end
+ *       def Chatty.method_added(id)
+ *         puts "added: #{id}, respond_to?: #{method_defined? id}"
+ *       end
+ *       def self.one()     end
+ *       def two()          end
+ *       def Chatty.three() end
+ *     end
+ *
+ *  <em>produces:</em>
+ *
+ *     adding: two, respond_to?: false
+ *     added: two, respond_to?: true
+ *
+ */
+
+/*
+ * Document-method: method_added
+ *
+ *  call-seq:
+ *     method_added(symbol)
+ *
+ *  Invoked as a callback whenever a method (except singleton method)
+ *  is added to the class.
+ *
+ *     module Chatty
+ *       def Chatty.singleton_method_added(id)
+ *         puts "Adding #{id}"
+ *       end
+ *       def self.one()     end
+ *       def two()          end
+ *       def Chatty.three() end
+ *     end
+ *
+ *  <em>produces:</em>
+ *
+ *     Adding 2
+ *
+ */
+
+/*
+ * Document-method: singleton_method_adding
+ *
+ *  call-seq:
+ *     singleton_method_adding(symbol)
+ *
+ *  Invoked as a callback whenever a singleton method is adding to the
+ *  receiver.  This method is called before method added process.
+ *
+ *     module Chatty
+ *       def Chatty.singleton_method_adding(id)
+ *         puts "adding: #{id}, respond_to?: #{self.respond_to? id}"
+ *       end
+ *       def Chatty.singleton_method_added(id)
+ *         puts "added: #{id}, respond_to?: #{self.respond_to? id}"
+ *       end
+ *       def self.one()     end
+ *       def two()          end
+ *       def Chatty.three() end
+ *     end
+ *
+ *  <em>produces:</em>
+ *
+ *     adding: singleton_method_added, respond_to?: false
+ *     added: singleton_method_added, respond_to?: true
+ *     adding: one, respond_to?: false
+ *     added: one, respond_to?: true
+ *     adding: three, respond_to?: false
+ *     added: three, respond_to?: true
+ *
+ */
+
+/*
  * Document-method: singleton_method_added
  *
  *  call-seq:
@@ -533,7 +618,7 @@ rb_obj_tap(VALUE obj)
  *
  *     module Chatty
  *       def Chatty.singleton_method_added(id)
- *         puts "Adding #{id.id2name}"
+ *         puts "Adding #{id}"
  *       end
  *       def self.one()     end
  *       def two()          end
@@ -2488,6 +2573,7 @@ Init_Object(void)
     rb_define_method(rb_cBasicObject, "!=", rb_obj_not_equal, 1);

     rb_define_private_method(rb_cBasicObject, "singleton_method_added",
rb_obj_dummy, 1);
+    rb_define_private_method(rb_cBasicObject,
"singleton_method_adding", rb_obj_dummy, 1);
     rb_define_private_method(rb_cBasicObject,
"singleton_method_removed", rb_obj_dummy, 1);
     rb_define_private_method(rb_cBasicObject,
"singleton_method_undefined", rb_obj_dummy, 1);

@@ -2497,6 +2583,7 @@ Init_Object(void)
     rb_define_private_method(rb_cModule, "included", rb_obj_dummy, 1);
     rb_define_private_method(rb_cModule, "extended", rb_obj_dummy, 1);
     rb_define_private_method(rb_cModule, "method_added", rb_obj_dummy, 1);
+    rb_define_private_method(rb_cModule, "method_adding", rb_obj_dummy, 1);
     rb_define_private_method(rb_cModule, "method_removed",
rb_obj_dummy, 1);
     rb_define_private_method(rb_cModule, "method_undefined",
rb_obj_dummy, 1);

Index: vm_method.c
===================================================================
--- vm_method.c	(リビジョン 22272)
+++ vm_method.c	(作業コピー)
@@ -10,7 +10,7 @@ static void rb_vm_check_redefinition_opt

 static ID object_id;
 static ID removed, singleton_removed, undefined, singleton_undefined;
-static ID added, singleton_added;
+static ID added, singleton_added, adding, singleton_adding;

 struct cache_entry {		/* method hash table. */
     ID mid;			/* method's id */
@@ -125,6 +125,17 @@ rb_add_method(VALUE klass, ID mid, NODE
     if (OBJ_FROZEN(klass)) {
 	rb_error_frozen("class/module");
     }
+
+    if (node && mid != ID_ALLOCATOR && ruby_running) {
+	if (FL_TEST(klass, FL_SINGLETON)) {
+	    rb_funcall(rb_iv_get(klass, "__attached__"), singleton_adding, 1,
+		       ID2SYM(mid));
+	}
+	else {
+	    rb_funcall(klass, adding, 1, ID2SYM(mid));
+	}
+    }
+
     rb_clear_cache_by_id(mid);

     /*
@@ -749,6 +760,13 @@ rb_alias(VALUE klass, ID name, ID def)
 	singleton = rb_iv_get(klass, "__attached__");
     }

+    if (singleton) {
+	rb_funcall(singleton, singleton_adding, 1, ID2SYM(name));
+    }
+    else {
+	rb_funcall(klass, adding, 1, ID2SYM(name));
+    }
+
     orig_fbody->nd_cnt++;

     if (st_lookup(RCLASS_M_TBL(klass), name, &data)) {
@@ -1132,7 +1150,9 @@ Init_eval_method(void)

     object_id = rb_intern("object_id");
     added = rb_intern("method_added");
+    adding = rb_intern("method_adding");
     singleton_added = rb_intern("singleton_method_added");
+    singleton_adding = rb_intern("singleton_method_adding");
     removed = rb_intern("method_removed");
     singleton_removed = rb_intern("singleton_method_removed");
     undefined = rb_intern("method_undefined");

-- 
// SASADA Koichi at atdot dot net

In This Thread