Ruby Lightning Talks

Tonight's LRUG meeting consisted of 8 quick 20x20 format presentations (20 slides, 20 seconds per slide) on a range of Ruby related topics.

Matt Patterson -- a talk about dpkg-tools

Matt's talk is about rubygems vs an Operating System's native packaging format.

  • Rubygems are OS independent packages of Ruby code.
  • OS packages are language agnostic, designed to work on a specific OS.

There's a debate raging; Ruby developers want to deploy to any architecture quickly, without waiting for native packages to arrive. System administrators don't want to have a second package management system playing around with their platforms. Who's right?

They're both right, and automation is the key thing here, but we mustn't forget that system administrators need to be able to maintain the operating system in a robust manner. Matt's proposed solution is dpkg-tools (available on github), a way to quickly install gems onto your Debian based systems, without actually installing the gem itself. It builds .deb files for you.

Manually re-packaging gems as operating system packages is not a good idea; it's not efficient, and is a clear violation of DRY. We're back to automation again.

dpkg-tools is easy to use; it gives you a single command to run to create your Debian package. It's also a bit hacky, as there's no rubygems developer API for Matt to build on top of, but it works. Matt is using a similar approach on his own projects to automate the installation and setup of Rails apps on his own servers.

What's coming next for dpkg-tools?

  • Right now you need to type 50 commands to build 50 packages, so he's working on dependency support so that all your dependencies will get built automatically.
  • There's some refactoring to do.
  • Something to do with Phusion packages (though I missed exactly what that was).

More information is available on github, or at Matt's site:

Thomas Pomfret -- Ruby and XMPP

XMPP is an eXtensible Messaging and Presence Protocol, for real-time communication. It's an open technology. Suitable uses include authentication, presence, contact lists, one to one messaging, many to many messaging, notifications and service discovery.

Inside your applications you could use it to send notificaations (think of it as an alternative to sending an email), handle instant messaging, group chat, gaming (see chesspark.com), or for systems control.

Why should you care about XMPP? Thomas says it's extensible, scalable, secure and works well in real-time systems. How does it compare to HTTP? Lots of real-time systems have been implemented in HTTP using a polling approach, in which the client continually has to check whether or not state has changed on the server. With XMPP your client just needs to register interest in an event or message queue, after which the server will inform the client when necessary.

There are two gems available: XMPP4r and XMPP4r-simple. The simple gem exposes common tasks, but you need the full gem for anything relevantly complicated. Here's an example (which I hope I copied down correctly...):

require 'rubygems'
require 'xmpp4r-simple'

im = Jabber::Simple('user@example.com', 'password')
im.deliver('friend@example.com', 'Hello!')

Thomas then went through examples of using the xmpp4r gem for setting up a chat room with Jabber, and sending/receiving messages. He also introduced ActionMessenger which serves a similar purpose to ActionMailer in Rails, but rather than sending emails it's designed to send instant messages.

Apparently it's not a good idea to call XMPP code directly from a Rails/Merb controller (presumably because it could block, and controller actions should be snappy). Also bear in mind that large messages could become queued up if you send too many of them.

There's an XMPP PeepCode screencast and an XMPP O'Reilly book that are well worth checking out, and lots more information available online.

Slides from Thomas's talk are available from his blog.

Julian Burgess -- A cry for help (an anti-talk)

Julian's talk was an interesting journey into how much he's learnt since he started using Ruby.

Back in the day Julian discovered HTML. Then VBscript. Good fun, but there was a limit to the complexity of the things he could build. Then he came across RSS and XML, and noticed that eBay's feedback system is a bit weird (the numbers only ever go up -- why is that?). So he decided to try and do something better. .Net didn't really do the job, but somebody suggested Rails. Wahey. Then he fell into a "chasm of learning" and picked up lots of new stuff like SVN. And Linux. Then Julian started going to more meetings like LRUG and noticed everybody was using Macs. Sounds familiar.

Then he applied for a Rails job in parliament. Despite the job title he didn't end up doing much Rails (mmm, that kind of behaviour reminds me of government), but was still working on his eBay solution in the background. One night (presumably whilst coding on his eBay solution) he wanted a kebab. But was the kebab shop open? Recognising a problem without a solution, Julian decided to make an app that would tell him when things are open (a slightly grander solution than nipping down there to check, I think you'll agree).

An entertaining talk.

Tom ten Thij - Debugging with ruby-debug

To use the Ruby debugger you can require the ruby-debug gem, then call the debugger function within your code:

require 'rubygems'
require 'ruby-debug'

debugger

If you put a debugger function call at the end of a function it'll skip it, so make sure it's followed by another statement. You can also pass a block to the debugger when launching it:

require 'rubygems'
require 'ruby-debug'

Debugger.start { ... }

Alternatively you can start the debugger from the command line without modifying your code:

$ rdebug myscript.rb

Once the debugger has opened you can type help to see a list of available commands. Immediately useful commands include next (or n) to step through to the next statement, and list or l to page through your source code (you can move back and forwards; try help list for more information). display lets you look at the value of a variable as you step through your program (similar to watching a variable in many IDEs).

You can step up and down the stack frames with up and down. You move into different contexts as you go up and down, allowing you to inspect local variables at various points in your stack. where will show you your call stack, and you can dump your variables with info (try i v to show local and instance variables in the current stack frame, and help info to find out what else info can do for you).

You can also set breakpoints with break (abbreviated to b -- do you see the pattern here?), which is very handy, as you can then use continue to skip ahead to your next breakpoint, rather than stepping over every statement.

Cheers Tom, a useful introduction. I've used the debugger a fair bit in the past myself, and heartily recommend this article for more details.

Roland Swingler - Something about rubygame

Roland normally works with the web, but had a fiddle with games programming over Christmas. He decided to remake Pong, as it "has all the elements that you need for a game and none that you don't". He used RubyGame, a port of pygame which provides direct access to the SDL framework.

When programming with RubyGame you start off with a main game loop.

You can't really move anything in RubyGame. All you can do is draw things on surfaces. To animate stuff you re-draw the entire surface (the screen by default), but that's a bit of a pain if you only want to change a small area of the screen. So you have sprites; surfaces that cover a small section of the screen. To get much more of an idea of it you'd really need to see his example code, which I haven't had time to jot down (20 seconds per slide is a bit too quick for me!).

Roland then talked us through how his ball and paddle sprite objects (remember, he's rewritten Pong) work out whether or not they need to bounce off each other, and how to handle events such as key presses, mouse movements, etc.

RubyGame looks like rather good fun. There's no physics engine (but you can use Chipmunk -- another gem), and you can hook in sounds, etc.

Steve Ganly - "rubysmokes" - A proposal for smoke testing ruby

Smoke tests are not (just in case you thought they were) anything like soak tests (which you run repeatedly to see if things eventually break). Smoke tests are more akin to the behaviour you get when you turn on a dud piece of electronics for the first time (you can get a puff of blue smoke).

In the Perl community a bunch of smoke tests are run on multiple architectures whenever new code is checked in to the Perl interpreter. The results are emailed out to interested parties, made available on a web page, passed on via IRC bots, etc. It sounds like it works rather well.

You can build Perl in lots of different ways (e.g. with lots of different command line options). There are also different versions of Perl (e.g. pugs, parrot). These different versions of Perl are built by Test::Smoke inside a for loop. See www.test-smoke.org.

Steve wondered if there was anything similar for the Ruby community; there wasn't.

How should Ruby do it?

  • Don't just build from source, but build native packages on different platforms (e.g. Ubuntu, BSD).
  • Run the tests for multiple versions of Ruby.
  • When running tests take note of the local hardware and OS, which gems are installed, available databases, etc.
  • Make it easy for people to run the tests and submit their results.
  • Store all the results on a web site, send project specific results to the relevant mailing lists.

Steve has setup http://rubysmokes.com (which needs some content) and will be creating a mailing list soon.

Tom Armitage - Twit4Dead - Scripting Post-Apocalyptic Zombie Fun in Ruby

In Team Fortress (the game) your character will automatically point out to a passing medic that you've been hurt, and the medic will heal you. The audio acts somewhat like an in-game messaging bus. Left 4 Dead took this basic idea and built on it (I hope I understood this basic gaming history correctly, and apologise in advance to avid fans if I wrote it all down wrong).

Twitter is also a messaging bus... So Tom decided to see if he could make four twitter bots that would talk to each other in a similar manner to Left 4 Dead. A rather amusing idea.

It's based on a state machine, for which Tom is using a Ruby library called Alter Ego. It looks like a very nice way of defining states, and what happens when you transition between them. He talked us through his code for the bots. Nicely done, and the results (see http://icanhaz.com/twit4dead) are rather amusing.

Interesting things that Tom learnt on the way:

  • Don't publish to twitter in real-time. It's really important that all the messages get through (presumably so that the resulting twitter conversation makes sense), so you have to stagger publishing to twitter.
  • State machines are great fun, especially when you're not doing user roles or authentication.
  • Building stuff that appears to be smart (but is actually dumb) is far easier than building something that really is smart.

Chris Lowis - Ruby and the GNU Scientific Library and/or R

R is an interpreted language, influenced in design by Scheme and S. R comes with a runtime that supports graphics, has a debugger, etc. It's cross platform (Mac, Windows and Linux are all supported). R is great for statistical analysis (correlations, k-means clustering, etc.), plotting complex graphs and overlaying data on maps. By the sounds of it, you name it, R does it.

Unsurprisingly, there are ruby bindings:

$ export R_HOME=/Library/Frameworks/R.framework/Resources
$ sudo gem install rsruby -- --with-R-dir=$R_HOME

The value for R_HOME shown above works on Mac, for Linux you'll want something like /usr/lib/R. Be careful not to miss out the two hyphens after rsruby or the = character infront of $R_HOME.

With RSRuby you can use all the R routines directly from within Ruby code, without knowing the R language. You can do it from within irb too. RSRuby converts slice.index into the method slice_index. Here's a small example (the last line -- presumably the one that outputs the PDF -- is missing, as the slide changed just before I got to it, but you get the general idea):

require 'rubygems'
require 'rsruby'

r = RSRuby.instance
x = r.rnorm(10000)
r.pdf('./plots/histogram.pdf')
r.hist(x,
       :xlim => [-4, 4],
       :main => '1000 Normal Random Variables',
       :xlab => 'x',
       :ylab => 'y',
       :col => 'lavender')
r.dev_off.call

Chris then showed us how to use R to find out whether or not there's a correlation between how often you tweet, and how many people follow you, analysing the behaviour of the LRUG followers (one of whom was doing 64 tweets per day). It was a really good demo of what R and RSRuby are capable of (as you can see from his slides).

For more info, try these links:

A great introduction, and I'll definitely be having a closer look at RSRuby.

Published on in Ruby