西山和広です。

At Fri, 11 Apr 2008 19:23:23 +0900,
Kazuhiro NISHIYAMA wrote:
> 
> とりあえずApprovedになっていて簡単そうなものをbackportしてみています。
> (Process.exec, Object#tap, Symbol#to_procなど)

Symbol#to_procは単純にtrunkのstring.cからそのままruby_1_8のobject.cに
入れてもうまくいかなかった(:to_s.to_proc.call(1)でもno receiver givenに
なる)ので、あきらめました。

Index: object.c
===================================================================
--- object.c	(リビジョン 15977)
+++ object.c	(作業コピー)
@@ -1205,7 +1205,34 @@
     return sym;
 }
 
+static VALUE
+sym_call(VALUE args, VALUE sym, int argc, VALUE *argv)
+{
+    VALUE obj;
 
+    if (argc < 1) {
+	rb_raise(rb_eArgError, "no receiver given");
+    }
+    obj = argv[0];
+    return rb_funcall(obj, (ID)sym, argc - 1, argv + 1);
+}
+
+/*
+ * call-seq:
+ *   sym.to_proc
+ *
+ * Returns a _Proc_ object which respond to the given method by _sym_.
+ *
+ *   (1..3).collect(&:to_s)  #=> ["1", "2", "3"]
+ */
+
+static VALUE
+sym_to_proc(VALUE sym)
+{
+    return rb_proc_new(sym_call, (VALUE)SYM2ID(sym));
+}
+
+
 /***********************************************************************
  *
  * Document-class: Module
@@ -2749,6 +2776,7 @@
     rb_define_method(rb_cSymbol, "to_s", sym_to_s, 0);
     rb_define_method(rb_cSymbol, "id2name", sym_to_s, 0);
     rb_define_method(rb_cSymbol, "to_sym", sym_to_sym, 0);
+    rb_define_method(rb_cSymbol, "to_proc", sym_to_proc, 0);
     rb_define_method(rb_cSymbol, "===", rb_obj_equal, 1); 
 
     rb_define_method(rb_cModule, "freeze", rb_mod_freeze, 0);
Index: test/ruby/test_symbol.rb
===================================================================
--- test/ruby/test_symbol.rb	(リビジョン 15977)
+++ test/ruby/test_symbol.rb	(作業コピー)
@@ -74,4 +74,8 @@
     assert_inspect_evaled(':$0')
     assert_inspect_evaled(':$1')
   end
+
+  def test_to_proc
+    assert_equal %w(1 2 3), (1..3).map(&:to_s)
+  end
 end


-- 
|ZnZ(ゼット エヌ ゼット)
|西山和広(Kazuhiro NISHIYAMA)