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:
parent
aaebe67919
commit
d47be39735
2 changed files with 75 additions and 47 deletions
20
ChangeLog
20
ChangeLog
|
@ -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
102
eval.c
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue