From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: poffice@blade.nagaokaut.ac.jp Delivered-To: poffice@blade.nagaokaut.ac.jp Received: from kankan.nagaokaut.ac.jp (kankan.nagaokaut.ac.jp [133.44.2.24]) by blade.nagaokaut.ac.jp (Postfix) with ESMTP id 865931F0739 for ; Tue, 9 Dec 2008 02:34:25 +0900 (JST) Received: from funfun.nagaokaut.ac.jp (funfun.nagaokaut.ac.jp [133.44.2.201]) by kankan.nagaokaut.ac.jp (Postfix) with ESMTP id 193EFEA50EC for ; Tue, 9 Dec 2008 02:30:52 +0900 (JST) Received: from localhost (localhost.nagaokaut.ac.jp [127.0.0.1]) by funfun.nagaokaut.ac.jp (Postfix) with ESMTP id 4921B1FA003 for ; Tue, 9 Dec 2008 02:30:54 +0900 (JST) X-Virus-Scanned: amavisd-new at funfun.nagaokaut.ac.jp Received: from funfun.nagaokaut.ac.jp ([127.0.0.1]) by localhost (funfun.nagaokaut.ac.jp [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id F8-RQlAI8MkN for ; Tue, 9 Dec 2008 02:30:54 +0900 (JST) Received: from voscc.nagaokaut.ac.jp (voscc.nagaokaut.ac.jp [133.44.1.100]) by funfun.nagaokaut.ac.jp (Postfix) with ESMTP id 2629F1FA001 for ; Tue, 9 Dec 2008 02:30:54 +0900 (JST) Received: from carbon.ruby-lang.org (carbon.ruby-lang.org [221.186.184.68]) by voscc.nagaokaut.ac.jp (Postfix) with ESMTP id 39102952441 for ; Tue, 9 Dec 2008 02:30:51 +0900 (JST) Received: from beryllium.ruby-lang.org (beryllium.ruby-lang.org [127.0.0.1]) by carbon.ruby-lang.org (Postfix) with ESMTP id 325F13C21EBA7; Tue, 9 Dec 2008 02:24:17 +0900 (JST) Received: from fb41.asp.home.ne.jp (fb41.asp.home.ne.jp [203.165.10.45]) by carbon.ruby-lang.org (Postfix) with ESMTP id 4948D3C21F119 for ; Tue, 9 Dec 2008 02:24:15 +0900 (JST) Received: from vss33.asp.im.home.ad.jp (vss33.asp.home.ne.jp [203.165.10.168]) by fb41.asp.home.ne.jp (8.14.1/v8031100) with ESMTP id mB8HUltW024018 for ; Tue, 9 Dec 2008 02:30:47 +0900 (JST) Received: from mail.bc9.jp (www.bc9.jp [202.89.240.19]) by mxo42.asp.home.ne.jp (8.14.1/v8081100) with ESMTP id mB8HUkPg026655 for ; Tue, 9 Dec 2008 02:30:46 +0900 (JST) Received: from sharui.kanuma.tochigi (202-127-187-186.users.bc9.ne.jp [202.127.187.186]) by mail.bc9.jp (Postfix) with ESMTP id 9579BE09B0 for ; Tue, 9 Dec 2008 02:30:46 +0900 (JST) Delivered-To: ruby-core@ruby-lang.org Date: Tue, 9 Dec 2008 02:24:15 +0900 Posted: Tue, 09 Dec 2008 02:30:46 +0900 From: Nobuyoshi Nakada Reply-To: ruby-core@ruby-lang.org Subject: [ruby-core:20430] Re: Array#to_proc To: ruby-core@ruby-lang.org Message-Id: <20081208173046.9579BE09B0@mail.bc9.jp> In-Reply-To: References: <4f4a0fba0812080453x4ae6a3c7n40c0e5cc59fc40de@mail.gmail.com> X-ML-Name: ruby-core X-Mail-Count: 20430 X-MLServer: fml [fml 4.0.3 release (20011202/4.0.3)]; post only (only members can post) X-ML-Info: If you have a question, send e-mail with the body "help" (without quotes) to the address ruby-core-ctl@ruby-lang.org; help= User-Agent: Wanderlust/2.14.0 (Africa) SEMI/1.14.6 (Maruoka) FLIM/1.14.9 (=?ISO-8859-4?Q?Goj=F2?=) APEL/10.7 Emacs/22.2 (i486-pc-linux-gnu) MULE/5.0 (SAKAKI) X-Spam-Checker-Version: SpamAssassin 3.1.7-deb (2006-10-05) on carbon.ruby-lang.org X-Spam-Level: X-Spam-Status: No, score=-5.0 required=7.0 tests=BAYES_00,CN_202_127, CONTENT_TYPE_PRESENT,FORGED_RCVD_HELO autolearn=disabled version=3.1.7-deb Mime-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-Type: text/plain; charset=US-ASCII Precedence: bulk List-Id: ruby-core.ruby-lang.org List-Software: fml [fml 4.0.3 release (20011202/4.0.3)] List-Post: List-Owner: List-Help: List-Unsubscribe: Hi, At Mon, 8 Dec 2008 22:21:16 +0900, Florian Gilcher wrote in [ruby-core:20421]: > This might make sense for an Array of Symbols. But i've also seen use > of this > in other interpretations, like for chaining Arrays of procs. Other > uses could be > imagined. What about Symbol#call()? (1..3).collect(&:*.(2)) #=> [2, 4, 6] Index: string.c =================================================================== --- string.c (revision 20574) +++ string.c (working copy) @@ -6944,4 +6944,71 @@ sym_to_proc(VALUE sym) static VALUE +yield_call(VALUE dummy, VALUE proc, int argc, VALUE *argv) +{ + return rb_proc_call_with_block(proc, argc, argv, Qnil); +} + +static VALUE +sym_call_with_args(VALUE dummy, VALUE args, int argc, VALUE *argv) +{ + VALUE obj, sym, proc, *ptr = RARRAY_PTR(args); + long len = RARRAY_LEN(args); + volatile VALUE newargs; + ID id; + + if (argc < 1) { + rb_raise(rb_eArgError, "no receiver given"); + } + proc = ptr[--len]; + sym = ptr[--len]; + obj = *argv++; + if (!--argc) { + argc = len; + argv = ptr; + } + else if (len) { + VALUE *p; + newargs = rb_ary_tmp_new(argc + len); + rb_ary_store(newargs, argc + len - 1, Qnil); + p = RARRAY_PTR(newargs); + MEMCPY(p, argv, VALUE, argc); + MEMCPY(p + argc, ptr, VALUE, len); + argv = p; + argc += len; + } + id = SYM2ID(sym); + RB_GC_GUARD(args); + if (NIL_P(proc)) { + return rb_funcall3(obj, id, argc, argv); + } + else { + return rb_block_call(obj, id, argc, argv, yield_call, proc); + } +} + +/* + * call-seq: + * sym.call(*args) + * sym.(*args) + * + * Returns a _Proc_ object which respond to the given method by _sym_ with _args_. + * + * (1..3).collect(&:*.(2)) #=> [2, 4, 6] + */ + +static VALUE +sym_to_proc_with_args(int argc, VALUE *argv, VALUE sym) +{ + VALUE args, proc = 0; + if (rb_block_given_p()) proc = rb_block_proc(); + if (argc == 0 && !proc) return sym_to_proc(sym); + args = rb_ary_tmp_new(argc + 2); + rb_ary_store(args, argc + 1, proc); + MEMCPY(RARRAY_PTR(args), argv, VALUE, argc); + RARRAY_PTR(args)[argc] = sym; + return rb_proc_new(sym_call_with_args, args); +} + +static VALUE sym_succ(VALUE sym) { @@ -7214,4 +7281,5 @@ Init_String(void) rb_define_method(rb_cSymbol, "=~", sym_match, 1); + rb_define_method(rb_cSymbol, "call", sym_to_proc_with_args, -1); rb_define_method(rb_cSymbol, "[]", sym_aref, -1); rb_define_method(rb_cSymbol, "slice", sym_aref, -1); -- Nobu Nakada