1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* eval.c (proc_invoke): Proc#yield should pass through retry and

break like keyword yield. [ruby-talk:70034]

* eval.c (proc_invoke): orphan Proc now raises LocalJumpError for
  break and retry again.

* eval.c (rb_eval): ARGSCAT should splat the argument.

* eval.c (splat_value): splat operation function.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3729 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2003-04-25 08:54:52 +00:00
parent aaebe67919
commit d47be39735
2 changed files with 75 additions and 47 deletions

View file

@ -1,10 +1,20 @@
2003-04-24 Dave Thomas <dave@thomases.com>
Fri Apr 25 02:03:25 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (proc_invoke): Proc#yield should pass through retry and
break like keyword yield. [ruby-talk:70034]
* eval.c (proc_invoke): orphan Proc now raises LocalJumpError for
break and retry again.
* eval.c (rb_eval): ARGSCAT should splat the argument.
* eval.c (splat_value): splat operation function.
Thu Apr 24 23:37:02 2003 Dave Thomas <dave@thomases.com>
* lib/matrix.rb (Matrix#minor): Used Range#size, which no longer
exists.
2003-04-24 Dave Thomas <dave@thomases.com>
* lib/complex.rb (new!): Complex.new had been made private, but
Kernel#Complex called it. Re-exposed as new!.
@ -21190,3 +21200,7 @@ Fri Aug 15 19:40:43 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
Wed Aug 13 17:51:46 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
* version 1.1 alpha0 released.
Local variables:
add-log-time-format: current-time-string
end:

102
eval.c
View file

@ -2244,19 +2244,6 @@ svalue_to_avalue(v)
return tmp;
}
static VALUE
avalue_splat(v)
VALUE v;
{
if (RARRAY(v)->len == 0) {
return Qundef;
}
if (RARRAY(v)->len == 1) {
return RARRAY(v)->ptr[0];
}
return v;
}
static VALUE
svalue_to_mrhs(v, lhs)
VALUE v;
@ -2276,6 +2263,45 @@ svalue_to_mrhs(v, lhs)
return tmp;
}
static VALUE
avalue_splat(v)
VALUE v;
{
if (RARRAY(v)->len == 0) {
return Qundef;
}
if (RARRAY(v)->len == 1) {
return RARRAY(v)->ptr[0];
}
return v;
}
static VALUE
splat_value(v)
VALUE v;
{
if (NIL_P(v)) return rb_ary_new3(1, Qnil);
#if 1
/* hack to avoid invoke Object#to_a */
if (TYPE(v) != T_ARRAY) {
VALUE tmp = rb_check_array_type(v);
if (NIL_P(tmp)) {
VALUE origin;
ID id = rb_intern("to_a");
if (search_method(CLASS_OF(v), id, &origin) &&
origin != RCLASS(rb_cObject)->super) { /* exclude Object#to_a */
return rb_funcall(v, id, 0);
}
else {
return rb_ary_new3(1, v);
}
}
}
#endif
return avalue_splat(rb_Array(v));
}
static VALUE
class_prefix(self, cpath)
VALUE self;
@ -2660,31 +2686,7 @@ rb_eval(self, n)
break;
case NODE_SPLAT:
#if 0
/* simplified version after Object#to_a removed */
result = rb_eval(self, node->nd_head);
if (NIL_P(result)) result = rb_ary_new3(1, Qnil);
result = avalue_splat(rb_Array(result));
#else
result = rb_eval(self, node->nd_head);
if (NIL_P(result)) result = rb_ary_new3(1, Qnil);
if (TYPE(result) != T_ARRAY) {
VALUE tmp = rb_check_array_type(result);
if (NIL_P(tmp)) {
VALUE origin;
ID id = rb_intern("to_a");
if (search_method(CLASS_OF(result), id, &origin) &&
origin != RCLASS(rb_cObject)->super) { /* exclude Object#to_a */
result = rb_funcall(result, id, 0);
}
else {
result = rb_ary_new3(1, result);
}
}
}
result = avalue_splat(rb_Array(result));
#endif
result = splat_value(rb_eval(self, node->nd_head));
break;
case NODE_SVALUE:
@ -2845,7 +2847,7 @@ rb_eval(self, n)
case NODE_ARGSCAT:
result = rb_ary_concat(rb_eval(self, node->nd_head),
rb_eval(self, node->nd_body));
splat_value(rb_eval(self, node->nd_body)));
break;
case NODE_ARGSPUSH:
@ -6736,7 +6738,7 @@ proc_invoke(proc, args, pcall, self)
struct BLOCK _block;
struct BLOCK *data;
volatile VALUE result = Qnil;
int state;
int state, incoming_state;
volatile int orphan;
volatile int safe = ruby_safe_level;
volatile VALUE old_wrapper = ruby_wrapper;
@ -6770,6 +6772,7 @@ proc_invoke(proc, args, pcall, self)
POP_TAG();
POP_ITER();
incoming_state = state;
if (ruby_block->tag->dst == state) {
state &= TAG_MASK;
}
@ -6781,11 +6784,22 @@ proc_invoke(proc, args, pcall, self)
switch (state) {
case 0:
break;
case TAG_BREAK:
result = prot_tag->retval;
break;
case TAG_RETRY:
localjump_error("retry from proc-closure", Qnil);
if (pcall || orphan) {
localjump_error("retry from proc-closure", Qnil);
}
/* fall through */
case TAG_BREAK:
if (pcall) {
result = prot_tag->retval;
}
else if (orphan) {
localjump_error("break from proc-closure", prot_tag->retval);
}
else {
ruby_block->tag->dst = incoming_state;
JUMP_TAG(incoming_state);
}
break;
case TAG_RETURN:
if (orphan) { /* orphan procedure */