I want to first say that all that follows is basically a terrible idea, but I enjoy building evil projects once in awhile. If you are looking for a nice solution to running Ruby from the web checkout repl.it, TryRuby, or codepad.
In this post I show examples of how I setup Ruby code that can be executed on my statically generated blog. This is sort of a Ruby follow up to Javascript formatting and highlighting on Jekyll and Github pages. Although, it doesn’t show how to setup your own version as that wouldn’t be very safe or secure.
Once I had javascript code execution working, I really wanted to be able to do the same with Ruby. I could even envision some real world use cases for running Ruby from a page. I happened to be working on another project that seemed like a good fit to making Ruby from JS happen. I am going to start with some examples before getting into how the remote Ruby runner works.
(The first run might take as long as 60 seconds to return a result, more on why below)
require 'test/unit' class Client attr_accessor :name, :age def initialize(name, age) self.name = name self.age = age end def can_drink? age > 21 end end ClientTest = Class.new Test::Unit::TestCase do def test_can_drink client = Client.new('bruce', 20) assert_equal false, client.can_drink? end end
require 'pdfkit' kit = PDFKit.new('http://www.reddit.com/') Dir.mkdir('./artifacts') unless File.exists?('./artifacts') file = kit.to_file('./artifacts/temp_pdf_kit.pdf')
The Ruby script running is based on a couple projects that I am not really ready to release. I can explain the basic functions and components, but I am not saying this is a good idea. I also wouldn’t take this as a template for how anyone should try to embed Ruby examples into a blog. I must say that for just running some simple Ruby code this is in fact huge overkill. The pieces of my code running system are built to handle much more than simple script requests, I just realized it would be a simple feature to add to my other project for fun. Here are the steps taken to run Ruby from a static HTML site.
future_result
.future_result
and is polling for completed results.Unfortunately, the code for this isn’t really ready for general use. In fact it is quite a mess. I won’t get into why for now, but I can say that I have been playing around with many different development ideas and styles on my side projects and some really didn’t work well at all! I also have yet to come up with a security model that would make this really safe to share.
As mentioned earlier it can take a long time for the first request to respond. This is because I am not just hitting one server that is ready to handle my Ruby request. I am hitting a go between server which actually manages other servers and boots them up on demand. Once the script-responder server is up and running the response time is actually pretty good even with the go between server.
I could modify and combine small pieces of the two projects to allow anyone to easily setup a Heroku instance to execute arbitrary Ruby code. Which might be the best way to release and share this functionality. If there is any interest in being able to quickly and easily embed Ruby example code on blogs, let me know and I can likely whip that up. Just being able to run code on Heroku, wouldn’t satisfy my needs as I wanted to run code which couldn’t be installed onto Heroku systems.
I will post more on deferred-server and server-responder at some point in the future. For now you can read more about the deferred-server script runner in the examples section.
Also, you can check out my first real world usage to run custom Ruby on a static page. It uses a custom JS script on my resume, which runs embedded JS to on the fly build a PDF of my resume (click the PDF link to see it in action, view the page source to see how it works). This has been running ‘in production’ for months without issue. The source for custom Ruby on the page is pretty hilarious.
<div class="ruby-runner-custom" style="display:none;" data-sig="IhFw4kpAHfpiBkbNv0s4ALR8tjc=" data-auto-init="false">
<pre class="code">
require 'pdfkit'
kit = PDFKit.new('http://resume.mayerdan.com/?no_pdf=true')
file = kit.to_file('./artifacts/dan_mayer_resume.pdf')
</pre>
</div>
<script src="http://git-hook-responder.herokuapp.com/javascript/code-runner.js" type="text/javascript"></script>
<script>
var addPDFLink = function(currentPluggin) {
var element = '#formats';
$('#formats').append(' | <a class="run-button" href="#">PDF</a>');
$(element).find('.run-button').click(function(e) {
$(element).find('.run-button').text('generating...');
currentPluggin.runExample();
e.preventdefault;
return false;
});
};
$('.ruby-runner-custom').codeRunner({'initialize_method' : addPDFLink, 'follow_files' : 'true'});
</script>
I also use the deferred code running functionality in a slightly different way with a Ruby project. It follows the same basic flow, but opposed to JS the Ruby app can make requests to itself running on a deferred server. I use that functionality on my blog2ebook project to perform tasks that aren’t allowed or would take to long on Heroku, like running kindlegen to generate ebooks. This allows a app to serve as a front end on Heroku while doing larger backend tasks on a more robust server.
I will keep playing around with these systems and hopefully be sharing more and putting the to good use soon.