Rubygame 3: Day 22

Had a late start, and feeling a bit under the weather today, so not a whole lot of progress on Rubygame today. I did manage to take care of some thoughtless work like putting license/copyright headers on some of the new source files.

I was also thinking about keyboard events. It bugs me that keyboard events use integer constants (e.g. Rubygame::K_A) to identify the key that was pressed. This is one of those ugly style issues that Rubygame inherited from Pygame and SDL. My main objections to this style are:

  1. Awkward to use. You either have to include Rubygame or litter your code with Rubygame:: everywhere.
  2. Clutters up the Rubygame namespace with hundreds of constants.
  3. Similarly clutters the C code, which has a huge list of "rb_define_const(...)" calls.
  4. Too C-ish!

The obvious, Ruby-ish way is to use :symbols instead. Lovely, lovely :symbols. Instead of the cumbersome Rubygame::K_LEFT, you get the much easier to read :left.

And it actually requires much less code to implement the symbols than it does the integer constants. SDL has a SDL_GetKeyName function which returns a string like "left", "space", "a", "left shift". It's trivial to turn those strings into a Ruby symbol, and only slightly more difficult to sanitize them a bit, e.g. changing spaces to underscores to get :left_shift instead of :"left shift".

There are a few keys that don't work so great as symbols, because of the names SDL returns. The colon key, for example, is returned as the printable ":", rather than "colon". So, to make that a symbol, it has to become :":", which is not so pretty. Or backslash (:"\\") or double-quote (:"\""); also not very pretty. Prettier than Rubygame::K_QUOTEDBL, but not as pretty as :return or :tab or :3. (By the way, I actually had to look up K_QUOTEDBL in the docs just now — that gives you a clue about how memorable these constant names are.)

Since Rubygame 3.0.0 is my chance to break backwards compatibility in as many ways as I want, I'm considering trying to eliminate the keyboard integer constants and replace them with the symbols instead. Also perhaps for other things, like Surface/Screen flags (SWSURFACE, FULLSCREEN).


ippa submitted a comment on #

I love your thinking about better keyhandling.

Mainly repeating/agreeing with what you’re saying:

version #1: Their full names should be used, a written version of what I would verbaly call the key out loud. I wouldn’t say K_LCTRL, I would of course say :left_control, :tab, :four/:4

version #2: And/or as you also suggest, use what’s actually written on the keys on the keyboard, :a, :b, :#, :”:” .. etc. Guess this way becomes tricky for various keys, I can only suggest :left_ctrl for left control, and no good version for tab and shift :) .. and naturally space becomes tricky too ;)… but then the first version will come in and rescue us.

+1 for breaking current implementing by having both version 1 and 2 besides eachother if possible.

Have something interesting to add to the discussion? Email your thoughtful comments to