Project

General

Profile

Actions

Feature #6710

closed

new special binding specifier :isolated

Added by ko1 (Koichi Sasada) over 12 years ago. Updated almost 8 years ago.

Status:
Rejected
Target version:
[ruby-core:46262]

Description

=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

Updated by ko1 (Koichi Sasada) over 12 years ago

  • Description updated (diff)
  • Category set to core
  • Assignee set to matz (Yukihiro Matsumoto)
  • Target version set to 2.0.0

Updated by jballanc (Joshua Ballanco) over 12 years ago

=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

Updated by ko1 (Koichi Sasada) over 12 years ago

Hi,

(2012/07/09 23:19), jballanc (Joshua Ballanco) wrote:

I like this idea, but I have one question: why make this a special argument to eval and not to Binding.new?

Just a performance. My proposal doesn't make any binding object.
It is similar that `nil' specifier (means current binding).

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?

This is another feature. Make another ticket for it if you want.
I agree that we need more and more thought to introduce your proposal.

--
// SASADA Koichi at atdot dot net

Actions #4

Updated by mame (Yusuke Endoh) over 12 years ago

  • Status changed from Open to Assigned

Updated by matz (Yukihiro Matsumoto) about 12 years ago

  • Assignee changed from matz (Yukihiro Matsumoto) to ko1 (Koichi Sasada)

Ko1, explain why you need modify eval, where we can create new isolated binding.
I don't think small performance improvement is a good excuse.

Matz.

Updated by ko1 (Koichi Sasada) about 12 years ago

Yes, (small) performance issue.

Okay, let's discuss how to make such binding. I think we have several choice.

  • Binding.new
  • Binding.new(:isolated)

Or do we need to discuss jballanc's proposal in another ticket and reject this ticket? I'm okay this way.

Updated by mame (Yusuke Endoh) almost 12 years ago

  • Target version changed from 2.0.0 to 2.6

Updated by ko1 (Koichi Sasada) almost 8 years ago

  • Status changed from Assigned to Rejected
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0