Modifying the AST of a running Ruby script in-place

Is there a way to not merely construct the AST of a Ruby script, but
also to modify it in-memory, thus producing a different script? (I
realize that there’s no Ruby spec and thus, every Ruby implementation
is going to have a different parse tree and thus a different answer.
My question is confined mostly to MRI.)

As a simple example, suppose that I would like to write a method
called “subtractify(m)”. The subtractify method accepts another method
m as input, and then changes all uses of the + operator to -.
The result is a new, unbound method that can either replace the
original method or be attached somewhere else. If I were to bind this
new method to the original object and replace the original one
(similar to overwriting it with a new def), the result should be
equivalent to running the “subtractified” variant of the method with
the original object as the receiver.

Is that (or a similar situation) possible? If so, are there
limitations to what can and can’t be modified?

~ jf

John F.
Principal Consultant, BitsBuilder
LI: http://www.linkedin.com/in/johnxf
SO: User John Feminella - Stack Overflow

On Thu, 10 Feb 2011 21:01:31 +0900
John F. [email protected] wrote:

Is there a way to not merely construct the AST of a Ruby script, but
also to modify it in-memory, thus producing a different script? (I
realize that there’s no Ruby spec and thus, every Ruby implementation
is going to have a different parse tree and thus a different answer.
My question is confined mostly to MRI.)

The problem is, there is no more AST in runtime in MRI 1.9. This was the
biggest 1.9 change: in 1.8 Ruby has traversed and executed the AST
directly, and that was painfully slow. 1.9 now uses bytecode instead;
you can take a look at RubyVM::InstructionSequence.