diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-05-14 06:22:31 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-05-14 06:22:31 +0000 |
commit | eb6118992b77df9ddd3f95692d357e09b353c358 (patch) | |
tree | 75790afdc7305f70f15d2c9140a8a6d75c482c80 /eval.c | |
parent | c5d6a1ba48306652bb96bf0bf081c8c66cb45ef5 (diff) | |
download | ruby-eb6118992b77df9ddd3f95692d357e09b353c358.tar.gz |
* eval.c (rb_clear_cache_by_class): new function.
* eval.c (set_method_visibility): should have clear cache forq
updated visibility.
* numeric.c (flo_to_s): default format precision to be "%.16g".
* util.c (ruby_strtod): use own strtod(3) implementation to avoid
locale hell. Due to this change "0xff".to_f no longer returns 255.0
* eval.c (avalue_to_yvalue): new function to distinguish yvalue
(no-arg == Qundef) from svalue (no-arg == Qnil).
* eval.c (rb_yield_0): use avalue_to_yvalue().
* eval.c (assign): warn if val == Qundef where it means rhs is
void (e.g. yield without value or call without argument).
* parse.y (value_expr): need not to warn for WHILE and UNTIL,
since they can have return value (via valued break).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2457 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'eval.c')
-rw-r--r-- | eval.c | 62 |
1 files changed, 49 insertions, 13 deletions
@@ -217,6 +217,21 @@ rb_clear_cache_by_id(id) } } +static void +rb_clear_cache_by_class(klass) + VALUE klass; +{ + struct cache_entry *ent, *end; + + ent = cache; end = ent + CACHE_SIZE; + while (ent < end) { + if (ent->origin == klass) { + ent->mid = 0; + } + ent++; + } +} + void rb_add_method(klass, mid, node, noex) VALUE klass; @@ -2112,10 +2127,27 @@ avalue_to_svalue(v) } static VALUE +avalue_to_yvalue(v) + VALUE v; +{ + if (TYPE(v) != T_ARRAY) { + v = rb_ary_to_ary(v); + } + if (RARRAY(v)->len == 0) { + return Qundef; + } + if (RARRAY(v)->len == 1) { + return RARRAY(v)->ptr[0]; + } + return v; +} + +static VALUE svalue_to_mvalue(v) VALUE v; { - if (NIL_P(v)) return rb_ary_new2(0); + if (v == Qnil || v == Qundef) + return rb_ary_new2(0); if (TYPE(v) == T_ARRAY) { return v; } @@ -2511,10 +2543,10 @@ rb_eval(self, n) case NODE_YIELD: if (node->nd_stts) { - result = avalue_to_svalue(rb_eval(self, node->nd_stts)); + result = avalue_to_yvalue(rb_eval(self, node->nd_stts)); } else { - result = Qnil; + result = Qundef; /* no arg */ } result = rb_yield_0(result, 0, 0, 0); break; @@ -3745,21 +3777,21 @@ rb_yield_0(val, self, klass, pcall) RARRAY(val)->len); } } + else if (nd_type(block->var) == NODE_MASGN) { + massign(self, block->var, val, pcall); + } else { - if (nd_type(block->var) == NODE_MASGN) { - massign(self, block->var, val, pcall); - } - else { - if (pcall) val = avalue_to_svalue(val); - assign(self, block->var, val, pcall); + if (pcall) { + val = avalue_to_yvalue(val); } + assign(self, block->var, val, pcall); } } POP_TAG(); if (state) goto pop_state; } else if (pcall) { - val = avalue_to_svalue(val); + val = avalue_to_yvalue(val); } PUSH_ITER(block->iter); @@ -3849,7 +3881,7 @@ static VALUE rb_f_loop() { for (;;) { - rb_yield_0(Qnil, 0, 0, 0); + rb_yield_0(Qundef, 0, 0, 0); CHECK_INTS; } return Qnil; /* dummy */ @@ -3912,7 +3944,10 @@ assign(self, lhs, val, pcall) VALUE val; int pcall; { - if (val == Qundef) val = Qnil; + if (val == Qundef) { + rb_warning("assigning void value"); + val = Qnil; + } switch (nd_type(lhs)) { case NODE_GASGN: rb_gvar_set(lhs->nd_entry, val); @@ -5623,6 +5658,7 @@ set_method_visibility(self, argc, argv, ex) for (i=0; i<argc; i++) { rb_export_method(self, rb_to_id(argv[i]), ex); } + rb_clear_cache_by_class(self); } static VALUE @@ -6470,7 +6506,7 @@ proc_invoke(proc, args, pcall, self) ruby_frame->iter = ITER_CUR; if (!pcall) { - args = avalue_to_svalue(args); + args = avalue_to_yvalue(args); } PUSH_TAG(PROT_NONE); state = EXEC_TAG(); |