OSCON 2006

I’ve made it to OSCON ‘06 after being stuck in a plane sitting at the gate for almost two hours at Dulles airport. I’m dead tired so stay tune for coverage over the course of the conference.

July NovaRUG Meeting

Tonight was the monthly NovaRUG meeting and Brian Sletten presented on DRb while I presented on RJS. My presentation and code is available here. I think it went over pretty well and I made several new contacts after the meeting which is always nice. Brian’s presentation is available here – so I don’t need to provide the usual coverage that I do. He gave a very engaging and amusing talk that everyone enjoyed. One interesting note, not covered in his slides but played following his presentation, is that a Japanese band called The Blue Hearts wrote a song called “Rinda, Rinda� – though it appears to have no relation to the Rinda tuplespace library as the song was first released in 1987.

June NovaRUG Meeting

Tonight at NovaRUG we had two presenters: Tom Copeland and Xandy Johnson. Tom spoke about extending Ruby with C extensions and Xandy spoke about Rake. Tom walked through the ‘evolution’ of his Revolution Ruby library which provides Ruby bindings for the GNOME Evolution PIM (via the e-book library). His first example was the straight-forward way of extending Ruby with C (the code example looked very similar to those in Chapter 21 of the Pick Axe). There’s also an article at OnLamp about extending Ruby with C. His second example was more interesting, for me at least – he showed how to use Ruby DL2 to export C functions into a Ruby module using pure Ruby code! It’s as easy as this:

require 'dl/import'

module Foo
extend Importer

dlload 'libc'

extern "size_t strlen(const char *)"
end

s = "Hello, World!"
puts "#{s} is #{Foo.strlen(s)} characters long."

After that, Tom spoke briefly about SWIG for Ruby. Unfortunately, he had difficulty getting it to work and no one else present had been successful with it (or was willing to speak about it). Xandy was up next with an excellent overview of Jim Weirich’s Rake. He started off with a nice poem entitled ‘Ode to Rake’ which I will not republish as he was going to send it over to Jim and I don’t want to ruin that (there were suggestions that _why should turn it into a song). Xandy provided an overview of other popular build tools like Make and Ant (and we all had a good time complaining about Ant). Next he delved into the Rakefile sytax (after reminding us that Rake is all Ruby; so anything you can do in Ruby you can do in Rake) and discussed tasks, file tasks, directory tasks, rules, FileLists, sh (for calling out to the shell), ruby (for invoking another Ruby interpreter), package, rdoc and gem. Near the end of his presentation, he winged his way through namespaces, dependency import and multitask. Overall it was an excellent introduction to Rake which whetted our appetites for a deeper dive into Rake. Next month I’ll be presenting on Rails RJS Templates, on July 19th.

A Look at Rails Engines

A few months ago I heard about the ’controversy’ surrounding Rails Engines and meant to check them out, though work/life intervened and I never got around to it until now. So last week I setup a RubyForge project (thanks Rich and Tom!) called BlogEngine to learn the ins and outs of creating a Rails Engine. At first blush, Rails Engines seem to be plugins on steroids, incredibly powerful but somewhat dangerous. For those who haven’t yet visited the Rails Engines website:

Engines are a way of dropping in whole chunks of functionality into your existing application without affecting any of your existing code. Engines are like a slice of an application from top (views/helpers) to bottom (models) which can be dropped into an existing application and appear as if they always existed in the normal /app directory. Developers can selectively override parts of Engines as they need to handle their application (such as changing the user/home view to display a silly name, without affecting the rest of the Engine). Engines can be as lightweight as the simplest plugin, or as full-featured as your your (sic) imagination can conceive.

James Adam has done an excellent job documenting the Rails Engine plugin and the Wiki with how to create your own Rails Engines. That said, while I found the development of my BlogEngine to be relatively painless (as it was developed like any other Rails apps), once it was converted to a Rails Engine it was difficult to integrate into another project and get the interaction with the LoginEngine working smoothly. The Rails Engines plugin does make it dead simple to add a lot of functionality into your application with very little work. But due to the wholesale inclusion of models, views and controllers it does take a bit of work to get the engine tweaked to your liking (at least so that it integrates into your existing Rails app nicely). To create your own Rails Engine you would create a new Rails project, write your tests and app code as normal and then perform the following steps:

  1. Install the Rails Engine plugin:

    ./script/plugin install engines
    
  2. Generate the directory structure for your new engine and choose a license:

    ./script/generate engine MyNewEngine
    
  3. Move your engine files from the main app directory into the vendor/plugins/my_new_engine directory:

    mv app/models/my_model.rb vendor/plugins/my_new_engine/app/models/
    mv db/migrate/001_initial.rb vendor/plugins/my_new_engine/db/migrate/
    mv app/controllers/my_controller.rb vendor/plugins/my_new_engine/app/controllers/
    mv app/views/my vendor/plugins/my_new_engine/app/views/
    
  4. Modify config/environment.rb to start your engine:

    Engines.start :my_new_engine
    
  5. Include your new engine in ApplicationController/Helper:

    class ApplicationController < ActionController::Base
    include MyNewEngine
    end
    module ApplicationHelper
    include UploadEngine
    end
    
  6. Modify vendor/plugins/my_new_engine/lib/my_new_engine.rb with any configuration options you require and add any modules you need to vendor/plugins/my_new_engine/lib/my_new_engine/

  7. Read and then update the README in vendor/plugins/my_new_engine so that you and others can figure out how to use your new engine.

Some of the issues I had with Rails Engines were:

  • Model handling. For the BlogEngine, I relied upon the LoginEngine, unfortunately I had to enhance the User model with relationships to blogs, articles, etc – thankfully the LoginEngine was designed such that I could simply include the LoginEngine::AuthenticatedUser module. Thus you must take great care when developing an engine so that the models are setup properly.
  • Migration handling. Migrations with engines can be very dangerous as you must trust the source of the engine (though this is true for all code you incorporate into your application). That said, it would be nice if running

    rake migrate
    

    also ran the migrations for each of the installed engines. Note that the order in which the migrations is run is very important if the engines have dependencies on on another. Which brings me to the next item …

  • Engine dependencies. The init_engine.rb should allow you to require any pre-requisite engines. Then Engine.start wouldn’t care in which order the engines were started since they would be self-ordering.

  • Referencing image assets. The engines plugin provides support for accessing your CSS stylesheets and Javascript files via

    <%= engine_stylesheet "" %>
    

    and

    <%= engine_javascript "" %>
    
  • Referencing CSS and Javascript. In the above case you had to use the engine name as your .css and .js filenames or provide the additional filenames on the same line after the engine name. Since the engine should know where the view file came from it should look in that engine’s public directory for the stylesheet/Javascript files.

  • Testing Engines with fixtures. As long as you don’t allow the users of your engine to change your table names the fixtures you’ve written for your tests will work fine. Unfortunately, once the table names have changed it is up to the user to rename the fixture files.

In theory, Rails Engines appear to be quite nice, but in my limited amount of time using them I prefer to reuse plugins, write my own code from scratch or reuse other classes in lib.

May NovaRUG Meeting

Tonight Rich Kilmer presented his Alph Ruby to Flash bridge. I had checked out Alph before (version 0.0.3 from 2004) but was unable to get it working. Rich said that he’d place an updated copy up on RubyForge soon. The way to setup the bridge looks slightly different in his new version:

conn = Alph::ConnectionManager.new
flash = Alph::FlashVM.new("id", conn)

Rich also had a demo with multiple bar charts which were dynamically updated from the Ruby server when the user clicked on the ‘play’ button in the Flash VM running in the browser. If he posts the code, I’ll add a link to it. Basically the Flash code creates two movies within the root movie and adds a text field to each along with a button which calls back to the Ruby server. This Flash code is compiled with the MTASC compiler to create the SWF which runs in the Flash player (in the browser). The Ruby code uses the code I mentioned above (in a separate thread) and then registers itself for callbacks – when it is called back it injects the progress bar into the running Flash movies (and twiddles with the text in the text fields, also in the Flash movies). Alph is currently being used by InfoEther’s indi platform. In this case both the Flash client and the Ruby server run on the same machine. After his talk, Rich mentioned the haXe and Neko projects from Nicolas Cannasse of Motion-Twin. They book look like very interesting projects and there are rumors that Ruby is being ported to the Neko VM (so now we have Rite/YARV and others working on a VM for Ruby – why can’t all of these folks work together?) The next NovaRUG meeting will be at FGM in Reston, VA on June 28 – Xandy will be presenting on Rake. I’m definitely looking forward to it.