Block wrapper

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

In message “Re: [ruby-dev:30893] Re: block wrapper”
on Tue, 5 Jun 2007 13:05:58 +0900, Tanaka A. [email protected]
writes:

|> e$B$3$l$O;d$NJ}$G:n6H$7$^$9!#:#$9$0La$;$k$J$i?tF|Cf$K!"e(BYARVe$B%3%"e(B
|> e$B$G$NBP1~$,I,MW$J$iBP1~8e$9$0$KLa$7$^$9!#e(B
|
|e$B?tF|$O$?$C$?$H;W$$$^$9$,!“2?$+LdBj$,$”$j$^$7$?$+e(B?

e$B:n6H$9$k;~4V$,<h$l$J$$$H$$$&LdBj$,e(B…e$B!#e(B
e$B$9$$$^$;$s!"!:@Z$H@o$C$F$$$^$9!#e(B

In article E1HtJVx-0005m3-Sg@x31,
Yukihiro M. [email protected] writes:

|e$B$"$H!"0JA0e(B yield *v e$B$Ge(B wrapper e$B$,F0$+$J$/$J$C$?;~$K$^$D$b$He(B
|e$B$5$s$,e(B pp.rb e$B$rJQ$($?$N$O85$KLa$7$F$$$?$@$1$^$;$s$+e(B?

e$B$3$l$O;d$NJ}$G:n6H$7$^$9!#:#$9$0La$;$k$J$i?tF|Cf$K!"e(BYARVe$B%3%"e(B
e$B$G$NBP1~$,I,MW$J$iBP1~8e$9$0$KLa$7$^$9!#e(B

e$B?tF|$O$?$C$?$H;W$$$^$9$,!“2?$+LdBj$,$”$j$^$7$?$+e(B?

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

In message “Re: [ruby-dev:30894] Re: block wrapper”
on Tue, 5 Jun 2007 14:36:43 +0900, Yukihiro M.
[email protected] writes:

||> e$B$3$l$O;d$NJ}$G:n6H$7$^$9!#:#$9$0La$;$k$J$i?tF|Cf$K!"e(BYARVe$B%3%“e(B
||> e$B$G$NBP1~$,I,MW$J$iBP1~8e$9$0$KLa$7$^$9!#e(B
||
||e$B?tF|$O$?$C$?$H;W$$$^$9$,!“2?$+LdBj$,$”$j$^$7$?$+e(B?
|
|e$B:n6H$9$k;~4V$,<h$l$J$$$H$$$&LdBj$,e(B…e$B!#e(B
|e$B$9$$$^$;$s!”!:@Z$H@o$C$F$$$^$9!#e(B

e$B$H;W$C$?$N$G$9$,!“8=<BF(Hr$K$A$g$C$H:n6H$7$?$i$”$C$H$$$&4V$Ge(B
e$B$7$?!#LdBj$O$"$j$^$;$s$G$7$?$N$GLa$7$^$9!#e(B

In article [email protected],
Tanaka A. [email protected] writes:

e$B$3$3$G5?Ld$,$"$k$N$G$9$,!"e(Byield e$B$re(B e$B8=:_$Ne(B 1.9 e$B$Ne(B b.call e$B$NF0e(B
e$B:n$K$7$F$7$^$o$J$$$N$O$J$s$G$G$7$g$&e(B?

e$BJV;v$rBT$C$F$$$k$s$G$9$,!"$J$s$G$J$s$G$7$g$&e(B?

e$B$d$O$j5?Ld$G!“$H$F$bCN$j$?$$$N$G$9$,!”$J$s$G$J$s$G$7$g$&e(B?

e$B$I$3$K$3$@$o$j$,$“$k$N$+$o$+$i$J$$$N$G5$$KF~$k$+$I$&$+$O$o$+e(B
e$B$i$J$$$N$G$9$,!”;d$H$7$F$O<!$N$h$&$K$7$?$i$$$$$N$G$O$J$$$+$He(B
e$B;W$C$F$$$^$9!#e(B

  • b.call e$B$NF0:n$r4pK$H$7!"G[Ns$G%G!<%?$r<u$1EO$9e(B
  • |*x| e$B$G$=$NG[Ns$r<u$1<h$l!"e(Byield *x e$B$G$=$NG[Ns$r@_Dj$G$-$ke(B
    (e$B%i%C%Q!<$,=q$1$ke(B)
  • e$B%G!<%?$r<u$1<h$k$H$3$m$G;H$$>!<j$H8_49@-$r9M$($F$$$/$i$+:Ye(B
    e$B9)$r$9$ke(B

e$B$I$&$G$7$g$&$+e(B?

e$B$=$7$F!"$3$NJQ99$r9T$($P!"e(Bpp.rb e$B$NJQ99$r85$KLa$;$^$9$7!"e(B
test-all e$B$G<:GT$7$F$$$ke(B drb e$B$J$I$N$$$/$D$+$N<:GT$,@.8y$9$k$he(B
e$B$&$K$J$j$^$9!#e(B

Index: eval.c

RCS file: /src/ruby/eval.c,v
retrieving revision 1.947
diff -u -p -r1.947 eval.c
— eval.c 23 Sep 2006 21:29:47 -0000 1.947
+++ eval.c 26 Sep 2006 16:52:04 -0000
@@ -223,7 +223,7 @@ static int volatile freebsd_clear_carry_
VALUE rb_cProc;
VALUE rb_cBinding;
static VALUE proc_alloc(VALUE,struct BLOCK*,int);
-static VALUE proc_invoke(VALUE,VALUE,VALUE,VALUE,int);
+static VALUE proc_invoke(VALUE,VALUE,VALUE,VALUE);
static VALUE proc_lambda(void);
static VALUE rb_f_binding(VALUE);
static void rb_f_END(void);
@@ -1065,6 +1065,7 @@ typedef enum calling_scope {
static VALUE rb_call(VALUE,VALUE,ID,int,const VALUE*,struct
BLOCK*,calling_scope_t,int);
static VALUE module_setup(VALUE,NODE*);

+static VALUE massign_args(VALUE,NODE*,VALUE,int);
static VALUE massign(VALUE,NODE*,VALUE,int);
static void assign(VALUE,NODE*,VALUE,int);
static int formal_assign(VALUE, NODE*, int, const VALUE*, VALUE*);
@@ -2594,7 +2595,7 @@ call_trace_func(rb_event_t event, NODE *
id?ID2SYM(id):Qnil,
self ? rb_f_binding(self) : Qnil,
klass?klass:Qnil),

  •       Qundef, 0, 0);
    
  •       Qundef, 0);
    
    }
    if (raised) thread_set_raised();
    POP_TAG();
    @@ -2989,7 +2990,7 @@ rb_eval(VALUE self, NODE *n)
    ruby_current_node = node;
    }
    else {
  •   result = Qundef;	/* no arg */
    
  •   result = rb_ary_new2(0);	/* no arg */
    
    }
    SET_CURRENT_SOURCE();
    result = rb_yield_0(result, 0, 0, 0);
    @@ -4678,7 +4679,7 @@ rb_need_block(void)
    }

static VALUE
-rb_yield_0(VALUE val, VALUE self, VALUE klass /* OK /, int flags)
+rb_yield_0(VALUE args, VALUE self, VALUE klass /
OK */, int flags)
{
NODE *node, *var;
volatile VALUE result = Qnil;
@@ -4689,7 +4690,7 @@ rb_yield_0(VALUE val, VALUE self, VALUE
int old_vmode;
struct FRAME frame;
NODE *cnode = ruby_current_node;

  • int ary_args, lambda;
  • int lambda;
    int state, broken = 0;

    rb_need_block();
    @@ -4723,37 +4724,26 @@ rb_yield_0(VALUE val, VALUE self, VALUE
    node = block->body;
    var = block->var;
    lambda = block->flags & BLOCK_LAMBDA;

  • ary_args = flags & YIELD_ARY_ARGS;
    if (var) {
    PUSH_TAG(PROT_NONE);
    if ((state = EXEC_TAG()) == 0) {
    NODE bvar = NULL;
    block_var:
    if (var == (NODE
    )1) { /* no parameter || */
  •   if (lambda && val != Qundef) {
    
  •       if (TYPE(val) != T_ARRAY) {
    
  •   	rb_raise(rb_eArgError, "wrong number of arguments (1 for 0)");
    
  •       }
    
  •       else if (RARRAY_LEN(val) != 0) {
    
  •   if (lambda) {
    
  •       if (RARRAY_LEN(args) != 0) {
      	rb_raise(rb_eArgError, "wrong number of arguments (%ld for 0)",
    
  •   		 RARRAY_LEN(val));
    
  •   		 RARRAY_LEN(args));
          }
      }
      }
    
  •   else if (var == (NODE*)2) {
    
  •   if (TYPE(val) == T_ARRAY && RARRAY_LEN(val) != 0) {
    
  •       rb_raise(rb_eArgError, "wrong number of arguments (%ld for 0)",
    
  •   	     RARRAY_LEN(val));
    
  •   }
    
  •   }
      else if (!bvar && nd_type(var) == NODE_BLOCK_PASS) {
      bvar = var->nd_body;
      var = var->nd_args;
      goto block_var;
      }
      else if (nd_type(var) == NODE_ARGS) {
    
  •   if (!ary_args) val = svalue_to_avalue(val);
    
  •   formal_assign(self, var, RARRAY_LEN(val), RARRAY_PTR(val), 0);
    
  •   formal_assign(self, var, RARRAY_LEN(args), RARRAY_PTR(args), 0);
      }
      else if (nd_type(var) == NODE_BLOCK) {
      if (var->nd_next) {
    

@@ -4763,25 +4753,19 @@ rb_yield_0(VALUE val, VALUE self, VALUE
goto block_var;
}
else if (nd_type(var) == NODE_MASGN) {

  •   massign(self, var, val, lambda);
    
  •   massign_args(self, var, args, lambda);
      }
      else {
      if (lambda) {
    
  •       if (val == Qundef) {
    
  •   	rb_raise(rb_eArgError, "wrong number of arguments (0 for 1)");
    
  •       }
    
  •       if (TYPE(val) == T_ARRAY && RARRAY_LEN(val) != 1) {
    
  •       if (RARRAY_LEN(args) != 1) {
      	rb_raise(rb_eArgError, "wrong number of arguments (%ld for 1)",
    
  •   		 RARRAY_LEN(val));
    
  •   		 RARRAY_LEN(args));
          }
      }
    
  •   if (ary_args) {
    
  •       if (RARRAY_LEN(val) == 0)
    
  •   	val = Qnil;
    
  •       else
    
  •   	val = RARRAY_PTR(val)[0];
    
  •   }
    
  •   assign(self, var, val, lambda);
    
  •            if (RARRAY_LEN(args) == 0)
    
  •                assign(self, var, Qnil, lambda);
    
  •            else
    
  •                assign(self, var, rb_ary_entry(args, 0), lambda);
      }
      if (bvar) {
      struct BLOCK *b = ruby_frame->prev->prev->block;
    

@@ -4799,11 +4783,11 @@ rb_yield_0(VALUE val, VALUE self, VALUE
POP_TAG();
if (state) goto pop_state;
}

  • else if (lambda && ary_args && RARRAY_LEN(val) != 0 &&
  •    (!node || nd_type(node) != NODE_IFUNC ||
    
  • else if (lambda && RARRAY_LEN(args) != 0 &&
  •    (!node || (nd_type(node) != NODE_IFUNC && nd_type(node) != 
    

NODE_IFUNC1) ||
node->nd_cfnc != bmcall)) {
rb_raise(rb_eArgError, “wrong number of arguments (%ld for 0)”,

  •    RARRAY_LEN(val));
    
  •    RARRAY_LEN(args));
    
    }
    if (!node) {
    state = 0;
    @@ -4814,24 +4798,20 @@ rb_yield_0(VALUE val, VALUE self, VALUE
    PUSH_TAG(lambda ? PROT_NONE : PROT_YIELD);
    if ((state = EXEC_TAG()) == 0) {
    redo:
  • if (nd_type(node) == NODE_CFUNC || nd_type(node) == NODE_IFUNC) {
  •   if (node->nd_state == YIELD_FUNC_AVALUE) {
    
  •   val = svalue_to_avalue(val);
    
  •   }
    
  •   else {
    
  •   if (val == Qundef && node->nd_state != YIELD_FUNC_SVALUE)
    
  •       val = Qnil;
    
  •   }
    
  • if (nd_type(node) == NODE_CFUNC || nd_type(node) == NODE_IFUNC ||
    nd_type(node) == NODE_IFUNC1) {
    if ((block->flags&BLOCK_FROM_METHOD) && RTEST(block->block_obj)) {
    struct BLOCK *data, _block;
    Data_Get_Struct(block->block_obj, struct BLOCK, data);
    _block = *data;
    _block.uniq = block_unique++;
    ruby_frame->block = &_block;
  •   result = (*node->nd_cfnc)(val, node->nd_tval, self);
    
  •   result = (*node->nd_cfnc)(args, node->nd_tval, self);
      }
    
  •        else if (nd_type(node) == NODE_IFUNC1 && RARRAY_LEN(args) 
    

== 1) {

  •            result = (*node->nd_cfnc)(rb_ary_entry(args, 0), 
    

node->nd_tval, self);

  •        }
      else {
    
  •   result = (*node->nd_cfnc)(val, node->nd_tval, self);
    
  •   result = (*node->nd_cfnc)(args, node->nd_tval, self);
      }
    
    }
    else {
    @@ -4911,7 +4891,10 @@ rb_yield_0(VALUE val, VALUE self, VALUE
    VALUE
    rb_yield(VALUE val)
    {
  • return rb_yield_0(val, 0, 0, 0);
  • if (val == Qundef)
  •    return rb_yield_0(rb_ary_new2(0), 0, 0, 0);
    
  • else
  •    return rb_yield_0(rb_ary_new3(1, val), 0, 0, 0);
    

}

VALUE
@@ -4922,7 +4905,7 @@ rb_yield_values(int n, …)
VALUE val;

 if (n == 0) {
  • return rb_yield_0(Qundef, 0, 0, 0);
  • return rb_yield_0(rb_ary_new2(0), 0, 0, 0);
    }
    val = rb_ary_new2(n);
    va_start(args, n);
    @@ -4933,6 +4916,16 @@ rb_yield_values(int n, …)
    return rb_yield_0(val, 0, 0, 0);
    }

+VALUE
+rb_yield_splat(VALUE val)
+{

  • VALUE tmp = rb_check_array_type(val);
  • if (NIL_P(tmp)) {
  •    rb_raise(rb_eArgError, "not an array");
    
  • }
  • return rb_yield_0(tmp, 0, 0, 0);
    +}

/*

  • call-seq:
  • loop {|| block }
    

@@ -4951,59 +4944,71 @@ static VALUE
rb_f_loop(void)
{
for (;:wink: {

  • rb_yield_0(Qundef, 0, 0, 0);
  • rb_yield_0(rb_ary_new2(0), 0, 0, 0);
    CHECK_INTS;
    }
    return Qnil; /* dummy */
    }

static VALUE
-massign(VALUE self, NODE *node, VALUE val, int pcall)
+massign_args(VALUE self, NODE *node, VALUE args, int lambda)
+{

  • if (lambda)
  •    return massign(self, node, args, lambda);
    
  • if (!node->nd_head) /* |*v| */
  •    return massign(self, node, args, lambda);
    
  • if (!node->nd_head->nd_next && !node->nd_args) /* |v| */
  •    return massign(self, node, args, lambda);
    
  • /* |v1,|, |v1,*vs|, |v1,v2|, |v1,v2,|, |v1,v2,*vs|, etc. */
  • if (RARRAY_LEN(args) == 1)
  •    return massign(self, node, rb_ary_entry(args, 0), lambda);
    
  • return massign(self, node, args, lambda);
    +}

+static VALUE
+massign(VALUE self, NODE *node, VALUE val, int lambda)
{
NODE *list;

  • long i = 0, len;
  • long i = 0;
    volatile VALUE tmp;
  • VALUE *argv;
  • VALUE args;

    if (val == Qundef) {

  • argv = 0;
  • len = 0;
  •    args = rb_ary_new2(0);
    
    }
    else {
    tmp = rb_check_array_type(val);
    if (NIL_P(tmp)) {
  •   argv = &val;
    
  •   len = (val == Qundef) ? 0 : 1;
    
  •        args = rb_ary_new3(1, val);
    
    }
    else {
  •   argv = RARRAY_PTR(tmp);
    
  •   len = RARRAY_LEN(tmp);
    
  •        args = tmp;
    
    }
    }
    list = node->nd_head;
  • for (; list && i<len; i++) {
  • assign(self, list->nd_head, argv[i], pcall);
  • for (; list && i<RARRAY_LEN(args); i++) {
  • assign(self, list->nd_head, RARRAY_PTR(args)[i], lambda);
    list = list->nd_next;
    }
  • if (pcall && list) goto arg_error;
  • if (node->nd_args) {
  • if (lambda && list) goto arg_error;
  • if (node->nd_args && (long)(node->nd_args) != -2) {
    if ((long)(node->nd_args) == -1) {
    /* no check for mere `*’ */
    }
  • else if (!list && i<len) {
  •   assign(self, node->nd_args, rb_ary_new4(len-i, argv+i), pcall);
    
  • else if (!list && i<RARRAY_LEN(args)) {
  •   assign(self, node->nd_args, rb_ary_new4(RARRAY_LEN(args)-i, 
    

RARRAY_PTR(args)+i), lambda);
}
else {

  •   assign(self, node->nd_args, rb_ary_new2(0), pcall);
    
  •   assign(self, node->nd_args, rb_ary_new2(0), lambda);
    
    }
    }
  • else if (pcall && i < len) {
  • else if (lambda && i < RARRAY_LEN(args)) {
    goto arg_error;
    }

    while (list) {
    i++;

  • assign(self, list->nd_head, Qnil, pcall);
  • assign(self, list->nd_head, Qnil, lambda);
    list = list->nd_next;
    }
    return val;
    @@ -5013,11 +5018,11 @@ massign(VALUE self, NODE *node, VALUE va
    i++;
    list = list->nd_next;
    }
  • rb_raise(rb_eArgError, “wrong number of arguments (%ld for %ld)”,
    len, i);
  • rb_raise(rb_eArgError, “wrong number of arguments (%ld for %ld)”,
    RARRAY_LEN(args), i);
    }

static void
-assign(VALUE self, NODE *lhs, VALUE val, int pcall)
+assign(VALUE self, NODE *lhs, VALUE val, int lambda)
{
ruby_current_node = lhs;
if (val == Qundef) {
@@ -5068,7 +5073,7 @@ assign(VALUE self, NODE *lhs, VALUE val,
break;

   case NODE_MASGN:
  • massign(self, lhs, val, pcall);
  • massign(self, lhs, val, lambda);
    break;

    case NODE_CALL:
    @@ -5115,7 +5120,7 @@ assign(VALUE self, NODE *lhs, VALUE val,
    }
    cnt = lhs->nd_head->nd_alen;
    if (RARRAY_LEN(val) < cnt) {

  •   if (pcall) {
    
  •   if (lambda) {
          rb_raise(rb_eArgError, "wrong number of arguments");
      }
      else {
    

@@ -5144,11 +5149,11 @@ assign(VALUE self, NODE *lhs, VALUE val,
}

VALUE
-rb_iterate(VALUE (*it_proc)(VALUE), VALUE data1, VALUE
(*bl_proc)(ANYARGS), VALUE data2)
+rb_iterate_0(enum node_type functype, VALUE (*it_proc)(VALUE), VALUE
data1, VALUE (*bl_proc)(ANYARGS), VALUE data2)
{
int state;
volatile VALUE retval = Qnil;

  • NODE *node = NEW_IFUNC(bl_proc, data2);
  • NODE *node = NEW_NODE(functype, bl_proc, data2, 0);
    VALUE self = ruby_top_self;

    PUSH_TAG(PROT_LOOP);
    @@ -5180,6 +5185,18 @@ rb_iterate(VALUE (*it_proc)(VALUE), VALU
    return retval;
    }

+VALUE
+rb_iterate_splat(VALUE (*it_proc)(VALUE), VALUE data1, VALUE
(*bl_proc)(ANYARGS), VALUE data2)
+{

  • return rb_iterate_0(NODE_IFUNC, it_proc, data1, bl_proc, data2);
    +}

+VALUE
+rb_iterate(VALUE (*it_proc)(VALUE), VALUE data1, VALUE
(*bl_proc)(ANYARGS), VALUE data2)
+{

  • return rb_iterate_0(NODE_IFUNC1, it_proc, data1, bl_proc, data2);
    +}

struct iter_method_arg {
VALUE obj;
ID mid;
@@ -5198,6 +5215,18 @@ iterate_method(VALUE obj)
}

VALUE
+rb_block_call_splat(VALUE obj, ID mid, int argc, VALUE *argv, VALUE
(*bl_proc)(ANYARGS), VALUE data2)
+{

  • struct iter_method_arg arg;
  • arg.obj = obj;
  • arg.mid = mid;
  • arg.argc = argc;
  • arg.argv = argv;
  • return rb_iterate_splat(iterate_method, (VALUE)&arg, bl_proc,
    data2);
    +}

+VALUE
rb_block_call(VALUE obj, ID mid, int argc, VALUE *argv, VALUE
(*bl_proc)(ANYARGS), VALUE data2)
{
struct iter_method_arg arg;
@@ -5776,7 +5805,7 @@ rb_call0(VALUE klass, VALUE recv, ID id,
Data_Get_Struct(body->nd_cval, struct BLOCK, data);
EXEC_EVENT_HOOK(RUBY_EVENT_CALL, data->body, recv, id, klass);
}

  • result = proc_invoke(body->nd_cval, rb_ary_new4(argc, argv), recv,
    klass, 1);
  • result = proc_invoke(body->nd_cval, rb_ary_new4(argc, argv), recv,
    klass);
    if (event_hooks) {
    EXEC_EVENT_HOOK(RUBY_EVENT_RETURN, body, recv, id, klass);
    }
    @@ -6484,10 +6513,8 @@ static VALUE
    yield_under_i(VALUE arg)
    {
    VALUE *args = (VALUE *)arg;
  • int flags = YIELD_PUBLIC_DEF;

  • if (args[0] != Qundef) flags |= YIELD_ARY_ARGS;

  • return rb_yield_0(args[0], args[1], ruby_cbase, flags);

  • return rb_yield_0(args[0], args[1], ruby_cbase, YIELD_PUBLIC_DEF);
    }

/* block eval under the class/module context */
@@ -6507,7 +6534,7 @@ specific_eval(int argc, VALUE *argv, VAL
if (argc > 0) {
rb_raise(rb_eArgError, “wrong number of arguments (%d for 0)”,
argc);
}

  • return yield_under(klass, self, Qundef);
  • return yield_under(klass, self, rb_ary_new2(0));
    }
    else {
    const char *file = “(eval)”;
    @@ -7666,7 +7693,7 @@ call_end_proc(VALUE data)
    PUSH_FRAME(Qfalse);
    ruby_frame->self = ruby_frame->prev->self;
    ruby_frame->node = 0;
  • proc_invoke(data, rb_ary_new2(0), Qundef, 0, 1);
  • proc_invoke(data, rb_ary_new2(0), Qundef, 0);
    POP_FRAME();
    }

@@ -8426,7 +8453,7 @@ block_orphan(struct BLOCK *data)
}

static VALUE
-proc_invoke(VALUE proc, VALUE args /* OK /, VALUE self, VALUE klass,
int call)
+proc_invoke(VALUE proc, VALUE args /
OK */, VALUE self, VALUE klass)
{
struct BLOCK _block;
struct BLOCK data;
@@ -8434,12 +8461,10 @@ proc_invoke(VALUE proc, VALUE args /
OK
int state;
volatile int safe = ruby_safe_level;
volatile VALUE old_wrapper = ruby_wrapper;

  • volatile int pcall, lambda;
  • volatile int lambda;
    VALUE bvar = 0;

    Data_Get_Struct(proc, struct BLOCK, data);

  • pcall = call ? YIELD_ARY_ARGS : 0;
  • pcall |= YIELD_PROC_INVOKE;
    lambda = data->flags & BLOCK_LAMBDA;
    if (rb_block_given_p() && ruby_frame->callee) {
    if (klass != ruby_frame->this_class)
    @@ -8454,7 +8479,7 @@ proc_invoke(VALUE proc, VALUE args /* OK
    _block.block_obj = bvar;
    if (self != Qundef) _block.frame.self = self;
    if (klass) _block.frame.this_class = klass;
  • _block.frame.argc = call ? RARRAY_LEN(args) : 1;
  • _block.frame.argc = RARRAY_LEN(args);
    _block.frame.flags = ruby_frame->flags;
    if (_block.frame.argc && (ruby_frame->flags & FRAME_DMETH)) {
    NEWOBJ(scope, struct SCOPE);
    @@ -8469,7 +8494,7 @@ proc_invoke(VALUE proc, VALUE args /* OK
    state = EXEC_TAG();
    if (state == 0) {
    proc_set_safe_level(proc);
  • result = rb_yield_0(args, self, (self!=Qundef)?CLASS_OF(self):0,
    pcall);
  • result = rb_yield_0(args, self, (self!=Qundef)?CLASS_OF(self):0,
    YIELD_PROC_INVOKE);
    }
    else if (TAG_DST()) {
    result = prot_tag->retval;
    @@ -8493,8 +8518,7 @@ proc_invoke(VALUE proc, VALUE args /* OK
    JUMP_TAG(state);
    case TAG_RETURN:
    if (result != Qundef) {
  •   if (pcall) break;
    
  •   return_jump(result);
    
  •   break;
    
    }
    default:
    JUMP_TAG(state);
    @@ -8502,74 +8526,37 @@ proc_invoke(VALUE proc, VALUE args /* OK
    return result;
    }

-/* CHECKME: are the argument checking semantics correct? */

/*

  • call-seq:
  • prc.call(params,...)   => obj
    
    • prc.yield(params,...)   => obj
      
    • prc[params,...]        => obj
      
    • Invokes the block, setting the block’s parameters to the values in
    • params using something close to method calling semantics.
    • Generates a warning if multiple values are passed to a proc that
    • expects just one (previously this silently converted the parameters
    • to an array).
    • For procs created using Kernel.proc, generates an
    • error if the wrong number of parameters
    • are passed to a proc with multiple parameters. For procs created
      using
    • Proc.new, extra parameters are silently discarded.
    • For procs created using Kernel.lambda, generates an
    • error if the wrong number of parameters are passed to a proc with
    • multiple parameters.
    • For procs created using Proc.new or
    • Kernel.proc, extra parameters are silently discarded.
    • Returns the value of the last expression evaluated in the block.
      See
    • also Proc#yield.
    • Returns the value of the last expression evaluated in the block.
    • a_proc = Proc.new {|a, *b| b.collect {|i| i*a }}
      
    • a_proc.call(9, 1, 2, 3)   #=> [9, 18, 27]
      
    • a_proc.yield(9, 1, 2, 3)  #=> [9, 18, 27]
      
    • a_proc[9, 1, 2, 3]        #=> [9, 18, 27]
      
    • a_proc = Proc.new {|a,b| a}
      
    • a_proc.call(1,2,3)
      
    • produces:
    • prog.rb:5: wrong number of arguments (3 for 2) (ArgumentError)
      
    • 	from prog.rb:4:in `call'
      
    • 	from prog.rb:5
      
    • a_proc.call(1,2,3)        #=> 1
      
    • a_lambda = lambda {|a| p a }
      
    • a_lambda.call(1,2)        #=> wrong number of arguments (2 for 
      
  1. (ArgumentError)
    */

VALUE
rb_proc_call(VALUE proc, VALUE args /* OK */)
{

  • return proc_invoke(proc, args, Qundef, 0, 1);
    -}

-/*

    • call-seq:
    • prc.yield(params,...)   => obj
      
    • Invokes the block, setting the block’s parameters to the values in
    • params in the same manner the yield statement does.
    • a_proc = Proc.new {|a, *b| b.collect {|i| i*a }}
      
    • a_proc.yield(9, 1, 2, 3)   #=> [9, 18, 27]
      
    • a_proc.yield([9, 1, 2, 3]) #=> [9, 18, 27]
      
    • a_proc = Proc.new {|a,b| a}
      
    • a_proc.yield(1,2,3)	  # => [1]
      
  • */

-VALUE
-rb_proc_yield(int argc, VALUE *argv, VALUE proc)
-{

  • switch (argc) {
  •  case 1:
    
  • if (!NIL_P(argv[0])) {
  •   return proc_invoke(proc, argv[0], Qundef, 0, 0);
    
  • }
  • /* fall through */
  •  case 0:
    
  • return proc_invoke(proc, Qundef, Qundef, 0, 0);
  •  default:
    
  • return proc_invoke(proc, rb_ary_new4(argc, argv), Qundef, 0, 0);
  • }
  • return proc_invoke(proc, args, Qundef, 0);
    }

/* :nodoc: */
@@ -8591,7 +8578,7 @@ rb_proc_arity(VALUE proc)
var = data->var;
if (var == 0) {
if (!data->body) return 0;

  • if (nd_type(data->body) == NODE_IFUNC &&
  • if ((nd_type(data->body) == NODE_IFUNC || nd_type(data->body) ==
    NODE_IFUNC1) &&
    data->body->nd_cfnc == bmcall) {
    return method_arity(data->body->nd_tval);
    }
    @@ -8614,7 +8601,7 @@ rb_proc_arity(VALUE proc)
    n++;
    list = list->nd_next;
    }
  • if (var->nd_args) {
  • if (var->nd_args && var->nd_args != (NODE *)-2) {
    if (var->nd_args != (NODE *)-1 && nd_type(var->nd_args) ==
    NODE_POSTARG) {
    return -n-1-var->nd_args->nd_head->nd_alen;
    }
    @@ -9399,7 +9386,7 @@ rb_proc_new(
    VALUE val)
    {
    struct BLOCK *data;
  • VALUE proc = rb_iterate((VALUE(*)(VALUE))mproc, 0, func, val);
  • VALUE proc = rb_iterate_splat((VALUE(*)(VALUE))mproc, 0, func,
    val);

    Data_Get_Struct(proc, struct BLOCK, data);
    data->body->nd_state = YIELD_FUNC_AVALUE;
    @@ -9424,7 +9411,7 @@ method_proc(VALUE method)
    if (nd_type(mdata->body) == NODE_BMETHOD) {
    return mdata->body->nd_cval;
    }

  • proc = rb_iterate((VALUE(*)(VALUE))mproc, 0, bmcall, method);
  • proc = rb_iterate_splat((VALUE(*)(VALUE))mproc, 0, bmcall, method);
    Data_Get_Struct(proc, struct BLOCK, bdata);
    bdata->body->nd_file = mdata->body->nd_file;
    nd_set_line(bdata->body, nd_line(mdata->body));
    @@ -9586,7 +9573,7 @@ Init_Proc(void)
    rb_define_method(rb_cProc, “clone”, proc_clone, 0);
    rb_define_method(rb_cProc, “dup”, proc_dup, 0);
    rb_define_method(rb_cProc, “call”, rb_proc_call, -2);
  • rb_define_method(rb_cProc, “yield”, rb_proc_yield, -1);
  • rb_define_method(rb_cProc, “yield”, rb_proc_call, -2);
    rb_define_method(rb_cProc, “arity”, proc_arity, 0);
    rb_define_method(rb_cProc, “[]”, rb_proc_call, -2);
    rb_define_method(rb_cProc, “==”, proc_eq, 1);
    @@ -11975,7 +11962,7 @@ rb_thread_start_1(void)
    if ((state = EXEC_TAG()) == 0) {
    if (THREAD_SAVE_CONTEXT(th) == 0) {
    new_thread.thread = 0;
  •   th->result = rb_proc_yield(RARRAY_LEN(arg), RARRAY_PTR(arg), 
    

proc);

  •   th->result = rb_proc_call(proc, arg);
    
    }
    th = th_save;
    }
    @@ -13071,7 +13058,7 @@ rb_f_catch(VALUE dmy, VALUE tag)
    tag = ID2SYM(rb_to_id(tag));
    PUSH_TAG(tag);
    if ((state = EXEC_TAG()) == 0) {
  • val = rb_yield_0(tag, 0, 0, 0);
  • val = rb_yield_0(rb_ary_new3(1, tag), 0, 0, 0);
    }
    else if (state == TAG_THROW && tag == prot_tag->dst) {
    val = prot_tag->retval;
    Index: hash.c
    ===================================================================
    RCS file: /src/ruby/hash.c,v
    retrieving revision 1.172
    diff -u -p -r1.172 hash.c
    — hash.c 25 Sep 2006 05:57:37 -0000 1.172
    +++ hash.c 26 Sep 2006 16:52:04 -0000
    @@ -994,7 +994,7 @@ static int
    each_pair_i(VALUE key, VALUE value)
    {
    if (key == Qundef) return ST_CONTINUE;
  • rb_yield(rb_assoc_new(key, value));
  • rb_yield_values(2, key, value);
    return ST_CONTINUE;
    }

@@ -1027,7 +1027,7 @@ static int
each_i(VALUE key, VALUE value)
{
if (key == Qundef) return ST_CONTINUE;

  • rb_yield_values(2, key, value);
  • rb_yield(rb_assoc_new(key, value));
    return ST_CONTINUE;
    }

Index: node.h

RCS file: /src/ruby/node.h,v
retrieving revision 1.78
diff -u -p -r1.78 node.h
— node.h 23 Sep 2006 21:29:47 -0000 1.78
+++ node.h 26 Sep 2006 16:52:04 -0000
@@ -120,6 +120,7 @@ enum node_type {
NODE_BMETHOD,
NODE_MEMO,
NODE_IFUNC,

  • NODE_IFUNC1,
    NODE_DSYM,
    NODE_ATTRASGN,
    NODE_PRELUDE,
    @@ -248,6 +249,7 @@ extern NODE ruby_top_cref;
    #define NEW_DEFS(r,i,a,d) NEW_NODE(NODE_DEFS,r,i,NEW_RFUNC(a,d))
    #define NEW_CFUNC(f,c) NEW_NODE(NODE_CFUNC,f,c,0)
    #define NEW_IFUNC(f,c) NEW_NODE(NODE_IFUNC,f,c,0)
    +#define NEW_IFUNC1(f,c) NEW_NODE(NODE_IFUNC1,f,c,0)
    #define NEW_RFUNC(b1,b2) NEW_SCOPE(block_append(b1,b2))
    #define NEW_SCOPE(b) NEW_NODE(NODE_SCOPE,local_tbl(),0,(b))
    #define NEW_BLOCK(a) NEW_NODE(NODE_BLOCK,a,0,0)
    Index: parse.y
    ===================================================================
    RCS file: /src/ruby/parse.y,v
    retrieving revision 1.460
    diff -u -p -r1.460 parse.y
    — parse.y 25 Sep 2006 05:57:37 -0000 1.460
    +++ parse.y 26 Sep 2006 16:52:04 -0000
    @@ -1228,7 +1228,7 @@ mlhs : mlhs_basic
    | tLPAREN mlhs_entry rparen
    {
    /
    %%%*/
  •   	$$ = $2;
    
  •   	$$ = NEW_MASGN(NEW_LIST($2), 0);
          /*%
      	$$ = dispatch1(mlhs_paren, $2);
          %*/
    

@@ -2888,13 +2888,7 @@ block_param0 : mlhs_item
block_param : block_param0
{
/%%%/

  •                    if ($1->nd_alen == 1) {
    
  •                        $$ = $1->nd_head;
    
  •                        rb_gc_force_recycle((VALUE)$1);
    
  •                    }
    
  •                    else {
    
  •                        $$ = NEW_MASGN($1, 0);
    
  •                    }
    
  •                    $$ = NEW_MASGN($1, 0);
          /*%
      	$$ = blockvar_new($1);
          %*/
    

@@ -2902,7 +2896,7 @@ block_param : block_param0
| block_param0 ‘,’
{
/%%%/

  •   	$$ = NEW_MASGN($1, 0);
    
  •   	$$ = NEW_MASGN($1, -2);
          /*%
      	$$ = blockvar_new($1);
          %*/
    

@@ -7837,11 +7831,7 @@ new_yield(NODE *node)

 if (node) {
no_blockarg(node);
  • if (nd_type(node) == NODE_ARRAY && node->nd_next == 0) {
  •   node = node->nd_head;
    
  •   state = Qfalse;
    
  • }
  • else if (node && nd_type(node) == NODE_SPLAT) {
  • if (node && nd_type(node) == NODE_SPLAT) {
    state = Qtrue;
    }
    }
    Index: ruby.h
    ===================================================================
    RCS file: /src/ruby/ruby.h,v
    retrieving revision 1.153
    diff -u -p -r1.153 ruby.h
    — ruby.h 23 Sep 2006 21:29:47 -0000 1.153
    +++ ruby.h 26 Sep 2006 16:52:04 -0000
    @@ -646,7 +646,9 @@ VALUE rb_yield_splat(VALUE);
    int rb_block_given_p(void);
    void rb_need_block(void);
    VALUE rb_iterate(VALUE()(VALUE),VALUE,VALUE()(ANYARGS),VALUE);
    +VALUE rb_iterate_splat(VALUE()(VALUE),VALUE,VALUE()(ANYARGS),VALUE);
    VALUE rb_block_call(VALUE,ID,int,VALUE*,VALUE()(ANYARGS),VALUE);
    +VALUE rb_block_call_splat(VALUE,ID,int,VALUE
    ,VALUE()(ANYARGS),VALUE);
    VALUE rb_rescue(VALUE(
    )(ANYARGS),VALUE,VALUE()(ANYARGS),VALUE);
    VALUE rb_rescue2(VALUE(
    )(ANYARGS),VALUE,VALUE()(ANYARGS),VALUE,…);
    VALUE rb_ensure(VALUE(
    )(ANYARGS),VALUE,VALUE(*)(ANYARGS),VALUE);
    Index: string.c
    ===================================================================
    RCS file: /src/ruby/string.c,v
    retrieving revision 1.280
    diff -u -p -r1.280 string.c
    — string.c 22 Sep 2006 09:08:58 -0000 1.280
    +++ string.c 26 Sep 2006 16:52:04 -0000
    @@ -4087,7 +4087,10 @@ rb_str_scan(VALUE str, VALUE pat)
    while (!NIL_P(result = scan_once(str, pat, &start))) {
    match = rb_backref_get();
    rb_match_busy(match);
  • rb_yield(result);
  •    if (TYPE(result) == T_STRING)
    
  •        rb_yield(result);
    
  •    else
    
  •        rb_yield_splat(result);
    
    str_mod_check(str, p, len);
    rb_backref_set(match); /* restore $~ value */
    }
    Index: lib/getoptlong.rb
    ===================================================================
    RCS file: /src/ruby/lib/getoptlong.rb,v
    retrieving revision 1.16
    diff -u -p -r1.16 getoptlong.rb
    — lib/getoptlong.rb 10 Jun 2006 01:20:23 -0000 1.16
    +++ lib/getoptlong.rb 26 Sep 2006 16:52:04 -0000
    @@ -289,7 +289,7 @@ class GetoptLong
    @canonical_names.clear
    @argument_flags.clear
  • arguments.each do |*arg|
  • arguments.each do |arg|

    Find an argument flag and it set to `argument_flag’.

Index: lib/mkmf.rb

RCS file: /src/ruby/lib/mkmf.rb,v
retrieving revision 1.263
diff -u -p -r1.263 mkmf.rb
— lib/mkmf.rb 26 Sep 2006 16:05:21 -0000 1.263
+++ lib/mkmf.rb 26 Sep 2006 16:52:04 -0000
@@ -1230,7 +1230,7 @@ EXTSTATIC = #{$static || “”}
STATIC_LIB = #{staticlib unless $static.nil?}
#{!$extout && defined?($installed_list) ? “INSTALLED_LIST =
#{$installed_list}\n” : “”}
"

  • install_dirs.each {|*d| mfile.print(“%-14s= %s\n” % d) if
    /^[[:upper:]]/ =~ d[0]}
  • install_dirs.each {|d| mfile.print(“%-14s= %s\n” % d) if
    /^[[:upper:]]/ =~ d[0]}
    n = ($extout ? ‘$(RUBYARCHDIR)/’ : ‘’) + ‘$(TARGET).’
    mfile.print "
    TARGET_SO = #{($extout ? ‘$(RUBYARCHDIR)/’ : ‘’)}$(DLLIB)
    Index: lib/optparse.rb
    ===================================================================
    RCS file: /src/ruby/lib/optparse.rb,v
    retrieving revision 1.69
    diff -u -p -r1.69 optparse.rb
    — lib/optparse.rb 26 Sep 2006 15:49:40 -0000 1.69
    +++ lib/optparse.rb 26 Sep 2006 16:52:04 -0000
    @@ -1422,7 +1422,7 @@ class OptionParser
    def search(id, key)
    block_given = block_given?
    visit(:search, id, key) do |k|
  •  return block_given ? yield(k) : k
    
  •  return block_given ? yield(*k) : k
    
    end
    end
    private :search
    Index: lib/pp.rb
    ===================================================================
    RCS file: /src/ruby/lib/pp.rb,v
    retrieving revision 1.50
    diff -u -p -r1.50 pp.rb
    — lib/pp.rb 11 Jul 2006 04:58:43 -0000 1.50
    +++ lib/pp.rb 26 Sep 2006 16:52:04 -0000
    @@ -220,13 +220,13 @@ class PP < PrettyPrint
    def seplist(list, sep=nil, iter_method=:each) # :yield: element
    sep ||= lambda { comma_breakable }
    first = true
  •  list.__send__(iter_method) {|v|
    
  •  list.__send__(iter_method) {|*v|
       if first
         first = false
       else
         sep.call
       end
    
  •    yield(v)
    
  •    yield(*v)
     }
    
    end

Index: sample/test.rb

RCS file: /src/ruby/sample/test.rb,v
retrieving revision 1.102
diff -u -p -r1.102 test.rb
— sample/test.rb 25 Sep 2006 06:07:35 -0000 1.102
+++ sample/test.rb 26 Sep 2006 16:52:04 -0000
@@ -134,13 +134,13 @@ def f; yield [[]]; end; f {|a| test_ok(a
def f; yield [[]]; end; f {|a| test_ok(a == [])}
def f; yield [
[1]]; end; f {|a| test_ok(a == [1])}
def f; yield [*[1,2]]; end; f {|a| test_ok(a == [1,2])}
-def f; yield *[]; end; f {|a| test_ok(a == [])}
-def f; yield *[1]; end; f {|a| test_ok(a == [1])}
-def f; yield *[nil]; end; f {|a| test_ok(a == [nil])}
-def f; yield *[[]]; end; f {|a| test_ok(a == [[]])}
-def f; yield [[]]; end; f {|a| test_ok(a == [])}
-def f; yield [[1]]; end; f {|a| test_ok(a == [1])}
-def f; yield [[1,2]]; end; f {|a| test_ok(a == [1,2])}
+def f; yield *[]; end; f {|a| test_ok(a == nil)}
+def f; yield *[1]; end; f {|a| test_ok(a == 1)}
+def f; yield *[nil]; end; f {|a| test_ok(a == nil)}
+def f; yield *[[]]; end; f {|a| test_ok(a == [])}
+def f; yield [[]]; end; f {|a| test_ok(a == nil)}
+def f; yield [[1]]; end; f {|a| test_ok(a == 1)}
+def f; yield [[1,2]]; end; f {|a| test_ok(a == 1)}

def f; yield; end; f {|a,| test_ok(a == nil)}
def f; yield nil; end; f {|a,| test_ok(a == nil)}
@@ -156,7 +156,7 @@ def f; yield [*[1,2]]; end; f {|a,| test
def f; yield *[]; end; f {|a,| test_ok(a == nil)}
def f; yield *[1]; end; f {|a,| test_ok(a == 1)}
def f; yield *[nil]; end; f {|a,| test_ok(a == nil)}
-def f; yield *[[]]; end; f {|a,| test_ok(a == [])}
+def f; yield *[[]]; end; f {|a,| test_ok(a == nil)}
def f; yield [[]]; end; f {|a,| test_ok(a == nil)}
def f; yield [[1]]; end; f {|a,| test_ok(a == 1)}
def f; yield [[1,2]]; end; f {|a,| test_ok(a == 1)}
@@ -164,14 +164,14 @@ def f; yield [[1,2]]; end; f {|a,| tes
def f; yield; end; f {|*a| test_ok(a == [])}
def f; yield nil; end; f {|*a| test_ok(a == [nil])}
def f; yield 1; end; f {|*a| test_ok(a == [1])}
-def f; yield []; end; f {|*a| test_ok(a == [])}
-def f; yield [1]; end; f {|*a| test_ok(a == [1])}
-def f; yield [nil]; end; f {|*a| test_ok(a == [nil])}
-def f; yield [[]]; end; f {|*a| test_ok(a == [[]])}
-def f; yield [1,2]; end; f {|a| test_ok(a == [1,2])}
-def f; yield [
[]]; end; f {|a| test_ok(a == [])}
-def f; yield [
[1]]; end; f {|a| test_ok(a == [1])}
-def f; yield [
[1,2]]; end; f {|*a| test_ok(a == [1,2])}
+def f; yield []; end; f {|*a| test_ok(a == [[]])}
+def f; yield [1]; end; f {|*a| test_ok(a == [[1]])}
+def f; yield [nil]; end; f {|*a| test_ok(a == [[nil]])}
+def f; yield [[]]; end; f {|*a| test_ok(a == [[[]]])}
+def f; yield [1,2]; end; f {|a| test_ok(a == [[1,2]])}
+def f; yield [
[]]; end; f {|a| test_ok(a == [[]])}
+def f; yield [
[1]]; end; f {|a| test_ok(a == [[1]])}
+def f; yield [
[1,2]]; end; f {|*a| test_ok(a == [[1,2]])}

def f; yield *[]; end; f {|*a| test_ok(a == [])}
def f; yield *[1]; end; f {|a| test_ok(a == [1])}
@@ -195,7 +195,7 @@ def f; yield [
[1,2]]; end; f {|a,b,*c|
def f; yield *[]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}
def f; yield *[1]; end; f {|a,b,*c| test_ok([a,b,c] == [1,nil,[]])}
def f; yield *[nil]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}
-def f; yield *[[]]; end; f {|a,b,*c| test_ok([a,b,c] == [[],nil,[]])}
+def f; yield *[[]]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}
def f; yield [[]]; end; f {|a,b,*c| test_ok([a,b,c] == [nil,nil,[]])}
def f; yield [[1]]; end; f {|a,b,*c| test_ok([a,b,c] == [1,nil,[]])}
def f; yield [[1,2]]; end; f {|a,b,*c| test_ok([a,b,c] == [1,2,[]])}
@@ -964,23 +964,23 @@ IterTest.new([1]).each1 {|x| test_ok(x =
IterTest.new([2]).each2 {|x| test_ok(x == [2])}
#IterTest.new([3]).each3 {|x| test_ok(x == 3)}
IterTest.new([4]).each4 {|x| test_ok(x == 4)}
-IterTest.new([5]).each5 {|x| test_ok(x == [5])}
+IterTest.new([5]).each5 {|x| test_ok(x == 5)}
IterTest.new([6]).each6 {|x| test_ok(x == [6])}
#IterTest.new([7]).each7 {|x| test_ok(x == 7)}
IterTest.new([8]).each8 {|x| test_ok(x == 8)}

IterTest.new([[0]]).each0 {|x| test_ok(x == [0])}
-IterTest.new([[1]]).each1 {|x| test_ok(x == 1)}
-IterTest.new([[2]]).each2 {|x| test_ok(x == [2])}
+IterTest.new([[1]]).each1 {|x| test_ok(x == [1])}
+IterTest.new([[2]]).each2 {|x| test_ok(x == [[2]])}
IterTest.new([[3]]).each3 {|x| test_ok(x == 3)}
IterTest.new([[4]]).each4 {|x| test_ok(x == [4])}
IterTest.new([[5]]).each5 {|x| test_ok(x == [5])}
-IterTest.new([[6]]).each6 {|x| test_ok(x == [6])}
-IterTest.new([[7]]).each7 {|x| test_ok(x == [7])}
+IterTest.new([[6]]).each6 {|x| test_ok(x == [[6]])}
+IterTest.new([[7]]).each7 {|x| test_ok(x == 7)}
IterTest.new([[8]]).each8 {|x| test_ok(x == [8])}

-IterTest.new([[0,0]]).each0 {|*x| test_ok(x == [0,0])}
-IterTest.new([[8,8]]).each8 {|*x| test_ok(x == [8,8])}
+IterTest.new([[0,0]]).each0 {|*x| test_ok(x == [[0,0]])}
+IterTest.new([[8,8]]).each8 {|*x| test_ok(x == [[8,8]])}

def m0(v)
v
Index: test/ruby/test_assignment.rb

RCS file: /src/ruby/test/ruby/test_assignment.rb,v
retrieving revision 1.10
diff -u -p -r1.10 test_assignment.rb
— test/ruby/test_assignment.rb 10 Jul 2006 08:36:34 -0000 1.10
+++ test/ruby/test_assignment.rb 26 Sep 2006 16:52:04 -0000
@@ -90,22 +90,22 @@ class TestAssignment < Test::Unit::TestC
def f; yield([[1]]); end; f {|a| assert_equal([1], a)}; undef f
def f; yield([
[1,2]]); end; f {|a| assert_equal([1,2], a)}; undef
f

  • def f; yield(*[1]); end; f {|a| assert_equal([1], a)}; undef f
  • def f; yield(*[nil]); end; f {|a| assert_equal([nil], a)}; undef f
  • def f; yield(*[[]]); end; f {|a| assert_equal([[]], a)}; undef f
  • def f; yield([[1]]); end; f {|a| assert_equal([1], a)}; undef f
  • def f; yield(*[1]); end; f {|a| assert_equal(1, a)}; undef f

  • def f; yield(*[nil]); end; f {|a| assert_equal(nil, a)}; undef f

  • def f; yield(*[[]]); end; f {|a| assert_equal([], a)}; undef f

  • def f; yield([[1]]); end; f {|a| assert_equal(1, a)}; undef f

    def f; yield; end; f {|*a| assert_equal([], a)}; undef f
    def f; yield(nil); end; f {|*a| assert_equal([nil], a)}; undef f
    def f; yield(1); end; f {|*a| assert_equal([1], a)}; undef f

  • def f; yield([]); end; f {|*a| assert_equal([], a)}; undef f
  • def f; yield([1]); end; f {|*a| assert_equal([1], a)}; undef f
  • def f; yield([nil]); end; f {|*a| assert_equal([nil], a)}; undef f
  • def f; yield([[]]); end; f {|*a| assert_equal([[]], a)}; undef f
  • def f; yield([1,2]); end; f {|*a| assert_equal([1,2], a)}; undef f
  • def f; yield([*[]]); end; f {|*a| assert_equal([], a)}; undef f
  • def f; yield([*[1]]); end; f {|*a| assert_equal([1], a)}; undef f
  • def f; yield([*[1,2]]); end; f {|*a| assert_equal([1,2], a)}; undef
    f
  • def f; yield([]); end; f {|*a| assert_equal([[]], a)}; undef f

  • def f; yield([1]); end; f {|*a| assert_equal([[1]], a)}; undef f

  • def f; yield([nil]); end; f {|*a| assert_equal([[nil]], a)}; undef
    f

  • def f; yield([[]]); end; f {|*a| assert_equal([[[]]], a)}; undef f

  • def f; yield([1,2]); end; f {|*a| assert_equal([[1,2]], a)}; undef
    f

  • def f; yield([*[]]); end; f {|*a| assert_equal([[]], a)}; undef f

  • def f; yield([*[1]]); end; f {|*a| assert_equal([[1]], a)}; undef f

  • def f; yield([*[1,2]]); end; f {|*a| assert_equal([[1,2]], a)};
    undef f

    def f; yield(*[]); end; f {|a| assert_equal([], a)}; undef f
    def f; yield(
    [1]); end; f {|a| assert_equal([1], a)}; undef f
    @@ -129,7 +129,7 @@ class TestAssignment < Test::Unit::TestC
    def f; yield(
    []); end; f {|a,b,c| assert_equal([nil,nil,[]],
    [a,b,c])}; undef f
    def f; yield(
    [1]); end; f {|a,b,c| assert_equal([1,nil,[]],
    [a,b,c])}; undef f
    def f; yield(
    [nil]); end; f {|a,b,*c| assert_equal([nil,nil,[]],
    [a,b,c])}; undef f

  • def f; yield(*[[]]); end; f {|a,b,*c| assert_equal([[],nil,[]],
    [a,b,c])}; undef f
  • def f; yield([[]]); end; f {|a,b,c| assert_equal([nil,nil,[]],
    [a,b,c])}; undef f
    def f; yield(
    [
    []]); end; f {|a,b,c| assert_equal([nil,nil,[]],
    [a,b,c])}; undef f
    def f; yield(
    [[1]]); end; f {|a,b,c| assert_equal([1,nil,[]],
    [a,b,c])}; undef f
    def f; yield(
    [
    [1,2]]); end; f {|a,b,*c| assert_equal([1,2,[]],
    [a,b,c])}; undef f
    Index: test/ruby/test_iterator.rb
    ===================================================================
    RCS file: /src/ruby/test/ruby/test_iterator.rb,v
    retrieving revision 1.21
    diff -u -p -r1.21 test_iterator.rb
    — test/ruby/test_iterator.rb 10 Jul 2006 08:36:34 -0000 1.21
    +++ test/ruby/test_iterator.rb 26 Sep 2006 16:52:04 -0000
    @@ -150,22 +150,22 @@ class TestIterator < Test::Unit::TestCas
    IterTest.new([1]).each1 {|x| assert_equal(1, x)}
    IterTest.new([2]).each2 {|x| assert_equal([2], x)}
    IterTest.new([4]).each4 {|x| assert_equal(4, x)}
  • IterTest.new([5]).each5 {|x| assert_equal([5], x)}
  • IterTest.new([5]).each5 {|x| assert_equal(5, x)}
    IterTest.new([6]).each6 {|x| assert_equal([6], x)}
    IterTest.new([8]).each8 {|x| assert_equal(8, x)}

    IterTest.new([[0]]).each0 {|x| assert_equal([0], x)}

  • IterTest.new([[1]]).each1 {|x| assert_equal(1, x)}
  • IterTest.new([[2]]).each2 {|x| assert_equal([2], x)}
  • IterTest.new([[1]]).each1 {|x| assert_equal([1], x)}
  • IterTest.new([[2]]).each2 {|x| assert_equal([[2]], x)}
    IterTest.new([[3]]).each3 {|x| assert_equal(3, x)}
    IterTest.new([[4]]).each4 {|x| assert_equal([4], x)}
    IterTest.new([[5]]).each5 {|x| assert_equal([5], x)}
  • IterTest.new([[6]]).each6 {|x| assert_equal([6], x)}
  • IterTest.new([[7]]).each7 {|x| assert_equal([7], x)}
  • IterTest.new([[6]]).each6 {|x| assert_equal([[6]], x)}
  • IterTest.new([[7]]).each7 {|x| assert_equal(7, x)}
    IterTest.new([[8]]).each8 {|x| assert_equal([8], x)}
  • IterTest.new([[0,0]]).each0 {|*x| assert_equal([0,0], x)}
  • IterTest.new([[8,8]]).each8 {|*x| assert_equal([8,8], x)}
  • IterTest.new([[0,0]]).each0 {|*x| assert_equal([[0,0]], x)}
  • IterTest.new([[8,8]]).each8 {|*x| assert_equal([[8,8]], x)}
    end

def m(var)
@@ -359,6 +359,9 @@ class TestIterator < Test::Unit::TestCas

class H
def each

  •  yield [:key, :value]
    
  • end
  • def each_pair
    yield :key, :value
    end
    end
    @@ -366,8 +369,13 @@ class TestIterator < Test::Unit::TestCas
    def test_assoc_yield
    [{:key=>:value}, H.new].each {|h|
    h.each{|a| assert_equal([:key, :value], a)}
  •  h.each{|*a| assert_equal([:key, :value], a)}
    
  •  h.each{|a,| assert_equal(:key, a)}
    
  •  h.each{|*a| assert_equal([[:key, :value]], a)}
     h.each{|k,v| assert_equal([:key, :value], [k,v])}
    
  •  h.each_pair{|a| assert_equal(:key, a)}
    
  •  h.each_pair{|a,| assert_equal(:key, a)}
    
  •  h.each_pair{|*a| assert_equal([:key, :value], a)}
    
  •  h.each_pair{|k,v| assert_equal([:key, :value], [k,v])}
    
    }
    end