Starting a new job in December
November 13th, 2009
I am very pleased and excited to announce that I have accepted a Senior Developer position with Cyrus Innovation, Inc. Cyrus is based in New York City. I will be, at least for the foreseeable future, assigned to a team working on-site at a New Jersey client. It’s a work-place I’ve been in before (I’ve done training for them), and I know some of the other members of the Cyrus team who work there. So while it’s definitely a big change for me and a new adventure, it’s also a familiar and collegial environment that I already know I like working in.
And it really is a big change! The last full-time job I had was my professorship at Seton Hall University (1992-2005).
The question is (drumroll…) why now?
Throughout the years that I’ve been doing freelance and independent consulting and training, I’ve regarded the prospect of a fulltime job with ambivalence. On the one hand, it’s less independent. And much of the brainstorming I’ve done this year about whether or not to seek a fulltime job has been kind of depressing, because it’s been motivated largely by the fact that my freelance business has dropped off a great deal (and I have no marketing skills, which means that when the market gets tight, I tend not to remain competitive). I’ve also been conflicted about fulltime jobs because I am very settled where I live and do not want to move.
On the other hand, I’ve always understood that a fulltime job would provide a measure of continuity and security that I’m increasingly feeling the lack of in my independent work. And, even more importantly, there’s the sense of belonging to a team of colleagues. I’ve always looked with a pang of envy at friends who are part of a development team, and whenever I’ve spent even a couple of weeks on a team helping out, it’s been incredibly stimulating. I always go through a big learning spurt when I work directly with other developers, and I don’t do nearly enough of it.
So I’d reached the point where I was interested in a full-time job but, fussy customer that I am, it had to be one that didn’t require me to sell my house and move, and that I had very, very good reason to believe would provide me with the kind of collegial environment that had been, for four years, the thing I had pined for the most as an independent. (I also didn’t want to telecommute, because sitting alone in my house literally all the time is not the right formula for me.)
Well, fast forward a bit and here I am, having found what I was hoping to find! That’s the story. I start December 7. (And all the “date that will live in infamy” jokes have already been made :-) Wish me luck!
The Compleat Rubyist: what's it all about?
October 17th, 2009
First things first:
In case you haven’t heard about it, I’m very excited to report that I am teaming up with two other Ruby programmer-authors, namely:
- Gregory Brown, author of Ruby Best Practices, and
- Jeremy McAnally, author of Ruby in Practice
to present The Compleat Rubyist, a two-day Ruby training event in Tampa, Florida, January 22-23 2010.
The idea behind the event
It all started with the books.
We got the idea of doing some kind of joint project because our books (including the two above, plus my book, The Well-Grounded Rubyist) complement each other really nicely. My book is a language tutorial. Jeremy’s book (to which both Greg and I contributed) contains advice about using Ruby in a series of application contexts. Greg’s book makes a different kind of pass through the language, with an eye to idiomatic, productive techniques.
A training event seemed like the perfect collaborative effort. We’ve designed an unusual format, optimized for in-depth learning and for a workshop/hands-on style.
Who’s it for?
I’ve been training Ruby programmers for years, and I can tell you that it’s very common to become quite good at Ruby but still have room for getting deeper into how things work, what the best practices are, and other areas.
I’d say that’s the “sweet spot” for our attendees: people who have been using Ruby, and want to go further in their understanding and skills.
Does that mean intermediate? advanced? talented beginner?
Hard to say. I’d like to think that almost any Ruby programmer can get something out of spending two days with us. (And we’re hoping to get a lot out of it too.) We’re not that concerned with pinpointing a level. Have a look at the event description, and decide whether it sounds good for you.
See you there, we hope!
We’re happy to field questions, if you have any. There’s a contact link on the event website, as well as links for registering and for more info about the venue.
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.
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!
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!
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.

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!