» Ruby (tinyrb) on iPhone

Some caveats...

First, tinyrb isn't technically ruby. It's a subset of ruby intended to be fast, embedable, portable and have low memory usage. It's also still in development and as the author (macournoyer) says "not useable for real things" yet. And last, I was having trouble getting garbage collection working so I gave up and just turned it off.

But who cares! Tinyrb is awesomely tiny, and super fun to play around with! So I wanted to see if I could get it running on the iPhone – and I did. To get it running on your phone check out the source and sample project http://github.com/probablycorey/iphone-loves-tinyrb/tree/master

The sample app doesn't do much of anything. It just prints some words out to stdout, but it does so using ruby!

Tinyrb on the iPhone from scratch

  • Grab the original tinyrb source from github.

  • Remove the vendor dependencies we won't need for the iphone (freegetopt, gc, peg)

  • Compile a PCRE static lib for the iPhone. If you don't know how check out this post.

  • Delete tinyrb/vm/tr.c we don't need it since will will instantiate the vm directly from within the app.

  • tinyrb uses GC_malloc to allocate space, since I couldn't figure out how to get GC working on the iphone I punted and just have tinyrb never cleanup after itself. Below is the code I changed in tr.h.

// Need this function because tinyrb expects malloc's to return zeroed out memory
void *zeroed_malloc(size_t size) {
  void *value = malloc(size);
  if (value != 0) memset(value, 0, size);
  return value;
}

// Don't let the GC function do anything!
void _noop();

/* allocation macros */
#define TR_MALLOC            zeroed_malloc
#define TR_CALLOC(m,n)       calloc((m)*(n))
#define TR_REALLOC           realloc
#define TR_FREE(S)           free(s)

#define GC_INIT              _noop
#define GC_gcollect          _noop
  • Get rid of #include <gc.h> and change #include <pcre.h> to #include "pcre.h"

  • Create an xcode iPhone project. Add the "pcre", "vm" and "lib" folders to the project. When adding the "lib" folder make sure you choose "Create Folder References for added folders" instead of "Recursively create groups for added folders". This will add the lib files to the application bundle so the tinyrb VM can access them at runtime.

  • You have to change the app's current working directory to the bundle path. Tinyrb expects to find the "lib" folder to be in the cwd.

  • You need to name the VM variable "vm", a lot of the tinyrb macros rely on this.

  • Now just start up the VM and send it some ruby. It will output it all to stdout.

vm = TrVM_new();    

NSString *input = [NSString stringWithFormat:@"a = 'does this work?'; puts a + ' YEAH'"];
NSString *input = [NSString stringWithFormat:@"a = 4; puts a + 6"];
TR_FAILSAFE(TrVM_eval(vm, [input UTF8String], "<eval>"));

User Comments

Recent Posts

  • Interactive console for iOS! - August 20, 2010
  • Archive

    • Letter to Steve Jobs - April 11, 2010
    • Wax talks to Twitter - October 20, 2009
    • How does iPhone Wax work? - October 19, 2009
    • Setting up iPhone Wax - October 18, 2009
    • Ruby (tinyrb) on iPhone - May 03, 2009
    • Building PCRE static lib for the iPhone - May 02, 2009
    • Amazon EC2 + Chef = Mmmmm - March 29, 2009
    • Objective-c key paths - February 13, 2009
    • POW! - December 26, 2008
    • Abusing Ruby's question mark methods. - November 28, 2008
    • Git hooks make me giddy - November 07, 2008
    • Ruby Equality! equal? eql? == and === - October 26, 2008
    • Ruby, Rails and Google Sitemaps - October 20, 2008
    • Projects

      • Wax Obj-C to Lua bridge for iPhone.
      • Pow a Ruby library for making file & directory manipulation easy.
      • MiniMagick a tiny RMagick replacement.