[Feature:trunk] argument delegation

e$B$J$+$@$G$9!#e(B

http://www.rubyist.net/~matz/20100615.html#p01
e$B$r<BAu$7$F$$^$7$?!#e(B
foo(…)e$B$G%V%m%C%/$^$G%3%
!“e(Bfoo(…)e$B$O%V%m%C%/H4$-$K$7$F$”$j$^$9!#e(B

diff --git i/compile.c w/compile.c
index 4621cd9…d769c56 100644
— i/compile.c
+++ w/compile.c
@@ -2729,7 +2729,6 @@ defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *ret,
return 1;

   case NODE_SUPER:
  •  case NODE_ZSUPER:
    
    ADD_INSN(ret, nd_line(node), putnil);
    ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_ZSUPER), 0,
    needstr);
    @@ -2919,6 +2918,67 @@ setup_args(rb_iseq_t *iseq, LINK_ANCHOR *args,
    NODE *argn, unsigned long *flag)
    POP_ELEMENT(args);
    break;
    }
  • case NODE_DELEGATE: {
  •  int i;
    
  •  rb_iseq_t *liseq = iseq->local_iseq;
    
  •  if (argn->nd_state) *flag |= VM_CALL_SUPER_BIT;
    
  •  argc = INT2FIX(liseq->argc);
    
  •  /* normal arguments */
    
  •  for (i = 0; i < liseq->argc; i++) {
    
  • int idx = liseq->local_size - i;
  • ADD_INSN1(args, nd_line(argn), getlocal, INT2FIX(idx));
  •  }
    
  •  if (!liseq->arg_simple) {
    
  • if (liseq->arg_opts) {
  •    /* optional arguments */
    
  •    int j;
    
  •    for (j = 0; j < liseq->arg_opts - 1; j++) {
    
  •  int idx = liseq->local_size - (i + j);
    
  •  ADD_INSN1(args, nd_line(argn), getlocal, INT2FIX(idx));
    
  •    }
    
  •    i += j;
    
  •    argc = INT2FIX(i);
    
  • }
  • if (liseq->arg_rest != -1) {
  •    /* rest argument */
    
  •    int idx = liseq->local_size - liseq->arg_rest;
    
  •    ADD_INSN1(args, nd_line(argn), getlocal, INT2FIX(idx));
    
  •    argc = INT2FIX(liseq->arg_rest + 1);
    
  •    *flag |= VM_CALL_ARGS_SPLAT_BIT;
    
  • }
  • if (liseq->arg_post_len) {
  •    /* post arguments */
    
  •    int post_len = liseq->arg_post_len;
    
  •    int post_start = liseq->arg_post_start;
    
  •    if (liseq->arg_rest != -1) {
    
  •  int j;
    
  •  for (j=0; j<post_len; j++) {
    
  •      int idx = liseq->local_size - (post_start + j);
    
  •      ADD_INSN1(args, nd_line(argn), getlocal, INT2FIX(idx));
    
  •  }
    
  •  ADD_INSN1(args, nd_line(argn), newarray, INT2FIX(j));
    
  •  ADD_INSN (args, nd_line(argn), concatarray);
    
  •  /* argc is setteled at above */
    
  •    }
    
  •    else {
    
  •  int j;
    
  •  for (j=0; j<post_len; j++) {
    
  •      int idx = liseq->local_size - (post_start + j);
    
  •      ADD_INSN1(args, nd_line(argn), getlocal, INT2FIX(idx));
    
  •  }
    
  •  argc = INT2FIX(post_len + post_start);
    
  •    }
    
  • }
  •  }
    
  •        break;
    
  •      }
    
    default: {
    rb_bug(“setup_arg: unknown node: %s\n”,
    ruby_node_name(nd_type(argn)));
    }
    @@ -4115,8 +4175,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR
    *ret, NODE * node, int poped)
    }
    break;
    }
  •  case NODE_SUPER:
    
  •  case NODE_ZSUPER:{
    
  •  case NODE_SUPER: {
    

    DECL_ANCHOR(args);
    VALUE argc;
    unsigned long flag = 0;
    @@ -4124,72 +4183,12 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR
    *ret, NODE * node, int poped)

    INIT_ANCHOR(args);
    iseq->compile_data->current_block = Qfalse;

  • if (nd_type(node) == NODE_SUPER) {
  •  argc = setup_args(iseq, args, node->nd_args, &flag);
    
  • }
  • else {
  •  /* NODE_ZSUPER */
    
  •  int i;
    
  •  rb_iseq_t *liseq = iseq->local_iseq;
    
  •  argc = INT2FIX(liseq->argc);
    
  •  /* normal arguments */
    
  •  for (i = 0; i < liseq->argc; i++) {
    
  • int idx = liseq->local_size - i;
  • ADD_INSN1(args, nd_line(node), getlocal, INT2FIX(idx));
  •  }
    
  •  if (!liseq->arg_simple) {
    
  • if (liseq->arg_opts) {
  •    /* optional arguments */
    
  •    int j;
    
  •    for (j = 0; j < liseq->arg_opts - 1; j++) {
    
  •  int idx = liseq->local_size - (i + j);
    
  •  ADD_INSN1(args, nd_line(node), getlocal, INT2FIX(idx));
    
  •    }
    
  •    i += j;
    
  •    argc = INT2FIX(i);
    
  • }
  • if (liseq->arg_rest != -1) {
  •    /* rest argument */
    
  •    int idx = liseq->local_size - liseq->arg_rest;
    
  •    ADD_INSN1(args, nd_line(node), getlocal, INT2FIX(idx));
    
  •    argc = INT2FIX(liseq->arg_rest + 1);
    
  •    flag |= VM_CALL_ARGS_SPLAT_BIT;
    
  • }
  • if (liseq->arg_post_len) {
  •    /* post arguments */
    
  •    int post_len = liseq->arg_post_len;
    
  •    int post_start = liseq->arg_post_start;
    
  •    if (liseq->arg_rest != -1) {
    
  •  int j;
    
  •  for (j=0; j<post_len; j++) {
    
  •      int idx = liseq->local_size - (post_start + j);
    
  •      ADD_INSN1(args, nd_line(node), getlocal, INT2FIX(idx));
    
  •  }
    
  •  ADD_INSN1(args, nd_line(node), newarray, INT2FIX(j));
    
  •  ADD_INSN (args, nd_line(node), concatarray);
    
  •  /* argc is setteled at above */
    
  •    }
    
  •    else {
    
  •  int j;
    
  •  for (j=0; j<post_len; j++) {
    
  •      int idx = liseq->local_size - (post_start + j);
    
  •      ADD_INSN1(args, nd_line(node), getlocal, INT2FIX(idx));
    
  •  }
    
  •  argc = INT2FIX(post_len + post_start);
    
  •    }
    
  • }
  •  }
    
  • }
  • argc = setup_args(iseq, args, node->nd_args, &flag);

    /* dummy receiver */
    ADD_INSN1(ret, nd_line(node), putobject,

  •  nd_type(node) == NODE_ZSUPER ? Qfalse : Qtrue);
    
  •  (flag & VM_CALL_SUPER_BIT) ? Qfalse : Qtrue);
    
  • flag &= ~VM_CALL_SUPER_BIT;
    ADD_SEQ(ret, args);
    ADD_INSN3(ret, nd_line(node), invokesuper,
    argc, parent_block, LONG2FIX(flag));
    diff --git i/gc.c w/gc.c
    index 58e4550…0d5fbad 100644
    — i/gc.c
    +++ w/gc.c
    @@ -1671,7 +1671,7 @@ gc_mark_children(rb_objspace_t *objspace, VALUE
    ptr, int lev)
    goto again;

    case NODE_ZARRAY: /* - */

  • case NODE_ZSUPER:
  • case NODE_DELEGATE:
    case NODE_VCALL:
    case NODE_GVAR:
    case NODE_LVAR:
    diff --git i/insns.def w/insns.def
    index f75007d…6c1efdc 100644
    — i/insns.def
    +++ w/insns.def
    @@ -993,10 +993,10 @@ send
    {
    const rb_method_entry_t *me;
    VALUE recv, klass;
  • rb_block_t *blockptr = 0;
  • rb_block_t *blockptr = (op_flag & VM_CALL_SUPER_BIT) ?
    GET_BLOCK_PTR() : 0;
    int num = caller_setup_args(th, GET_CFP(), op_flag, (int)op_argc,
    (rb_iseq_t *)blockiseq, &blockptr);
  • rb_num_t flag = op_flag;
  • rb_num_t flag = op_flag & ~VM_CALL_SUPER_BIT;
    ID id = op_id;

    /* get receiver */
    diff --git i/node.c w/node.c
    index 65bc541…f2900d3 100644
    — i/node.c
    +++ w/node.c
    @@ -408,10 +408,17 @@ dump_node(VALUE buf, VALUE indent, int comment,
    NODE *node)
    F_NODE(nd_args, “arguments”);
    break;

  •  case NODE_ZSUPER:
    
  • ANN(“super invocation with no argument”);
  • ANN(“format: super”);
  • ANN(“example: super”);
  •  case NODE_DELEGATE:
    
  •    if (node->nd_state) {
    
  •  ANN("argument delegation with block");
    
  •  ANN("format: ...");
    
  •  ANN("example: foo(...)");
    
  •    }
    
  • else {

  •  ANN("argument delegation without block");
    
  •  ANN("format: ..");
    
  •  ANN("example: foo(..)");
    
  • }
    break;

    case NODE_ARRAY:
    

diff --git i/node.h w/node.h
index f8cf7de…74320c0 100644
— i/node.h
+++ w/node.h
@@ -96,8 +96,8 @@ enum node_type {
#define NODE_VCALL NODE_VCALL
NODE_SUPER,
#define NODE_SUPER NODE_SUPER

  • NODE_ZSUPER,
    -#define NODE_ZSUPER NODE_ZSUPER
  • NODE_DELEGATE,
    +#define NODE_DELEGATE NODE_DELEGATE
    NODE_ARRAY,
    #define NODE_ARRAY NODE_ARRAY
    NODE_ZARRAY,
    @@ -414,7 +414,7 @@ typedef struct RNode {
    #define NEW_FCALL(m,a) NEW_NODE(NODE_FCALL,0,m,a)
    #define NEW_VCALL(m) NEW_NODE(NODE_VCALL,0,m,0)
    #define NEW_SUPER(a) NEW_NODE(NODE_SUPER,0,0,a)
    -#define NEW_ZSUPER() NEW_NODE(NODE_ZSUPER,0,0,0)
    +#define NEW_DELEGATE(b) NEW_NODE(NODE_DELEGATE,0,0,b)
    #define NEW_ARGS(m,o) NEW_NODE(NODE_ARGS,o,m,0)
    #define NEW_ARGS_AUX(r,b) NEW_NODE(NODE_ARGS_AUX,r,b,0)
    #define NEW_OPT_ARG(i,v) NEW_NODE(NODE_OPT_ARG,i,v,0)
    diff --git i/parse.y w/parse.y
    index 9fac5bd…735d1bf 100644
    — i/parse.y
    +++ w/parse.y
    @@ -2399,6 +2399,20 @@ opt_paren_args : none

opt_call_args : none
| call_args

  • | tDOT2
  •    {
    
  •    /*%%%*/
    
  •  $$ = NEW_DELEGATE(0);
    
  •    /*%
    
  •    %*/
    
  •    }
    
  • | tDOT3
  •    {
    
  •    /*%%%*/
    
  •  $$ = NEW_DELEGATE(1);
    
  •    /*%
    
  •    %*/
    
  •    }
    
    ;

call_args : command
@@ -3647,7 +3661,7 @@ method_call : operation paren_args
| keyword_super
{
/%%%/

  •  $$ = NEW_ZSUPER();
    
  •  $$ = NEW_SUPER(NEW_DELEGATE(1));
       /*%
     $$ = dispatch0(zsuper);
       %*/
    

diff --git i/test/ruby/test_method.rb w/test/ruby/test_method.rb
index 7be70b0…a04a285 100644
— i/test/ruby/test_method.rb
+++ w/test/ruby/test_method.rb
@@ -345,4 +345,38 @@ class TestMethod < Test::Unit::TestCase
obj.extend(m)
assert_equal([:m1, :a], obj.public_methods(false), bug)
end
+

  • def test_argument_delegate
  • class << (o = Object.new)
  •  def foo(*args)
    
  •    yield(*args)
    
  •  end
    
  •  def foo1(*)
    
  •    foo(...)
    
  •  end
    
  •  def foo2(*)
    
  •    foo1(...)
    
  •  end
    
  •  def bar(*args, &block)
    
  •    [args, block]
    
  •  end
    
  •  def bar1(*)
    
  •    bar(..)
    
  •  end
    
  •  def bar2(*)
    
  •    bar1(..)
    
  •  end
    
  • end
  • called = nil
  • assert_equal([42], o.foo1(42) {|*x| called = x})
  • assert_equal([42], called)
  • called = nil
  • assert_equal([42], o.foo2(42) {|*x| called = x})
  • assert_equal([42], called)
  • called = :not_called
  • assert_equal([[42], nil], o.bar1(42) {|*x| called = true})
  • assert_equal(:not_called, called)
  • assert_equal([[42], nil], o.bar2(42) {|*x| called = true})
  • assert_equal(:not_called, called)
  • end
    end

e$B1sF#$G$9!#e(B

2010e$BG/e(B6e$B7ne(B16e$BF|e(B18:57 Nobuyoshi N.
[email protected]:

Matzにっき(2010-06-15) e$B$r<BAu$7$F$_$^$7$?!#e(B

argument delegation e$B$O!"e(B

  • e$B%V%m%C%/$r0z$-7Q$,$;$?$$$@$1e(B (e$B0z?t$OJQ$($?$$e(B)
    e$B$H$-$KITJXe(B
  • e$B0z?t$NJQ?t$X$&$C$+$jBeF~$7$F!"4V0c$C$?0z?t$,EO$k;v7o$,B?H/$7$=$&e(B
  • define_method e$B$G%5%]!<%H$G$-$F$$$J$$e(B
    (e$B>-MhE*$K$5$l$kM=Dj$O$"$k!)e(B)

e$B$N$G!“$”$s$^$j9%$-$8$c$J$$$G$9!#e(B

e$B%V%m%C%/$r0z$-7Q$,$;$k$N$,LLE]$/$5$$$H$$$&F05!$O$H$F$b$h$/$o$+$k$N$G!"e(B

foo(a, b, c, &)

e$B$H=q$$$?$i$3$N%3%s%F%-%9%H$N%V%m%C%/$rEO$9!"$H$$$&$N$O$I$&$G$7$g$&$+!#e(B

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:41623] [Feature:trunk] argument delegation”
on Wed, 16 Jun 2010 18:57:40 +0900, Nobuyoshi N.
[email protected] writes:

|Matzにっき(2010-06-15) e$B$r<BAu$7$F$_$^$7$?!#e(B

e$B<j$,Aa$$!#e(B

|foo(…)e$B$G%V%m%C%/$^$G%3%_!“e(Bfoo(…)e$B$O%V%m%C%/H4$-$K$7$F$”$j$^$9!#e(B

foo(…)e$B$OITMW$@$H;W$$$^$9!#e(B

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:41625] Re: [Feature:trunk] argument
delegation”
on Thu, 17 Jun 2010 03:36:56 +0900, Yusuke ENDOH [email protected]
writes:

|argument delegation e$B$O!“e(B
|
|(1) e$B%V%m%C%/$r0z$-7Q$,$;$?$$$@$1e(B (e$B0z?t$OJQ$($?$$e(B) e$B$H$-$KITJXe(B
|(2) e$B0z?t$NJQ?t$X$&$C$+$jBeF~$7$F!“4V0c$C$?0z?t$,EO$k;v7o$,B?H/$7$=$&e(B
|(3) define_method e$B$G%5%]!<%H$G$-$F$$$J$$e(B (e$B>-MhE*$K$5$l$kM=Dj$O$”$k!)e(B)
|
|e$B$N$G!”$"$s$^$j9%$-$8$c$J$$$G$9!#e(B

(1) e$B$K$D$$$F$O!“%V%m%C%/$r0z$-7Q$,$;$?$$;~$K$O!“L@<(E*$K%V%m%Ce(B
e$B%/$r0z$-EO$;$P$h$$e(B(e$B$R$H$D$N$3$H$r$7$?$$$H$-$K!”$R$H$D$N$3e(B
e$B$H$r$9$l$P$h$$!#>iD9@-$O$J$$e(B)e$B$N$G!”<jEv$F$NI,MW$,$“$k$+e(B
e$B$I$&$+5?Ld$G$9!#:#2s$NF05!$O!V$R$H$D$N$3$H$r$9$k$N$K!”$Ue(B
e$B$?$D$N$3$H$r=q$+$J$$$H$$$1$J$$!W$H$$$&>iD9@-$G$9$+$i!#e(B

(2)
e$B$3$l$Oe(Bsupere$B$G$b$=$&$G$9$h$M!#@N!“e(Bsupere$B$O0z?t$NJQ?t$KBeF~e(B
e$B$7$F$b$=$N$^$^EO$k;EMM$@$C$?$N$G$9$,!”e$NLdBj$G$"$-e(B
e$B$i$a$^$7$?!#e(B

(3)
e$B>-MhE*$K$O!"e(Bdefine_methode$B$G$b%5%]!<%H$5$l$k$Y$-$@$H;W$$$^e(B
e$B$9!#$G$-$F$J$$$N$Oe$N@)Ls$@$H;W$C$F$/$@$5$$!#e(B

|e$B%V%m%C%/$r0z$-7Q$,$;$k$N$,LLE]$/$5$$$H$$$&F05!$O$H$F$b$h$/$o$+$k$N$G!“e(B
|
| foo(a, b, c, &)
|
|e$B$H=q$$$?$i$3$N%3%s%F%-%9%H$N%V%m%C%/$rEO$9!”$H$$$&$N$O$I$&$G$7$g$&$+!#e(B

e$B7+$jJV$7$K$J$j$^$9$,!“$3$l$G$O!V$R$H$D$N$3$H$r$9$k$N$K!”$U$?e(B
e$B$D$N$3$H$r=q$+$J$$$H$$$1$J$$!W$H$$$&>iD9@-$,2r7h$G$-$F$^$;$s!#e(B
e$B<B<ADI2C$Oe(B2e$BJ8;z$@$+$iIiC4$O7Z$/$J$j$^$9$,!#e(B

e$B$,!“$b$H$b$H$NF05!$H$OJL$H$7$F!”!Ve(B&e$B!We(B1e$BJ8;z$G$=$N%3%s%F%-%9%He(B
e$B$N%V%m%C%/$rEO$9$N$O!“LLGr$$%”%$%G%#%"$@$H;W$$$^$9!#$3$N>l9ge(B
e$B$O!“2>0z?t%j%9%H$N%V%m%C%/0z?t$,$J$/$F$b!”%V%m%C%/$rEO$9$3$He(B
e$B$K$J$k$s$G$9$+$M!#e(B

                            e$B$^$D$b$He(B e$B$f$-$R$me(B /:|)

2010e$BG/e(B6e$B7ne(B17e$BF|e(B6:31 Yukihiro M.
[email protected]:

|(1) e$B%V%m%C%/$r0z$-7Q$,$;$?$$$@$1e(B (e$B0z?t$OJQ$($?$$e(B) e$B$H$-$KITJXe(B

(1) e$B$K$D$$$F$O!“%V%m%C%/$r0z$-7Q$,$;$?$$;~$K$O!“L@<(E*$K%V%m%Ce(B
e$B%/$r0z$-EO$;$P$h$$e(B(e$B$R$H$D$N$3$H$r$7$?$$$H$-$K!”$R$H$D$N$3e(B
e$B$H$r$9$l$P$h$$!#>iD9@-$O$J$$e(B)e$B$N$G!”<jEv$F$NI,MW$,$“$k$+e(B
e$B$I$&$+5?Ld$G$9!#:#2s$NF05!$O!V$R$H$D$N$3$H$r$9$k$N$K!”$Ue(B
e$B$?$D$N$3$H$r=q$+$J$$$H$$$1$J$$!W$H$$$&>iD9@-$G$9$+$i!#e(B

e$B:#2s$NOC$K$O$J$<$+?($l$i$l$F$$$J$$$s$G$9$,!“e(B
e$B$3$N5!G=$NGX7J$N$R$H$D$K$O%-!<%o!<%I0z?t$,$”$k$h$&$K;W$($^$9!#e(B

e$B%-!<%o!<%I0z?t$r2C$($?$H$-$K!"%-!<%o!<%I0z?t$,e(B
e$BIaDL$N0z?t$G$b%V%m%C%/0z?t$G$b$J$$$b$N$H$9$k$H!"e(B
e$B$9$Y$F$N0z?t$r0z$-EO$9$N$Ke(B
3e$B$D$=$l$>$l$K$D$$$F0z$-EO$5$J$$$H$$$1$^$;$s!#e(B

e$B$=$l$rHr$1$k$?$a$K%-!<%o!<%I0z?t$rIaDL$N0z?t$N0lIt$K$9$k$H$$$&$3$H$K$7$?$i!“e(B
e$BH?O@$,=P$^$/$C$F;EMM$,$^$H$^$i$J$+$C$?!”$H$$$&$N$,;d$NG’<1$G$9!#e(B
[ruby-talk:162431]

e$B$=$l$J$i$9$Y$F$N0z?t$r0z$-EO$9$?$a$N5!G=$r$D$1$k!“$H$$$&%”%$%G%“$re(B
[ruby-talk:162561] e$B$de(B [ruby-dev:30892]
e$B$K=q$$$?$3$H$,$”$j$^$9$,!"e(B
e$B$=$N;~E@$G$OH?1~$rF@$i$l$^$;$s$G$7$?!#e(B

e$B$=$&$$$&N.$l$G:#2s$N$r8+$k$H!“$”$jF@$kJ}8~$@$H;W$&$o$1$G$9$,!“e(B
2e$B$D7|G0$,$”$j$^$9!#e(B

e$B:#$OIaDL$N0z?t$H%V%m%C%/0z?t$N$U$?$D$7$+$J$$$N$G!“e(B
e$B$R$H$D$rJQ$($k$J$i!”;D$j$O$R$H$D$7$+$“$j$^$;$s!#e(B
e$B$7$?$,$C$F!”;D$j$9$Y$F$r0z$-EO$9$N$O$R$H$D=q$1$P:Q$_$^$9!#e(B

e$B$7$+$7!"%-!<%o!<%I0z?t$,F~$k$H$_$C$D$K$J$k$N$G!“e(B
e$B$R$H$D$rJQ$($k$J$i!”;D$j$O$U$?$D$K$J$j$^$9!#e(B
e$B;D$j$9$Y$F$r0z$-EO$9$N$K$U$?$D=q$/I,MW$,=P$F$-$^$9!#e(B
e$B$*$=$i$/$3$l$O$&$l$7$/$J$$$G$7$g$&!#e(B

e$B$D$^$j!“e(Bargument delegation
e$B$O%-!<%o!<%I0z?t$rF~$l$k$H$-$K:$$kLdBj$r2r7h$9$ke(B
e$B$+$b$7$l$J$$$H;W$C$?$i!”<B:]$N$H$3$m$O$“$^$j2r7h$7$F$$$J$$!”$H$$$&$o$1$G$9!#e(B

|(3) define_method e$B$G%5%]!<%H$G$-$F$$$J$$e(B (e$B>-MhE*$K$5$l$kM=Dj$O$"$k!)e(B)

(3) e$B>-MhE*$K$O!"e(Bdefine_methode$B$G$b%5%]!<%H$5$l$k$Y$-$@$H;W$$$^e(B
e$B$9!#$G$-$F$J$$$N$Oe$N@)Ls$@$H;W$C$F$/$@$5$$!#e(B

e$B$b$&$R$H$D$Oe(B define_method e$B$de(B lambda e$B$H$N4XO"$G$9!#e(B

… e$B$H$$$&9=J8$K$OL>A0$,F~$C$F$$$J$$$N$G!"e(B

def f(a)
lambda {|b|
g(…)
}
end

e$B$H$7$?$H$-$Ke(B … e$B$O$I$N0z?t$r;X$9$N$+ITL@$G$9!#e(B

e$B;EMM$H$7$F$I$A$i$+$K8GDj$9$k$3$H$O$G$-$k$G$7$g$&$,!"e(B
e$B%W%m%0%i%^$,A*$Y$k$h$&$J9=J8$K$O$J$C$F$$$^$;$s!#e(B

e$B$=$N$&$A!"A*$Y$k$h$&$K$9$k9=J8$,MW5a$5$l$k$h$&$K$J$k$s$8$c$J$$$G$7$g$&$+!#e(B

e$B1sF#$G$9!#e(B

2010e$BG/e(B6e$B7ne(B17e$BF|e(B6:31 Yukihiro M.
[email protected]:

|(1) e$B%V%m%C%/$r0z$-7Q$,$;$?$$$@$1e(B (e$B0z?t$OJQ$($?$$e(B) e$B$H$-$KITJXe(B

(1) (e$BN,e(B) e$B:#2s$NF05!$O!V$R$H$D$N$3$H$r$9$k$N$K!"$Ue(B
e$B$?$D$N$3$H$r=q$+$J$$$H$$$1$J$$!W$H$$$&>iD9@-$G$9$+$i!#e(B

e$B$J$k$[$I!#!VDL>o$N0z?t$H%V%m%C%/0z?t$r$^$H$a$Fe(B delegate
e$B$7$?$$!We(B
e$B$H46$8$?$3$H$,$"$^$j$J$+$C$?$N$G!"F05!$r4*0c$$$7$F$$$^$7$?!#e(B

lib/ e$B$rAF$C$]$/C5$7$F$_$?$i!“e(B24 e$B2U=j$[$I8+$D$+$j$^$7$?e(B
(e$B%a!<%k$Ne(B
e$B:G8e$KE=$j$D$1$F$”$j$^$9e(B) e$B!#$=$l$J$j$K<{MW$O$"$k$N$+$J!#e(B

e$B$,!“$b$H$b$H$NF05!$H$OJL$H$7$F!”!Ve(B&e$B!We(B1e$BJ8;z$G$=$N%3%s%F%-%9%He(B
e$B$N%V%m%C%/$rEO$9$N$O!“LLGr$$%”%$%G%#%"$@$H;W$$$^$9!#$3$N>l9ge(B
e$B$O!“2>0z?t%j%9%H$N%V%m%C%/0z?t$,$J$/$F$b!”%V%m%C%/$rEO$9$3$He(B
e$B$K$J$k$s$G$9$+$M!#e(B

e$BDL>o$N0z?t$O4X78$J$/!“%V%m%C%/0z?t$r0z$-7Q$,$;$?$$;vNc$J$i!”>e$He(B
e$BF1$8$h$&$J8!:w$Ge(B 183 e$B2U=je(B (e$B>e$Ne(B 24 e$B2U=j$r4^$`e(B)
e$B$b8+$D$+$C$?$N$G!"e(B
& e$B$N>JN,5-K!$O@'HsM_$7$/$J$C$F$-$^$7$?!#e(B

$ ruby check.rb
lib/drb/drb.rb
1079: def method_missing(msg_id, *a, &b)
1083: return obj.send(msg_id, *a, &b)

lib/test/unit/assertions.rb
22: def assert_raise(*args, &b)
23: assert_raises(*args, &b)

lib/rake.rb
743: def create_rule(*args, &block)
744: Rake.application.create_rule(*args, &block)

lib/rake.rb
844:def task(*args, &block)
845: Rake::Task.define_task(*args, &block)

lib/rake.rb
862:def file(*args, &block)
863: Rake::FileTask.define_task(*args, &block)

lib/rake.rb
868:def file_create(args, &block)
869: Rake::FileCreationTask.define_task(args, &block)

lib/rake.rb
892:def multitask(args, &block)
893: Rake::MultiTask.define_task(args, &block)

lib/rake.rb
918:def rule(*args, &block)
919: Rake::Task.create_rule(*args, &block)

lib/scanf.rb
607: def scanf(str,&b)
608: return block_scanf(str,&b) if b

lib/scanf.rb
687: def scanf(fstr,&b)
689: block_scanf(fstr,&b)

lib/scanf.rb
716: def scanf(fs,&b)
717: STDIN.scanf(fs,&b)

lib/rubygems/user_interaction.rb
62: def use_ui(new_ui, &block)
63: Gem::DefaultUserInteraction.use_ui(new_ui, &block)

lib/optparse.rb
832: def accept(*args, &blk) top.accept(*args, &blk) end
836: def self.accept(*args, &blk) top.accept(*args, &blk) end

lib/optparse.rb
1202: def on(*opts, &block)
1203: define(*opts, &block)

lib/optparse.rb
1216: def on_head(*opts, &block)
1217: define_head(*opts, &block)

lib/optparse.rb
1230: def on_tail(*opts, &block)
1231: define_tail(*opts, &block)

lib/optparse.rb
1425: def visit(id, *args, &block)
1427: el.send(id, *args, &block)

lib/csv.rb
2308:def CSV(*args, &block)
2309: CSV.instance(*args, &block)

lib/erb.rb
334: def percent_line(line, &block)
336: return @scan_line.call(line, &block)

lib/erb.rb
334: def percent_line(line, &block)
341: @scan_line.call(line, &block)

lib/matrix.rb
1457: def map2(v, &block) # :yield: e1, e2
1459: els = collect2(v, &block)

lib/set.rb
613: def initialize(*args, &block) # :nodoc:
615: initialize(*args, &block)

lib/delegate.rb
141: def method_missing(m, *args, &block)
144: target.respond_to?(m) ? target.send(m, *args, &block) :
super(m, *args, &block)

lib/open-uri.rb
27: def open(name, *rest, &block) # :doc:
35: open_uri_original_open(name, *rest, &block)

count: 24

$ cat check.rb
count = 0
Dir.glob("lib/**/.rb").each do |path|
next unless File.file?(path)
open(path) do |file|
while line = file.gets
if line =~ /^(\s
)def\s+[\d\w]+((.,.&.))/ #
e$BN>J}0z$-7Q$,$;$k;vNce(B
#if line =~ /^(\s
)def\s+[\d\w]+(.(&.))/ #
e$B%V%m%C%/0z?t$r0z$-7Q$,$;$k;vNce(B
sig = line
lineno = file.lineno
re1 = /^\s{#{ $1.size }}end/
re2 = Regexp.new(Regexp.quote($2))
while line = file.gets
break if re1 =~ line
if re2 =~ line
puts path
puts “#{ lineno }:#{ sig }”
puts “#{ file.lineno }:#{ line }”
puts
count += 1
end
end
end
end
end
end
puts “count: #{ count }”

e$BA0ED$G$9!#e(B

argument delegatione$B$K$D$$$F$O$^$@BVEY$r7h$a$+$M$F$$$k$N$G$9$,!"e(B
super(…)e$B$,F3F~$5$l$?$i!"e(B(e$B7Y9p$r=P$9$J$I$N0\9T%9%F%C%W$r7P$Fe(B)
e$B3g8L$J$7e(Bsupere$B$Oe(Bsuper()e$B$HF1$80UL#$K$7$F$7$^$C$F$O$I$&$G$7$g$&$+!#e(B

2010e$BG/e(B6e$B7ne(B17e$BF|e(B6:31 Yukihiro M.
[email protected]:

(2) e$B$3$l$Oe(Bsupere$B$G$b$=$&$G$9$h$M!#@N!“e(Bsupere$B$O0z?t$NJQ?t$KBeF~e(B
e$B$7$F$b$=$N$^$^EO$k;EMM$@$C$?$N$G$9$,!”e$NLdBj$G$"$-e(B
e$B$i$a$^$7$?!#e(B

supere$B$G$O%V%m%C%/0z?t$X$NBeF~$,H?1G$5$l$J$$F0:n$K$J$C$F$$$^$9$,!"e(B
argument delegatione$B$G$O$I$&$J$j$^$9$+e(B?

def foo(&b)
b = lambda { puts “lambda in foo” }
bar(…)
end

e$B$H$$$&%1!<%9$NOC$G$9$,!#e(B

e$B!!$5$5$@$G$9!%e(B

(2010/06/17 6:31), Yukihiro M. wrote::

e$B$H$r$9$l$P$h$$!#>iD9@-$O$J$$e(B)e$B$N$G!"<jEv$F$NI,MW$,$"$k$+e(B
e$B$I$&$+5?Ld$G$9!#:#2s$NF05!$O!V$R$H$D$N$3$H$r$9$k$N$K!"$Ue(B
e$B$?$D$N$3$H$r=q$+$J$$$H$$$1$J$$!W$H$$$&>iD9@-$G$9$+$i!#e(B

(2) e$B$3$l$Oe(Bsupere$B$G$b$=$&$G$9$h$M!#@N!“e(Bsupere$B$O0z?t$NJQ?t$KBeF~e(B
e$B$7$F$b$=$N$^$^EO$k;EMM$@$C$?$N$G$9$,!”e$NLdBj$G$"$-e(B
e$B$i$a$^$7$?!#e(B

(3) e$B>-MhE*$K$O!"e(Bdefine_methode$B$G$b%5%]!<%H$5$l$k$Y$-$@$H;W$$$^e(B
e$B$9!#$G$-$F$J$$$N$Oe$N@)Ls$@$H;W$C$F$/$@$5$$!#e(B

e$B!!!Ve$N@)Ls!W$O$=$N$H$*$j$G!$8@8l%G%6%$%s$H$7$F$"$k$Y$-$G$O$J$$$H;We(B
e$B$$$^$9!%e(B

e$B!J<BAu$,4JC1$+$I$&$+$OJL$NOC$G$9$1$I!Ke(B

e$B!!$=$l$OCV$$$H$$$F!$$3$l!$$=$s$J$K;H$&$s$G$7$g$&$+!%$“$^$j;H$o$J$$5!G=e(B
e$B$K!$?7$7$$5-9f$rF~$l$k$N$ODq93$,$”$j$^$9!%$H$/$K!$e(Bfoo(…)
e$B$H$+!$5<;we(B
e$B%3!<%I$G$h$/;H$&$N$G!$Dq93$,$"$j$^$9!%J8L.$G$o$+$k$C$A$c$o$+$k$s$G$9$,!%e(B

e$BMxMQNc!'e(B
http://rurema.clear-code.com/query:(...)/

e$B!!1sF#$5$s$Ne(B

|e$B%V%m%C%/$r0z$-7Q$,$;$k$N$,LLE]$/$5$$$H$$$&F05!$O$H$F$b$h$/$o$+$k$N$G!“e(B
|
| foo(a, b, c, &)
|
|e$B$H=q$$$?$i$3$N%3%s%F%-%9%H$N%V%m%C%/$rEO$9!”$H$$$&$N$O$I$&$G$7$g$&$+!#e(B

e$B$NOC$O!$$“$”!$$"$C$?$i;H$&$+$b!$$H;W$$$^$7$?!%e(B

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:41634] Re: [Feature:trunk] argument
delegation”
on Thu, 17 Jun 2010 13:58:53 +0900, Shugo M.
[email protected] writes:

|argument delegatione$B$K$D$$$F$O$^$@BVEY$r7h$a$+$M$F$$$k$N$G$9$,!"e(B
|super(…)e$B$,F3F~$5$l$?$i!"e(B(e$B7Y9p$r=P$9$J$I$N0\9T%9%F%C%W$r7P$Fe(B)
|e$B3g8L$J$7e(Bsupere$B$Oe(Bsuper()e$B$HF1$80UL#$K$7$F$7$^$C$F$O$I$&$G$7$g$&$+!#e(B

e$B$&!<$s!“e(Bsupere$B$,e(Bsuper()e$B$N0UL#$G$”$C$F$&$l$7$$$N$O!"e(B

  • e$B%k!<%k$,>/$J$/$J$ke(B
  • e$BL50z?te(Bsupere$B$N8F$S=P$7$,==J,$KB?$$e(B

e$B$N$$$:$l$+$@$H;W$&$N$G$9$,!“A0<T$O7k6I$Oe(BRubye$B$N@_7W$G$OM%@hEYe(B
e$B$,Dc$$!V0l4S@-!W$r9b$a$k$H$$$&$3$H$J$N$G!”$3$N:]!V$&$l$7$$!We(B
e$B$H$OI>2A$7$^$;$s!#e(B

e$B8e<T$G$9$,!"$3$l$,<B:]E*$K$&$l$7$$$N$Oe(B

  • supere$B$r4^$`%a%=%C%I$,0z?t$r#18D0J>e<u$1<h$je(B
  • supere$B$K$O$R$H$D$bEO$5$J$$e(B

e$B$H$$$&%1!<%9$@$1$G!"e(Bsupere$B$N;H$$F;$N$&$AB?$/$r4^$`e(B(e$B$H;W$o$l$ke(B)

  • supere$B$r4^$`%a%=%C%I$,0z?t$r#18D0J>e<u$1<h$je(B
  • supere$B$K$=$N$^$^EO$9e(B

e$B>l9g!“$3$l$^$Ge(Bsupere$B$@$1$G$9$s$@$b$N$re(Bsuper(…)e$B$H=q$+$M$P$J$ie(B
e$B$:!”$A$C$H$b$&$l$7$/$"$j$^$;$s!#e(B

  • supere$B$r4^$`%a%=%C%I$,0z?t$r#18D0J>e<u$1<h$je(B
  • supere$B$K$OJL$N0z?t$rEO$9e(B

e$B>l9g!“e(Bargment delegatione$B$OLr$KN)$?$J$$$N$O;v<B$G$9$,!”$=$l$Oe(B
supere$B$re(Bsuper()e$B$K$9$k$3$H$H$OL54X78$G$7$g$&!#e(B

|supere$B$G$O%V%m%C%/0z?t$X$NBeF~$,H?1G$5$l$J$$F0:n$K$J$C$F$$$^$9$,!"e(B
|argument delegatione$B$G$O$I$&$J$j$^$9$+e(B?
|
| def foo(&b)
| b = lambda { puts “lambda in foo” }
| bar(…)
| end
|
|e$B$H$$$&%1!<%9$NOC$G$9$,!#e(B

e$B!Ve(Bsupere$B$HF1$8F0:n!W$H$$$&$N$,4pK$@$H;W$$$^$9!#K\Ev$O!"DL>oe(B
e$B0z?t$bBeF~$,H?1G$5$l$J$$$h$&$K$7$?$$$N$G$9$,!"e(BYARVe$B$N<BAu$@$He(B
e$BFq$7$$$HJ9$$$?$h$&$J5$$,$7$^$9!#e(B

                            e$B$^$D$b$He(B e$B$f$-$R$me(B /:|)

(2010/06/17 14:53), Yukihiro M. wrote::

e$B!Ve(Bsupere$B$HF1$8F0:n!W$H$$$&$N$,4pK$@$H;W$$$^$9!#K\Ev$O!"DL>oe(B
e$B0z?t$bBeF~$,H?1G$5$l$J$$$h$&$K$7$?$$$N$G$9$,!"e(BYARVe$B$N<BAu$@$He(B
e$BFq$7$$$HJ9$$$?$h$&$J5$$,$7$^$9!#e(B

e$B!!<BAu$8$c$J$/$F%Q%U%)!<%^%s%9$rM}M3$K$*4j$$$7$^$7$?!%0z?tNN0h$N%3%T!<e(B
e$B$r!$%9%?%C%/%U%l!<%@Q$$4$H$K9T$&$N$O7y$G$9!J7y$J$N$O26$@$1$+$b!K!%e(B

zsuper e$B$,$"$C$?$H$-$@$1!$$H$$$&$N$be(B eval

e$B$,$"$k$+$i7k6I%@%a!%e(B

e$B!!0UL#E*$K$b!$8D?ME*$K$Oe(B 1.9 e$B$N;EMM$,9%$-$J$N$G$9$,!%e(B

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:41629] Re: [Feature:trunk] argument
delegation”
on Thu, 17 Jun 2010 10:45:11 +0900, SASADA Koichi [email protected]
writes:

|e$B!!$=$l$OCV$$$H$$$F!$$3$l!$$=$s$J$K;H$&$s$G$7$g$&$+!%$“$^$j;H$o$J$$5!G=e(B
|e$B$K!$?7$7$$5-9f$rF~$l$k$N$ODq93$,$”$j$^$9!%$H$/$K!$e(Bfoo(…) e$B$H$+!$5<;we(B
|e$B%3!<%I$G$h$/;H$&$N$G!$Dq93$,$"$j$^$9!%J8L.$G$o$+$k$C$A$c$o$+$k$s$G$9$,!%e(B
|
|e$BMxMQNc!'e(B
|クエリ:(...) | るりまサーチ

e$B$=$s$J$KIQHK$K;H$&$+$H8@$&$H!"$=$3$^$G$G$O$J$$$H;W$$$^$9!#$,!“e(B
e$BA4A3$J$$$o$1$G$O$”$j$^$;$s$7!“7+$jJV$7$K$J$j$^$9$,!”!V$d$j$?e(B
e$B$$$3$H$KBP$9$k>iD9@-!W$+$i9M$($k$H<jEv$F$r$7$?J}$,$h$$$H;W$$e(B
e$B$^$9!#e(B

e$B$7$+$7!“!Ve(B…e$B!W$K$=$3$^$G$3$@$o$C$F$$$k$o$1$G$O$”$j$^$;$s$N$G!"e(B
e$BB>$NJ8K!$G$b9=$$$^$;$s!#$?$@$7!“e(BRe$B$de(BLuae$B$G$OF1$8L\E*$K!Ve(B…e$B!W$,e(B
e$B;H$o$l$F$$$^$9$+$i!”$=$s$J$K0-$$0F$G$b$J$$$@$m$&$H;W$C$F$^$9!#e(B

e$BA0ED$G$9!#e(B

2010e$BG/e(B6e$B7ne(B17e$BF|e(B14:53 Yukihiro M.
[email protected]:

e$B$,Dc$$!V0l4S@-!W$r9b$a$k$H$$$&$3$H$J$N$G!"$3$N:]!V$&$l$7$$!We(B
e$B$H$OI>2A$7$^$;$s!#e(B

e$B6/$$$F$$$($PA0<T$G$9$,!"%k!<%k$,>/$J$/$J$k$3$H$=$N$b$N$,$&$l$7$$e(B
e$B$N$G$O$J$/$F!"DL>o$N%a%=%C%I8F=P$7$@$He(B()e$B$rIU$1$J$/$F$b$h$$$N$K!“e(B
supere$B$N$H$-$@$10z?t$,$J$$$N$Ke(B()e$B$rIU$1$J$$$H$$$1$J$$$N$,e(B(e$B8+$?L\e(B
e$BE*$Ke(B)e$B5$;}$A0-$$!”$H$$$&M}M3$G$9!#e(B

e$B8e<T$G$9$,!"$3$l$,<B:]E*$K$&$l$7$$$N$Oe(B

  • supere$B$r4^$`%a%=%C%I$,0z?t$r#18D0J>e<u$1<h$je(B
  • supere$B$K$O$R$H$D$bEO$5$J$$e(B

e$B$H$$$&%1!<%9$@$1$G!"e(B

e$B;d$N7P83$G$O!"e(Binitializee$B$r%!<%P!<%i%$%I$9$k$H$-$Ke(Bsuper()e$B$H=q$+$J$$$He(B
e$B$$$1$J$/$F5$;}$A0-$$$H46$8$k$3$H$,7k9=$"$j$^$7$?!#e(B
e$B$A$J$_$KI8=`E:IU%i%$%V%i%j$K$
$1$ke(Bsuper/super()e$B$NMxMQ2U=j$rD4$Y$?$H$3$me(B

super: 391e$B2U=je(B
super(): 292e$B2U=je(B

e$B$H$$$&7k2L$G$7$?!#0U30$H$$$$>!Ii$8$c$J$$$G$7$g$&$+!#e(B

supere$B$N;H$$F;$N$&$AB?$/$r4^$`e(B(e$B$H;W$o$l$ke(B)

  • supere$B$r4^$`%a%=%C%I$,0z?t$r#18D0J>e<u$1<h$je(B
  • supere$B$K$=$N$^$^EO$9e(B

e$B>l9g!“$3$l$^$Ge(Bsupere$B$@$1$G$9$s$@$b$N$re(Bsuper(…)e$B$H=q$+$M$P$J$ie(B
e$B$:!”$A$C$H$b$&$l$7$/$"$j$^$;$s!#e(B

5e$BJ8;z$N@aLs$,=EMW$K$J$k$[$I$h$/;H$&5!G=$G$b$J$$$H;W$&$N$G!"e(B
e$BC;$$5-=R$G:Q$$3$H$h$j$b!"B>$N5!G=$H$NN?d$Ge(Bsupere$B$N5sF0$re(B
e$B?dB,$G$-$k$3$H$NJ}$,MxE@$,Bg$-$$$h$&$K;W$$$^$9!#e(B

e$B$?$@!“8_49@-$NLdBj$b$”$ke(B(e$B4{B8$N%9%/%j%W%H$O5!3#E*$KCV49$G$-$ke(B
e$B$s$8$c$J$$$+$H;W$$$^$9$,e(B)e$B$N$G!"$=$l$[$I6/$/$O<gD%$7$^$;$s!#e(B

e$B!Ve(Bsupere$B$HF1$8F0:n!W$H$$$&$N$,4pK$@$H;W$$$^$9!#K\Ev$O!"DL>oe(B
e$B0z?t$bBeF~$,H?1G$5$l$J$$$h$&$K$7$?$$$N$G$9$,!"e(BYARVe$B$N<BAu$@$He(B
e$BFq$7$$$HJ9$$$?$h$&$J5$$,$7$^$9!#e(B

e$B@-G=>e$NM}M3$H$$$&$3$H$GN;2r$7$^$7$?!#e(B

e$B8D?ME*$K$O!“0z?t$KBeF~$9$k$N$O0-$$%9%?%$%k$@$H;W$C$F$k$N$G!”$I$C$A$G$be(B

e$B$$$$$s$G$9$1$I!#e(B

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:41641] Re: [Feature:trunk] argument
delegation”
on Thu, 17 Jun 2010 17:05:10 +0900, Shugo M.
[email protected] writes:

|e$B;d$N7P83$G$O!"e(Binitializee$B$r%!<%P!<%i%$%I$9$k$H$-$Ke(Bsuper()e$B$H=q$+$J$$$He(B
|e$B$$$1$J$/$F5$;}$A0-$$$H46$8$k$3$H$,7k9=$"$j$^$7$?!#e(B
|e$B$A$J$_$KI8=`E:IU%i%$%V%i%j$K$
$1$ke(Bsuper/super()e$B$NMxMQ2U=j$rD4$Y$?$H$3$me(B
|
| super: 391e$B2U=je(B
| super(): 292e$B2U=je(B
|
|e$B$H$$$&7k2L$G$7$?!#0U30$H$$$$>!Ii$8$c$J$$$G$7$g$&$+!#e(B

e$B$&!<$s!“;d$,e(B lib/**/.rb e$B$G?t$($?$ie(B
super()e$B!"$D$^$jL@<(E
$KL5e(B
e$B0z?t$G8F$S=P$7$?e(Bsupere$B$Oe(B66e$B2U=j$7$+8+$D$+$j$^$;$s$G$7$?!#$&$Ae(B2
e$B2U=j$O%a%=%C%I$K0z?t$,$J$$$N$Ge(Bsupere$B$G$bF1$8$3$H$G$9!#5U$K0EL[e(B
e$B$K0z?t$r0z$-EO$9e(Bsupere$B$Oe(B243e$B2U=j$G$9!#>/!9$N?t$($b$l$,$”$C$F$be(B
e$B$*$+$7$/$J$$$G$9$,!“$”$^$j$K$b0c$&$N$G!"$b$7$+$7$F?t$(J}$,0ce(B
e$B$&!)e(B

|5e$BJ8;z$N@aLs$,=EMW$K$J$k$[$I$h$/;H$&5!G=$G$b$J$$$H;W$&$N$G!"e(B
|e$BC;$$5-=R$G:Q$$3$H$h$j$b!"B>$N5!G=$H$NN?d$Ge(Bsupere$B$N5sF0$re(B
|e$B?dB,$G$-$k$3$H$NJ}$,MxE@$,Bg$-$$$h$&$K;W$$$^$9!#e(B

e$B;d!"$1$C$3$&e(B(e$B0z?tE>Aw$Ne(B) super e$B;H$&$s$@$1$I$J!#e(B

                            e$B$^$D$b$He(B e$B$f$-$R$me(B /:|)

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:41631] Re: [Feature:trunk] argument
delegation”
on Thu, 17 Jun 2010 12:05:22 +0900, Tanaka A. [email protected]
writes:

|e$B$=$&$$$&N.$l$G:#2s$N$r8+$k$H!“$”$jF@$kJ}8~$@$H;W$&$o$1$G$9$,!“e(B
|2e$B$D7|G0$,$”$j$^$9!#e(B
|
|e$B:#$OIaDL$N0z?t$H%V%m%C%/0z?t$N$U$?$D$7$+$J$$$N$G!“e(B
|e$B$R$H$D$rJQ$($k$J$i!”;D$j$O$R$H$D$7$+$“$j$^$;$s!#e(B
|e$B$7$?$,$C$F!”;D$j$9$Y$F$r0z$-EO$9$N$O$R$H$D=q$1$P:Q$$^$9!#e(B
|
|e$B$7$+$7!"%-!<%o!<%I0z?t$,F~$k$H$
$C$D$K$J$k$N$G!“e(B
|e$B$R$H$D$rJQ$($k$J$i!”;D$j$O$U$?$D$K$J$j$^$9!#e(B
|e$B;D$j$9$Y$F$r0z$-EO$9$N$K$U$?$D=q$/I,MW$,=P$F$-$^$9!#e(B
|e$B$*$=$i$/$3$l$O$&$l$7$/$J$$$G$7$g$&!#e(B

e$B!V$R$H$D$rJQ$($k!W$H$$$&0UL#$,$$$^$$$AFI$_<h$l$J$+$C$?$N$G$9e(B
e$B$,!“$3$l$O$?$H$($P!”!VDL>o$N0z?t$NA0$K$R$H$DJL$N0z?t$r2C$($k!We(B
e$B$H$+!"!VDL>o0z?t$OF1$8$@$,!"EO$9%V%m%C%/$@$1JQ$($k!W$H$+$=$&e(B
e$B$$$&0UL#$J$s$G$7$g$&$+!#e(B

e$B$@$H$9$k$H!“$$C$7$c$k$3$H$OM}2r$G$-$^$9!#$?$@$7!"$$$^$N$H$3e(B
e$B$m%-!<%o!<%I0z?t$ODL>o$N0z?t$N0lIt$H$7$F07$
$&$H;W$C$F$$$k$Ne(B
e$B$G!”$"$^$jLdBj$K$O$J$i$J$$$+$b$7$l$^$;$s!#e(B

|e$B$b$&$R$H$D$Oe(B define_method e$B$de(B lambda e$B$H$N4XO"$G$9!#e(B
|
|… e$B$H$$$&9=J8$K$OL>A0$,F~$C$F$$$J$$$N$G!"e(B
|
|def f(a)
| lambda {|b|
| g(…)
| }
|end
|
|e$B$H$7$?$H$-$Ke(B … e$B$O$I$N0z?t$r;X$9$N$+ITL@$G$9!#e(B

e$B3N$+$K!#$?$@$7!“!V0lHVFbB&$N0z?t!W$H$+!Ve(Blambdae$B$OL5;k!”%a%=%Ce(B
e$B%I$N0z?t!W$G$b$I$A$i$G$b$“$^$jLdBj$J$$$h$&$J5$$b$7$^$9!#$H$$e(B
e$B$&$N$b!”$3$N5-K!$O!“$G$-$J$$$3$H$r$G$-$k$h$&$K$9$k$b$N$G$O$Je(B
e$B$/$F!”$a$s$I$/$5$$$b$N$r$h$j3Z$KI=8=$7$h$&$H$$$&$b$N$G$9$+$i!“e(B
e$B;EMM$NJ#;(2=$rHr$1$F$”$kDxEY$G!V$"$-$i$a$k!W$H$$$&$N$O==J,$"e(B
e$B$j$($kH=CG$@$H;W$$$^$9!#e(B

|e$B;EMM$H$7$F$I$A$i$+$K8GDj$9$k$3$H$O$G$-$k$G$7$g$&$,!"e(B
|e$B%W%m%0%i%^$,A*$Y$k$h$&$J9=J8$K$O$J$C$F$$$^$;$s!#e(B
|
|e$B$=$N$&$A!"A*$Y$k$h$&$K$9$k9=J8$,MW5a$5$l$k$h$&$K$J$k$s$8$c$J$$$G$7$g$&$+!#e(B

e$B$=$N$h$&$J;EMM$N$R$H$D$N0F$H$7$F$O!“!Ve(B…e$B!W$=$N$b$N$r<0$H$7$Fe(B
e$B$7$^$C$F!”$=$NCM$re(B[ruby-talk:162561]e$B$G<($5$l$?$h$&$J%*%V%8%'e(B
e$B%/%H$K$9$kJ}K!$,$"$j$^$9$M!#$=$N>l9g$K$O!Ve(Be$B!W$H!Ve(Bobje$B!W$NJ}e(B
e$B$,NI$$$+$b$7$l$^$;$s$,!#e(B

e$B$D$^$j!"e(B

def f(a)
c = **
lambda {|b|
g(**c) # ae$B$rEO$9e(B
}
end

def f(a)
lambda {|b|
g(**) # be$B$rEO$9e(B
}
end

e$B$H$$$&$3$H$G$9$M!#$?$@!“e(Bover spece$B$J0u>]$,$”$j$^$9!#e(B

                            e$B$^$D$b$He(B e$B$f$-$R$me(B /:|)

e$B!!$5$5$@$G$9!%e(B

(2010/06/17 15:17), Yukihiro M. wrote::

|e$B!!0UL#E*$K$b!$8D?ME*$K$Oe(B 1.9 e$B$N;EMM$,9%$-$J$N$G$9$,!%e(B

e$BFC$K:#$N$G$O%@%a$H;W$C$F$k$o$1$G$O$J$$$N$G$9$,e(B(e$B0z?t$r=q$-49e(B
e$B$($k$d$D$,0-$$e(B)e$B!"$?$@$7!"$5$5$@$/$s$,$I$&$7$F!Ve(B1.9 e$B$N;EMM$,e(B
e$B9%$-!W$J$N$+!"$=$NM}M3$K$O4X?4$,$"$j$^$9!#e(B

e$B!!=q$-49$($k<+M3$,$"$k$N$G!$$=$C$A$N$[$&$,$$$$$+$J$!!$$H!%e(B

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:41636] Re: [Feature:trunk] argument
delegation”
on Thu, 17 Jun 2010 15:03:33 +0900, SASADA Koichi [email protected]
writes:

|e$B!!<BAu$8$c$J$/$F%Q%U%)!<%^%s%9$rM}M3$K$*4j$$$7$^$7$?!%0z?tNN0h$N%3%T!<e(B
|e$B$r!$%9%?%C%/%U%l!<%@Q$$4$H$K9T$&$N$O7y$G$9!J7y$J$N$O26$@$1$+$b!K!%e(B

e$B$=$&$$$($P$=$&$@$C$?$h$&$J!#e(B

|e$B!!0UL#E*$K$b!$8D?ME*$K$Oe(B 1.9 e$B$N;EMM$,9%$-$J$N$G$9$,!%e(B

e$BFC$K:#$N$G$O%@%a$H;W$C$F$k$o$1$G$O$J$$$N$G$9$,e(B(e$B0z?t$r=q$-49e(B
e$B$($k$d$D$,0-$$e(B)e$B!“$?$@$7!”$5$5$@$/$s$,$I$&$7$F!Ve(B1.9
e$B$N;EMM$,e(B
e$B9%$-!W$J$N$+!“$=$NM}M3$K$O4X?4$,$”$j$^$9!#e(B

                            e$B$^$D$b$He(B e$B$f$-$R$me(B /:|)

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:41644] Re: [Feature:trunk] argument
delegation”
on Thu, 17 Jun 2010 22:29:19 +0900, Yusuke ENDOH [email protected]
writes:

|e$BDL>o$N0z?t$O4X78$J$/!“%V%m%C%/0z?t$r0z$-7Q$,$;$?$$;vNc$J$i!”>e$He(B
|e$BF1$8$h$&$J8!:w$Ge(B 183 e$B2U=je(B (e$B>e$Ne(B 24 e$B2U=j$r4^$`e(B) e$B$b8+$D$+$C$?$N$G!"e(B
|& e$B$N>JN,5-K!$O@'HsM_$7$/$J$C$F$-$^$7$?!#e(B

e$B$3$l$ONI$$%“%$%G%#%”$@$H;W$$$^$9!#$b$7$+$9$k$H85$N%"%$%G%#%"e(B
e$B$h$j$b!#e(B

e$BA0ED$G$9!#e(B

2010e$BG/e(B6e$B7ne(B17e$BF|e(B19:06 Yukihiro M.
[email protected]:

e$B0z?t$G8F$S=P$7$?e(Bsupere$B$Oe(B66e$B2U=j$7$+8+$D$+$j$^$;$s$G$7$?!#$&$Ae(B2
e$B2U=j$O%a%=%C%I$K0z?t$,$J$$$N$Ge(Bsupere$B$G$bF1$8$3$H$G$9!#5U$K0EL[e(B
e$B$K0z?t$r0z$-EO$9e(Bsupere$B$Oe(B243e$B2U=j$G$9!#>/!9$N?t$($b$l$,$“$C$F$be(B
e$B$*$+$7$/$J$$$G$9$,!”$“$^$j$K$b0c$&$N$G!”$b$7$+$7$F?t$(J}$,0ce(B
e$B$&!)e(B

~/src/ruby/**/*.rbe$B$G$d$C$F$^$7$?!#e(B
e$B$G!"B?$$$N$Oe(BTke$B$_$?$$$G$7$?!D!#e(B

|5e$BJ8;z$N@aLs$,=EMW$K$J$k$[$I$h$/;H$&5!G=$G$b$J$$$H;W$&$N$G!"e(B
|e$BC;$$5-=R$G:Q$$3$H$h$j$b!"B>$N5!G=$H$NN?d$Ge(Bsupere$B$N5sF0$re(B
|e$B?dB,$G$-$k$3$H$NJ}$,MxE@$,Bg$-$$$h$&$K;W$$$^$9!#e(B

e$B;d!"$1$C$3$&e(B(e$B0z?tE>Aw$Ne(B) super e$B;H$&$s$@$1$I$J!#e(B

e$B$^$“!”<+J,$b7k9=;H$C$F$k$+$b$7$l$^$;$s$,!"$&$l$7$+$C$?$3$H$Oe(B
e$B$9$0$KK:$l$F!"ITK~$K;W$C$?$3$H$@$13P$($F$$$k$H$$$&$3$H$+$be(B
e$B$7$l$^$;$s!#e(B

e$B!!$5$5$@$G$9!%e(B

e$B!!$"$^$j$K=k$/$FL$,3P$a$^$7$?!%e(B

(2010/08/25 0:30), Yusuke ENDOH wrote:

diff --git a/vm_insnhelper.c b/vm_insnhelper.c

  •  *block = GET_BLOCK_PTR();
    
  • }
    else if (blockiseq) {
    blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp);
    blockptr->iseq = blockiseq;

e$B!!$G$-$l$P!$e(BVM_CALL_ARGS_BLOCKTRGH_BIT e$B$rA}$d$9$s$8$c$J$/e(B
e$B$F!$e(BVM_CALL_ARGS_BLOCKARG_BIT
e$B$@$1$I!$e(Bblockiseqe$B!!$+$J$s$+$NCM$rFC<l$K$7e(B
e$B$F$*$/$H$+!$$=$&$$$&<BAu$K$7$F$b$i$($k$H$$$$$s$8$c$J$$$+$H;W$$$^$9!%e(B

e$B!JL?Na%*%Z%i%s%I$N%P%j%(!<%7%g%s$,8:$C$?J}$,?’!9$&$l$7$$!Ke(B

e$B1sF#$G$9!#e(B

2010e$BG/e(B6e$B7ne(B17e$BF|e(B6:31 Yukihiro M.
[email protected]:

e$B$,!“$b$H$b$H$NF05!$H$OJL$H$7$F!”!Ve(B&e$B!We(B1e$BJ8;z$G$=$N%3%s%F%-%9%He(B
e$B$N%V%m%C%/$rEO$9$N$O!“LLGr$$%”%$%G%#%"$@$H;W$$$^$9!#$3$N>l9ge(B
e$B$O!“2>0z?t%j%9%H$N%V%m%C%/0z?t$,$J$/$F$b!”%V%m%C%/$rEO$9$3$He(B
e$B$K$J$k$s$G$9$+$M!#e(B

e$B%Q%C%A$r=q$$$F$_$^$7$?!#;W$C$?$h$j>.$5$/=q$1$^$7$?!#e(B

def foo
yield
end

def bar
foo(&)
end

bar { p 1 } #=> 1

e$B%+%C%3$r>JN,$7$?>l9g!"e(B

foo &
bar

e$B$H$$$&$N$,e(B foo & bar e$B$J$N$+e(B foo(&); bar
e$B$J$N$+[#Kf$H$$$&LdBj$,e(B
e$B$"$j$^$7$?!#$,!"8_49@-=E;k$Ge(B foo & bar
e$B$H2r<a$9$k$h$&$K$J$C$F$$e(B
e$B$^$9!#$H$$$&$+=q$$$F$_$?$i$=$&$J$C$?!#e(Bconflict e$B$O=P$^$;$s!#e(B

diff --git a/compile.c b/compile.c
index 2fd804c…3f8c331 100644
— a/compile.c
+++ b/compile.c
@@ -2863,8 +2863,13 @@ setup_args(rb_iseq_t *iseq, LINK_ANCHOR *args,
NODE *argn, unsigned long *flag)
INIT_ANCHOR(arg_block);
INIT_ANCHOR(args_splat);
if (argn && nd_type(argn) == NODE_BLOCK_PASS) {

  • COMPILE(arg_block, “block”, argn->nd_body);
  • *flag |= VM_CALL_ARGS_BLOCKARG_BIT;
  • if ((VALUE)argn->nd_body != (VALUE)-1) {
  •  COMPILE(arg_block, "block", argn->nd_body);
    
  •  *flag |= VM_CALL_ARGS_BLOCKARG_BIT;
    
  • }
  • else {
  •  *flag |= VM_CALL_ARGS_BLOCKTRGH_BIT;
    
  • }
    argn = argn->nd_head;
    }

diff --git a/node.c b/node.c
index 65bc541…85574b4 100644
— a/node.c
+++ b/node.c
@@ -621,7 +621,12 @@ dump_node(VALUE buf, VALUE indent, int comment,
NODE *node)
ANN(“example: foo(x, &blk)”);
F_NODE(nd_head, “other arguments”);
LAST_NODE;

  • F_NODE(nd_body, “block argument”);
  • if ((VALUE)node->nd_body != (VALUE)-1) {

  •  F_NODE(nd_body, "block argument");
    
  • }

  • else {

  •  F_MSG(nd_body, "block argument", "-1 (anonymous)");
    
  • }
    break;

    case NODE_DEFN:
    

diff --git a/parse.y b/parse.y
index e085088…b0b946b 100644
— a/parse.y
+++ b/parse.y
@@ -2459,6 +2459,14 @@ block_arg : tAMPER arg_value
$$ = $2;
%*/
}

  • | tAMPER
  •    {
    
  •    /*%%%*/
    
  •  $$ = NEW_BLOCK_PASS(-1);
    
  •    /*%
    
  •  $$ = dispatch0(anonymous_block_arg);
    
  •    %*/
    
  •    }
    
    ;

opt_block_arg : ‘,’ block_arg
diff --git a/vm_core.h b/vm_core.h
index 7676b2f…f0fa3a3 100644
— a/vm_core.h
+++ b/vm_core.h
@@ -544,6 +544,7 @@ typedef struct {
#define VM_CALL_TAILRECURSION_BIT (0x01 << 6)
#define VM_CALL_SUPER_BIT (0x01 << 7)
#define VM_CALL_OPT_SEND_BIT (0x01 << 8)
+#define VM_CALL_ARGS_BLOCKTRGH_BIT (0x01 << 9)

#define VM_SPECIAL_OBJECT_VMCORE 0x01
#define VM_SPECIAL_OBJECT_CBASE 0x02
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 985a2fb…2a127d7 100644
— a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -261,6 +261,10 @@ caller_setup_args(const rb_thread_t *th,
rb_control_frame_t *cfp, VALUE flag,
*block = blockptr;
}
}

  • else if (flag & VM_CALL_ARGS_BLOCKTRGH_BIT) {
  •  rb_control_frame_t *reg_cfp = cfp;
    
  •  *block = GET_BLOCK_PTR();
    
  • }
    else if (blockiseq) {
    blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp);
    blockptr->iseq = blockiseq;