Keyword..end Matching – More Than Just Brackets!
I don’t know about you, but I find that I am forever getting lost in Ruby code – especially other people’s Ruby code!
It can be tricky to see which
end matches which beginning even in a short piece of well-indented code like this….
But real-world Ruby programs are often huge, have far more nested levels, many more
ends and may not even be scrupulously indented…
To take an example – just the other day I found myself browsing through the code of a fairly well known Ruby application (out of diplomacy, I shan’t say which one!), trying to track down some information when, all of a sudden, a few thousand lines deep, I ran into a massed squadron of
ends like this:
At the time I was trying to work out the scope of a certain object. I knew it was declared somewhere inside one of the innumerable methods, classes and modules in this file but, for the life of me I couldn’t figure out which. The serried ranks of
ends only told me that it was in scope somewhere in the mass of code above – but short of counting up all the
ends in that mass of code and matching them with all the
modules, figuring precisely which scope the object was in would be purely a matter of guesswork.
At that point, all I really wanted to do was to figure out what each of those
ends actually ended! In other words, I wanted to be able to match
ends with their beginnings – maybe by getting the text caret to jump to the matching keyword delimiter (for example,
module) and back again, just as I can match brackets by pressing the Ctrl+] hotkey to move the cursor from one bracket to the next.
Oh well, if you want a feature and you happen to be the developer of the software, you have no option but to do it yourself. Or, then again, you can delegate – which, to be honest, is exactly what I did in the present case. I happened to mention to my colleague, Dermot Hogan, (the lead developer of Ruby In Steel) that keyword..end matching would be darned fine thing to have - and this is what he came up with (I’ve deliberately enlarged the cursor in this animation to show you the effect)…
The great thing is that this works just as well in files containing thousands of lines of unindented and densely packed Ruby code. I don’t know how I ever managed without it!