(A cheesy homepage for Justin Collins)
Spellcheck/Suggest for RubyGems

As a result of a Ruby bounty, I wrote a patch for RubyGems which provides suggestions when you try to install a gem and you get the name a little wrong. You can see all the details here.

Now that RubyGems 1.3.7 is out, I’m going to go ahead and provide a patched version for those who frequently forget, mistype, or misspell gem names (this includes myself).

Download .tar.gz

Download .zip

After decompressing, I recommend installing it with

ruby setup.rb --no-rdoc --no-ri

(and probably sudo).

Here are some examples of what this adds to your RubyGems experience:

$ gem install Blah
ERROR:  Could not find a valid gem 'Blah' (>= 0) in any repository
        Possible alternatives: blahblahblah

$ gem install Nkojiri
ERROR:  Could not find a valid gem 'Nkojiri' (>= 0) in any repository
        Possible alternatives: nokogiri

$ gem install blue
ERROR:  Could not find a valid gem 'blue' (>= 0) in any repository
        Possible alternatives: bluecloth, BlueCloth, bluefeather,
         blue_light_special, blue_light_special_heroku_fork, glue, bluepill,
         blueprintr, blueprints, bluepay, ...

$ gem install sinatar-capcha
ERROR:  Could not find a valid gem 'sinatar-capcha' (>= 0) in any repository
        Possible alternatives: sinatra-captcha, sinatra-cache, sinatra-cas, sinatra-auth,
         sinatra, sinatra-any, sinatra_app_gen, sinatra-flash, sinatra-dm, sinatra-dm-auth,
         sinatra-doc, sinatra-erb, sinatra-compass, ...

Suspicous of Gemcutter stats

Recently, the main Ruby Gems hosting has moved from RubyForge to Gemcutter. This is pretty cool, and I was excited to publish my first gem there (the JRuby gdbm library I’ve mentioned before).

I get excited imagining that people actual use my stuff, so I’ve been tracking the downloads reported by Gemcutter. I seem to recall there being a problem a little while ago with numbers being off, but I thought that had been solved. In any case, I was surprised by the number of downloads (up to 137 now). It’s not very high for most things, I guess, but for a library for a specific dbm for a specific Ruby implementation, it seems suspicious.

My current theory is that people are installing it on accident, perhaps thinking that they need it to use gdbm in the main Ruby implementation (or perhaps others?). Fortunately, I’ve checked it out, and it appears that even if you install it this way, it will not interfere with the gdbm library in Ruby’s standard library. This is likely because the gem paths are later in the search path. Of course, if Ruby’s standard gdbm is not working for you, then my gem probably won’t either, unless you are using it with JRuby, as intended.

In retrospect, perhaps I should have named the gem a little bit better, to avoid confusion…


Ruby links

Here’s some links to interesting Ruby information. I intend to update it periodically.

Ruby Doc – Best site for looking up the core Ruby API and the standard libraries.

AllGems – Documentation for most Ruby gems.

Ruby Forum – Mirrors of the main Ruby mailing lists. Some are read-only.

Gemcutter – The new gem hosting site.

RubyForge – The old Ruby project hosting site. It is slowly being phased out.

Try Ruby – The new Try Ruby page, where you can go through an interactive tutorial directly in your browser.

Ruby Inside – Popular Ruby blog, with frequent articles.

Ruby Flow – Community-submitted Ruby links.

Ruby Trends – View and vote for trends in Ruby software, books, and more.

Ruby Pulse – Screencasts of Ruby software and libraries.

Ruby Subreddit – Reddit site for Ruby. Not incredibly active.

Ruby Stack Overflow – Ruby questions on Stack Overlow.

Confreaks – Not strictly Ruby, but videos from many Ruby events are available for streaming.


Actual Brat Release

I’ve been working on my little language a bit more lately, instead of doing work I really should be doing.

Now that Brat is working pretty well, I thought I would make a release. It’s basically just a snapshot of the current Subversion repository, but I know people would rather download a tar file than use SVN to check something out. It is only for Linux at the moment, but maybe I will get it working on Windows sometime. It should work with Ruby 1.8.6, 1.8.7, and 1.9.

Alright, on to language stuff. I recently changed the scoping rules to be more what a person might expect: any scope can access its outer scopes (rather than before, which used the Neko default of copying the outer scope). This makes the toplevel variables something like globals, except not quite.

Example:
a = { x }
x = 1
p a   #Error - x was not defined when a was
b = { x }
p b   #Prints '1'
c = { x = x + 1 }
c
p b   #Prints '2'

And recursive functions no longer need to be attached to an object:

rec = { x | false? x < 1, { p x; rec(x - 1) } }
rec 10

Bad news is that my current approach does not do a good job of releasing memory. But that is a problem for another day.

Of course, many bugs large and small have been fixed along the way. I hope to at least get this language to the point where I use it regularly. I think it is an interesting and probably odd mix of object-oriented and functional programming.

Also, I set up a discussion group in case Brat generates any attention.


New kams release and I’m sick

I’ve released a new version of kams (0.2.0).

Today is the first day of the new quarter, but I don’t have class and I’m sick. So I’m staying at home. Yay.


Ruby 1.9.1 Memory Savings?

Okay, in my last post I was talking about some changes I was making to kams to make it work with Ruby 1.9.1.

Today I happened to glance at the memory usage. This is just after starting up the server and I have about ~830 game objects in the world (I expect that to be a small number, given that I only have 152 rooms, 325 exits, and the rest are random things like clothing). Under Ruby 1.8.7, this takes ~36MB of memory. Under 1.9.1RC1, it’s only 16MB. Less than half.

Nice. Now to look for areas where memory may be leaking…


Some changes for Ruby 1.9.1pre2

Here are a few things I have found so far while making kams compatible with Ruby 1.9.1:

  • Small eventmachine change needed as shown here.
  • require 'md5' changed to require 'digest/md5' and MD5 changed to Digest::MD5 (this works with 1.8.7, too.)
  • Any hashes which were defined not using => (i.e., {'a', '1', 'b', '2'} ) have to now use =>
  • One issue required some version checking: the Observable module in 1.8.7 uses an array, in 1.9.1 it uses a hash. This doesn’t matter much to me, except when Observable objects are marshalled and this goes along with them. What I have done for now is set it to an array or hash as appropriate when loading the objects (there is no content for it, in either case).
  • Array#to_s has changed. In 1.8.7, [].to_s => ””. In 1.9.1, [].to_s => “[]”. Somewhat annoying, but easy to handle.
  • Have to deal with Object#instance_variables and Object#instance_methods returning arrays of symbols instead of strings.
  • Ran into an issue with Mutex#try_lock. Asking about a solution now…

Update – No one answered my question about Mutex#try_lock, but someone fixed it anyway :)


Neat Ruby Regex Tool

Rublar is a very neat little website for testing out Ruby regular expressions.


RSS – I can think of a few things it ought to stand for

I typically use Liferea for keeping track of RSS feeds (works great at school so I don’t waste as much time browsing websites) but, for whatever reason it isn’t working right for me on my laptop. “So,” I thought, “why not create my own little dealie using some Ruby and some pairs of Shoes? I mean, I’m sure it will be straightforward, right?”

Ha. Ha.

First of all, I went looking for some Ruby RSS libraries. There are a few out there. I tried simple-rss, because it seemed nice and…simple. Installed just fine, ran it using this site’s feed. It crashed. Didn’t work at all. Lame. Looked a few others, but they seemed to have a few too many dependencies or were out of date.

But, wait! Ruby comes with it’s very own RSS parser (and generator) in the standard library! Great! Too bad the documentation is lacking and confusing at best. I managed to find a nice little article over at rubybook.ca (haven’t really investigated the site much) which has some details about parsing RSS and Atom with the standard library. Awesome.

Then I got sidetracked by something else. I wanted to be hip and not disturb the webservers too much, so naturally I wanted to use conditional GETs so that if a feed hasn’t been updated I don’t download the whole thing again. Seems like a great idea. Then I got seriously confused. Why? Because this ‘Last-Modified’ header is not something that is sent back all the time. I wasted a bunch of time trying to figure out if there is a way to request the information, but it doesn’t sound like it. If it’s there, great, if not, either make up your own timestamps or forget about it.

I managed to get back on track and even wrote up a nice little class for handling subscriptions when I found out the really bad part: My own website’s feed didn’t provide the data Ruby’s RSS parser expected. Great. I looked at a few others. It seems like RSS feeds are generally okay, but Atom feeds are all over the place. After fiddling around for a while, I made my code a little flexible and moved on.

I wrote a hideous shoes application.

Then I gave up, because I was tired of dealing with it. Maybe I’ll come back to it later.

However, I did change this site’s feed over to an RSS feed instead of Atom. If you were actually using the Atom feed, you can still do so, but the auto-discovery and link at the bottom are set to RSS.


I only blog when I shouldn’t

Yeah, pretty much as the title says. I only think to do this when I am trying to think of anything possible I can do to avoid doing work.

So, in lieu of anything actually insightful to share, have a look at this, a little ways down. Note how the new 1.9.1 version of Ruby is blowing everything else away. Pretty awesome. I’m excited for the real release and for certain things (cougheventmachine cough) to have official support for it. Things are looking up in Rubyland.


Hehe

Check this out.

It’s so wildly inaccurate is makes me giggle.


I made a software release

The first release of the Kingdoms of Ahln MUD Server (kams) is available over here.


Tiny App Launcher

Story

I just upgraded my lab desktop to Mandriva 2008.1. As usual, my first action was to install Xfce. That all worked well until I hit my usual Alt+F2 to launch a program. Nothing happened. I tried again. Still nothing. So I checked out the keyboard shortcuts, thinking they might be messed up. After actually finding where Alt+F2 gets set (there are a few different places in Xfce where keybindings are created), I saw it was indeed set up to run xfrun4, Xfce’s little run dialog.

I headed to the console (another aggravation: I am used to using gnome-terminal for my console, because I like its tabs and general feel. But it is way too slow for some reason and, even more importantly, I cannot figure out how to make the cursor stop blinking. It drives me nuts) and ran xfrun4 from there. Result: segfault

After poking around to see if there are any other little things like xfrun4 (something I have done before, actually), I gave up and wrote my own.

Requirements

Code
#!/bin/env ruby
require "rubygems"
require "zerenity/entry"
require "zerenity/warning"

loop do
        begin
                program = Zerenity.Entry(:title => "Run")
                if program
                        exec program
                end
                break
        rescue Interrupt
                break
        rescue Errno::ENOENT
                Zerenity.Warning(:text => "Program not found.",
                                 :title => "Error")
        rescue Exception => e
                Zerenity.Warning(:text => e.inspect, :title => "Error")
        end
end

Thrilling Conclusion

I dropped this in a file in /usr/bin/ and changed the keybinding…and that’s it. Works well enough, though it would be nice to have autocomplete/history stuff. But Zerenity does not have that (yet).


The Light at the End of a Tunnel Sorta

So I mentioned the shared whiteboard thing previously. I have been facing some serious headaches over one of the projects in particular. I don’t want to mention the name, but it’s been a real pain.

Why has it been such a problem? Well, let us see…first of all, it is not just one project, but two: a modified Java KVM and a modified J2ME compiler, two separate projects by two different people. I was able to track down the modified KVM code, which has been both a good and a horrible thing (horrible because it’s lead me down twisty paths I would not have known existed otherwise). However, I do not have the source for the modified compiler. This means that, while I can peer into the inner workings of the KVM and even poke around a bit, I cannot recompile the entire thing. This means no adding libraries or features not already present, because if I write it in C, the (modified) compiler may not compile them and if I do it in Java the KVM may not run it.

However, I am getting ahead of myself. What was the beginning of the issue? Quite simply, I needed to write an application with a GUI. Didn’t seem like a problem. But it is, because the project I need to use underneath is an extension of J2ME, and not the fancy MIDP version, but the tiny, teensy weensy CLDC version. That means no GUI.

BUT! I was in luck, because the person who extended the KVM (Kilobyte Virtual Machine…the J2ME VM from Sun) provided a nice little IPC interface to use with external programs. Cool! Oh, wait…the API is in C?? Why?? (Note: Probably because after working to an extend a virtual machine written in C, writing some shared memory IPC stuff was likely a cinch.) Java would have been so much more convenient…

But, wait again. I don’t need to write the GUI in C, though. Doesn’t Ruby have nice C bindings? Reads up on those… Yes, cool. Oh, wait, there’s a neato thing called SWIG which will even do most of the work for me? Neat! So I spent a while getting that all working, including writing wrapper methods (in C) and everything. I got to the point where Ruby would load the C libraries and even run them. But then I hit more trouble.

Most of the library is nice low-level handling of semaphores. And it was not working properly. I believe I traced this to the shared memory not being written correctly, thus giving me bogus semaphore IDs. However…I can’t change that part. I was able to mess around with the IPC code, because it was thankfully separate from the rest of the VM (that is, the API was). But it’s no good if the VM itself needs changed.

So I finally gave up. On the IPC stuff anyways. I looked at what I had available and decided, no matter how ridiculous it is, it’s better to be ridiculous than not working at all.

Before I explain the silliness I ended up with this evening, let me explain a bit how these VMs work. You do not simply run programs on them. Oh, no. First you start the VM (including setting up a virtual network topology), then you can either ‘inject’ applications into the system, or register services at particular VMs, which the applications can visit.

Also, the only kind of I/O really available in the limited world of J2ME is printing out to stdin and stderr. That’s pretty much it (in this implementation). I couldn’t open sockets, read files, or anything. At least, I couldn’t figure out how to.

So, what did I do? Well, something like this: I have a GUI written in Ruby and Tk, which will launch the VM and attach a file handle to the stdout of the VM. It then registers a ‘Whiteboard’ service, which will receive messages from other VMs regarding what’s happening on the remote whiteboards. So far, so good. Now, if the VM wishes to communicate to the GUI, it can do so by simply using a System.out.println(). Good enough, Ruby makes it easy to parse and deal with such things. But what about from the GUI to the VM? Well…what it does is ‘inject’ an application into the system, passing any information it needs to as command line arguments. Yes. That is right. Command line arguments for IPC.

Amazingly…it works. It’s going to take a little more tweaking, but I now have more to show for approximately two hours of work than the past days I’ve spent fighting with C APIs and semaphores and accessing shared memory and digging through J2ME documentation for hope.


UI in Java and Ruby

For my research, I need to implement a shared whiteboard, which is a fairly common example of collaborative software. I’m doing it with three different projects handling the communication side of it. Since two of these can be directly tied in with Java, it made since to start with a Java UI. The third, for some inexplicable reason, chose to implement IPC through a C interface. So, for that one, I’ll be writing the UI using Ruby.

I have completed a basic prototype for both, which just implements the ‘drawing’ part of the whiteboard. They have exactly the same amount of functionality (draw lines, save the history) and do it basically the same way (start line on mouse click, save points and draw as the mouse moves). I didn’t try to make these as short as possible, just as equivalent as possible.

The Java version, using AWT, is 95 lines long. The Ruby version, using Tk, is 50 lines long. Not too big of a difference, considering how short they are.

However…each line in Java seems quite a bit longer than the Ruby version. What if we compare based on the number of characters, rather than the number of lines? Hmmmm…the Java version comes out with 2831 characters, while the Ruby version only has 978! That is a lot less typing! (A third, basically).

Oh, well. Sigh…

Edit: Oops, I forgot I also wrote a convenience class for the Java version that stored the history. But it wasn’t really necessary and I did not do so in the Ruby version, so the comparison above is still accurate, I think.