Issue #12093 has been updated by dalehamel (Dale Hamel).


Howdy,

Sorry to ping a 3 year old issue, i Just wanted to add my 2 cents here.

I came across this issue when googling for a way to evaluate an instruction sequence with a particular binding. I'm working on an experimental gem that would inject "breakpoints" in arbitrary lines in ruby methods, with the idea that eBPF / bpftrace can be used to read values from these overridden methods. I've written up my early approach to this at https://bpf.sh/production-breakpoints-doc/index.html

Right now i'm using a block to 'handle' the original source code in its original binding, but i have to use ruby's 'eval' method to do this.

I'd ideally like to precompile the original source code sequence, and evaluate this with the original binding.


> This enables the following code, but doesn't seem useful to me.


So in my case, this would be *exactly* what I want and extremely useful.

Say I have the original method:

```ruby
 def some_method
       a = 1
       sleep 0.5
       b = a + 1
 end
```

Then it currenly is transformed into:

```ruby
 def some_method
 local_bind=binding; ProductionBreakpoints.installed_breakpoints[:test_breakpoint_install].handle(local_bind) do
 <<-EOS
       a = 1
       sleep 0.5
       b = a + 1
 EOS
 end
  ProductionBreakpoints.installed_breakpoints[:test_breakpoint_install].finish(local_bind) do
 <<-EOS
 EOS
 end
     end
```

where those strings are just passed to `eval` with that original method binding. I think I could improve the performance of this if i could just precompile that source when I'm redefining the method, so that i don't have to take the overhead of eval each time this code is executed.

Nobu's patch looks like it would allow me to do this, eg by compiling the source and storing it on my "breakpoint" object to just be evaluated in the context of the caller's binding.

There may be other ways to do this, just wanted to add my 2 cents to this issue as it seemed most relevant.

I know this is a bit of an esoteric metaprogramming case, but it seems like the patch is pretty small and simple. I wonder if it still applies relatively easily (3 years later - sorry!)?

----------------------------------------
Feature #12093: Eval InstructionSequence with binding
https://bugs.ruby-lang.org/issues/12093#change-79803

* Author: pavel.evstigneev (Pavel Evstigneev)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
Implementing this feature can boost template engine performance

Currently Kernel#eval can accept binding argument, so code running with eval will have access to local variables and current instance. This feature used by template languages

ERB: https://github.com/ruby/ruby/blob/trunk/lib/erb.rb#L887
Erubis: Can't find code on github, but it uses instance_eval or Kernel#eval
Haml: https://github.com/haml/haml/blob/master/lib/haml/engine.rb#L115

My proposal is to make RubyVM::InstructionSequence#eval to recieve binding argument. So it can be used for caching templates. As I see from ERB and Haml, cached template is stored as ruby code string, every time when we render template that string (ruby code) is evaluated, internally ruby will parse it into RubyVM::InstructionSequence and then evaluate.

Before I try to implement it myself in ruby, but could not. Lack of experience with C https://github.com/Paxa/ruby/commit/f5b602b6d9eada9675a4c002c9a5a79129df73a6 (not working)



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

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