Feature #21365
openAdd `Namespace#eval`
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 notinstance_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 ofinstance_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".