My new Ruby book is out!
June 10th, 2009
I’m realizing that the new book isn’t getting enough buzz, so here’s some buzz!
My new book, The Well-Grounded Rubyist, is now out and available from the publisher as well as Amazon and other retailers and stores.
If you’re learning Ruby, or want to learn Ruby, or want to refresh your Ruby knowledge and get more deeply into it…read this book!
I talk more about the book in my recent interviews for InfoQ, On Ruby, and RubyLearning.
Some reviews and comments
Here are some review quotations, from various sources:
I think this book is a definite read and should be in every Ruby developer’s library....
Excellent. Easy to read, but not dumbed down. I came away with a much deeper understanding of WHY oop is used, and how to use it in ruby....
If you are looking to understand ruby, look no further.
David does an excellent job going beyond the language and hitting those concepts in the built-in classes and modules that you need to know and will experience in the real-world.
You can also find complete reviews here and here.
(And don’t get confused if some sites have a different-looking cover. There were two cover designs. The new one is the one you see here.)
Enjoy!
"The Well-Grounded Rubyist" now available in PDF!
April 21st, 2009
It’s been a busy few days, with the release of not my Ruby 1.9 Envycasts but also the PDF version of my new book The Well-Grounded Rubyist.
TWGR is an expanded, updated, Ruby-only reworking of my 2006 book “Ruby for Rails”. It targets Ruby 1.9.1, and includes a great deal of new material (enough that it took me almost a year longer than I thought it would to write :-) The book is entirely about the Ruby language, not Rails. Lots of readers of R4R encouraged me to write a “just-Ruby” book, and here it is!
I’m looking forward to the release of the paper version on May 1, too. Not sure yet whether there are Kindle and/or Sony e-reader versions coming, but I’ll keep you posted.
Is this an early use of the slang "cool"?
March 20th, 2009
Here’s a passage from The Man in Lower Ten by Mary Roberts Rinehart, published in 1906. I’ve included some context but the main thing I’m interested in is the appearance of the word “cool” in the second paragraph.
“Nonsense,” he said. “Bring yourself. The lady that keeps my boarding-house is calling to me to insist. You remember Dorothy, don’t you, Dorothy Browne? She says unless you have lost your figure you can wear my clothes all right. All you need here is a bathing suit for daytime and a dinner coat for evening.”
“It sounds cool,” I temporized. “If you are sure I won’t put you out—very well, Sam, since you and your wife are good enough. I have a couple of days free. Give my love to Dorothy until I can do it myself.”
I can’t see what “cool” means in the second paragraph, other than “cool” in the slang sense that we use it. My understanding is that “cool” in that sense started, or at least came into common usage, during or after World War II. In any case, 1906 seems insanely early for it.
But what else could it mean in the quotation above? The wardrobe described in the first paragraph doesn’t suggest a particularly cool climate. Is there some other nuance of the word I’m not getting?
I shall leave comments open on this one, at least until the spam gets intolerable.
Did I mention Ruby training in Atlanta, April 1-3?
March 14th, 2009
The answer is…yes! I did mention it. But I’ll mention it again.
Want to learn Ruby, and learn it right?
Come to Atlanta for three days and learn Ruby from:
- me (author of Ruby for Rails, The Well-Grounded Rubyist, and other stuff; long-time Ruby programmer; one of the most experienced Ruby trainers on the planet)
- Jeremy McAnally (“mrneighborly”, author of Ruby in Practice, creator of the Ruby Hoedown (annual conference))
- Rick Olson (“technoweenie”, member of the Rails core team; plugin writer extraordinaire)
You gotta better way to learn Ruby?
I doubt it. Just read that list of instructors again… and you get training materials, a book (“Ruby in Practice”), and lunches.
There’s registration info here, and you can contact me directly with any questions.
Hope to see you there!
P.S. If you’re a Ruby expert but have friends or co-workers or employees who could use an accelerated intro/intermediate course, send them along!
Ruby training in Atlanta, April 1-3!
February 16th, 2009
Want to learn Ruby, or improve what you already know? Come to Atlanta!
Ruby Power and Light and ENTP are teaming up to present a three-day Ruby course in Atlanta. You can get more info, and register, here.
Training will be by me and Ruby developer/author Jeremy McAnally (“mrneighborly”). And Rick Olson (“technoweenie”) will be there too, helping with the training and sagely dispensing Ruby wisdom and advice. (Seriously!) It will be at the Georgia Tech Hotel & Conference Center.
Please email me if you have any questions. Otherwise, see you there!
Why athletes thanking God for victories is stupid
February 2nd, 2009
I hate it when athletes thank God when they win. My reasons for hating it have nothing to do with my own atheism. I hate it because it’s narcissistic and because it’s theologically infantile.
If you win a game and then thank God, and do not thank God when you lose, you are going on record as believing that God wanted you to win, and that a victory by your opponent would have represented a thwarting of God’s plan.
But how do you know? Isn’t it possible that losing is what God has planned for you, and that it will do you good? Maybe losing will strengthen your character. Maybe your opponent needs the win (or the prize money) more than you do, and God somehow managed to figure that out in spite of being dazzled by your greatness. Maybe you should be thanking God for protecting you from the sin of pride by not letting you win a spiritually meaningless, entirely earthly contest.
But I’ve never seen an athlete drop to his or her knees and thank God after a loss. Why not? Because the ones who thank God when they win have a dinky, anthropomorphic conception of God. Their God is “the man upstairs,” the Santa Claus figure, the parent who may or may not give them the birthday present they want. And to hell with the other kids. Me, Me, Me.
So what gives? Where does this all come from? Whose big idea was it to thank God only for bringing about what they themselves wanted to happen anyway?
Let’s go back to ancient times. Things were different with respect to thanking gods, because there were lots of gods and the gods took sides in the contest. It made sense for the Greeks to thank Athena for the victory over the Trojans because Athena was, at some Olympian level, duking it out with Ares and Aphrodite. The Greeks’ powerful friends prevailed over the Trojans’ powerful friends. And the Greeks understood that someone had actually made an effort on their behalf, faced uncertainty, and prevailed. So they thanked her.
Dear athlete: Do you think that God faces uncertainty when you play a tennis match?
Do you think that God has to make an effort on your behalf to make sure you win?
Do you think that God’s enemy is rooting for your opponent?
And if you don’t think all that, what exactly are you thanking God for when you win? I mean exactly. Not just vaguely that you’re happy, and happiness feels good, so it must come from God. That’s theological babytalk.
The best thing that can be said about thanking God for an athletic victory and not for a loss is that it’s an ignorant corruption of what was a perfectly reasonable pagan practice. If you’re a monotheist and thank God for a win, you’re making a statement about your own inherent worth, and what you believe is God’s opinion of that worth, in comparison to the inherent worth of your opponent. You’re asserting that your victory is of the Lord to an extent that a victory by your opponent would not have been. And you’re implying unmistakeably that your opponent is in league with God’s enemy.
In other words, thanking God for an athletic victory is stupid, uninformed, thoughtless, self-absorbed, and about as far from anything religious or spiritual as you can get. I understand the whole thing about religion not being the same as rational thought. But this isn’t even the same as religious thought. It’s just vanity.
RailsConf registration (and a hiatus year for RailsConf Europe)
January 23rd, 2009
Registration is now open for RailsConf 2009 (May 4-7). You can get more details, and register, at the RailsConf 2009 website.
RailsConf is taking place in Las Vegas, one of my favorite cities. Yes, I know what a weird and ironic place it is. But for whatever reason, I’ve always found it extremely enjoyable. May is a good time to go—hopefully not to hot to step outside!
There’s a lot going on at RailsConf this year, highlighted by its timing in the wake of the Rails/Merb merger decision. There will be lots of merger news and highlights, along with the usual great lineup of talks and, above all, the chance to meet and get to know other Rails developers as well as Rails core team members, authors, bloggers, and pretty much the whole gang!
A hiatus year for RailsConf Europe
Ruby Central and O’Reilly have decided to take a hiatus from producing RailsConf Europe this year, for the simple reason that it didn’t bring in enough revenue last year to justify doing it again, particularly given the tight economy and the need to err on the side of caution. RailsConf Europe has always been a really great event, and people who go to it really love it, but we need a year of retrenchment while we figure out how to get everyone else to realize how great it is! Plans for 2010 are not certain yet; we’re taking it one year at a time.
Meanwhile, the Ruby and Rails communities continue to produce an astonishing number of high-quality, uniquely branded and flavored events. I’m not even going to try to list them all here. Do a search, though, and you may very well find one near you.
Son of 10 things to be aware of in Ruby 1.9!
January 16th, 2009
I’m happy to see that my recent 10 things to be aware of in moving to Ruby 19 article has proven helpful to lots of people. This article is a follow-up.
The goal of the article was to point out 1.9 features and changes that might cause your existing code not to run correctly, or not to run at all. I went a bit soft, though: two of the original ten (hashes being ordered and the changes in method-argument syntax) weren’t really things that might break your 1.8 code.
So I feel I owe the world two more code-breaking 1.9 features! And they’re here, along with a bonus one.
But first, some links
The denizens of ruby-talk have provided lots of helpful ideas and feedback. James Edward Gray II and others mentioned M17N, a topic on which I defer to the more expert among us, especially James who has written a multi-part M17N guide. He’s going to be expanding it to include 1.9 encoding, so keep an eye on it.
Brian Candler suggested that people might be interested in the presentation by me and Dave Thomas at RubyConf 2008 on Ruby 1.9: What to Expect. We cover some pitfalls but also some new, non-pitfall features you might want to know about.
If you’re interested in Ruby 1.9 generally, you might be interested in my forthcoming book The Well-Grounded Rubyist, which is a fully revised, revamped, “Ruby only” second incarnation of my 2006 book Ruby for Rails.
Apologies to anyone I’ve failed to credit, and thanks to all for the feedback.
And with that, here are the pitfalls! (Speaking of pitfalls, I think I’ve remembered all the <pre> tags this time….)
String indexing behavior has changed
(Thanks to Michael Fellinger and Robert Dober)
In Ruby 1.8, indexing strings with [], as in "string"[3], gives
you an ASCII code:
>> "string"[3] => 105
In order to get a one-character-long substring, you have to provide a length:
>> "string"[3,1] => "i"
In Ruby 1.9, the indexing operation gives you a character.
>> "string"[3] => "i"
Also, kind of along the same lines, the ?-notation now gives a character rather than a code. In 1.8:
>> ?a => 97
and in 1.9:
>> ?a => "a"
if-conditions can no longer end with a colon
In 1.8 you can do this:
if x:
puts "Yes!"
end
In 1.9, you can’t use that colon any more. The same is true of when clauses in case statements. This will not parse in 1.9:
case x when 1: "yes!" end
Bonus thing! No more default to_a
In 1.9 you cannot assume that every object has a to_a method.
You’ve probably seen warnings about this in 1.8, and the day of
reckoning has now arrived.
>> "abc".to_a NoMethodError: undefined method `to_a' for "abc":String
You can use the Array method to turn anything into an array. If it’s
an array already, it returns the object itself (not a copy). If it’s
anything else, it tries to run to_ary and to_a on it (in that order),
and if those aren’t available, it just wraps it in an array.
Array isn’t new, but we’re likely to be using it a lot more
now that there’s no default to_a operation.
Have fun!
10 things to be aware of in moving to Ruby 1.9
January 14th, 2009
Update: There’s a sequel to this post, called Son of 10 things…
I’ve been writing a lot about Ruby 1.9 (my book The Well-Grounded Rubyist is due out in a couple of months), and I thought I’d share my personal list of things you need to be careful of as you go from 1.8 to 1.9. This is not a list of changes; it’s a list of changes that you really need to know about to get your 1.8 code to work in 1.9, things that have a relatively high likelihood of biting you if you don’t know about them.
Strings are no longer enumerable
You can’t do string.each and friends any more. This has an impact, for
example, on the Rack interface, where there has in the past been a requirement
that the third item in the returned array respond to each.
Block argument semantics
This is a big change, and a big topic. The salient point is that when you do this:
array.each {|x| ... }
the block parameter list is handled like a method parameter list. In 1.8, blocks
use assignment semantics, so that @ is like @x=. That’s why in 1.8 you can do:
array.each {|@x| ... }
(assign to an instance variable) or even:
array.each {|self.attr| ... }
(call the attr= method on self). You can’t do those things in 1.9; the parameters are bound
to the arguments using method-argument semantics, not assignment semantics.
Block variables scope
Block parameters are local to the block.
x = 1
[2,3].each {|x| }
In 1.8, x would now be 3 (outside the block). In 1.9 the two x’s are not the
same variable, so the original x is still 1.
However, a variable that (a) already exists, and (b) is not a block parameter, is not local to the block.
x = 1
[2,3].each {|y| x = y }
x is now 3. If you want or need to shield your existing variables from being
used inside the block, declare variables as block local by putting them after a
semi-colon in the parameter list:
x = 1
[2,3].each {|y;x| x = y }
x is still 1.
Method argument semantics
Method arguments do some new things too. In particular, you can now put required arguments after the optional argument glob parameter:
def my_meth(a,*b,c)
There aren’t too many situations where you’d want to do this (though there are one or two).
The * operator has changed semantics
Compare 1.8:>> a = [1,2] => [1, 2] >> *b = a => [[1, 2]] >> b => [[1, 2]]
and 1.9:
>> a = [1,2] => [1, 2] >> *b = a => [1, 2] >> b => [1, 2]
I’ve always interpreted the * operator in the following way:
The expression *x represents the contents of the array x, as a
list.
In 1.8, *b = [1,2] means that [1,2] is the contents of the array b, which
means that b is [[1,2]]. The 1.9 semantics don’t seem to behave that way. I’m
not sure what the new general rule for * is, or whether maybe I was wrong that
there was such a rule that governed all cases (though I can’t think of an
exception).
Hashes are ordered
This isn’t likely to bite you but it’s something to be aware of, both in your own code and in looking at the code of others. Hashes are ordered by insertion order. Reassigning to a key does not change the insertion placement of that key.
method and friends return symbols
Expressions like obj.methods and klass.instance_methods return symbols instead
of strings in 1.9. That means that you might have to do to_s operations on them,
if you need them as strings. However…
Symbols are string-like
... symbols have become very string-like. You can match them against regular
expressions, run methods like #upcase and #swapcase on them, and ask them their
size (i.e., their size in characters). I’m not sure what the purpose of this is. I’d just as soon
have symbols not be any more string-like than they absolutely have to be.
Gems are automatically in the load path
When you start Ruby (or irb), your load path ($:) will include the necessary
directories for all the gems on your system. That means you can just require
things, without having to require rubygems first. You can manipulate the load
path per gem version with the gem method.
Lots of enumerable methods return enumerators
Called without a block, most enumerable methods now return an enumerator. It’s
fairly unusual to use the return value of blockless calls to map, select, and
others, but it’s worth knowing that now you cannot assume that, for example,
Array#each will always return its receiver.
You can use this feature to chain enumerators, though the circumstances in which chaining enumerators really buys you anything are pretty few. I don’t know of a case where you would do this:
array.map.other_method { ... }
with the exception of map.with_index. The map call is essentially a pass-through
filter here. (This was not true in early versions of 1.9, where you could attach
knowledge of a block to a chained enumerator, but that behavior was removed.)
Incidentally, you win the prize (which is endless glory :-) if you can account for the difference between these two snippets:
>> {1 => 2}.select {|x,y| x }
=> {1=>2}
>> {1 => 2}.select.select {|x,y| x }
=> [[1, 2]]
It’s all about enumerators….
If you’re careful about these changes, and keep an eye out for others, you should be able to continue to have fun with Ruby in version 1.9 and beyond!
Cool wishlist management at WishSight!
December 29th, 2008
Announcing the opening of WishSight!
WishSight is for managing wishlists and gift-giving. It lets you see who’s given (or promised) what to whom, and it lets gift-givers for particular people communicate with each other, via a comment-board, so that they don’t duplicate gifts.
It’s based on a Christmas-list application I wrote in 2005 that my family and friends have been using every year since then. It’s completely merchant-unaffiliated. You can post links for the gifts you want, and they can be links to any merchant.
WishSight helps you cut down on gift duplication, and increases the chances that people will get things they actually want, without the gift-givers having to do a round-robin of email or phone calls to pin down who’s buying what. And chances are they don’t all know each other anyway—which doesn’t matter on WishSight, because you all communicate by leaving comments directly on your mutual friend’s wishlist.
All you have to do is:
- sign up
- list the email addresses of people who you want to be able to see your wishlist
- get those people to sign up and “whitelist” your email address
- list your wishes
- stake “claims” on other people’s wishes
There’s no stealth: the email addresses are only used internally to determine who’s allowed to see whose wishlist. Also, you can list email addresses even if the people haven’t signed up yet. Once they do sign up, they will automatically have permission to see your wishlist and claim your wishes. No two-sided “handshakes” required; you just whitelist people.
Have fun, and let me know if any questions or problems!
On the menu this season: Muslims and gays
December 21st, 2008
Don’t get me wrong. I’m not saying that other forms of hate and prejudice are extinct, or even on the wane. But it feels like the stars anti-Muslim sentiment and homophobia are in the ascendancy.
It’s very much about statements that don’t sound aggressive or hateful, on the surface, but that would never be made if hate didn’t lurk just below. I’m thinking, for example, of a report I heard on the radio of some attack or other, involving “three Muslims of middle-eastern descent.” I might have the phrasing of the “middle-eastern descent” part wrong (though it was that or close to it). In any case, the salient bit, for me, was “three Muslims.”
When was the last time you heard a crime described as having been committed by “three Christians”? How about “A Jew broke into a convenience store…”? So what’s up with “three Muslims”?
What’s up, of course, is hate. I don’t think the radio announcer or the newswriter hates Muslims. But they do operate under a compulsion to mention explicitly that Muslims are Muslims, and ultimately that’s so that the listenership can be put on alert to hate them. Does the phrase “three Muslims” have explanatory power? Did these people do whatever they did because they are Muslims? No. There’s no reason to mention their religion except out of habit of mentioning the fact that Muslims are Muslims.
Back when I was a university professor (1992-2005; in this case somewhere around 2003, I think), the school newspaper had a kind of “person-in-the-street” feature, where they’d ask a few people around campus a question and print selected answers. One week, the question was something about Iraq. One of the people quoted in the feature said something along the lines of, “Bomb them all off the face of the earth.” Or “Blow them all up”—words to that effect.
My response was to call the editor-in-chief of the newspaper into my office and have a little chat with him. I was under no institutional imperative to do so—I was not involved with the paper directly—but it seemed to me that I had an opportunity to teach him perhaps the most important lesson of his college career. “If the question of the week had been about how to improve the cafeteria food,” I asked him, “and someone had said, ‘Line the whole cafeteria staff against the wall and shoot them dead,’ would you have printed it?”
Of course he would not have, and said that he would not have. “The fact that what we would not say about the cafeteria workers, we would say about the entire population of a Muslim country,” I explained, “is the dehumanization process at work.” I do believe he understood and took my point on board.
So we mention that people are Muslims, and we lower the bar when it comes to suggesting (or, if you like, joking about) their violent deaths. And it’s all very dangerous and should be sending up serious alarms.
Labeling the gay as gay is an even more popular pastime. The world has settled for a breathtakingly stunted view of what homosexuality entails, and how it manifests itself. It manifests itself, by the way, as itself, not as an obsession with the song “YMCA” or an expertise in designer footware. Hey, more power to you if you have that expertise. But the set of all men who do intersects in a miniscule subset with the set of all men whose primary sexual orientation is toward men. Ditto for all the stereotypes.
Of course, the world can’t deal with the idea that homosexuality manifests itself only as itself, because if that’s true, it means you can’t tell who’s gay; and that, like being unable to tell who’s Jewish, is unacceptable. The workaround is to pretend that you can tell who’s gay, resorting to babytalk about your “gaydar” when the stereotypes, as they must, fail you.
And then, following a fairly tight train of thought, there’s hatred of gays.
First of all, let me explain that I include, as hatred, the “love the sinner, hate the sin” horseshit espoused by the Catholic church. It is, to be sure, a kinder, gentler hatred than the burning-at-the-stake kind. The idea is that you’re enlightened enough to acknowledge that some people just are gay. But you also understand that, as gays, they must never indulge in the kinds of sexual activities they feel interested in. So you, as the compassionate believer, offer to contribute to their happiness by giving them support and encouragement as they fight to maintain their chastity.
How noble.
The church, of course, has two thousand years of experience disguising hate as love. But this one is particularly devious and malign. Let’s cut to the chase: the only reason that one adult human being would try to stop another adult human being, on a lifelong basis, from attaining romantic and/or erotic satisfaction is that he or she (human one) hates him or her (human two). No amount of theological stroking can change that. It’s hate.
Not news, of course, that the Pope and friends hate gays. But interesting to see how slimy and prurient they can get, in the process. Anyway, let’s move on.
Actually we can borrow a concept from the church: “invincible ignorance.” When I read the stuff about homosexuality being a choice (note that it’s not that sexual preference is a choice, just homosexuality—which makes it kind of weird to describe it as a choice), my reaction is that if you put twenty articulate, knowledgeable people in a room for twenty years with the person who’s taking the “choice” position, that person would emerge still saying that homosexuality is a choice. There’s no point of entry for explanation, and no point of contact with reality.
It’s pathetic, but I still count it as hate. At least it leads to hate. Or from hate, perhaps. Or maybe these people are actually choosing to be vicious, and could stop themselves if they really wanted to. It’s hard to know. They’re not saying.
With gay marriage on the news radar these days, more and more of this kind of discourse is showing up: the choice thing, but also the “gays recruit people” thing (which is actually backwards; have these people ever watched television commercials?) and, most disturbingly of all, the “gays prey on children” thing. And each of these things embodies two problems: first, that people believe it; and second, that it’s acceptable to say it publicly.
Which hateful statements are acceptable and which aren’t is a kind of lump under the carpet that moves around but never goes away. Unfortunately, the underlying hate never goes away either—and ultimately, no matter which targeted people or groups we’re talking about, it’s the underlying hate that matters. But who gets to say what, and when, and with what consequences (or lack thereof) is, in itself, something that I think it’s worth keeping fairly close tabs on.
Probative Programming: the physical unification of code and tests
November 30th, 2008
I’m encouraged by a couple of recent conversations to go public with this possible wacky idea. It has to do with code and testing.
I’ll start with the idea, and then say something about why I’m thinking along these lines.
The idea is for a programming system designed in such a way that the code and its tests are physically together, in one file. Furthermore, that file is not executable. You have to run it through a dedicated filter utility to generate the actual code file(s) from it.
So it’s a bit like, and indeed inspired by, Knuth’s Literate Programming, where the code and its documentation are fused together in a single file which contains both but is, itself, neither. You can’t execute that file; you have to generate the real code files from it.
Adapting the master-file idea to testing, as I envision it, would also entail the following constraint: that the system would refuse to generate the code files unless the code involved already had tests, and those tests passed. In other words, the whole system would militate against using untested code in production, by physically obstructing the creation of executable code files for untested stretches of code.
It seems to me that this would make for a much more sensible and efficient flow of energy than what we’ve got now. What we’ve got now are separate files, and therefore the possibility of running untested code. As long as that possibility exists, people will run untested code. Reordering things so that the creation of the executable code comes after the successful test run would, potentially, realign the energy of the whole process in a very productive way.
As things stand now, the energy is flowing in a wrong and wasteful way. The evidence for this is sociological, at least as much as it is technical. Thorough testing involves keeping the code and the tests in contact with each other through willpower and force, like holding like ends of two magnets together. Therefore, people who test consistently end up with bragging rights, which they often exercise. I hasten to add that I’m not talking about the really accomplished, masterful engineers of the great testing frameworks we’ve got available to us. Those people are above bragging. But there’s a sub-population that isn’t.
I’m really tired of seeing the test police needling people about not having written tests. It’s not that people shouldn’t write tests. Like I said, it’s about the energy flowing the wrong way. The whole culture of test machismo is, start to finish, a waste of energy and, above all, doesn’t work. You can’t get the whole world to write tests by trying to shame people into it, one person at a time. As long as the technical conditions allow for untested code, untested code there will be.
So we’ve got untested code, alongside a culture of testier-than-thou assertiveness. Neither is good.
And then there’s the programming should be fun thing. Programming should be fun. Testing should be a big part of programming. Therefore, testing should be fun. However, it’s acquired a sort of “do it because it’s good for you” aura, like using a treadmill or eating your vegetables. Again, this take on testing is wasteful and irrelevant—but it arises directly from the physical possibility of running untested code, and will not go away as long as that possibility exists.
I’ve made some very sketchy, preliminary attempts to see what a Probative Programming file might look like, for a Ruby program. It’s a daunting task, and one I may or may not ever succeed at. But I’m convinced that something along these lines is both possible and desirable.
Finally, if there are existing systems that do what I’m describing, or anything substantially similar to it, I’d be interested in hearing about them.
RESTful Rails for the restless
November 24th, 2008
QuickStarts-R-Us
As one of the most active Rails trainers on the circuit, I come up a lot against the challenge of introducing RESTful Rails to relative newcomers. It’s a challenge because the REST support in Rails is very high-level and, even for the diligent, basically impossible to understand deeply without a knowledge of the subsystems—in particular, the routing system—on which it is built.
I believe it’s possible, nonetheless, to understand up front how the RESTful support in Rails fits into the subsystems that support it; and I believe that it’s beneficial to gain such an understanding. My purpose is thus to provide a “QuickStart” introduction, not to the practice of writing RESTful Rails applications but to the way the REST support in Rails fits into what’s around and beneath it. If you want to do RESTful Rails but either find it too magical or don’t quite understand how it relates to the framework overall (does it add? supersede? enhance?), then this article may be of interest to you.
You may wonder why I’m not making use of the Rails scaffolding. That is, as they say, “a whole nother” story. Short answer: the scaffolding gives you a quick start, but also a quick end. It explains nothing and leaves you with a lot of work to do to reverse the ill effects of having a lot of “one-size-fits-none” code lying around your application directory.
So no scaffolding. Also, no REST theory—but by all means have a look at the theory once you get into the practice. It’s just not my focus here.
In what follows, I’ve tried to be concise—minimalist, almost. I’d advise not skimming over anything, even if you think you already know it. I’m chosing the path carefully. If you don’t trust me as a guide, that’s another matter entirely :-) If you do, welcome.
What a (non-RESTful) Rails application does
The job of a Rails application is to provide responses to requests. Responses are generated by controller actions, which are (in Ruby terms) instance methods of controller classes.
When your application receives a request, the first order of business is to figure out which action to execute. The subsystem that does this is the routing system. It’s the routing system’s job, for every request, to determine two things:
1. controller
2. action
If it cannot determine those two things, it has failed, and you get a routing error. If it can, the routing has succeeded. End of story. (You might get a “No such action” error, but that’s not the routing system’s problem. The routing system has done its job if it comes up with an action, whether the action exists or not.)
The main information that the routing system uses to determine which controller and action you want for a given request is the request URL. By definition, every URL that’s meaningful to your application can be resolved to a controller/action pair. If the URL contains information beyond that which is needed to determine a controller and action, that information gets stored in the params hash, to which the controller action has access. (That’s how you get params[:id], for example.)
The routing system uses a rule-based approach to resolving URLs into controller/action pairs. The rules are stored in routes.rb. A rule might say, for example (paraphrased here in English), “A URL with (1) a string, (2) a slash, (3) a string, (4) a slash, and (5) an integer means: execute action (3) of controller (1) with params[:id] set to (5)” (and indeed the default routing rule says exactly that). Rules can be specific, to the point of silliness. It’s perfectly possible to program the routing system so that “/blah” means: “the show action of the students controller with params[:id] set to 1010.” There’s almost certainly no point in such a mapping, but the point is that you can program the routing system in a fine-grained way.
In the non-RESTful case, the URL is all that the routing system needs to do its job of performing a rule-based determination of a controller and an action.
In the RESTful case, it isn’t.
Enter the verbs
This is the crux of RESTful routing in Rails. Everything else flows directly from this, so make sure you understand it.
Instead of routing based solely on rule-driven mapping of each URL to a controller/action pair, RESTful Rails adds another decision gate to the chain: the HTTP request method of the incoming request. That method will be one of GET, POST, PUT, or DELETE. It’s the combined information—URL plus request method—that the RESTful routing uses to determine the controller and the action.
That means that for every incoming request, the correct controller/action pair is determined not per URL, but per URL per request method. That, in turn, means that a given URL, such as this:
http://blah.blah/houses/14
might map to two or more different controller/action pairs. It all depends on the HTTP request method.
In theory, any one URL can be routed to as many as four controller/action pairs, because any one URL can be used in a GET, PUT, POST, or DELETE request. In practice there aren’t that many permutations, because some combinations of request method and URL semantics are not meaningful. But the principle is what matters: a single URL no longer has an unambiguous meaning, but must be interpreted in conjunction with the request method.
Furthermore, these conjoined interpretations are hard-coded to a pre-determined set of seven actions: index, show, delete, edit, update, new, and create. (You can add custom ones, but those are the canonical ones.) For example, the “houses” URL above, if requested as a GET, automatically routes to the show action of the houses controller, with params[:id] set to 14. If submitted with a PUT, it goes to the update action. A URL with no id field (/houses) goes either to index or to create, depending on the request method. And so forth.
That, as I say, is the crux of the matter: routing based on URL plus request method. Keep this in mind as you get into the details and bells and whistles of RESTful Rails.
Interpreting requests, though, is only half of the job of the routing system. The other half is the generation of strings.
RESTful URL generation
When you write this in your view:
<%= link_to "Click here for help", :controller => "users", :action => "help" %>
your view ends up containing this:
<a href="/users/help">Click here for help</a>
It’s the routing system that does the job of processing the link_to arguments and figuring out what the URL (or, in this case, the relative path) in your tag should consist of.
The same thing happens with RESTful routing, except that you never have to spell out the controller and action. Instead, you call yet more helper methods. Compare this:
<%= link_to "User profile for #{user.name}",
:controller => "users",
:action => "show",
:id => user.id %>
with this:
<%= link_to "User profile for #{user.name}", user_path(user) %>
You don’t have to define the method user_path. It comes into being automatically, when you write:
map.resources :users
in routes.rb. And it has a simple job: return the right string, in this case the string ”/users/14” (assuming that user.id is 14).
For every resource you route, you get a fistful of such methods: user_path(user), users_path, new_user_path, and edit_user_path (plus all of these with _url instead of _path). These methods do nothing but generate strings. They have no knowledge of request methods or REST. In fact, they’re just examples of named routes—methods that generate the right strings for specific routing rules—and you can use named routes in routes.rb even without REST. The only REST-related special treatment is that map.resources automatically writes a bunch of these methods for you. You can think of map.resources as, primarily, a macro that writes named route methods, much as attr_accessor automatically writes getter and setter methods.
The specifics of what the various RESTful named route methods do is for future study. The point here is to see the roadmap. You do map.resources :users, and from that point on, you can use methods in your views to create URL strings, rather than having to spoonfeed the information about which controller, action, and id are involved.
But that still leaves the question of the request method. How does ”/users/14” know which action to trigger when clicked?
Specifying request methods
When you write view code that generates path strings (with link_to, form_for, link_to_remote, etc.), you want the right string, obviously, but you also need the link, when clicked, to use a particular HTTP request method for the request. Otherwise the RESTful routing system won’t have enough information to make sense of the URL.
The helper methods that generate hyperlinks all have sensible HTTP request method defaults (which you can override if needed). link_to generates a link that will submit a GET request. form_for generates a POST form tag (method=“post”), unless you tell it to use PUT (which is conventional for update operations, as opposed to new record creation operations), and so forth.
Again, the named route methods don’t have request method intelligence. The enclosing hyperlink-writing methods (link_to and friends) do. They just used the named route methods as lower-level helpers for the specific purpose of generating the right strings.
Invisible ink
One of the challenges of using RESTful routing in Rails is that you end up with not very much information available to you visually. When you write a RESTful form in your view, let’s say for an update:
<% form_for :house, :url => house_path(@house.id),
:html => { :method => :put } do |f| %>
<% end %>
you never see the word “update” in routes.rb, nor in the URL, nor in the view templates, nor in the HTML source of your rendered views. You just have to know that a thing_path-style named route, coupled with a request method override to PUT (override of the default POST for form_for, that is), will result in a form that, when submitted, will send a PUT request to the update action of the houses controller. And you have to trust that the routing system will succeed in so routing it.
RESTful routing pushes most of the routing intelligence—which, as you now know, means the determination of a controller/action pair from an incoming request—under the surface. You have to learn how the REST-ified routing system thinks. The early phases of learning RESTful routing tend to involve memorizing the combinations of named routes and request methods, and which action they point to. The good news is that there’s a finite number of them, and they make sense. If it seems like routing soup, hang in there and look closely at the logic. It will come clear.
The rest…
That’s the basics. There’s a lot more to it, including (but not limited to) more “magic” shortcuts. But if you get the basic ideas you’ll be in good shape.
- The basic routing system resolves a URL to a controller/action pair.
- RESTful routing resolves a URL/request-method combination to a controller/action pair.
- map.resources :things generates a bunch of named routes (things_path, etc.) for you automatically.
- You don’t see as much visual evidence of the routing logic with RESTful routing as with non-RESTful routing, so you have to learn exactly what it’s thinking, especially the seven hard-coded action names.
Now go forth and REST. Oh, one more thing. Here’s a chart I once made, showing how the named routes map through the request methods to the seven canonical actions. The chart uses the _url methods (which give you the whole thing, including http://), but the _path versions would exist too.

Why I am suspicious of the bailout bill
October 3rd, 2008
The bailout bill has just passed. I know very little about economics, little enough that I don’t feel entitled to a strong opinion one way or the other on whether the bill should have passed. But I am suspicious of it.
I’m suspicious of it, for one thing, because of the fear-mongering that has surrounded it; it’s very reminiscent of the ongoing “Terrorists will come and kill your family if the executive branch doesn’t get a blank check for waging undeclared war” campaign, and things in that vein.
But I’m even more suspicious of the bill because of all the rhetoric about how it will help “Main Street” as well as “Wall Street”. I don’t know whether it will or not, but what troubles me is the fact that this kind of rhetoric makes it sound like Congress and the Bush administration are desperate to help Main Street. The fact is that, in general, they’re not.
Every microsecond of every day in the history of this country there have been uncountable opportunities for the government to help citizens with financial problems, difficulty paying for a home, lack of job opportunities, inability to get credit, and all the rest of it. The thrust of the behavior of the government for most of the history of the country has been not to bother helping such people to any significant degree.
Now, all of a sudden, helping Main Street leaps to the front of the congressional and executive agenda. I’m disinclined to buy it. If the common weal were really a government priority, we would have known by now. I find it immensely suspicious that the greatest outpouring of social concern, at least as measured in money, comes tethered to a Wall Street bailout.
If Main Street is going to benefit from the delivery of a de facto blank check to Wall Street, surely it would not benefit any less from having money delivered to it directly. But you don’t hear any talk of, say, the government purchasing houses for the victims of fiscal mismanagement. I suppose it would have taken too long to draft a bill that did that; and as we know, the earth would have left its axis if the bill had not been passed this week….
Tracks a-go-go at RubyConf 2008!
September 13th, 2008
Ruby Central is gearing up for RubyConf 2008, which has a fantastic program and which you can still register for (at time of writing, anyway!).
People have noticed, naturally, that we’ve gone over entirely to a multi-track format (except for keynotes and a couple of other special slots). And they’re surprised; we used to be one-track, and then last year we were multi-track but with a good dose of plenary sessions.
So I thought I’d say something about the multi-trackedness of RubyConf 2008, for anyone who’s interested.
The bottom line is that we’ve scheduled multiple tracks because we got so many really, really good proposals. Of course we can’t accept all of them; we can’t be that multi-track. There will always be a cutoff, and where the cutoff comes always involve a judgment call. This time around the judgment was that the number of talks we’d have to exclude, in order to dilute the multi-trackedness significantly, was too great.
In fact, we started drafting a schedule without explicitly discussing the multi-track issue; it mostly emerged from what we jotted down, and then it continued to make sense to us as we started analyzing the track issue more closely.
People have asked whether it’s about the size of the event. It is, in a couple of ways—subtle ways, perhaps, but important.
For one thing, we know that not every speaker is comfortable getting up in front of 500 people. Lots are, but it’s still a lot to ask. Breakout sessions make for situations in which more speakers are likely to be comfortable.
Of course, if there are only fifteen speakers, we could easily find people who don’t mind a big audience. But what about that “only fifteen speakers” thing?
In a conference with 400-500 people present, it’s definitely more fun if, say, twelve percent of the people prowling the halls and sitting next to you at lunch are speakers, instead of two or three percent. Having fifteen speakers at an event with over 400 people isn’t the same, for anyone, as having fifteen speakers at an event with sixty people. If the ratio is too lop-sided, it gets too much into the “us and them” thing. We’ve never been into that.
Another reason we’re OK with moving toward a multi-track format is the proliferation and success of the Ruby regional conferences, many of which are one-track. Everyone should attend, at some point, a one-track conference. It’s really cool the way everyone at such a conference shares the same experience. My first conference was a one-track academic film conference in 1985, and it was great. And the wonderful flowering of the Ruby regional conference culture means that, even if it isn’t at RubyConf, many Rubyists will get a chance to have that experience.
We started our regional conference grant program in 2006 in the hope that “regional” wasn’t going to mean “provincial”—that regional conferences could be top-notch events—and that hope has been fulfilled beyond what we could possibly have wished for. (And certainly way beyond what we can take credit for. The regional organizers have been amazing!) These high-quality small events can address many needs and desires, including the desire for the experience of a one-track format.
In sum, the RubyConf format for 2008 is a format for its time, its year, its configuration of the Ruby world. We’re nothing but excited about it and hope you’ll come and share the fun!
Back from RailsConf Europe 2008
September 6th, 2008
I got home yesterday from RailsConf Europe 2008 in Berlin, and am very happy to say that the event was a major success.
It was particularly gratifying to hear from many attendees that they found the program content more advanced and more instructive than last year. It’s always hard to fine-tune the level of talks across a big program like this, and I’m really glad to have evidence that people overall felt it had gone in the right direction.
Highlights included keynote addresses by David Heinemeier Hansson and Jeremy Kemper, as well as a Rails core team panel discussion with David, Jeremy, and Michael Koziarski. DHH led us through some very interesting thoughts on the notion of “legacy” code, and how that concept plays out with respect to one’s own development and growth as a programmer. Jeremy talked about performance, and masterfully expanded the horizon beyond the shop-worn “Does Rails scale?” stuff to some very specific and powerful techniques for evaluating and adjusting performance.
We also held a “Symposimi” (the name is based on a misspelling in the program; it should have been “Symposium” but came out “Symposimi,” and I decided that sounded really cool!) on the subject of Ruby versions and implementations—who’s using what, what’s targeting what, the pros and cons of moving to 1.8.7 and/or 1.9. A symposimi is a town-meeting-like gathering of people who want to ask and answer questions about a topic. It’s more audience-based than a symposium, and less hierarchical.
The symposimi was fun for me because I got to do some live code demos, which I usually don’t at the conferences I’m an organizer of!
Lots of people asked about next year. We don’t know yet where RailsConf Europe will be in 2009. Probably not Berlin, just because we’d like to move it around. If you have suggestions (and a rationale other than that you happen to live there :-) by all means let me know.
Now that RCE2008 is over, I’m looking forward to RubyConf. Stay tuned for announcements of the program and registration!
Pseudo-persuasion in online discourse
August 6th, 2008
I know it’s pointless—I’m not going to make a dent in it—but I feel moved to say something about the biggest problem in online discourse: pseudo-persuasion.
The term is a bit awkward, but you’ll recognize what I’m talking about because it monopolizes an almost literally incredible proportion of email lists, news groups, blog comments, and IRC chats, and you’ve seen plenty of it. I’m talking about the endless stream of this vs. that. Emacs vs. vi, Ruby vs. Python, Ubuntu vs. Redhat, Mac vs. PC, tabs vs. spaces, and all the monumentally huge and boring rest of it.
Yes, there are interesting comparative points you can make about all of these pairings. Yes, some people make interesting points. I’m not talking about those points. I’m talking about the other 99.99% of online comparative talk, the inexhaustible store of “mine is better than yours” drivel, the vacuous chatter that, despite its vacuity, manages to choke and clog the online world as if it were of substance.
I call it pseudo-persuasion because it sounds like persuasive speech, but isn’t. It is persuasive neither in effect, nor in intent. Millions upon millions of words pour forth—arguments in favor of A and against B, checklists of assertions and accusations, praise of features and denouncement of shortcomings—all delivered in the most fervent persuasive language but not one syllable actually persuading anyone of anything, and not one syllable written in the expectation of persuading anyone of anything.
Have you ever said to yourself, “Gee, someone on IRC said that Emacs keybindings aren’t intuitive, so starting tomorrow I’ll switch to vi”? Have you ever met anyone who, after asking a question about a Linux problem and receiving an answer consisting of the single utterance, “OS X!!”, proceeded to run out and buy a Mac? Did you start using your current favorite programming language because someone told you, in so many words, that the one you had been using sucked and this one was better?
My late father used to say that “No one ever convinces anyone of anything.” He didn’t believe it literally, or he would not have bothered co-authoring the brief in Brown v. Board of Education. In general, he didn’t mean it with regard to legal and forensic argumentation. He did mean it, however, with regard to cocktail party chatter, exchanges among politically widely-separated colleagues, heated classroom arguments among students, and the like: day-to-day exchanges where the urge to state an opinion does not imply an inclination to take someone else’s opinion seriously.
Non-persuasive persuasion can serve a purpose. It’s good, for example, for students to put their thoughts into words, even though they’re not really listening to each other. Usually, though, it’s just a way to fill otherwise awkward social time.
When people yap at each other about Emacs and vi, however, it’s not filling awkward social time. To be honest, I don’t know what it’s doing. It certainly is not debate. It sounds like debate, and it uses rhetorical devices that are also found in debate. But it is not debate. No one can “win”, no one is listening to anyone else, and the likelihood of persuasion being achieved approaches zero. Nothing is at stake, and no one actually expects any conclusion, outcome, or productivity to emerge from the exchange.
But my case against pseudo-persuasion is not that the practitioners don’t take each other seriously enough. They hardly could, given how much of this crap there is. My case against it is that it’s a staggering waste of time, mental energy, and passion. Can you imagine what would have happened if, over the past couple of decades, participants in online forums had taken, say, five percent of the time they’ve spent pissing at each other, and used it instead to collaborate on software or technical writings?
Co-Training with Erik Kastner
July 20th, 2008
My friend and nearly-neighbor Erik Kastner is going to be joining me to teach the Ruby Power and Light course “Advancing With Rails” in Edison, New Jersey, August 18-21. This will be RPL’s first co-taught course, and I’m really looking forward to it.
See the calendar at Ruby Power and Light for more info!
July 6-12 is "Link To Something Other Than Wikipedia" Week!
July 4th, 2008
During the week of July 6-12, I invite and encourage everybody who includes links in their email, blog posts, online chats, and other documents, to link to something other than Wikipedia.
I’m not trying to be a Wikipedia slayer. It wouldn’t matter if I were; that’s not going to happen.
I just want to remind everyone that there are thousands and thousands of interesting, well-informed, thought-provoking, educational websites out there, written by professors, researchers, doctors, artists, scientists, practitioners of every craft and industry—and however you slice it, these websites are getting a raw deal when it comes to links.
It’s not about whether Wikipedia articles are accurate or not. Some are, some aren’t. But that’s true of
The best thing about the Web is that it isn’t an encyclopedia. And Wikipedia is evidence that when Web culture meets encyclopedia culture, encyclopedia culture wins. Sure, Wikipedia is collaborative. Most encyclopedias are. They still give off an aura of total, centralized, complete knowledge and authority. And that’s not very Web-like, is it?
So:
- If you’ve got a point to make about grammar, look for an English (or whatever language it is!) professor’s site. There are some great ones. Point the person you’re arguing with to a couple of those.
- Countries have their own informational websites, some official and some written by people who live there. Many of them are multi-lingual. Are they “balanced”? Probably not, at least not in the network news way. So much the better! Balance on the Web emerges from the quantity and interplay of sites. It’s not supposed to be embodied in every document. How boring!
- Wikipedia is great for technology-related topics. But so are lots of other sites. Are you sure that Wikipedia’s description of the algorithm you’re discussing on that mailing list is really the best? the clearest? the most engaging?
- You get the idea! Strike a blow for the richness of the Web, and for the beauty of discourse that doesn’t try to be poker-faced and non-committal, even about important issues. Rediscover the expertise of the many Web contributors who write about their own specialties and have taken the time to share their thoughts.
There’s a lot to learn at Wikipedia, but it’s time to spread the linkage!
Slide words (if that's really what they're called)
June 7th, 2008
A guy I was chatting with in the men’s lounge of the spa at Harrah’s in Atlantic City was telling me about “slide words.” I can’t find anything about them (and I’ve tried “slider words” and a few other variants) anywhere. I don’t think he made the term up, and he certainly didn’t think he had.
Anyway, even though I can’t find any background information or previous discussion, I am going to talk about “slide words” (or whatever they’re called).
A slide word, I gather, is a word or phrase that has come to serve as shorthand for an entire argument—except that the argument isn’t really there. We’re all just supposed to think it is. The slide word acts as a black hole, drawing further discussion and thoughtful debate into itself and killing it.
Slide words are bad because they take the place of actual analysis of situations and events. Every slide word has a kind of implicit, “Sigh. Here we go again” attached to it, even though the “again” part is asserted through the use of the slide word itself and not actually demonstrated.
I have something to say here about three slide words: conspiracy theory, Chinese menu, and bikeshed.
“Conspiracy theory”
“Conspiracy theory” is perhaps the best example of a slide word. Consider the following exchange, which is made up but is actually very similar to several I have had:
Other Person: Why haven’t we heard about it?
Me: It was in the news briefly. I guess it was considered more prudent to downplay it.
Other Person: That sounds like a conspiracy theory.With the invocation of the term “conspiracy theory,” all further discussion of what might have actually happened is discredited. The events surrounding the death of John Kipalani’s son need not be examined in any detail; nor need the press coverage (or lack thereof). “Conspiracy theory” plays the role of a rebuttal of the statements about the Challenger disaster, even though it has no actual connection to them.
Here’s another example:Me: The only people who profited from 9/11 in any way, financially or politically, were George W. Bush and his family and friends. I therefore assume, as a matter of the simplest logic, that Bush had something to do with it.
Other Person: What are you, a conspiracy theorist?Again, the slide word (or slide phrase) gets played as if it were a trump card, when in fact it has nothing whatsoever to do with the question of Bush’s culpability in the 9/11 attacks, and neither refutes the logic that’s on offer nor adds information that might bring about a reconsideration of that logic.
“Chinese menu”
Another slide word I’ve come across, in a somewhat narrower setting, is “Chinese menu.”
When I was teaching at a university, I was involved in lots of discussions, formal and otherwise, about core curricula: what they should include, how they should be administered, and so on. I remember that in one series of such discussions, any time anyone suggested anything along the lines of having students choose one or more courses from each of several course groupings, someone else would say, “That’s like a Chinese menu.” Eventually it became just “Chinese menu.”
I have no memory of any discussion of
“Bikeshed”
Another slide word, a rather obnoxious one that seems to be enjoying considerable popularity these days, is “bikeshed.” If someone says “bikeshed,” they’ve said all they need to say (or at least all they think they need to say, and certainly all they’re planning to say) to establish that what you have been talking about is trivial and not worth discussing.
Saying “bikeshed” to someone, instead of telling that person outright that you find his or her statements trivial and worthless, is not only needlessly indirect but, in most cases I’ve seen, wrong.
The original bikeshed concept, as I understand it (which is from second-hand accounts, so I could be wrong), had to do with the phenomenon of committees spending more time arguing over what color to paint the company bikeshed, than over the allocation of funds to build a nuclear power plant.
The problem with the typical usage of “bikeshed” today is that there’s no nuclear power plant in the picture. It’s more likely to be a bunch of people on an email list discussing the best name for a proposed new method in Ruby, or something like that. Then someone who feels superior to the discussion (which would exclude the creator of Ruby, as well as many of his colleagues, associates, and friends) comes along and says “Bikeshed.”
But if we weren’t talking about method names, we’d be talking about literal constructors for runtime objects. And if not that, then perhaps the question of whether parentheses around parameter lists in method definitions should be mandatory. All of these things are important to people interested in the Ruby programming language; but, with respect, I will state unequivocally that none of them is as important an issue as nuclear power.
Furthermore, saying “bikeshed” implies
that you think the group you’re addressing not only is wasting its time on the
current topic, but has a history of spending too
Thus slide words. I’m glad there’s a name for them, even though it’s puzzling that the only person who seems to have heard the name is that guy at Harrah’s.
Death of a racehorse
May 4th, 2008
I’ve always vaguely disliked horse races. The anthropomorphizing of the horses, the claims that they know that they’re involved in a race and that they share the goals of their owners, is manifestly silly and self-serving. And the whipping always bothered me. I suppose I made myself believe that horses didn’t really care and that an attack with a whip was, to them, kind of like a verbal exhortation to us. (Not that verbal exhortations can’t be painful, but they’re not physical).
The death of Eight Belles shocked me out of my indifferent, complacent position.
All the crap in the news about how noble she was, how competitive her spirit, how great her self-sacrifice… it’s all smug and disgusting beyond belief, despite the accompanying descriptions of the tears glistening in the eyes of the various stakeholders. What really happened was that this horse was forced to run as fast as she could, for reasons she could not understand and that had nothing to do with her well-being, and as a direct result, her legs fell apart, and then someone killed her.
That’s it; that’s all there is to it.
Why is this allowed to go on? Is it simply because more horses survive races than don’t?
For some reason, we continue to give the benefit of the doubt to this bizarre, nasty, money-drenched “sport”. Except that for me, at this point, there is no doubt, and no further conferral of the benefit.
In part 1 of this two-part post, I explained my concern that the word “resource” has become too closely associated in Rails-related usage with some combination of model, database table, and controller/model stack—none of which do justice, as definitions or even first approximations, to the concept of a REST resource as originally described by Roy Fielding. Here, I’m going to expand on this observation by exploring a few ramifications of the same topic.
Resources, controllers, and models (or lack thereof)
As I explained in the previous post, the concept of “resource” has no database implications—indeed, no implementation implications. A resource does not have to have a corresponding model. It also does not have to have a corresponding controller. Resources are far more high-level than controllers and models. Controllers and models are tools with which you provide access to representations of resources.
However, if you want to draw a line between resources and Rails, by far the better line to draw is the one that points to controllers rather than models. A controller is not a resource, but it comes closer than anything else in your application to taking on the features of your resources. Models are another big step away.
If controllers are closest to resources, how does this play out? One way is in the creation of resources for which requests are handled by a controller that has no corresponding model.
My favorite example of a likely modelless resource is the shopping cart. In Ruby for Rails, I use a shopping cart in my central example. When I started working on this application, I tried to model it directly; I imagined I would have a ShoppingCart class, a shopping_carts table, and so forth.
I quickly realized, however, that I didn’t need that. What I was calling a “shopping cart” was really a virtual construct or, in Rails terms, a view. I had Order objects and Customer objects, and the shopping cart was basically a screen showing all of a particular customer’s open orders. Calling it a “shopping cart” was just a kind of semantic sugar. There was no need to persist it separately from the persistence of the orders and the customer.
If I were writing the same application today using RESTful idioms, I would in all likelihood do:
map.resources :customers do |c|
c.resource :shopping_cart
end
or words to that effect. I would then have a shopping_carts controller, with a show action (probably leaving all the related CRUD stuff back in the orders controller, though there might be several ways to approach that part of it). And I would, without hesitation, describe the shopping cart as a resource—even though it has no ShoppingCart model behind it. From the perspective of the consumers of my resources, it doesn’t matter whether there’s a ShoppingCart model (and shopping_carts database table) or not. I can decide on the best application design, and use RESTful Rails techniques to support my design decisions appropriately.
A resource is not a model, and it’s also not a controller. Identifying the resource with the controller is, however, somewhat closer to the mark. The controller layer conforms most closely to the resource mapping, which makes sense since the controller is the port of call when someone connects to your application.
Another area where misunderstandings arise in the course of designing RESTful services in Rails is in the matter of how identifiers (URI) map to resources—and not just how, but how many.
Identifiers and resources: not always one-to-one
I’ve seen people tie themselves in knots trying to come up with the best way to label and/or nest resources. One of the principles that’s gotten lost in the mix is that the ratio between resources and identifiers does not have to be one-to-one. Fielding states:
[A] resource can have many identifiers. In other words, there may exist two or more different URI that have equivalent semantics when used to access a server. It is also possible to have two URI that result in the same mechanism being used upon access to the server, and yet those URI identify two different resources because they don’t mean the same thing.
Therefore, it’s possible that this:
http://dabsite.com
and this:
http://dabsite.com/welcome
can identify the same resource, which would probably be described as something like “The welcome and orientation information at dabsite.com”. The reason they’re the same resource is not that they generate the same HTML. Rather, they’re the same resource because they’re published as the same resource.
It’s also possible that this:
http://dabsite.com/orders/211 # 211th order in the system
and this:
http://dabsite.com/orders/042208-003 # third order placed on 4/22/08
identify different resources, even if the third order placed on 4/22/08 happens to be the 211th order in the system. That’s because resources are not database rows. In this case, the two requests might generate the same HTML, but still pertain to different resources.
You don’t have to make a point of having a non-one-to-one ratio between your resources and your identifiers. Just be aware that if such a ratio emerges, in either direction, you’re not doing anything inherently “unRESTful.”
CRUD and REST and resources
One of the nice things about the REST support in Rails is that it dovetails with CRUD-based thinking about modeling. I add in haste: REST is not CRUD, and CRUD is not REST. (That’s no secret, but I want to go on record with it.) But in Rails, there’s a nice relationship between them.
The REST support in Rails emphasizes the convention of CRUD operations. map.resources gives you a fistful of named routes that have built-in knowledge of CRUD action names. The emphasis on CRUD at this level encourages you to think of modeling for CRUD. Instead of having, say, a users controller with a borrow_book action, you can have a loans controller with a create action. In many cases, this way of thinking might also wag the dog of your domain modeling. Thinking about CRUD in the controller might, for example, lead you to conclude that you should have a Loan model.
It’s perfectly fine—indeed, in my view, it’s very productive—to think along these lines, to bring your modeling and your REST-friendly CRUD operations into harmony, as long as you understand that none of this is actually about resources as such. Rather, it’s about the Rails flavor of implementing the handlers that underpin the creation of resource representations.
Does that sound like just a lot of extra words? It isn’t. It’s a lot of words, but they’re not extra. Again, it’s important not to squeeze the entire framework into the “resource” label. Let a resource be a resource, and let the handler layers be handler layers. They’re nicely engineered—but they’re not resources.
And then there’s the word “representation,” which crept into my “extra words” sentence but which is the least extra of all of them.
Representations: the one that got away
The representation is, in my view, the one that got away: the central concept in REST that no one in the Rails world ever seems to talk about. We need to, though. It’s vitally important.
Your server does not traffic in resources. It traffics in representations of resources. Users of your application do not receive resources. They receive representations. The distinction is big; at stake is the entire meaning, and meaningfulness, of the notion of a resource.
We need the concept of “representation” because it’s the part of REST theory that relieves the pressure on the term “resource.” After all, how can a resource be a “conceptual mapping” (Fielding) and a sequence of bytes that a server sends you and a controller-model stack…? It can’t, and it’s only the first of these things. The second, the response itself, delivers a representation of a resource.
One resource can have many representations. There’s no big news here; we all know that a server can give us a text version of Jane Eyre or a movie version or an audio version. (I’ll refrain from getting philosophical about whether or not a book and a movie are “the same” in any deep sense. They’re the same enough, in this context.) The point is that we don’t need to mush everything into the term “resource.” Rather, we benefit by yanking that term up to the high level where it belongs, and applying the term “representation” to the actual response we’re getting.
Fielding has much more on representations in his dissertation, and I’m not going to try to paraphrase it here. My point is to encourage the liberal use of the term in Rails discourse about REST. The poor term “resource” has already been given too much to do. We need to delegate some of the domain description to the other terms that apply to it.
Now what?
The use of the term “resource” to mean things that, I’ve argued here, it really doesn’t mean is rather deeply entrenched, and widespread, in Rails discourse. I don’t have any quick fix for this. I do have a few recommendations, though.
First, read Roy Fielding’s dissertation. You can skip to chapters 5 and 6 and get a great deal out of them.
Second, pay particular attention to the concept of the representation. I don’t think we can get much further in exploring REST and Rails unless the representation makes a comeback. “Resource” is just plain spread too thin in the way it’s used in and around Rails, and there’s no reason why it has to be, if we look at the theory as a whole.
Third, and last, don’t assume that any deviation from the out-of-the-box behaviors in your RESTful Rails applications is unRESTful. The defaults are in place because they’re high percentage. But they’re just as opinionated as the rest of Rails, and in some respects more so. That’s OK, but do understand that they’re REST-friendly tools. They’re not a definitive statement on the entirety of what REST is.
REST is not an easy topic, and it’s unlikely that anyone is going to create a way for you to create and maintain RESTful applications, over time, without you trying to get a handle on it and developing your own understanding of resources, representations, requests, and responses. I hope these posts will help you out in that endeavor.
References
Fielding, Roy Thomas. Architectural Styles and the Design of Network-based Software Architectures.. Doctoral dissertation, University of California, Irvine, 2000.
Getting out of Ruby's way: code beauty and/or greatness
March 28th, 2008
Chad Fowler wrote an interesting article this week on the subject of Great Ruby Code. The article concludes with an invitation for comment:
Anyway, I still don’t have a satisfactory list of great Ruby code. I’d like to build such a list. So, please leave a comment saying the name of an open source Ruby project you feel represents truly great Ruby code.
My comments are somewhat “meta”, and I had an interesting chat with Chad about the whole topic of greatness in Ruby code after I’d read the article, so I thought I’d make my comments here in an article of my own.
For me, the very concept of great Ruby code contains the seeds of its own destruction. Here’s why.
When I see Ruby code and think, “This is great,” what I usually mean, at least as a first approximation, is that Ruby is great. I don’t mean that everything written in Ruby is automatically great. But I do find that a lot of what’s involved in writing what I consider beautiful Ruby code is getting out of Ruby’s way. Ruby is famous for getting out of your way; but you can and should return the favor.
I’m slipping between “great” and “beautiful,” which isn’t fair but maybe that’s part of the problem: I’m not sure what pure greatness in Ruby code would be, because I tend to perceive Ruby code in terms of beauty—not down to the millihelen,[1] perhaps, but as an overall matter—rather than greatness; and I can’t really give an individual programmer “credit,” so to speak, for the beauty I find in, say, yield or class << object or the technically unnecessary but, in my view, manifestly elegant class/module distinction.
Then there’s the subjectivity issue (as many of you non-fans of class << object are probably thinking right about now!). Of course Chad isn’t anticipating universal agreement on what’s great in Ruby code. But for me, the impossibility of consensus is another seed of the very concept’s own destruction. It’s an irony, even a paradox: if there is such a thing as greatness in Ruby code, we’ll never find it because once we shift the discussion to the plane of “What do you consider great?”, it’s likely to unravel in the same way that discussions about what’s great in any art unravel.
And about that art thing: Coding is of course an art, but it’s a peculiar one in that the artist is operating within the boundaries set by another artist&mash;namely, the designer of the language. (Note that I said coding, not programming. I’m not trying to drive a wedge between them, but as Knuth and others have shown us, there are aspects to the art of computer programming that are not about this or that language, and I’d like to keep the terminology at least a bit separate.) Is it like music? Are we interpreting Matz’s score? Or is Matz the playwright, we the actors? Or perhaps Matz is like whoever invented baseball: a set of rules within which we elect to operate. Well, there are great baseball players….
Maybe greatness in Ruby is ours to lose: If you follow stylistic best practices (which is another, but in my view related, matter), and above all let the language talk to you and don’t “write {Java,C,Perl,...} in Ruby,” your code will be great, or beautiful if you prefer, because you’ve collaborated successfully with Ruby. And yes, I do think that Ruby confers an advantage here over many other languages. For me, the most important key to Ruby’s beauty and its greatness is that Ruby code gets clearer, rather than more cryptic, as it gets shorter. I don’t want to jump through the hoop of reciting all the obvious facts (that this can be true in other languages; that Ruby code can be cryptic; etc.). I present it for what it is: my take on the magic of Ruby. I’ve always said that as you work on a Ruby program, code disappears from your screen. So it does—and the program becomes more, rather than less, expressive and communicative.
There’s no tidy stopping point to this exploration, and that’s as it should be. I encourage you to go to Chad’s article and read it and respond. I don’t expect us to end up with a definitive list of great Ruby code. But what Chad is doing is inviting us to look—really look—and I find it well worth the trouble.
[1] A millihelen is the amount of beauty required to launch one ship. (I wish I could take credit for that one but I only know it as an old joke.)
Short-circuit (||=) post -- CORRECTION
March 26th, 2008
There was a response to my post from yesterday on Procnew.com, which pointed out that when you’ve got this:
x ||= y
it doesn’t expand to this:
x or x = y
(which is what I said in my last post) but rather to this:
x || x = y
I believe that’s right. It’s kind of hidden until you do:
a = x ||= y
and you start to see that it behaves like the || expansion, not the or expansion.
The example on Procnew.com has one glitch, which is that on line 9 of the irb session, it’s using a value that’s already set (h[:y]), so it’s never going to jump over the || anyway. Still, I believe the point is right.
Pending other edge-case edge-cases, anyway…. :-)
A short-circuit (||=) edge case
March 25th, 2008
In Ruby, you can conditionally set a variable like this:
x ||= 1
If x is not initialized—or if it is set to nil or false—it will be assigned 1. If it’s already set to a Booleanly true value (i.e., anything other than nil or false), it will remain unchanged.
Most descriptions of this idiom, including mine, have said that it expands to this:
x = x || 1
Last year, though, an edge case came to light on the ruby-talk mailing list. It involves hashes with default values.
Trouble in ||=-land
Here’s an irb session illustrating the case. First, we’ll create a hash with a default value of 1.
>> h = Hash.new(1)
=> {}
Remember that the default value is what the hash returns for non-existent keys. There are no assignment implications; referring to a non-existent key does not result in setting that key in the hash.
>> h[:x]
=> 1
>> h
=> {} # still empty!
Now let’s try the ||= idiom.
>> h[:x] ||= 2 => 1
Once again, no assignment has taken place:
>> h
=> {}
This struck a number of us on the mailing list as weird. It certainly means that ||= does not expand the way we had assumed it did. Here’s the proof: try the expanded version, and you’ll see that it does assign to the hash, as you’d expect.
>> h[:x] = h[:x] || 2
=> 1
>> h
=> {:x=>1}
So there we have proof that x ||= y and x = x || y are not interchangeable.
That raises two questions: first, what does x ||= y expand to, and second, do we like it?
The true expansion of ||=
At RubyConf 2007, I was running a “Ruby Clinic”, where people could come and go and ask questions about Ruby. Matz stopped by for a while, and the ||= topic came up. He explained that the real expansion is:
x or x = y
Note (a day later): It’s been pointed out to me that expansion as x || x = y is more accurate. I believe that’s right, though my examples here didn’t flush it out.
Sure enough, expanding it this way produces parallel results in the hash case. Continuing the same irb session:
>> h
=> {:x=>1}
>> h[:y] ||= 3
=> 1
After that conditional assignment, the hash has not changed.
>> h
=> {:x=>1}
And expanding it in the “or” style also does not change the hash:
See “Note”, above.
>> h[:y] or h[:y] = 3
=> 1
>> h
=> {:x=>1}
That clears that up. But do we like the way this plays out with hash defaults?
Editorial comments
I have mixed feelings about it. I can see that it makes sense. On the other hand, I can’t help thinking that when you write this:
hash[:x] ||= 2
you’re really expecting the hash to end up with an :x key. In other words, my gut feeling is that it should mean:
hash[:x] = 2 unless hash.has_key?(:x)
However, I understand that having it mean that would involve special-casing the hash case, and in the long run, I’m not in favor of that.
So what it comes down to is: heads up a bit with ||=. It works fine, but you need to know the real expansion.
I’ve commented on the main Rails mailing list and elsewhere about some concerns I have about the way the term “resource” has been adopted into Rails practice and discussions. I’d like to explain those concerns in a little more detail.
In this post, I’ll talk about the definition of a resource and why it’s a good idea not to overpaint the original definition with a redefinition based on the specifics of Rails. In the next, follow-up post, I’ll comment on several closely related issues, including the usefulness of model-less resources, why it’s better (though not perfect) to identify a controller with a resource than to identify a model with a resource, the relation between CRUD and resources, and the role of the “representation”—an important and concept often overlooked in discussions of REST in Rails.
Controller + model: what a resource isn’t
The problem, in a nutshell, is that the term “resource” has come to be understood widely as meaning “ActiveRecord model” or, perhaps more commonly, “controller-model stack.” People say that they’ve “created an item resource” when what they mean is that they’ve generated a item model and an items controller. There’s no reason for there not to be a short, concise term for “name-matched controller-model stack.” But that word should not be “resource.”
Equating “resource” with controller-model stack has the unfortunate effect of leaving us without a term to refer to what Roy Fielding originally meant by “resource”—which is definitely not “controller-model stack” or anything like it. (More on what a resource is presently.) Fielding’s description of a resource is deeply interesting, and worth protecting from terminological drift. Moreover, there’s no loss involved. In fact, by teasing apart the threads of what’s a resource and what isn’t, we can actually get more out of the RESTful tools available in Rails.
Defining “resource” as controller + model severely limits imaginative thought about how a resource, in the original sense, might play out in Rails. By imaginative, I do not mean improvisatory or chaotic. The Rails REST conventions are very powerful and tremendously useful, and I’m fine with being conservative about deviating from them ad hoc. But I wince when I see people agonizing because they’ve manipulated Model A in Controller B, and think that they’ve violated RESTful principles because they’re crossing resource lines. That’s not how it works; that’s not how the concept of resource maps to Rails technology.
Obviously Rails uses controllers and models, so whatever a resource is, somewhere along the line it’s likely to involve those things in a Rails application. The wrong turn, though, is in assuming that a resource is a controller and/or model.
I tend to think that much of this way of viewing the matter comes from the so-called resource scaffolding. It’s easy to understand why Rails developers, presented with a tool that generates a controller-model chain and calls it a “resource,” would either not see the need to question the terminology, or would be reluctant to do so. But there is a need to question it. The term “resource,” as used very commonly in Rails discussions, bears much more resemblance to how it’s used in the context of Rails scaffolding than how it’s used by Fielding. That doesn’t benefit anyone.
Scaffolding or not, something has led people to think that a resource consists of a controller and a matching model. It doesn’t.
What a resource is
Rails is database-intensive, so the temptation exists to conclude that the word “resource” has something to do with database tables and persistence. Fielding could hardly state the case against this perspective more strongly:
The resource is not the storage object. The resource is not a mechanism that the server uses to handle the storage object.
Already one has to wonder how the generation of an ActiveRecord model and migration ever came to be viewed as part of creating a resource per se (as it is in the scaffolding). Anyway—Fielding goes on to define what a resource is:
The resource is a conceptual mapping — the server receives the identifier (which identifies the mapping) and applies it to its current mapping implementation (usually a combination of collection-specific deep tree traversal and/or hash tables) to find the currently responsible handler implementation and the handler implementation then selects the appropriate action+response based on the request content.
This sentence is a bit more complex than the first two, and it’s worth breaking it down for the sake of seeing how it might map to Rails.
The key idea is that a resource is a conceptual mapping. You send a resource identifier to a server. The server sends back a response (a “representation” of the resource, as we learn elsewhere). In between, the server does what it has to in order to generate the response.
The response is a representation, not a resource. And the mechanisms by which the representation is generated are not, themselves, the resource. In Rails, those mechanisms typically include the routing system (which I would roughly identify with what Fielding calls “the current mapping implementation”) and the controller objects with their actions (the “responsible handler implementation”). Again, these mechanisms are not the resource. And the model layer, which lies yet further away in the architecture, is really not the resource.
The benefit of splitting hairs over the terminology is that it points the way to recovering Fielding’s original concept of a resource, of which I don’t get very many glimpses in the typical discussion of RESTful support in Rails. To the extent that you are setting up models and controllers and RESTful routing, you are putting in place the wiring that will allow your system to fulfill its contract as a provider of representations of certain resources. To the extent that you are determining what resources your system is responsible for, you’re performing a task that has no dependency on Rails or any other specific software tools.
The robustness of resources
Part of the problem with using “resource” to refer directly to parts of the Rails application itself is that it introduces a fragility into the concept of resource, and the identity of specific resources, that really shouldn’t be there. If you declare that your system is responsible for the Resource N, then it shouldn’t matter how many controllers, actions, models, and database tables you use. I don’t mean that it doesn’t matter in terms of software design. I mean that Resource N should be above the fray. It should be robust enough not to depend for its identity as a resource on the specifics of the way you handle the mapping of identifiers to representations.
It’s instructive in this context to consider how the concept of “resource” plays out when you’re serving a static HTML page. The way it plays out is the same as the way it plays out when you’re generating a dynamic response. In other words, whether or not something is a resource has nothing to do with the question of whether or not its representations are generated dynamically, nor with the question of whether a database has been queried or a template rendered in the process of the production of a representation.
This is just terminological common sense. Imagine if you were publishing information about resources available through your system, and you had to explain that sometimes they weren’t really “resources” because they didn’t hit a Rails controller and database table. That would be ludicrous. Obviously a resource is a resource, not because of how its representation is generated behind the scenes but because a representation is returned, however it’s generated, based on a mapping of identifiers to request handlers.
So if you start thinking of controllers and models as actually being resources, you’ve painted yourself into a corner where you have no term that describes a resource in a higher-level sense—no way to identify the “conceptual mapping” that Fielding stipulates. Controllers and models are part of the handling and response mechanism. They are not resources.
But once you decouple the notion of resource from the specifics of how Rails applications generate representations of resources, a lot of other things fall into place. In the second half of this essay, I’ll be looking at several REST-related topics that I think benefit directly from the liberating and sense-making effect of observing the distinctions among resource, representation, and handler mechanisms.
References
Fielding, Roy Thomas. Architectural Styles and the Design of Network-based Software Architectures. Doctoral dissertation, University of California, Irvine, 2000
Upcoming Rails training, 2008!
March 22nd, 2008
Long time, no blog. But now I'm out of hibernation.
I've got some Rails training courses coming up, including:
- Advancing with Rails, April 14-17, New York City
- Intro to Rails, June 9-12, Berlin, Germany
- Advancing with Rails, June 16-19, Berlin, Germany
- Intro to Rails, June 24-27, London (at Skills Matter)
See Ruby Power and Light for details.
The Berlin courses are being taught in English. The info about them on the Web might only be in German... but you can always contact me for more info if you're interested. Berlin is a very cool place -- I highly recommend it!
"Advancing with Rails" training in Berlin, Nov. 19-22
October 19th, 2007
I suspect it won’t appeal to the Thanksgiving-inclined, but I’ll be teaching my “Advancing With Rails” course, for intermediate Rails developers, in Berlin, Germany, November 19-22.
Advancing With Rails is designed for people who have done some Rails… read a couple of books… and want to keep going and get better at it. I’ll be covering Ruby language topics as well as Rails techniques and best practices.
The course will be conducted in English, though I speak German and can field questions in either language.
More info here.
Upcoming Rails training in New Jersey!
September 14th, 2007
My Ruby/Rails consultancy, Ruby Power and Light, LLC, is offering two Ruby on Rails training courses this Fall, both hosted by Exceed Education in Edison, New Jersey:
- Introduction to Ruby on Rails, October 23-26
- Advancing With Rails, November 6-9
I will be the instructor for both.
You can get more information on the courses, and on signing up, at Ruby Power and Light—just follow the links in the banner box.
Reflections on Wikipedia
September 4th, 2007
I love reading Wikipedia, and I’ve learned a lot from doing so. I’m not, in other words, rabidly anti-Wikipedia. But I do have a few serious concerns about it.
It seems to me that Wikipedia is, in effect whether or not in intent, pushing the Web in exactly the direction it isn’t best suited for: namely, centralization of information. Mailing list posts and IRC channels are full of links to Wikipedia articles, on everything from… well, on lots of things. It seems that the standard way of saying, “If you’re not familiar with the term I just used, here’s how to learn about it” is to provide a Wikipedia link.
I strongly suspect that this is automatic on the part of the people doing it—automatic, that is, rather than based on a thorough search of all the resources available on a given topic and a reasoned decision about which is best-written and/or most informative. That’s the thing: Wikipedia provides something close to one-stop shopping. You’ll find something on almost anything.
Furthermore, Wikipedia itself seems to buy into and cultivate the image of itself as a centralized, objective source of information about everything. One symptom of this is the fact that links within Wikipedia articles are always, or very nearly always, links to other Wikipedia articles. In spite of how open it is, in terms of contributions, it’s ultimately a closed system.
Yes, external sources are indicated at the bottom of articles. But the providing of sources, while important in terms of academic honesty and paper-trailing, never stopped scholarly publications from taking something very close to a “voice of God” position with regard to their subject matter. And it doesn’t stop Wikipedia from doing the same thing. How often have you bothered to go look up all the books and articles listed at the bottom of a Wikipedia article, and carefully analyzed how the information was gleaned and pieced together?
The editorial emphasis on balance and completeness and objectivity is another troubling sign. What’s wrong with balance? What’s wrong with it is that it’s a mirage. Any undergraduate who’s taken a reasonably decent mass communication course knows that what the news media call “balance” is simply an editorial or presentational style. And it requires constant reinforcement. “We report; you decide,” says Fox. “We’ll give you the world,” says at least one radio station (or conglomerate, probably, at this point). The idea is that the discouse provides a perfect substitute for the reality, so you can consider yourself to have been served the reality when you consume the discourse.
Wikipedia operates, I believe, in exponentially greater faith than the news media. But the philosophy of representation is the same, and it’s very old-school. An article is a simulacrum of a discrete, finite reality, and an article’s suitability for publication can be measured by how closely it has cloned that reality. While there’s often room for improvement, every article has the noble goal of achieving a perfect fit with its subject matter, and the potential to do so.
The fact, however, is that it’s not in the nature of written discourse to be a perfect fit with some arbitrary slice of reality. It doesn’t work that way. There’s no shame in acknowledging this, but Wikipedia battles against it.
What troubles me is not just that it’s child’s play to debunk the “voice of God” philosophy of discourse, but that I’d thought the Web was doing a pretty good job teaching people that reality and discourse actually map to each other sloppily, crazily, contradictorily, and ironically. Measured both by its editorial policies and by its wide, eager adoption as a centralized authority, Wikipedia unfortunately pushes against this more intriguing and, I would argue, more balanced take on things.