Archive for the 'ruby' Category

My Ruby IDE

I’ve decided to use the Intellij IDEA Ruby plugin as my Ruby IDE when working on larger projects and use Aquamacs Emacs for quick work. I think you should all buy IDEA too, so that they are encouraged to make it as good a Ruby editor as it is a Java editor.

Some people use Emacs for large projects. I’m handicapped in doing that because I have an unusually bad short-term memory. So I will often want two or three windows of code plus one shell/test window open. Or at least, I will want wicked fast ways of switching to recently used files. I’ve never found an Emacs workflow that makes having more than two visible buffers comfortable. And Emacs has a more cumbersome way of flipping to recent files than IDEA, plus it doesn’t have the convenient navigational sidebar of modern tools.

I should note that my Emacs skills froze more than a decade ago, so I may be unaware of today’s goodness. In fact, looking in my .emacs file, I see this:


(setq shell-mode-hook
      '(lambda ()
	 (my-shell-setup)
	 (setq mode-line-format
	       (list "%b--" 'default-directory "---%M---%3p---%[(%m: %s)%]%-"))
	 (local-set-key "^j" 'shell-send-input) ; stupid Bridge box
))

The “stupid Bridge box” is a terminal concentrator from around 1987.

I tried TextMate for a couple of months. I approve of the idea, but in practice I had two problems. There’s something about the logic of the key combinations that doesn’t work for me. The way similar commands are organized into related key groups (variants of key modifiers) will not stick in my head, so I was constantly trying control-shift-meta-cokebottle, getting the wrong result, trying shift-control-cokebottle, etc. (And one of the wrong key combinations I often picked—I forget which—made a not-obvious change to the file that would surprise me next time I ran the tests.) Also, the seams kept showing: globalish commands that don’t work because I’m in the sidebar not a source file, the way my tabs kept filling up with files that I’d never intentionally visited, and the like. And the current lack of window splitting is a deal-killer.

I gave NetBeans a shorter trial, and I can’t remember why I didn’t like it.

IDEA has the advantage that I use it for Java, so many of my reflexes carry over. And I always found it had some of that mystical goodness that originally made me prefer Ruby to Python: when I guessed at how something would work, most often I was right.

Still: besides the fact that an upgrade cost me USD 149 (5 euros), it has some disadvantages.

  • The Ruby plugin is beta. I haven’t found too many bugs, but features are incomplete. It’s missing many of TextMate’s nice little Rails features. (But at least you don’t have to install a hack to rerun the last test from anywhere you are.)

  • Because it’s a Ruby IDE wedged into a Java IDE, it may be confusing for people unfamiliar with Java (and, perhaps, Java in IDEA). For example, the General Preferences has these entries: Project JDK (”Ruby SDK 1.8.6″), Project Language Level (irrelevant for Ruby, but on my machine I could choose 1.3, 1.4, or 5.0), and Project Compiler Output (irrelevant).
    (Project setup doesn’t push Java in your face quite that much.)

  • The worst is that it sometimes decides to spend a lot of memory and CPU doing something. When my pokey little MacBook (1.83Ghz, 2G memory) is trying to drive both its screen and a 24 inch external monitor, Time Machine has decided to kick in, and I’ve got various other things running (like Safari, which also likes to suck down CPU while doing nothing visible), IDEA can get slow. I’ll end up typing faster than it can echo characters.

Despite those things, I find IDEA somehow hits a sweet spot where I’m actually working with the code, not the editor (the old ready-to-hand vs. present-to-hand distinction). With other tools, I felt more friction.

Scripting your Mac with Ruby

Unless the contract contains unexpected surprises, I’ll be writing a book on scripting your Mac with Ruby for the Pragmatic Bookshelf. Like Everyday Scripting, it will teach by way of projects. I’m looking for reviewers and ideas. The ideas could be projects to do or technologies to cover (e.g., Growl).

By way of example, here are my notes about the first project.


Pretend you're someone who needs to be reminded to take breaks
from the computer. This program provides them.

First version periodically opens textedit on a file that says
"Stretch!" (The handy 'open' command.)

Next: Make it start running at login (startup items)

Next: Tell TextEdit to go fullscreen. (RubyOSA and all that
goes with it.)

Window that says 'Stretch'

Next: That big screen message is awfully jarring. Use growl
when the interval expires. Resort to the in-your-face screen
when activity shows I’m ignoring the growl message.

Next: Control app with a preference file.

Maybe: add a menubar item (like MoodBlast’s) that lets you set
preferences and reset the timer. (Too early in the book for
this?)

Maybe: Do a spiffier full-screen display than TextEdit. How
about mimicking something like Highlight to write over
the screen? (Maybe could take over Highlight’s splash screen?)

Another project I want to do is write a plugin to Mail that will let me kill threads in ruby-talk as a way of controlling the flood.

Ruby hackery needed

Here’s a kind of code I find myself habitually writing until I realize I can’t implement it:


    watch {
      # some calculation
    }.and_whenever(:something_happened) {
      # do something
    }.and_whenever(:something_else_happened) {
      # do something else
    }

What I want this to do is:

  • Stash away the block with “some calculation”

  • Run the second block. This does something that will affect the calculation.

  • Run the third block. This does something else that will affect the calculation.

  • Run the first block, then undo the effects of the following blocks.

The problem is that I don’t see a way to know when you’ve reached the end of the chain of 2nd, 3rd, … blocks, and it’s now time to execute the first block.

Now, there are alternatives. You can put the blocks in the right order. You can make a single and_whenever that takes a hash from names to lambdas as its single argument (presuming the order of evaluation doesn’t matter). You can put a “sentinel” method at the end of the chain, like .ok_do_it_now.

What I’m wondering if there’s some clever way of making the original form work.

Mailing lists for gems

I’ve created both “announce” and “discuss” mailing lists for my different gems:

gossip 0.3.2

I just committed a change to a project Laurent Bossavit and I are working on. As a result of that, the following happened:

  1. This came via Jabber:
    A Jabber message
  2. This was posted to Twitter:
    A twitter post
  3. This came in email:
    A mail message
  4. This was sent to Campfire:
    a chatroom message

Had I deployed a new version, I would have gotten deployment messages to each of the above, plus in our Trac timeline:

Trac timeline

(Trac does a perfectly fine job of handling commits on its own.)

That’s all due to a library of mine called Gossip, which provides a unified interface to all those destinations. It comes with three utility scripts:

  • svntell, which you’ve seen.

  • watchdog, which reports on the output and duration of a command. (It’s derived from the script in Part 4 of Everyday Scripting with Ruby.)

  • fanout, a command that relays a message to the distant destinations. (Our Vlad task uses it to report on deployments.)

The commands and library use the User-Choices library, so they’re configurable up the wazoo.

All this: done in service of ease at work.

I hope you use it.

User-Choices 1.1.0 released

User-Choices is a unified interface to configuration files, command-line options and arguments, and the environment. Here’s the beginning of the tutorial:

Suppose you have a command-line application that uses some number of, oh, let’s say “connections”. Most of the time, a user will want the same number of connections, so you’ll let them set a personal default in a configuration file. Sometimes they want to change the default. Maybe they’ll want a one-time change; for that, a command-line option is best. But sometimes they’ll want to make the change for an entire login session; for that, setting an environment variable is most convenient.

The User-Choices gem gives your code a unified interface to all those sources. Your code can obey the user’s choices without having to bother (much) about how she made them.

This version is derived from the one used in Part 4 of Everyday Scripting with Ruby. However, there are minor incompatible changes to the interface. Sorry about that. In return, you can now use YAML for configuration files, and empty argument lists are handled more gracefully when choices can also be made in the environment or a config file.

Fluid.rb 1.0.1 released

Class Fluid provides dynamically scoped (”fluid”) variables modeled after those of Common Lisp. It also gives you a convenient way to reversibly change the values of globals.

Fluid variables are useful when you want to pass information among related classes and methods without passing arguments all over the place, but you also want something a little more controlled than globals. They’re not useful all that often, but they come in handy once in a while.

The documentation (rdoc) gives more explanation and examples, such as the code that produces this amazing, never-before-seen feat of prettyprinting:

Everyday Scripting utilities at Rubyforge

Everyday Scripting with Ruby comes with a library, anachronistically called s4t-utils. It’s mainly used behind the scenes to simplify working with scripts, but it also has a pile of utilities I use frequently.

By putting s4t-utils in a script’s third-party folder, a script writer can hand out her script as a single zip file and not force people to install different bits and pieces. (Rubygems handles collecting and installing multiple bits, but (1) using gems would require my scripters to make gems, and (2) they’d also have to run a local gem server for their local gems.)

However, if you’re making gems anyway (like I’m doing these days), s4t-utils might as well be another gem your gem depends on. So s4t-utils is now available from Rubyforge and thus via gem install --remote s4t-utils.

This version has a few small additions. It also has documentation of the general-purpose utilities.

Graphical workflow tests for Rails - alpha version released

For many web apps, it’s important to get the user’s workflow right. Consider a Rails app that uses some variant of acts as authenticated to handle user registration and login. Here’s one way of describing an example of normal registration:

John visits the home page.
John follows the “sign up” link.
(John is now on the signup page.)
John signs up as “john”, email “john@example.com”, password “sloop”.
(John is now on the welcome page.)
John waits for activation email…
John clicks on a URL ending in an activation code.
(John is now on the login page.)
John logs in as “john”, password “sloop”.
(John is now on the member page.)

Here’s another:

A registration workflow

Which is better? If I were trying to design the workflow—get it so that it’s right for the users—I’d much rather use a picture (whether drawn in OmniGraffle, as this was, or on a napkin or whiteboard.) Why?

  1. It’s easier to “zoom out” from a picture, to ignore the details. When I do that, I’m more likely to notice missing workflows or stupidities in the ones that I have.

  2. As a designer, I’ll soon have to explain my thinking to others. It’s easier to explain a picture because it’s sitting right there in front of both of you, visible in two-dimensional space. It’s simple to refer to something you already mentioned: point at it. A wealth of context gets recalled by that simple gesture. If it’s not readily recalled, you can decorate the graphic with something that jogs the memory. Pictures make for a much more fluid way of communicating.

  3. Our minds are in bodies; and bodies have minds of their own. We think kinesthetically and visually, not (just) by banging propositions together according to the rules of some kind of logic. The more ways you think about something, the fewer mistakes you’ll make.

But there’s one big disadvantage of pictures from the point of view of the test-driven (behavior-driven, example-driven) programmer: they’re not executable.

Until now

I’ve released an alpha version of an open-source library that converts such pictures into Ruby tests. Below the fold, I show how the workflow picture becomes a Rails integration test.

✂——✂——✂——✂——✂——✂——✂——✂——✂——✂——
(more…)

Graffle 0.1.0 released

As far as I know, there’s only one other person in the world who cares about testing Rails apps from OmniGraffle documents. (Hi, Tom!) Still, since I always make a fuss to clients about how important it is to reinforce discipline and ease the release process by frequently releasing potentially usable product as widely as possible—and since I believe what I say—it’s time for a release:

The first, minimally bearable version of my OmniGraffle parser/decorator is available for download. You can also read the documentation online.

Picture of graffle documentation