Issue #16924 has been reported by Wuerfel21 (Ada Gottenstr=E4ter).

----------------------------------------
Feature #16924: instance_eval equivalent for RubyVM::InstructionSequence
https://bugs.ruby-lang.org/issues/16924

* Author: Wuerfel21 (Ada Gottenstr=E4ter)
* Status: Open
* Priority: Normal
----------------------------------------
# Abstract
Proposal to expose the ability to evaluate precompiled ISEQs in non-topleve=
l contexts.
# Background
A common pattern used for certain kinds of DSL is to instance_eval entire f=
iles, like this:
```ruby
___dsl_object.instance_eval(File.read(___path),___path,0)
```
This has certain advantages and disadvantages over other methods of executi=
ng DSL code (mainly that the global namespace is not being polluted by eith=
er the DSL itself or the code running in the DSL). I find it very useful.

Ruby exposes the RubyVM::InstructionSequence API, allowing caching of parsi=
ng/compilation steps to speed up execution. However, the resulting code can=
 only be evaluated at the top level, disallowing it's use with DSLs designe=
d to be instance_eval'd.

# Proposal
Add a `RubyVM::InstructionSequence#eval_in_instance` method that could be u=
sed to replace
```ruby
___dsl_object.instance_eval(File.read(___path),___path,0)
```
with
```ruby
iseq =3D RubyVM::InstructionSequence.compile_file(___path)
# iseq could be cached here
iseq.eval_in_instance(___dsl_object)
```
Note that while instance_eval makes local variables available if the evalua=
ted argument is a string, this new method would not (as the local variables=
 can't be known at compile time). This discrepancy already exists between  =
RubyVM::InstructionSequence#eval and all other standard library functions n=
amed eval, so I assume it's okay.

This new method could also replace some use cases of Kernal#eval (any where=
 the passing of local variables is not required).
# Implementation
From a cursory glance at the relevant code, this seems like a fairly simple=
 feature to implement. Maybe an additional parameter to `#compile` is neede=
d to change the ISEQ type, I'm not sure. If no one who is more experienced =
at working with Ruby internals wants to step up to implement this feature, =
I will try it myself.

# Discussion
There is a rejected feature #12093 about evaluating ISEQs with a binding (w=
hich is not possible since the compiler needs to know the local variables o=
f a binding to compile for it, thus the request got rejected). There was so=
me talk about evaling inside an instance in the comments, but I assume that=
 was forgotten about due to the ticket being closed. Therefore I think open=
ing this new ticket is justified.




-- =

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

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=3Dunsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>