Stupid Job Postings: “step up” and “Non-benefited” edition

Posted by amy on August 29, 2007

Oh, come on now, people:

You are a creative thinker that communicates effectively and possesses the individual leadership and accountability to “step up” and deliver high quality results in a fast paced environment while maintaining focus and a sense of humor.

I also saw a job posting with the headline “Web Designer/Developer – Full-time Non-Benefited Position”. Isn’t that called a ‘contractor’? Though I suppose that a lot of contractor work is really just being a full-time employee without benefits or unemployment insurance, you’d think that the company that’s searching for such would make it sound slightly more attractive. Especially since there is theoretically supposed to be a distinct difference between 1099 consulting work and employee work, tax-wise.

In other stupid job postings news, here’s a good discussion on what makes a _decent_ job posting, from a Thoughtworks guy in India, Sidu Ponnappa. In particular, he notes the difference between a job asking for people who are passionate about Ruby, for example, and one looking for people who are passionate in general. (I still think passion is overrated, though. Except where cheese is concerned. I am passionate about cheese. For example, this Vermont Brie is really fantastic. If only someone would make a truly artisan domestic parm…! But I digress…) Anyway, he suggests that one rank postings by the number of requirements in them that were clearly written by an HR person or someone else with no idea of what the job actually entails.The more HR speak, the lower the job posting ranking. I think someone needs to write a flog for job postings.

Popularity: 22% [?]

Annals of Idiotic Bugs

Posted by amy on August 21, 2007

I’ve decided I like bugs. Not in production code, of course, but in development code, yay for bugs. Fixing my code teaches me far more than writing it did. Perhaps that’s because, with example code and snippets and tutorials all over the internet, much of the code that I write I don’t really write. I copy something I saw from something else and modify it to suit my own needs, or I look it up in a recipe book, or I see someone else’s solution on a mailing list… When you’re new to a language, you often use code that you don’t quite understand. I’m curious, so I try to understand it, but I don’t always have the time.

But then you get the bugs. And to fix the bug, you have to understand the code. (no, I know, that’s not really true. you can fiddle around with bug fixes just like regular code, and find someone else’s fix and implement it and it works and you’re in a hurry so you don’t care why it works, just that it does…)

Anyway, most normal developer bugs are stupid. I suppose there are great developers out there whose bugs are subtle and interesting. Most of mine, anyway, are quite stupid.

Here are some of my stupid bugs:

1) Implemented a slideshow. Stored stuff in the session to use during the slideshow. At end of slideshow, remembered to clear the slideshow stuff out of the session. Yay for me! Oops, child calling, check in code!

Max: “Um, Amy, how come playing a slideshow deletes all the photos in the slideshow?”

Me: “Dunno, maybe it has something to do with clearing the session? Why would deleting a thing from a session destroy it?”

Here’s what I had to clear the slideshow out of the session:
session[:slideshow].clear

Here’s what I should have had:
session[:slideshow] = nil

Oh, and here’s what was in the slideshow:
slideshow = domain_object.photos

So it’s not like my slideshow was just an array of any old ActiveRecord objects. It was a particular other ActiveRecord object’s personal array: i.e., an ActiveRecord AssociationCollection. AssociationCollections have a method called clear. Clear removes all the objects from the collection, like delete_all. Except delete_all doesn’t, according to the doc, destroy records, it just deletes them. And assoc_collect_.clear definitely destroys them, because not only did calling it kill the database records for my photos, it also killed the actual photos on the filesystem. So are clear and destroy_all the same thing? The doc is thin, so I went to the source:

# File vendor/rails/activerecord/lib/active_record/associations/association_collection.rb, line 67
67:       def clear
68:         return self if length.zero? # forces load_target if hasn't happened already
69:
70:         if @reflection.options[:dependent] && @reflection.options[:dependent] == :delete_all
71:           destroy_all
72:         else
73:           delete_all
74:         end
75:
76:         self
77:       end

So, domain_object.association_collection.clear does to the collection what domain_object.destroy would do, which is either to delete or destroy the associated records depending on what options you set in your call to has_many:

:dependent – if set to :destroy all the associated objects are destroyed alongside this object by calling their destroy method. If set to :delete_all all associated objects are deleted without calling their destroy method. If set to :nullify all associated objects’ foreign keys are set to NULL without calling their save callbacks.

I’d set :dependent => :destroy_all, so that’s what calling clear did. Oopsie!

Why did I use .clear anyway? Apparently I was thinking of my rake task rake db:sessions:clear.

In any case I didn’t want to be storing whole photo objects in my session anyway. I just wanted IDs: session[:slideshow] = domain_object.photos.collect { |p| p.id }

2) Wrote some boilerplate code for a create action. On failed validation, Rails complains there’s no create template to render. Why are you trying to render a create template, Rails, when I clearly ask you to render new upon failed validations:

render :action => new

Uh, because I told rails to render :action => nil. So rails defaulted to its standard "render the template whose name is the same as the action invoked" and went looking for a create template. What I needed to be saying was:

render :action => 'new'

Problem fixed. That one took me way too long to track down. I wish Ruby would complain to me about things that look like local variables but don’t seem to have any values attached to them. I’m not quite used to bug fixing a dynamic language, without the crutch of the compiler.

Right, what else?

3) If I want, temporarily, a list of all the photos in both a & b, where a & b are two different ActiveRecord objects, I should not do the following to get the list:

list = a.photos << b.photos

This moves all the photos in b over to a, permanently, in the database. This is one of the pitfalls of the syntactic sugar of methods that look like plain old operators. They’re not, really. ActiveRecord sometimes does more stuff than you want or expect it to, behind the scenes. Not a save or update in that code to warn me that I’m calling the db, but I am.

4) Oh, and the stupidest thing of all:


if  x = y
	#do stuff
else
	# do some other stuff
end

How come the ‘other stuff’ is never getting done!??
Duh, because X will always equal y if you assign it to y instead of checking to see if it == y!

Conclusion

This concludes the first edition of: Amy reports dumb things she did in Ruby code so you don’t have to do them too. C’mon, be original, and come up with your own bugs! I do not release my bugs under a Creative Commons license. I want royalties on all software including these particular bugs. I am going to implement DRM on these bugs. Don’t you dare steal my buggy code! It’s mine, mine, all mine!

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: 17% [?]

Stupid Job Postings: dream much? edition

Posted by amy on August 13, 2007

“Technically gifted and passionate RoR engineer wanted for one month”

As per policy, I won’t link to the offender. But what are the chances you will find a gifted and passionate engineer available RIGHT THIS SECOND to work a few hours a week for a month, at $50/hour, total payment capped at $2500?

I don’t like this whole job posting obsession with “passion,” anyway. It seems a bit much to demand not merely competence, productivity, honesty, attention to detail, professionalism, and time from employees/contractors, but also passion. It’s a bizarre conceit, I think, somewhat akin to the invention of romantic love in marriage. It’s an attempt to paper over an economic transaction under the guise of emotional attachment. It’s not enough for workers to give our time, our energy, our thoughts, and our creativity to our work — we must also give our very selves, the part of us that is able to feel passion.

I resent this attempt to colonize my emotional landscape. I don’t blame individual job-posters, of course; they’re just using the job-listing language of the day, and not thinking very much about what, actually, it means. Perhaps only freakish people who spent too much time reading cultural studies in college stop to think about the meaning of the current vogue for demanding passionate employees.

Is there evidence I haven’t seen that passionate employees are better employees? Passion does not necessarily improve one’s personal life; I don’t know why it would necessarily improve one’s professional life. On the contrary, passion would seem to most often be a disability at work. It clouds reason and judgment. It encourages overexertion followed by disappointment and ennui. It contributes to misunderstanding and strife, shortens tempers, and fosters unrealistic expectations.

Perhaps I’m just being pedantic, and what the job-listers really mean is “looking for someone who likes their work” but they must use “passionate” because of rampant adjective inflation. I think it’s perfectly reasonable to want to hire people who like to do the job. But that’s not the kind of information you’ll glean until you talk with someone anyway, so there doesn’t seem to be any point in putting it as a requirement on a job listing.

I see “passionate engineer wanted” and think “unrealistic and possibly abusive employer/client”. My passion is not your business, people. Ask me to be professional, mature, conscientious, skilled, creative, honest, efficient, knowledgeable, curious, persistent, thoughtful, and engaged — I can be all these things. But don’t ask me to be passionate. It’s not a love affair, it’s a job.

Popularity: 33% [?]

Textmate File Open tip: type a forward slash, get an open path box

Posted by amy on August 10, 2007

Yesterday I discovered, entirely by accident, that when you’ve got an Open File window in Textmate, hitting the forward slash / does precisely what you’d like it to do: drops down a box that allows you to type the path to the file to open, complete with tab completion, as in a command prompt.

I’m sure everyone in the world already knew this, but I’m still pretty new to Textmate, and even though I have the excellent Textmate book, there are only so many tips and shortcuts your brain can pick up at once.

It turns out that ordinary Finder windows also have a shortcut to get a path text entry box, but it’s not nearly as intuitive ( command-shift-G) as a simple /, and the tab completion is not as nice, because it tries to discourage you from getting into the guts of your computer. For example, in Textmate, if you type /u – tab, it gives you /usr; in the Finder, it tries to give you /Users . I understand that this makes sense for the average Finder user, but it’s still oddly disorienting.

Through the wonders of google, I just found out that there’s a way to make your Finder stop hiding root:

As you know, the Finder hides the standard Unix files and folders from you. You can “Go To Folder…” and type in the name of the folder such as /var/log, but that’s fiddly and you still don’t see the “dot” files, so for any serious session, it’s probably easier to drop into Terminal. Except, there’s a terminal command that will make all files and folders display in your Finder. defaults write com.apple.finder AppleShowAllFiles -bool true et voila

This works, I’ve tried it, but then I put it back the way it was because I decided I really didn’t want my dad mucking around in root while he’s checking his email. (Sorry, Dad.)

It’s easy to forget that the windowing system is just a windowing system — it’s not the OS. And that Finder is just an application. And that even the command prompt, which I am comfortable enough in (but not like Max, who is really one of the best commandline geeks I’ve ever known) is just a shell. Abstractions on top of abstractions, and all of them leaky…

Popularity: 11% [?]

On satisfying clients

Posted by max on August 09, 2007

Our next-youngest client, Ari (4), executed this project without our assistance. It worked out magnificently. Take two glossy magazine pages, a bunch of tape, and wrap pages around feet. Apply tape. Voilà: Magazine slippers / goblin shoes / “skates”.

Ari in his magazine skates

This is one reason not to ration tape.

Popularity: 11% [?]

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.

Discussion

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: 13% [?]

Choking on all the attention! And, Career Advice from Cary Tennis

Posted by amy on August 05, 2007

So we got some really nice links this week, and with the links, a bunch of click-throughs. And some wonderful comments, all of which we deeply appreciate. And now of course, I’m choking . I have about 20 posts in various states of readiness, from “just an idea” to “nearly done but I suddenly think it sucks and wasn’t a good idea for a post in the first place”, but nothing ready to go.

Oh wait, here’s something to keep you from dumping us off your feedreader (or dumping us faster, who knows?!). A snippet of a column by Cary Tennis, Salon’s advice columnist , responding to someone who can’t decide whether to give up a career opportunity for his girlfriend, whom he loves passionately:

You say one cannot calculate the value of a job or a relationship, but I do not think that is true. I think one must calculate it. Courts are called upon to do so. Moreover, intuitively we do it anyway. For instance, suppose that you and she settle down and have a good relationship and good jobs. Say that one day a supernatural being comes to the door and says that you must give up either the job or the relationship. Which would you choose? Which would you consider expendable? Which would you consider replaceable?

While in science many problems are difficult because they are complex, in life many problems are difficult because they are simple, but we are human and we want everything. While in the conduct of science we would never suspend physical laws to get the result we seek, in life we try that all the time: Can one person be in two places at the same time? Well, people say no, but maybe in this case … I don’t know … if I accumulate enough free miles maybe I could fly from Toronto to Oakland enough times that I could appear to be in two places at once …

I don’t think so.

If you’re reading this blog and wondering why Max and I have this crazy idea that we’ll somehow each work part-time, or consult together, or work out of the house, or do something weird and web-worker-daily-ish, and we don’t want to travel much for work and we don’t want long commutes and we don’t want to be these people, toiling away in the “Silicon Valley salt mines” — that’s why: We’ve got one life to live here, people, and we can’t be in two places at once.

Popularity: 14% [?]

10 things I didn’t know about Reddit

Posted by amy on August 02, 2007

So I woke up this morning and saw that 7 people had saved my method_missing post to delicious. How can this be? I wondered. Who even reads this blog? We checked our stats and saw a bunch of pageviews, because someone linked to us from Reddit (No, we didn’t submit ourselves. We have two small children, here, people, we don’t have time to go around flogging our blog under pseudonyms. We barely have time to flog … never mind). Anyway, then someone else commented, quite correctly :

This isn’t “10 things you should know”. It’s ten paragraphs, each assigned a number for no reason other than the fact that “X things…” lists are better reddit/digg-bait.

It’s funny, because I had a whole paragraph in the original draft about precisely that. I went back and forth about calling the post 10 things, and I went back and forth about numbering the things, and I dithered about the numbering, and the post took me three hours to write and I had other things to do, so I finally decided that the paragraph about whether to call the post “10 things…” was gratuitous meta-blogging, took it out, and left the numbers in.

I’ve never written a 10-things post before. I’m not a ‘pro-blogger’. I do sometimes read posts like ’10 tips to publicize your blog’ though, because I need money, and therefore I need work, and so one way I can try to drum up Ruby on Rails work is to try to contribute to the community in some useful way, and if you’re going to contribute it helps if people are reading you, at least a teeny bit. Etc. So what the hell, I thought, I’ve been meaning to write about method_missing for a while, I’ll see if I can do it in a 10 things format.

So I wrote out all my thoughts about method_missing, and it looked nothing like 10 things. I reorganized it to make the major points more obvious. I took out some stuff that didn’t belong. I revised. Still more of a meander than a 10 things. More revising. Better structure, but not 10 unrelated things; more like 10 points, each leading to one another. (Hmm, an essay. But the internets don’t like essays! ) Okay, I did my best, I thought, time for bed.

And then I wake up and there we are on reddit, with the harsh light of a tiny amount of publicity showing me up as an obnoxious blogging publicity-hound.

Oh well. 7 people thought the post was interesting and useful enough to save to delicious, so that’s something.

And no, I don’t really have a list of 10 things I didn’t know about Reddit. Just one: I had no idea how successful a tactic it was to call something “10 things…”. Beyond my wildest dreams. Though I don’t think I’ll be doing it again anytime soon. Go ahead, reddit readers, flame away!!

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: 58% [?]