diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2003-06-02 04:49:46 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2003-06-02 04:49:46 +0000 |
commit | 6125313d69c158b423d1f4aff2e206cfd43a036a (patch) | |
tree | a1a78a9425305557dcff6569806876989c9098c3 /eval.c | |
parent | f5a7f85917abed4d64ad908a4837e0db0499c951 (diff) | |
download | ruby-6125313d69c158b423d1f4aff2e206cfd43a036a.tar.gz |
* array.c (push_values_at): Array#values_at should work with
ranges too.
* range.c (rb_range_beg_len): length calculation was wrong.
* eval.c (rb_call): should set T_ICLASS in the frame->last_class.
[ruby-core:01110]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3899 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'eval.c')
-rw-r--r-- | eval.c | 18 |
1 files changed, 16 insertions, 2 deletions
@@ -5041,6 +5041,7 @@ rb_call(klass, recv, mid, argc, argv, scope) int noex; ID id = mid; struct cache_entry *ent; + VALUE k = klass; if (!klass) { rb_raise(rb_eNotImpError, "method `%s' called on terminated object (0x%lx)", @@ -5051,17 +5052,30 @@ rb_call(klass, recv, mid, argc, argv, scope) if (ent->mid == mid && ent->klass == klass) { if (!ent->method) return rb_undefined(recv, mid, argc, argv, scope==2?CSTAT_VCALL:0); - klass = ent->origin; + k = ent->origin; id = ent->mid0; noex = ent->noex; body = ent->method; } - else if ((body = rb_get_method_body(&klass, &id, &noex)) == 0) { + else if ((body = rb_get_method_body(&k, &id, &noex)) == 0) { if (scope == 3) { return rb_undefined(recv, mid, argc, argv, CSTAT_SUPER); } return rb_undefined(recv, mid, argc, argv, scope==2?CSTAT_VCALL:0); } + if (BUILTIN_TYPE(k) == T_MODULE) { + while (!(BUILTIN_TYPE(klass) == T_ICLASS && RBASIC(klass)->klass == k)) { + klass = RCLASS(klass)->super; + if (!klass) { + rb_raise(rb_eTypeError, "%s is not included in %s", + rb_class2name(k), + rb_class2name(CLASS_OF(recv))); + } + } + } + else { + klass = k; + } if (mid != missing) { /* receiver specified form for private method */ |