Bug #10466
closedrb_eval_string_wrap does not actually wrap in a module binding
Description
rb_eval_string_wrap
says that it "evaluates the given string under a module binding in an isolated binding", but this isn't true.
Run the following:
#include <ruby.h>
int main(int argc, char* argv[])
{
ruby_init();
int state;
rb_eval_string_protect("X = 2", &state);
rb_eval_string_wrap("X = 3", &state);
rb_eval_string_protect("puts X", &state);
return ruby_cleanup(0);
}
Expected:¶
outputs 2
Actual:¶
outputs
eval:1: warning: already initialized constant X
eval:1: warning: previous definition of X was here
3
It looks like rb_eval_string_wrap
tries to wrap it
th->top_wrapper = rb_module_new();
th->top_self = rb_obj_clone(rb_vm_top_self());
rb_extend_object(th->top_self, th->top_wrapper);
But it ends up calling ruby_eval_string_from_file
which uses rb_vm_top_self()
as self
, thus undoing the wrapping.
rb_load
can perform similar wrapping, but there it works properly.
Files
Updated by retro (Josef Šimánek) about 10 years ago
You can reproduce this without C code also.
Module.new {X = 5} #=> #<Module:0x000000012186c0>
Module.new {X = 5} #=> #<Module:0x00000001209da0>
(irb):2: warning: already initialized constant X
(irb):1: warning: previous definition of X was here
And since rb_eval_string_wrap
is really wrapping code into module, this works without warning:
#include <ruby.h>
int main(int argc, char* argv[])
{
ruby_init();
int state;
rb_eval_string_wrap("self::Y = 'wrap'", &state);
rb_eval_string_wrap("self::Y = 'wrap'", &state);
return ruby_cleanup(0);
}
Updated by jeremyevans0 (Jeremy Evans) over 5 years ago
I agree this a bug. The documentation states for rb_eval_string_wrap
that This is same as the binding for loaded libraries on "load('foo', true)"
, but that doesn't appear to be the case. load('foo', true)
evaluates with an anonymous module in Module.nesting
, but rb_eval_string_wrap
uses an empty Module.nesting
.
The attached patch should fix the issue by setting a cref, so that rb_eval_string_wrap
evaluates the string with an anonymous module in Module.nesting
. I'm not sure if this is the best way to fix it, and would appreciate if another committer could review this patch. Unfortunately, there are no tests for the rb_eval_string_wrap
function and nothing internally seems to use this method.
Updated by ko1 (Koichi Sasada) over 5 years ago
- Status changed from Open to Assigned
- Assignee set to ko1 (Koichi Sasada)
Updated by jeremyevans (Jeremy Evans) about 5 years ago
- Status changed from Assigned to Closed
Applied in changeset git|e4db0443bcfc94f9183e8ea72fb4ab560aa005bf.
Make rb_eval_string_wrap specify a cref so constant setting works correctly
Fixes [Bug #10466]