Project

General

Profile

Actions

Feature #21365

open

Add `Namespace#eval`

Added by tenderlovemaking (Aaron Patterson) 5 days ago. Updated about 11 hours ago.

Status:
Open
Assignee:
-
Target version:
-
[ruby-core:122242]

Description

I would like a way to eval code on to a Namespace object. Could we add an eval method that doesn't take a binding object? Writing a new file every time I want to test Namespaces is too cumbersome.

Thanks!

Updated by matheusrich (Matheus Richard) 4 days ago

I'm curious why eval and not instance_eval?

Updated by Eregon (Benoit Daloze) 4 days ago

Yep, agreed it'd be far more convenient for testing Namespace.

matheusrich (Matheus Richard) wrote in #note-1:

I'm curious why eval and not instance_eval?

Why instance_eval? The distinction between eval/class_eval/instance_eval does not seem relevant here.

Though of course the semantics should be the same as writing the code to a file + Namespace#require so e.g. ns.eval "def foo = 42" defines method foo on ns' copy of Object methods.

Updated by matheusrich (Matheus Richard) 4 days ago

@Eregon (Benoit Daloze) I feel like that's more consistent with the rest of the language. I can't remember if any object as a eval method. But evaluating some code in a particular instance context makes me think of instance_eval.

Updated by ufuk (Ufuk Kayserilioglu) 4 days ago

matheusrich (Matheus Richard) wrote in #note-3:

@Eregon (Benoit Daloze) I feel like that's more consistent with the rest of the language. I can't remember if any object as a eval method. But evaluating some code in a particular instance context makes me think of instance_eval.

I am not sure I understand. All objects have an eval method in the form of Kernel#eval: https://ruby-doc.org/3.4.1/Kernel.html#method-i-eval

Updated by matheusrich (Matheus Richard) 4 days ago

@ufuk (Ufuk Kayserilioglu) fair point. Although it is a private method, so we're never doing "foo".eval(bar).

Updated by Eregon (Benoit Daloze) 1 day ago

ns.eval "self" would be the Namespace "main" object, not the Namespace instance itself, so instance_eval would be a bad fit here.

AFAIK, instance_eval is only called as such because any def foo; end inside it will definite a singleton method on the instance.
And similarly class_eval defines def foo; end as a class instance method.
This is not relevant here, def foo; end would have normal top-level def semantics (in that namespace).

Updated by fxn (Xavier Noria) 1 day ago ยท Edited

instance_eval modifies the nesting in the eval'ed code. Since namespaces are modules, instance_eval already works:

ns = Namespace.new
ns.instance_eval "p Module.nesting"

That prints [Namespace].

I believe @tenderlovemaking (Aaron Patterson) wants a regular top-level execution context, where the nesting would be empty, in particular (mod https://bugs.ruby-lang.org/issues/21318).

Updated by matheusrich (Matheus Richard) 1 day ago

Thanks for the clarification, everyone!

Updated by fxn (Xavier Noria) about 11 hours ago

I want to clarify that I explained that instance_eval works, and what it does, because Namespace is a Module.

But that does not mean I believe that is good.

Namespaces try to be one thing, but by being modules they carry other things that, in my view, are not quite coherent with the feature.

It is another instance of my hunch that namespaces should be a new entity with new rules.

In this particular case, I believe they should not respond to instance_eval, or module_eval or anything. Precisely, the proposed eval in this ticket is what makes sense to me: "run this code in your execution context".

Actions

Also available in: Atom PDF

Like1
Like0Like0Like0Like0Like0Like0Like0Like0Like0