Project

General

Profile

Bug #10466

rb_eval_string_wrap does not actually wrap in a module binding

Added by silverhammermba (Max Anselm) over 2 years ago. Updated over 2 years ago.

Status:
Open
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
ruby 2.1.4p265 (2014-10-27 revision 48166) [x86_64-linux]
[ruby-core:66049]

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.

History

#1 [ruby-core:66739] Updated by retro (Josef Šimánek) over 2 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);
}

Also available in: Atom PDF