Issue #10466 has been updated by Josef Simanek.


You can reproduce this without C code also.

```ruby
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:

```c
#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);
}
```



----------------------------------------
Bug #10466: rb_eval_string_wrap does not actually wrap in a module binding
https://bugs.ruby-lang.org/issues/10466#change-50331

* Author: Max Anselm
* Status: Open
* Priority: Normal
* Assignee: 
* Category: 
* Target version: 
* ruby -v: ruby 2.1.4p265 (2014-10-27 revision 48166) [x86_64-linux]
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN
----------------------------------------
`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.




-- 
https://bugs.ruby-lang.org/