Issue #6710 has been updated by jballanc (Joshua Ballanco).


=begin
I like this idea, but I have one question: why make this a special argument to `eval` and not to `Binding.new`? I've wanted `Binding` to become better specified and more refined for some time now, and I think this would be a good step in the right direction. I think at some point it would be good to think about all of the things that can happen in a binding (e.g. specify locals, shadow locals, function defs, shadow defs, new classes, reopening classes, etc.), and give an API to tell bindings what they can and cannot do.

So, in this case, ISOLATED_BINDING would be something like
    b = Binding.new(TOPLEVEL_BINDING) # New binding "inherits" from Top Level (but not same as class inheritance)
    b.live_locals = false             # This binding will not propagate locals to its "parent" binding (TOPLEVEL_BINDING, in this case)
    eval('def foo; end; a = 10', b)   # method foo is now available, but local "a" is not

This, obviously, requires a lot more thought and work, but for now we could maybe at least have `Binding.new(isolated: true)` as shorthand for the case described above? 
=end

----------------------------------------
Feature #6710: new special binding specifier :isolated
https://bugs.ruby-lang.org/issues/6710#change-27897

Author: ko1 (Koichi Sasada)
Status: Open
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: 2.0.0


=begin

= Abstract

New special binding specifier :isolated for the 2nd argument of eval() method.
eval(src, :isolated) evaluates `src' program on the same environment as `require' and 'load'.
It is a bit different from `TOPLEVEL_BINDING'.

= Background

We have TOPLEVEL_BINDING to evaluate source code on the main environment (self is `main', and so on).
However, TOPLEVEL_BINDING contains local variables which are evaluated in toplevel.

For example:

  x = 10
  eval('a=1', TOPLEVEL_BINDING)
  eval('b=2', TOPLEVEL_BINDING)
  eval('c=3', TOPLEVEL_BINDING)
  eval('p (a+b+c) * x', TOPLEVEL_BINDING) #=> 60

To simulate "require()" or "load()" method, the eval() method with TOPLEVEL_BINDING is not enough (require() and load() methods don't evaluate scripts within `main' environment.  Similar to `main' environment (self == main), but local variables aren't taken over).

BTW, eval() receive special binding specifier `nil' (which means current binding).

= Proposal

Introduce the new special binding specifier :isolated for the 2nd argument of eval() method.

eval(src, :isolated) evaluates `src' program on the new binding, which is same environment as `require' and 'load'.


== Usecase

Users can define toplevel methods, modules, classes on the any places.

  def m
    # define toplevel method foo()
    eval('def foo(); end', :isolated)
  
    # define ::Bar class
    eval('class Bar; end', :isolated)
  end

Users can make your own alternative require() method.

  def my_require(feature)
    ... # set src from feature
    eval(src, :isolated)
    ...
  end

== Consideration

* :isolated is good name or not?

I'm not sure the `isolated' is good name or not.

* ISOLATED_BINDING = :isolated

If make default constants ::ISOLATED_BINDING as a :isolated, then we can use it as `eval(src, ISOLATED_BINDING)', similar manner with TOPLEVEL_BINDING.

= Acknowledgment

Usa-san proposed the name `isolated'.  My first idea of this name is `empty'.

=end



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