sometimes 37 signals is so right on

Posted by amy on April 20, 2008

They just went to a four-day work week. “Urgency is poisonous!” says Jason. I couldn’t agree more.

Popularity: 63% [?]

No Ranting, No Railing, Just Grading

Posted by amy on January 15, 2008

A few of our students, people new to ruby and rails, are pretty turned off by the ranting and railing in the rails community that’s been on super-duper heavy display lately, what with the Zed thing and the Dreamhost thing and all. (No links, google Zed Shaw and Dreamhost Rails for your ownselves.)

These students want to know: what’s up with the rails community being so childish, ranty, obscene, profane, and macho? If rails wants to be treated like a grownup framework for grownups, shouldn’t rails act like a grownup? How are we supposed to take rails seriously when the guy in charge of rails thinks people who are offended by swearing are not worth his time? And why should we want to join a community that appears so unwelcoming?

To which I say the following:

First, my job is not to defend rails and all the people associated with it (Right, say students, your job is actually to finish grading our assignments. Could you finish?!? I’m working on it, I swear). If Rails is a ponzi scheme I have not been let in on it; I get no kickbacks from duping students into learning it. I am enthusiastic but not passionate about rails ( I believe, as I’ve said before, that my only true passion may be cheese), and I hope I’ve managed to share some of my enthusiasm with our students, without appearing cultish.

Second, I could point out that the Ruby and Rails communities are not isomorphic. There is a lot going on in Ruby that is not rails. But it’s also true that many people come to Ruby through Rails, so if the rails community is unwelcoming, then fewer people may make it over the hump to discover the Ruby in which Rails is built. That’s too bad, because they’d be missing out on something truly lovely. Still, there are other truly lovely languages out there too. “Let a hundred flowers bloom, let a hundred schools of thoughts contend,” except without all the reeducation camps.

Third, it’s possible that Rails will hit a wall due to personality problems. It’s also possible that, being young, Rails will grow out of its personality problems. If you don’t like the personality of the rails community right now, just wait, it’ll probably change. Or jump right in there with your own personality problems, mix it up a little.

Whatever happens, though, I think that Rails has a few good tricks that the rest of the web development community has and will continue to learn from. I think that Rails, like all frameworks, will someday go out of fashion, and then, out of date, and then, eventually, fade into obscurity. And I think more good and interesting and beautiful things will come out of Ruby.

In any case, as I wrote to one of the students who was a bit depressed by the recent rails flame wars:

For me, I know that if it had not been for rails getting popular, I would not have gotten into Ruby, and if I had not gotten into Ruby, it might have been much, much longer before I’d realized that life could get a whole lot better than:

Iterator iter = collection_thingy.getIterator();
while (iter.hasNext()) {
Thingy thingy = (Thingy);

No one can take each away from me.

Popularity: 73% [?]

Joel Spolsky Gets It Wrong

Posted by amy on December 28, 2007

Joel Spolsky recently posted the transcript a speech he gave to the Yale CS department on November 28th. It reads a bit like an extended recruiting pitch, which, of course, it is. Because why would he give a talk at Yale CS and not attempt to pick up some smart people to work for him while he was there?

Anyway, one section of the talk is all about how it sucks to write in-house software. Joel says it sucks because, first, you don’t get to work with cool technologies, because no one will let you:

you’re not going to allowed to build things with Ruby on Rails no matter how cool Ruby is and no matter how spiffy the Ajax is going to be. You’re going into Visual Studio, you’re going to click on the wizard, you’re going to drag the little Grid control onto the page, you’re going to hook it up to the database, and presto, you’re done.

Second, it sucks because you don’t get to work on a project past the point where it minimally solves the business problem at hand and because of that, you’re stuck building and fixing ugly, broken things for not enough money and no respect.

The key point about in-house development is that once it’s “good enough,” you stop. When you’re working on products, you can keep refining and polishing and refactoring and improving, and if you work for Facebook, you can spend a whole month optimizing the Ajax name-choosing gizmo so that it’s really fast and really cool, and all that effort is worthwhile because it makes your product better than the competition. So, the number two reason product work is better than in-house work is that you get to make beautiful things.

Third, it sucks because no one thinks in-house developers are very important:

Once at a Viacom Christmas party I was introduced to the executive in charge of interactive strategy or something. A very lofty position. He said something vague and inept about how interactivity was very important. It was the future. It convinced me that he had no flipping idea whatsoever what it was that was happening and what the internet meant or what I did as a programmer, and he was a little bit scared of it all, but who cares, because he’s making 2 million dollars a year and I’m just a typist or “HTML operator” or whatever it is that I did, how hard can it be, his teenage daughter can do that.

Therefore, says Joel, serious programmers should work at software product companies, like, say Fog Creek Software.

I’m sure a lot of in-house software development jobs are just like Joel says. But there are plenty of really rewarding in-house positions available. For example, what he describes is not at all what I experienced while working at Millennium Pharmaceuticals (2001 -2003, with some consulting work on and off after that). Informatics was pretty crucial to the company’s vision of how it would revolutionize drug research and development. Developers were respected, and we tried to make our software, if not very beautiful, at least not completely butt-ugly. There was room for plenty of innovation in what technology we used. It was a great place to work, and I worked with some amazing people there. I felt like the software I was making was actually helping people do their work, and it was work that they cared passionately about, and I understood how they could be passionate about it, even if I wasn’t myself passionate about it. Most of the code I wrote went to helping the molecular pathology department manage their experiment workflow. I thought the domain (biotech, and as far as what molpath was doing, basic disease research) was interesting. I was really happy there.

Conversely, I’ve found that I’m not really at my happiest working on consumer products. I don’t get excited about consumers. I think that their consumption is pretty much the least interesting aspect of people, and I think that when people are acting as consumers, they tend to be at their most demanding, irrational, and childish. I also don’t think that people like that Viacom executive who had so little respect for Joel are found only in big companies with big in-house software teams.

I like to help people get their work done. I like the philosophy of ‘good enough’. I don’t really care that much about ‘really fast and really cool’ unless someone convinces me there’s a very good reason to care about it, and the reason is better than “well, people will think it’s cooler and buy more of it.” I’m just not a very good capitalist that way.

In any case, plenty of software product companies make butt-ugly software that’s only just good enough, using awful techonology, so I really don’t think the distinction is a valid one. And I think that we’ll see that an increasing proportion of in-house software written in ruby on rails. Maybe it won’t have cool AJAX livesearch widgets in it. So what?

It’s not that I think appearances aren’t important. It’s not that I don’t think that there’s a place for consumer software products. And I know that lots of in-house software development sucks. But I think Joel is over-generalizing in order to make a stronger recruiting pitch. And I think that he wrongly assumes that what makes him happy is going to be what makes everyone else happy. That’s true at the level of basic human needs, of course, but not at the level of what floats your boat at work. Or rather, not in the way that Joel talks about it. Your satisfaction at work probably has a lot more to do with the length of your commute, whether you have clear goals and a sense of control, and if you have friends in your workplace than about whether you get to work with cool technology or make things faster and better just for the hell of it. Respect, sure, that’s important to have. But plenty of software product companies respect sales and marketing over development, and plenty of non-software-product corporations respect their developers.

Joel’s not really wrong here, of course. He just over-generalizes. He thinks his own experience must be everyone’s experience. He is sure that what he wants must be what everyone else wants.

Actually, it’s probably not that at all. He just really, really wants to pick up the cream of the Yale CS crop. He needs good developers, and gosh darn it, he’s gonna make his pitch to get them.

Popularity: 35% [?]

REST vs. SOA: thoughts from a member of the unwashed masses

Posted by amy on November 27, 2007

I have no recollection of how I ended up here:

On the REST front, if you’re claiming that it’s harder than the alternatives, to me that’s just a sign that you don’t understand it. Is REST simple? No, but neither is SOA. However, unlike SOA, which is fairly wishy-washy, noncommittal, and loose, REST’s constraints provide real, actual guidance for developers, and those same constraints also provide opportunities for significant flexibility, extensibility, performance, scalability, and serendipity. SOA’s contracts come with no rules or constraints, and thus can easily result in a system that’s extremely brittle, tightly-coupled, and virtually impossible to upgrade. SOA itself isn’t inherently bad, as it’s certainly a step above the “every application for itself” mode of development that’s so widely practiced. Unlike REST, though, SOA doesn’t go nearly far enough to provide real, useful guidance to the poor developer who has to actually write the stuff, make it work, and keep it running.

The author was responding to this guy:

This is the reason I am against dynamic languages and all of the fan-boy parts of IT. IT is no-longer a hackers paradise populated only by people with a background in Computer Science, it is a discipline for the masses and as such the IT technologies and standards that we adopt should recognise that stopping the majority doing something stupid is the goal, because the smart guys can always cope.

And that guy was responding, in turn, to this guy, who said that REST was like dynamic languages because both are loosey-goosey and flexible and don’t enforce contracts and type-checking.

The SOAP/WSDL/WS-* SOA view of the world is like a statically typed programming language, i.e. C++ or Java — everything is pre-defined, contracts govern everything, nobody can interact without following formal rules … and ideally, everything violating the rules (and policies) will get caught before even going into production.

So the chain is: 1) REST is very flexible compared to SOA, and that presents the danger that things that don’t work will be put into production. 2) REST is too complicated to be implemented by ordinary dumb programmers, and should be avoided. 3) REST is easier than than SOA because it provides very strict constraints.

So is REST easier or harder than SOA? Is it looser or stricter?

I just implemented my first REST API. I don’t see how anyone could say that it is ‘harder than the alternatives’, or that it doesn’t constrain developers very much. So I agree with the first quote, above. REST seems like a great idea to me. Anything that allows me to mostly avoid the complications of this many standards is good.

And also, obviously, I’m a big fan of dynamic languages now. I think I’d rather look at someone else’s crappy Ruby code than someone else’s crappy Java code, because at least there’s less of it. But I am, arguably, a Ruby fangirl right now, and given that I don’t have a CS degree, I guess I also count as one of the unwashed masses. And as a member of the masses, I can attest that no programming language in the world will stop us from doing something stupid. So we may as well enjoy ourselves while we’re doing it!

Popularity: 22% [?]

Database Constraints, Stereotypes, Rails, Culture, Talmud, Gender, MINASWAN, Religion. But ABSOLUTELY NO BONDAGE PLAY

Posted by amy on November 02, 2007

This post started out with a plan to compare constraints in software to bondage play, and suggest that DHH is a top who likes to constrain others (“opinionated software”) but is extremely uncomfortable being himself constrained (by, say, the database). I was going to suggest that DHH maybe needs to get a little bit more confident and comfortable being a ‘bottom’.

Now, that would have been a wildly, wildly inappropriate post, don’t you think? So it’s lucky for me that as I was writing it, I realized that not only was it inappropriate, it was completely unfair. So this post is still about rails culture, and still about database constraints, but I am not, I repeat, NOT arguing one way or another about DHH’s predilections in bondage play (assuming he has any, and if he does, not that there’s anything wrong with that ), about which I am, and hope and plan very much to remain, ignorant.

That out of the way, how did this all come up? Yeah, my mind’s a little twisted. But here you go:

My friend and partner-in-teaching-crime* (well, boss in teaching-crime, technically, and is teaching really a crime? To my students: do not answer that!) John complained recently about the difficulties of writing a migration to turn a plain HABTM join table (two foreign keys, no primary key, nuthin’ else) into a join table with state, linking two other tables with the :has_many :through association. Unfortunately, as he describes, ActiveRecord won’t let you add a primary key column to an already-existing table, so he had to migrate all the data over to a new table.

Couldn’t you just drop down to “execute ‘db-specific sql here’”? I asked.

Yeah, but you wouldn’t be database-agnostic, of course. John likes to be agnostic. He has historical reasons for that, just like I have historical reasons for thinking that ads comparing servers to who won’t give blow jobs are kinda offensive. But anyway, I don’t have those reasons that John does to prefer agnosticism. I figure that in most cases, people are sticking with the database they’ve got, so database agnosticism isn’t that important to me. The ORM is one of Mr. Spolsky’s leaky abstractions, and while that’s no excuse to start poking extra holes through just for the fun of it, I don’t have any need to pretend that the holes that exist aren’t really there.

In any case, I drop down to the database to put in foreign key constraints.

[Aside: John said in email:

"There is a distinction to be made between this narrow case of
agnosticism (fiddling with keys) and the general case. The narrow case
is easier to disregard. In the general case, it is very difficult to
argue against agnosticism, because the primary driver is: You get to
know less. That is frequently (more frequently than not) beneficial,
right? In the general case, I would rather write
user.find_all_by_last_name rather than the raw SQL. etc."

I agree wholeheartedly, and in that sense I too am in favor of database agnosticism. But obviously we have different levels of allegiance to the idea, because I would never have put in the effort to come up with a database-agnostic migration from a HABTM to a has many through relationship, and he did. Maybe it's just that I am lazier than he is, though...]

So this post was going to be about how it is the rails way not to use foreign key constraints at all, but to rely on ActiveRecord and your own unit testing to maintain data integrity. (hah!) And I was going to say “that’s freakin’ insane and evidence of all that is wrong with the whole culture of Rails.” But while it would be fun to see what this temporarily did to my site stats, (assuming it got dugg or reddited or something) it wouldn’t be fair.

I found very little evidence that not using foreign key constraints is considered to be a best practice by most people in the rails community. The main thing is this caboose posting, from last year. This was mostly a complaint about how big of a pain in the ass foreign keys are, especially where fixtures are concerned. But it actually only at the end claims that foreign keys are not needed, if you are using ActiveRecord Associations correctly. And even then, it’s a weak claim, about foreign keys in the development database:

The time thing sold me on not using foreign keys in development. I’m sure there are a number of arguments that can be made for using foreign keys etc etc, but it’s just stuff that gets in the way in a framework like rails. Do we test w/ foreign keys in place before milestones(what I’m leaning towards)? Do we test w/o the fks in place(obviously not :])? Maybe somebody can come up with a better way to handle them, but I don’t really think you need fks if you’re using rails associations correctly. If you are forced to use them though, the above approach might be a good place to start.

Okay, I found one other posting, from a guy who gave up his foreign key constraints (and wept) because they were too hard to use with fixtures. But most people in the comments of that post seems to think the problem there is not foreign key constraints, but fixtures, and that dropping the reliance on fixtures would be the smarter thing to do. Or fixing the fixtures, or whatever.

DHH has nothing to say on the matter that I could find. In AWDR, Dave Thomas explicitly advocates the use of foreign key constraints (2nd Edition, p. 324). Mostly what I found on the web about rails and foreign key constraints was a bunch of people talking about how they do use them and you’d be crazy and irresponsible not to. Yes, people differ on when in the development process they put them in (in fact, right this minute I have a development database with a near-complete lack of foreign key constraints, my rather pathetic excuse being that the client’s requirements are so changeable right now that we can hardly keep up with the foreign keys themselves…), how they use them with fixtures, and other details, but I really found very little evidence that anyone in the rails world seriously advocates putting into production web applications backed by databases without foreign key constraints. Relational database technology is mature, it’s well-tested, and it’s logical. I trust it much more than I trust either my own code or DHH’s. Database constraints are easy to use and good for you, just like flossing. And that appears to be the majority view.

So the evidence wasn’t there, and I had to rethink this post entirely. And so it’s become, in part, a post about stereotypes, and about culture, and about the ways that people confuse technologies, creators, fans, and users.

Rails is a technology. The technology exists in the context of a culture. The culture is greatly influenced by the fact that a single, very opinionated, um, strong personality developed the technology. Certain kinds of people are attracted to the opinionated personality, and become involved in the technology and its culture because of that. This is great for adoption of the technology. But then you get the fanaticism: rabid pro-Rails trolls who jump down the throats of people they perceive to be deviating from the One True Way of DHH. And equally rabid anti-rails trolls, screaming “Twitter”!

Now, is all this clash of personalities and hue and cry integral to the development of the technology, or is it epiphenomenal? (Is that a word?) I’m not sure. The anthropologist in me says it is, and that the culture of rails in some sense IS rails — drives its development, ensures or prevents its success, etc. The Marxist in me thinks perhaps the structure of rails itself is responsible for the culture surrounding it: the culture reifies the framework. And the poststructuralist in me suggests that, however determined things appear to be, however narrow and defined and boundaried and opinionated and one-true-wayed things appear, there’s always space for something else to arise.

There’s the One True Way of DHH. There are rabid fanboys. We talk of drinking the kool-aid, and we laugh at video advertisements comparing the separation of concerns, database-agnosticism, and ease-of-use of Rails to PHP, Java, et. al. “With rails, I can build a blog in 10 minutes,” we say. With rails, we never have to code again! Let’s just go to the beach instead! There was the Twitter developer scaling scandal, and the CDBaby switched-back-to-php-from-rails scandal, and a bunch of scandals I haven’t even heard of, no doubt. There’s the rails bandwagon, the rails hype, rails lets crappy developers wreak havoc quickly, rails is too slow, and rails is not ruby.

And that’s all fine and part of the fun, and part of the DHH Is Opinionated and So We Are Opinionated – ness of Rails culture.

But then there’s the technology, and lots of quiet, not-so-opinionated, flexible people who are using Rails because it’s a pretty good, pretty easy framework that helps them get their work done. There’s plenty of that too. And there’s no need to decry the partisan atmosphere of rails culture with a great big rending of garments about how the culture really has to change if it’s going to achieve more popularity, and it’s scaring people off because it seems too hyped, and badly executed rails projects are giving rails a bad name and how can we police that, and so on.

Let’s just all get on with our work, using rails, or not, as the work dictates. And in a mild-mannered matz-y way, talk about what we are doing, and why, and how, and what we like, or don’t, about it.

For me, rails is a web framework, not a religion. I know that not everyone feels or acts that way, and that’s fine for them. They can wave their hands and argue about what constitute a ‘scale’ for the purposes of determining if a fish is kosher, or if one should use foreign key constraints. Me, I’ve got to get dinner on the table.

* Max would like it noted that he thinks there’s something very trite about the expression “partner-in-crime”. He’s right, of course, but I think I’ll leave it in anyway, to annoy him.

Popularity: 24% [?]

In Which Amy Encounters a Superior Mind, Recognizes (Again) Her Own Incompetence, and Rededicates Herself to Alleviating the Problem, Though Not Without Some Concern About When She’ll Actually Find the Time to Do So

Posted by amy on October 29, 2007

A few weeks ago, I was introduced to Stevey’s Blog Rants. I started reading them, and I realized, yet again, that I am a crap developer.

I am a hack. I know nothing. I claim not to be a script kiddie, and I’ll stand by that claim, but only because those of us who are just competent enough to know that we are incompetent are EVER SO SLIGHTLY more competent than people who don’t realize that they are utterly incompetent.

I know people whose lack of ability to solve programming problems is always, always caused by some quirky gotcha in the language being used, and never ever by their utter lack of understanding of the most basic, fundamental aspects of programming. They’re sure they’re just misusing the subjunctive, and in reality, they’re babbling in gibberish that is less comprehensible than my 10-month-old’s. (Those people are always certain that everyone is simply misunderestimating them. Would that it were true!)

So I’m not that incompetent.


[ Ack, I am being attacked by a babbling infant. She has noises for "nurse now, mom" and noises for "check it out, mom, I'm turning on the stove!" and noises for "I'm sitting in a big poopy puddle" and noises for "stop typing now, mom, or I am going to jam the caps lock permanently on." That's the noise she's making right now, in fact, SO I BETTER GO BEFORE I FIND MYSELF YELLING AT THE INTERNETS ALL THE TIME. Back later.]

Right, back to how bad a developer I am. Can you believe I’m supposedly using this blog to drum up business? Hi, prospective clients! I suck! Let’s talk. Before you turn away in disgust and say “why should I talk to you, you sucky developer?” let’s get some perspective. Steve Yegge, who works at Google, and before Google worked at Amazon, also claims he sucks. Suckage is like wealth: graded on a curve. Steve Yegge says he sucks because he’s measuring himself against all the other developers there at Google. I say I suck because I’m measuring myself against Steve Yegge (though, don’t get me wrong, I also suck as compared to many developers suckier than Steve Yegge. Steve Yegge is several levels up in developer competence than I am. Several.) The principle holds, however. Developers who don’t think they suck are only hanging out with crappier developers. And not only does that mean that they don’t even know how incompetent they are, they also have no way of getting less incompetent even by osmosis, because they’re not putting themselves in a position to osmose anything from anyone else. ( I read a sample chapter in Chad Fowler’s My Job Went To India… about this, which made a huge impression on me:

Legendary jazz guitarist Pat Metheny has a stock piece of advice for young
musicians: “always be the worst guy in every band you’re in.”

Attempting to be the worst actually stops you from selling yourself short.
You might belong in the A band but always put yourself in the B band,
because you’re afraid. Acknowledging outright that you’re not the best
wipes away the fear of being discovered for the not-best person you are.
In reality, even when you try to be the worst, you won’t actually be.

This is why Max joined an orchestra this year, even though it’s a lot of effort and feels very far over his head. He’s learning a lot more than he would learn just playing by himself. It’s also one of the great disadvantages of independent contracting — the reduced opportunities to be part of a team of your betters. You really have to make more of an effort to seek out your betters to work with them, because you don’t always get to do it on your paid work.)

Anyway, you don’t want developers who don’t think they suck, dear prospective clients/employers. Stop looking for people who self-identify as ninjas and experts and superstars, and find some nice modest developers who have some sense that there’s stuff out there that they don’t know, and will admit that they don’t know that stuff not because they don’t NEED to know it, but just because, hey, they don’t know it. They’d be better developers if they did know it. They’d like to know it. Maybe it’s even on a list of things they’re going to learn. Maybe that list is far too long, and maybe they only have fifteen minutes every other week to even get the list out and look at it, but they have a list of stuff they don’t know that they think they SHOULD know.

In fact, what I’d do, if I were you, prospective employer/client, is ask: “Where are the holes in your technical knowledge?” I suppose that if people started doing that, we’d all start picking one or two safe-ish things to reply, like how everyone says, when asked what their weaknesses are, that they’re a perfectionist who hates being late. “Oh, I always get confused by my splay trees.”

Of course, Steve Yegge would probably tell me that splay trees are not a safe-ish reply at all. Everyone should know about splay trees. Fundamental stuff, splay trees are. He’s probably right. I don’t remember covering splay trees in my one data structures course, but that doesn’t mean I didn’t. I’ve never had occasion to use them in my developer life, but that doesn’t mean I wouldn’t, if I knew what they were and when I might. For all I know, I am using splay trees every day. So now I have to go learn about splay trees.

Actually, dear readers, I do have a plan for a fun, exciting, and exhausting project that will help me get some of that CS knowledge I am lacking. The project remains, right now, in super-secret stealth mode, except if you know my mom, in which case she’s told you all about it already. As it takes shape, I’ll reveal more details about it.(Or if it doesn’t end up taking shape, I’ll pretend I never wrote this and look at you all confused if you ask me whatever happened to my mysterious and exciting project I mentioned on the blog. What project? I’ll say. I never said there was any project. You’ll show me the actual words in which I said “oh, there’s a project”, and I’ll look you straight in the face and say “nope. Never said that. Didn’t write it. No project.” And you’ll shake your head and roll your eyes and let it slide, because that is what we do these days. )

Also: I think that I am getting way too obsessed with Steve Yegge. And given that Steve Yegge basically thinks I’m crap*, that’s probably unhealthy, don’t you think?* No, steve yegge did not drop by this blog and say “amy, you are crap.” But he did say “If you don’t know how compilers work, then you don’t know how computers work.” I don’t know how compilers work. And he frequently talks about how woefully deficient he considers programmers to be who are lacking a long list of skills and knowledge that I, too, lack. I would not, for example, pass his phone screen. If I had a job interview with Steve Yegge, he would skip the hello and go right to Do you have any questions for me?”. So I’m pretty sure he thinks I’m crap, even if he might be too polite to say it to my smiling avatar face.

Popularity: 14% [?]

how did I ever live without xkcd?

Posted by amy on October 10, 2007

John mentioned the webcomic xkcd in a post on our course site about his feeds, and now that I subscribe, I have absolutely no idea how I ever lived without it. Sudo make me a sandwich is hanging in our kitchen now.

heh heh, sanitize your database inputs! (imagine me pushing up my glasses while snorting, revenge of the nerds style.)

Popularity: 13% [?]

12 Steps to Testing in Rails

Posted by amy on August 17, 2007

We’ve several times complained about testing in rails. It’s difficult. It’s confusing. It’s time-consuming. No one really shows you how to do it well. There are too many choices for methods. You feel inadequate. Still, we soldier on. Or at least, in theory we soldiered on. In practice, our test code languished.

Until. A major refactoring was required on an app. Tried to convince client that feature requiring refactoring was not really that important. Oh, yes it is, says client. Okay, says I, and go in with a sledgehammer.

Well duh, I broke everything. I managed to implement the feature, and broke practically everything else in the process. And I couldn’t run my tests, which I’d been avoiding since long before the sledgehammer got involved, so they were in no shape to tell me what I’d broken anyway. And so Max just kept sending me Trac notifications from the other room, and I fell into despair when I realized that I had turned the code base into a steaming pile of putrid excrement. I don’t deserve to call myself a programmer, I thought. If only I had been diligently testing, this would never have happened.

So that was my ‘hit-bottom’ moment, when I realized that I had no control over my code and that I was ready to give my code over to the higher power of test-driven-development. I just had to figure out how to do it.

A lot of things were holding me back from making the transition to TDD. The biggest one, I discovered, was perfectionism and overwhelm. So many different ways to test. So many different things to test. So many different rails luminaries talking about their favored testing methods. So many different testing plugins, add-ons, and approaches. Too many decisions. I would sit down to write tests and just be absolutely paralyzed.

Once I realized that my big problem was perfectionism, I thought immediately of FlyLady. FlyLady is the reason our household is no longer buried in laundry and our kitchen is no longer buried in dirty dishes. FlyLady has some really great hacks for getting housework done, and those hacks can be applied to writing test code too.

Here are the most important points that Flylady makes:

  • The goal is “progress, not perfection”.
  • Baby steps will get you there.
  • You can do anything for 15 minutes.

FlyLady counsels us to start with the tools we have on hand, not to try to do everything all at once, to put one habit in place before we start worrying about others. Most importantly, she constantly reminds us that housework done badly still, in her words, “blesses” your household. In the same way, testing done badly still blesses your application. Any testing is better than no testing. Ugly, non-DRY, simple, non-idiomatic, inefficient tests are still tests, and they’re getting you closer to where you want to be, testing-wise.

With these principles in mind, I’ve finally been making progress on developing the TDD habit. Here’s my very own 12-step program for testing in rails. I sincerely hope it helps other fledgling Rails TDD programmers, and I’ll keep everyone posted on my progress.

1) Admit that without tests, you have no real idea of what your code does. You have no control over your code.

2) Forgive yourself for all the untested code that you’ve written in the past.

3) Open up any one of the generated test files in any one of your rails projects, and write a test. Just one. Do not write fixtures. Do not decide you really need to be using RSpec instead and get distracted downloading and playing around with it. Do not spend a lot of time reading other peoples’ clever testing strategies. Don’t even think about mocks or stubs. Just write a test. Start with unit tests, they’re easiest.

4) When you’re done writing the test, applaud yourself.

5) Now open up the terminal, cd to your project dir, and type “rake test”.

6) When the test is done running, applaud yourself.

7) Now make the test pass.

8) Again, applause.

9) Do the whole thing again. And again. And again. Don’t do it for more than 15 minutes at a time. Set a timer, write 15 minutes of awful, non-idiomatic, stinky, not DRY, trivial test code, and when the timer rings, ‘rake test’ and give yourself a cookie.

I’m only at step 9. I think steps 10, 11, and 12 will be:

10) After a long time, testing will start to feel more natural. You can take a few minutes to fiddle with fixtures, if you want. You can branch out into assertions you haven’t used before. Go crazy with assert_select. No, now is not the time to check out rspec, rbehave, or cruisecontrol. Just keep writing tests.

11) By now, you’ve started to write your tests before writing your code. You don’t have to look up assertions. You’ve developed opinions about how to organize your test code, and you know what really bugs you about test code, what you wish it could do differently, what trips you up and slows you down. Now, and only now, are you ready to look into the various testing plugins, tools, and alternate testing theories.

12) You are now a testing master. Spread the TDD gospel far and wide.

Popularity: 16% [?]

On tape, kids, and clients

Posted by amy on August 08, 2007

First, a parent hack. Got kids? You should be reading Parent Hacks. Not got kids? Read on anyway, I relate the whole thing to user requirements at the end.

The hack: As soon as your kid is old enough not to eat it, buy a multipack of store-brand magic tape. Provide your child with the tape, scissors, the contents of your recycle bin (purged of dangerous items), and a box of broken toys and other small household items. Now leave your kid alone with the stuff.

The most important part of the hack: do not ration the tape.


Ari loves tape. We used to ration it. We value conservation, and using up gobs and gobs of tape seemed useless, expensive, and just plain wasteful. We didn’t understand the things he did with it. They were incomprehensible and often ugly. He used too much of it. It all seemed pointless. Three things made us change our minds:

First, we realized that tape is so cheap it’s essentially free, even when used in quantity like Ari uses it. Ari can easily spend an hour on a taping project, without needing, wanting, or even acknowledging parental attention. A babysitter costs us at least $12/hour. So not rationing tape actually saves us money.

Second, we realized that the tape served the goal of conservation by enabling the transformation of, basically, garbage, into toys and games and arts and crafts. Yes, eventually the stuff did end up on the curb anyway, but it enjoyed a (sometimes very long) second life as a more-or-less elaborate Ari contraption.

Third, we realized that tape is a non-toxic, easy to clean up, and remarkably versatile project supply that allows both two- and three-dimensional constructions. Glue is also versatile, but much, much messier.

Finally, we realized that while the things Ari made with the tape seemed senseless to us, they were valuable, important, and even beautiful to him. This is often the case with our childrens’ projects. We’ve come to realize how often we say no to kids, just reflexively, for no other reason than that what they want doesn’t make any sense to us, the grownups. (“No, don’t use up all that tape. What do you need all that tape for? Why do you have to tape the giraffe to a stick and hang rubber bands off him? What’s so important about putting those toy people in a cardboard-reinforced tape shell and carrying them around in an old purse? What the hell for???”)

When we find ourselves saying no, we stop and ask if there’s really a good reason for the ‘no’. We try to say yes, when we can. And so, we say yes to as much tape as he wants, whenever he wants.

What this has to do with clients:

Clients, like kids, often want, do, and care about things we don’t understand. It’s our job to try to understand them, and it’s difficult, exhausting work. It’s much, much easier to dismiss them. “No, what do you want to be able to download spreadsheets for? Who cares about what color that dumb little button is? That’s a ridiculous process anyway, why should I make the software conform to it?”

We want to build software that we care about, and that we understand. But that’s not our job. Our job is to help our clients do what is important for them.

“How can you compare clients to kids?” you may ask. “What kind of whupped parent are you that you treat your kids like they’re your clients?” or conversely “Isn’t it a little insulting to treat your clients like they’re children?” I’m not arguing for not setting limits for your children. I’m arguing for respecting them as people whose values we do not always understand, just as we respect our clients as people whose values we do not always understand. (Software development is just like anthropology, only better paid, I’ve always said.) We have broad and deep expertise in many areas that our kids don’t, and in order to help them do what is important for them, we’ll have to draw on that. But the same goes for clients. We don’t let our kids go without brushing their teeth, even though it’s not important to them, because we understand that toothbrushing is part of the infrastructure of living. We don’t let our clients’ projects go without version control, even though they don’t care about version control, because version control is part of the infrastructure of software development. We should not be slavishly trying to meet our clients’ every needs any more than we should do that with our kids, and even when our kids are at their most infuriating and most incomprehensible, we should remember that to them, the things they care about are every bit as important as the things we care about are to us.

We’re not the boss of our kids, and we’re not the slaves of our clients. We’re just the consultants.

Popularity: 12% [?]

10 things you should know about method_missing

Posted by amy on August 01, 2007

[update, 9:27 a.m., 8/1/2007: welcome, reddit readers. annoyed at me for calling this post "10 things"? Well, then you'll really hate me after reading this post!]

1. method_missing is a Ruby kernel method and everyone should know about it.

2. Rails implements some of its funkiest magic with method_missing. When you ask your model to find_by_freaky_column_name, and it does so, that’s because ActiveRecord::Base overrides the kernel’s method_missing method.

3. method_missing is the method of last resort. When you send a message to a Ruby object, Ruby looks for a method to invoke with the same name as the message you sent. (There are a bunch of different ways to send the message, but the most common one is just obj.method_name. But you can make the fact that you are sending a message explicit by using obj.send(:method_name)). First it looks in the current self object’s own instance methods. Then it looks in the list of instance methods that all objects of that class share, and then in each of the included modules of that class, in reverse order of inclusion. Then it looks in that class’s superclass, and then in the superclass’s included modules, all the way up until it reaches the class Object. If it still can’t find a method, the very last place it looks is in the Kernel module, included in the class Object. And there, if it comes up short, it calls method_missingYou can override method_missing anywhere along that method lookup path, and tell Ruby what to do when it can’t find a method.

4. Sometimes people use method_missing to implement some default behavior they want to occur; more often they seem to use it as a kind of method factory or dispatcher. They have a class or module that they want to have many methods that do generally the same kinds of things, they’re not sure in advance which methods people will actually want to call, or there are so many of them, and they’re all so similar, that it seems like a waste to implement them all by hand. So they just say, okay, if someone gives me a method that doesn’t exist, I’ll assume that they’re trying to do this general kind of thing, and I’ll make them a method based on their name that does the thing they probably want it to do.Sometimes they make a new method and add it to the class (factory); sometimes they just do what needs to be done in method_missing itself (dispatcher).

5. Basically, method_missing is one of the features of Ruby that make it remarkably easy to create your own DSL for fun and profit. DSLs are Domain Specific Languages, which, if you didn’t know — and of course, dear reader, you did, because you are oh-so-up on all the oh-so-fashionable programming paradigms, are the big thing that Martin Fowler is talking about a lot these days.

6. Here’s the kernel’s method_missing implementation. It’s in C, so I have no freakin’ clue what it’s doing, but I know what the result is: a NoMethod error:

irb(main):227:0> "thingy".invoke_method_missing_for_demo_purposes("arg", "other arg")
NoMethodError: undefined method `invoke_method_missing_for_demo_purposes' for "thingy":String from (irb):227

7. Now here’s Jamis Buck showing us how ActiveRecord::Base overrides method_missing. It’s a long but fascinating article that takes you step-by-step through some Rails source code. Go look at it now.

8. method_missing is said to be slower than calling an actually-already existing method, unsurprisingly, given that it’s by definition invoked only after Ruby’s looked everywhere else for your method. The speed issue may or may not matter for your intended use, and my impression is that it usually doesn’t. #{usual disclaimer about benchmarking, using profilers, and not prematurely optimizing your code.}

9. method_missing can also be a bit opaque to users of your code, since dynamically created methods are, of course, not documented in the API.

10. The use of method_missing falls under the general technique of metaprogramming, which is a big deal in Ruby, and not something ordinary folks ever fool around with in many other languages (like Java). At least, I never fooled around with it in Java. But hey, what do I know? What is metaprogramming? C’mon, people, it’s right up there with DSLs in the list of things the kewl kids know. But actually, it really is pretty cool, and it really is pretty much the way Ruby works. And it’s not as difficult as (but waaaay more useful than) say, Lacan, despite the poststructuralist-sounding name and the fact that the metaprogramming wikipedia article makes it sound very fancy.

Ignore the wikipedia article, listen to _why, in a discussion of method_missing: “I don’t think the idea here is to save memory or speed. The idea behind metaprogramming is to teach Ruby your conventions and let it do some guessing, in order to save you some code.”

Don’t trust that _why and all his chunky bacon? Here’s David Black, equally reassuring:

One of the great accomplishments of Ruby is that its object and class model bring about a wonderful unity and simplicity. Even things that might seem like they should be hard or obscure are actually very transparent, once you have the hang of how the model works.Unfortunately, there’s a trend toward drawing an increasingly sharp line between regular programming and “metaprogramming” in Ruby discussions, where metaprogramming is understood to mean… well, I’m not sure what it’s understood to mean, the way it’s getting used in connection with Ruby, and that’s the problem.There’s no natural separation between programming and metaprogramming in Ruby, and no reason to make life harder by breaking them apart. The thrust of Ruby’s design is to dissolve complexities, so that even things that appear to be “wizardly” or full of “dark magic” actually make perfect sense in terms of a relative small number of underlying language principles.

So here’s your takeaway #{max gagging sound}: method_missing is cool. It’s metaprogramming. It’s used to save programmer time and typing, and to make DSLs or provide default behavior. Most famously in ActiveRecord dynamic finders. Metaprogramming is not scary, and method_missing, like other cool Ruby features, may or may not float your boat. That’s cool, either way.

_why says: “I never use method_missing. Maybe twice. And both times I didn’t use it, regretted it, forcefully ejected the code from a moving vehicle, shed nary a tear.” Then he goes on to enumerate some of the very cool ways he’s seen method_missing used elsewhere, in non-_why code.

So: know it, love it, use it, hate it, kill it, eat it, break it, think it. As they say at Ari’s preschool: “Have fun, be safe, and USE YOUR IMAGINATION!” Matz wants you to.

Popularity: 59% [?]