Compile Ruby Code to Binary & Execute It

Since the introduction of the RubyVM module in the Core API, Ruby developers have been able to get an insight into the internal workings of Ruby. The official Ruby documentation has a detailed explanation about the capabilities of this module if you’re into it. In this post, I will be discussing about how we can utilize this module to compile Ruby code to binary and load it back into another binding for execution at a later time.

Compile Ruby Code To Binary

Do not use the methods discussed below in your production environments.

Creating a sample program for compilation

Let us begin by creating a simple Ruby program that we can compile to binary. Here, I’ve just created a fibonacci.rb file containing the ruby implementation of the ever so famous fibonacci series algorithm.

# fibonacci.rb
PHI = (1+Math.sqrt(5))/2

def fibonacci(n)
  ((PHI ** n) - ((-PHI) ** -n)) / Math.sqrt(5)
end

fibonacci(100)

Designing a Ruby “Compiler” in Ruby.

Now we will create a compiler file compiler.rb which will help us compile the fibonacci.rb file we created in the first step to binary. We will be using this file to convert our ruby code to binary which can be stored and put away in a file.

# compiler.rb
source_code = File.open(ARGV[0], 'r')       # load the file from arguments

compiled_code = RubyVM::InstructionSequence.compile(source_code)
binary_code = compiled_code.to_binary

binary_file = File.open(ARGV[0].split('.').first + '.bin', 'w+')
binary_file.puts binary_code
binary_file.close

You can run the compiler to compile fibonacci.rb as follows:

$ ruby compiler.rb fibonacci.rb

After running the above command, the directory containing the fibonacci.rb file will also contain a binary file named fibonacci.bin. This file contains all our ruby code compiled to binary.

Execution Of The Compiled Binary Code

Now that we have the binary code of our sample program, we will create another ruby program to load the binary code and execute it in a separate binding. To achieve this, we shall create a new file called exec.rb and add the following code to it:

exec.rb
executable_binary_code = File.open(ARGV[0], 'r').readlines.join('')
compiled_instruction_sequence = RubyVM::InstructionSequence.load_from_binary(executable_binary_code)
compiled_instruction_sequence.eval

We will use the exec.rb file to execute our binary code as follows:

$ ruby exec.rb fibonacci.bin

And voila! There you go. The program successfully executes and prints the output on the screen. That’s how you compile Ruby code to binary and execute it.

This is a simple demonstration of a very powerful feature that has plenty of applications in real world development. Right tools in the right hands can work wonders.

Cheers 🍻 

Sreedev Kodichath

Sreedev Kodichath, a passionate software engineer, an avid blogger & an eloquent orator is the author of DevTechnica.

You may also like...

1 Response

  1. Scott Nichols says:

    This is a great article, and one that I was working with, but I ran into a small (or rather large) problem. I program Ruby in Sketchup, and found that when I got to the 2nd step for Designing a Ruby Compiler in Ruby, that the method #to_binary for the compiled_code was missing. Can you suggest a way to resolve this issue? Thanks, Scott.

Leave a Reply

Your email address will not be published. Required fields are marked *