REPL-ilze! Building an In-Browser Ruby REPL with Opal

One of the (many wonderful) features of Ruby that makes it such a great language for beginner coders is it's playground, IRB.

a super fun playground

*IRB is easily as fun as this playground*

IRB stands for Interactive Ruby Shell. It is a REPL (Read, Evaluate, Print, Loop) environment that you can load in your terminal. Inside IRB, you can write or copy/paste any snippets of Ruby code to execute and play around with. What if you're away from your own computer and need to run some Ruby code real quick? You don't want to grab someone else's machine and try to mess around replicating your own development environment. For this reason, it can be useful to have access to an in-browser REPL for manipulating and testing Ruby code. Enter, Opal.

What is Opal?

Opal is a source-to-source Ruby-to-Javascript compiler. It can be run in any browser. Opal parses Ruby code, translates it into Javascript, and executes that Javascript.

Why Use Opal?

Opal allows you to write your client-side code in Ruby, instead of Javascript. This makes for much happier Rubyists and keeps our client-side code concise and eminently readable. To learn more about the wonders of Opal, check out this great blog post by Jared White.

In this post, we'll set up a basic Opal-Rails app and implement Forrest Chang's opal-irb gem to construct and in-browser Ruby REPL, called repl-ize.

Setting Up Opal-Rails

1. Create a new Rails app with rails new in your terminal. Add gem 'rails-opal' to your Gemfile and bundle install.
2. Add the following to your config/application.rb file:

module MyApp  
  class Application < Rails::Application
    # These are the available options with their default value:
    config.opal.method_missing      = true
    config.opal.optimized_operators = true
    config.opal.arity_check         = false
    config.opal.const_missing       = true
    config.opal.dynamic_require_severity = :ignore

    # Enable/disable /opal_specs route
    config.opal.enable_specs        = true

    config.opal.spec_location = 'spec-opal'

3 . Rename app/assets/javascripts/application.js to app/assets/application.js.rb. Change the Sprockets' //= require statements to Ruby require methods and add the following requirements:

require 'opal'  
require 'opal_ujs'  
require 'turbolinks'  
require_tree '.'  

4 . That's it! Let's test it out and write our very first Opal script:

  • Create a file in app/assets/javascripts called hello_world.js.rb.
  • Fill it with the following code:
puts "sup, world?" # check the console!

# Dom manipulation
require 'opal-jquery'

Document.ready? do  
  Element.find('body > header').html = '<h1>Hello world!</h1>'
  • Create a a method in your Application controller, #hello and set the route path to be 'application/#hello' in config/routes. Create a corresponding hello.html.erb view and we should be up and running.
  • Start your server with rails s in the terminal and you should see "Hello World!" in the browser. Open up the Javascript console in your browser and you should see sup, world?

Now that we have opal-rails up and running, we can use the opal-irb gem to create our REPL.

Building the REPL with Opal-IRB

1 . Add the following to your Gemfile and bundle install.

gem 'opal'  
gem 'opal-jquery'  
gem 'opal-browser'  
gem 'opal-irb', github: 'fkchang/opal-irb', require: 'opal-irb-rails'  
gem 'jquery-ui-rails'  

2 . Add the Jquery-UI and Jquery Console stylesheets to your applicatioin.css

 *= require jquery-ui/dialog
 *= require opal-irb/jqconsole

3 . Include Code Mirror js/css by adding a call to the CDN in your application.html.erb:

<%= OpalIrbUtils.include_code_mirror.html_safe%>  

CodeMirror is a text editor implemented in JavaScript for the browser.

4 . Now, we're ready to place the necessary code for adding our REPL to the DOM. Create a file in app/assets/javascripts called repl.js.rb. Add the following code:

require 'opal_irb_jqconsole'

Document.ready? do  

And that's it! Most of this tutorial was guided by the Opal-IRB Read Me. For the styling, I used the Solarize theme (css available here).

subscribe and never miss a post!

Blog Logo

Sophie DeBenedetto

comments powered by Disqus
comments powered by Disqus