Skip to content

Commit 76c4663

Browse files
committed
Fix Namespace.current to show its caller's namespace
Calling rb_current_namespace() in rb_namespace_current() means to show the definition namespace of Namespace.current itself (it's the root always) but the users' expectation is to show the namespace of the place where the Namespace.current is called.
1 parent 4f47327 commit 76c4663

File tree

3 files changed

+16
-6
lines changed

3 files changed

+16
-6
lines changed

eval_intern.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,7 @@ VALUE rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg, VALUE block_
299299
VALUE rb_vm_call_cfunc_in_namespace(VALUE recv, VALUE (*func)(VALUE, VALUE), VALUE arg1, VALUE arg2, VALUE filename, const rb_namespace_t *ns);
300300
void rb_vm_frame_flag_set_ns_require(const rb_execution_context_t *ec);
301301
const rb_namespace_t *rb_vm_current_namespace(const rb_execution_context_t *ec);
302+
const rb_namespace_t *rb_vm_caller_namespace(const rb_execution_context_t *ec);
302303
const rb_namespace_t *rb_vm_loading_namespace(const rb_execution_context_t *ec);
303304
void rb_vm_set_progname(VALUE filename);
304305
VALUE rb_vm_cbase(void);

namespace.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,11 +455,12 @@ rb_namespace_s_getenabled(VALUE namespace)
455455
static VALUE
456456
rb_namespace_current(VALUE klass)
457457
{
458-
const rb_namespace_t *ns = rb_current_namespace();
458+
const rb_namespace_t *ns;
459459

460460
if (!rb_namespace_available())
461461
return Qnil;
462462

463+
ns = rb_vm_caller_namespace(GET_EC());
463464
VM_ASSERT(ns && ns->ns_object);
464465
return ns->ns_object;
465466
}

vm.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3052,13 +3052,21 @@ current_namespace_on_env(const VALUE *ep)
30523052
const rb_namespace_t *
30533053
rb_vm_current_namespace(const rb_execution_context_t *ec)
30543054
{
3055-
const rb_control_frame_t *cfp;
3055+
VM_ASSERT(rb_namespace_available());
3056+
return current_namespace_on_env(ec->cfp->ep);
3057+
}
30563058

3057-
if (!rb_namespace_available() || !ec)
3058-
return rb_root_namespace();
3059+
const rb_namespace_t *
3060+
rb_vm_caller_namespace(const rb_execution_context_t *ec)
3061+
{
3062+
const rb_control_frame_t *caller_cfp;
30593063

3060-
cfp = ec->cfp;
3061-
return current_namespace_on_env(cfp->ep);
3064+
VM_ASSERT(rb_namespace_available());
3065+
3066+
// The current control frame is MAGIC_CFUNC to call Namespace.current, but
3067+
// we want to get the current namespace of its caller.
3068+
caller_cfp = vm_get_ruby_level_caller_cfp(ec, RUBY_VM_PREVIOUS_CONTROL_FRAME(ec->cfp));
3069+
return current_namespace_on_env(caller_cfp->ep);
30623070
}
30633071

30643072
const rb_namespace_t *

0 commit comments

Comments
 (0)