[I suspect I’ll be writing a fair amount about Ruby, and am too lazy to come up with clever names. And I don’t want to rename old posts, so I’m retroactively declaring this to be Ruby notes 1 and this to be Ruby notes 2.]
I just learned about creating arrays of strings using %w{}
. Handy, that. I mean, it’s only a few keystrokes, but why not save keystrokes?
I also got around to running my tests with warnings turned on. The warnings suggested that I add parentheses in one place, which I was happy to do. The other thing the warnings suggested, though, annoyed me. As I mentioned yesterday, I wrote a mixin module which cached a value in an instance variable. When I turned on warnings, though, it complained about my referencing an uninitialized instance variable. I assumed (and still assume) that testing an uninitialized variable against nil is safe, but I like having my code warning-free. So what am I to do?
What I ended up doing is not caching that value: it was an untested optimization to begin with, and once I took the time to benchmark it (and a few variants which the interpreter was happier with), it proved to be useless. (At least it wasn’t a pessimization…) So now my code is a bit cleaner, and I was wrong to stick in that optimization.
Having said that, there are other situations in which such an optimization would be the correct thing to do. And this does point at something I’m not thrilled with about Ruby: inheritance and initializing state. For one thing, the whole inheritance picture is a bit muddled: mixin modules have their uses, but I’m not at all convinced that plain old inheritance isn’t a better idea. (Having said that, I also suspect that mixin modules enables useful hacks that can’t be done with some variety of multiple inheritance, I’m just not sure what those hacks are.) Setting that aside, in either case the superclass (or module) can’t set up its state appropriately. In the module case, it’s hard to set up the state at all, as I’ve learned; in the superclass case, constructors (a.k.a. initialize
) don’t automatically chain. And while I’m willing to trade off destructors for garbage collection, not having proper constructors bugs me.
Oh well; something would be wrong with me if I couldn’t quickly find something to be annoyed by in any programming language.
Another thought that my first optimization suggests: I could probably write a generic attr_cached
function that would turn any function that always returns the same value (for a given instance) into one which caches that value after the first time. That would be fun. Now I’m sad that I don’t have a reason to do that. :-( I suppose I don’t really need a reason, though, do I?
Post Revisions:
There are no revisions for this post.