microformats

Liminal Existence

Clouds in Iceland

Thursday, November 09, 2006

Announcing Jabber::Simple

Jabber::Simple [src, doc] is a simple (duh!) Ruby library that aims to make the implementation of basic Jabber functionality trivial. It is an extraction of the Jabber support that was added to Twitter, and is released under the GPL by Obvious. A line of code is worth a thousand words, so here is the complete code for sending a simple message to a Jabber user:

jabber = Jabber::Simple.new('rex@friendosaurus.com', 'password')
jabber.deliver("bront@friendosaurus.com", "Hey! I'm thinking of going Vegetarian - Any suggestions?")
Getting incoming messages is just as easy:

jabber.received_messages do |msg|
  puts "#{msg.body}" if msg.type == :chat
end
You can also set your status, and get information about your friends' statuses:

jabber.status(:away, "Eating at the Tree Cafe. I need a ladder.")

jabber.presence_updates do |update|
  friend = update[0]
  presence = update[2]
  puts "#{friend.jid} is #{presence.status}"
end

Installation


sudo gem install xmpp4r-simple
or download the package from RubyForge. Source code is also available, licensed under the GPLv2.

Yet Another Jabber Library?

There are a number of existing Jabber libraries for Ruby (jabber4r, xmpp4r, and Net::XMPP), so why Jabber::Simple? First off, Jabber::Simple does not aim to replicate any core XMPP protocol functionality present in these libraries — in fact, Jabber::Simple depends on xmpp4r and the Jabber::Simple#client and Jabber::Simple#roster methods expose all of xmpp4r's awesome functionality. When I started building in Jabber support for Twitter I'd used various Jabber clients, and even set up a simple Jabber server. Writing my own client, however, was a bit more complex. It turns out that the seamless experience of "adding a friend" and chatting with them is (unsurprisingly) comprised of a series of disjoint steps, and fraught with the peril of threads, XML streams, and arcane magic. The available libraries handle these tasks and many more admirably, but lack in elegance. My hope is that Jabber::Simple provides a sufficiently obvious interface with which to develop tools that use the Jabber protocol.

But Wait! There's More!

Now, you might shy away from writing that really cool chat-bot you've been meaning to write, saying "Wow, this is great, but setting up a Jabber server is a pain." --- but fear not! Go over to Google Talk and sign up for an account. Once you're done, use your Google Talk username and password, and start Jabbering. No really, it's that simple.

jabber = Jabber::Simple.new("you@gmail.com", "password")

Labels: , , ,

Monday, November 06, 2006

assert_before

I'm working on a Ruby Jabber client library to hide the numerous machinations and relatively steep learning curve that xmpp4r requires. It's nearly done, and I'm writing tests (it's an extraction from Twitter's Jabber support). A problem I was running into was the latency involved with Jabber requests; sending a message is almost instantaneous, but always requires at least a one second sleep before the assertion, sometimes much more (roster updates can be time consuming). I started sprinkling five to ten second sleeps throughout my code, but all of a sudden my tests were taking upwards of a minute to run, and there are only five tests! Here's a snippet that should help with all your variable-latency tests:

def assert_before(seconds, &block)
  error = nil
  begin
    Timeout::timeout(seconds) {
      begin
        yield
      rescue => e
        error = e
        sleep 0.5
        retry
      end
    }
  rescue Timeout::Error
    raise error
  end
end
use it in your tests like so:

def test_something_time_consuming_should_succeed_in_at_least_10_seconds
  assert_before 10.seconds do
    assert true, time_consuming_task()
  end
end
and as soon as your tests pass, the block will exit and continue on, completing your tests as quickly as possible.

Labels:

Borat, We Like.

I still haven't seen it, but here's what the Guardian has to say:
While there had been much early enthusiasm for the film following festival screenings, there were fears that the appetite for a bumbling anti-Semitic, pro-incest fake Kazakh who engages in an extended bout of vigorous nude wrestling with his producer might not be mainstream enough to translate to the box office.
Huh? How could there not be enough of an appetite for that?!

Labels:

Friday, November 03, 2006

The Knife

After seeing this video, I'm totally bummed about missing The Knife. Ray's been talking about it for weeks, but unfortunately they don't do many shows and tickets were selling for (at least) $200. Anyhow, for your viewing enjoyment:

Labels: , ,

.irbrc

irb is a wonderful tool; with a few tweaks and additions, though, it becomes essential. I spent too long getting by with just readline support, but today, finally, I added a few of the extensions that I've seen floating around on various ruby blogs. Now my tab completion and history run in overdrive, and the number of extra terminal windows I keep open has been reduced greatly. A quick summary of the features present:
  • Full readline support and tab completion
  • Copy-friendly prompt
  • Auto-indentation
  • Persistent history
  • Object#local_methods, to view methods unique to an object
  • Colourized output (via wirble)
  • Method finder. e.g., "hello".what?(5) #=> [:length, :size]
  • Colourized inline ri support (either Object#ri(*methods) or ri Object, works best with Ruby 1.8.5's much improved ri
  • Output spooling, via more, less or most. e.g., less { puts really_long_string }
  • Simple regular expression helper (/an/.show_match("banana"))
  • Textmate and Vi launching
You can get my .irbrc here: ~lattice/.irbc.

Labels: , ,

MacPorts, a PSA

When upgrading your ports on OS X, do not use the following command:

port upgrade all
It doesn't do what you expect. Unless, of course, you want TeXmacs and SimGear. And five hundred of their closest friends. Do this, instead:

port upgrade outdated

Labels: