Ruby Weekly is a weekly newsletter covering the latest Ruby and Rails news.

ClassRoom: A Ruby class server (or DRb on steroids)

By Peter Cooper / July 12, 2006

Classroomapple

Install now with sudo gem install classroom

ClassRoom (RubyForge project) is a project to develop a distributed 'class server' powered by DRb that I have been working on. Let's skip long explanations and jump into code. First, we'll create a very basic "Dog" class with some basic features:

class Dog
  attr_accessor :name

  def self.count
    @@count ||= 0
  end

  def initialize(options)
    self.name = options[:name]
    @@count ||= 0
    @@count += 1
  end
end

Next, we'll create a program that can use Dog via ClassRoom:

require 'rubygems'
require 'classroom'

class_server = ClassRoom::Client.new('classroom://:2001')
class_server.add_class(IO.read('dog.rb'))
class_server.load_class(:all)

puts "There are #{Dog.count} dogs"
fido = Dog.new(:name => "Fido")
puts "There are #{Dog.count} dogs"
rufus = Dog.new(:name => "Rufus")
puts "There are #{Dog.count} dogs"
puts "fido's name is #{fido.name}"

# => There are 0 dogs
# => There are 1 dogs
# => There are 2 dogs
# => fido's name is Fido

Take care to notice that at no point is dog.rb actually included/'require'd. The Dog class doesn't exist until line 6. What happens is that the script connects to a ClassRoom server, uploads the Dog class to it, and then loads all of the classes from the ClassRoom server to be used as if they're local (they're not, they run direct from the ClassRoom server, all the load does is create proxy classes).

If this looks a little familiar, it's because DRb provides some of this functionality. But DRb only lets you use an object remotely, whereas ClassRoom lets you use classes and objects naturally as you normally would. Class methods, object methods, initializers, etc, all work as you'd expect.

You can upload classes (or Modules or entire class hierarchies!) to a ClassRoom server on-the-fly and use them from any applications you like. You can, if you like, change the functionality of classes mid-execution and all of your client applications will use the new classes and methods seamlessly. Alternatively, you might want to load up classes from the server end only and allow them to be used by various applications. It's (mostly) up to you, and it's (mostly) seamless.

ClassRoom is VERY, VERY ALPHA right now, but if you know your bindings from your singletons, have a play with it. If you install the gem, there are about ten example demonstration scripts (including the server.rb you'll need) in the /examples folder where the gem is installed. These should fill in most of the gaps. In case you want to get experimenting immediately, here's a basic server:

require 'rubygems'
require 'classroom'

url = ClassRoom::ClassServer.prepare
# ClassRoom::ClassServerContainer.add_class(IO.read('someclass.rb')) 
puts "ClassRoom server running at #{url}"
ClassRoom::ClassServer.start

Have a play and leave some comments. I want to open this up even more next.

Comments

  1. Danno says:

    That's pretty nifty Pete!

    I was working on something similar for a Final Project last semester, but more asynchronousy.

    I'll make a note of looking at your code for ideas on how to clean-up/improve mine.

  2. anand says:

    "You can, if you like, change the functionality of classes mid-execution and all of your client applications will use the new classes and methods seamlessly."

    Very interesting.

  3. Peter Cooper says:

    Danno: I didn't think of it before you used the word 'asynchronous' but that definitely gives me some crazy ideas on how to speed this up (particularly for situations where the ClassRoom server is remote). :)

    Next step is to add a little more security to it so I can roll out a 'public' ClassRoom server with some classes for people to play with (chat rooms, MUDs, text adventures, etc..)

  4. Danno says:

    Oooh, glad I've given you an idea.

    I was focusing more on runtime systems as opposed to class distribution to be honest, but ClassRoom's looks like a solution to one of the issues that I had (specifically, how to hand classes out to clients).

    I especially like the fact that you can roll out class changes dynamically. That's super hot.

  5. Peter Cooper says:

    That's mostly a function of Ruby. The classes exist in a santized, separate module at the server end, but you can simply use Ruby's regular overriding / reflection to make changes, add methods, etc. :)

    I'm now working on making it so you can 'lock down' the module so you can, for instance, ONLY let clients use classes rather than upload their own. Once I do that, I'll roll out a public classroom server for people to play with.

    It might also be nice to make sure different IPs can't override each other's classes!

  6. Justin says:

    Cool, I also hacked a little project like this with an eye for creating an object browser. Does ClassRoom have the ability to "reset" to an initial state, for example before any classes have been loaded?

  7. Peter Cooper says:

    At which end? I just added some features to remove classes at the server end. At the client end, however.. not yet. One of the problems is that if you're not within a module, undefining classes is, well, hard. :(

  8. Ezra says:

    Hey Peter this is cool stuff man! DRb is one of my favorite parts of ruby. Awesome.

Other Posts to Enjoy

Twitter Mentions