I was recently playing with Rails again. A while back a site I was working on had an issue where the parameters from an uploaded form were all coming in as file objects – even the parts that didn’t correspond to uploaded files. The client in this case was some Java software using the Apache Httpclient library. We’d only recently upgraded Rails, and it turned out we were seeing the problem described here:
The problem was easily worked around. This led me on a hunt, however, for some documentation on how exactly you are meant to handle form uploads in Rails. About the only vaguely official-looking documentation I can find at this point is the Action Controller Overview guide, which has this to say:
Note that parameter values are always strings; Rails makes no attempt to guess or cast the type
Clearly baloney. If one of the form parts is a file upload, then what you get is an object with several methods defined including “read” to return the contents of the file as a string, as well as things like “original_filename” which tell you the filename as specified by the uploader. None of this is documented anywhere.
It’s this “we don’t need to document it” attitude that really annoys me about Rails. Sure, there’s all this magical stuff you can do with it and it has all these built-in goodies that can save you hours of coding just by using magic variable names (except for those times of course when you have to spend hours debugging, because you used one of those magic variable names by mistake and without realising). But there’s just no reliability with the API. The params hash for instance – what exactly am I allowed to do with a value I pull from the hash? Can I be sure that it will either be a string or one of these mysterious file upload objects? This isn’t the only omission in the documentation; for instance what does the “session” method in ActionController::Request actually return? What am I allowed to call on it?
This is the real strength of languages with strong typing – programs written in them are, to a certain degree, self-documenting. If I know what type a method actually returns then I know for certain what methods I can call. No nasty surprises when the framework developers suddenly decide to make it return a different kind of object!
Edit 27/8/2010: Another major strength of statically-typed languages that I forgot to mention is of course the ability to refactor code with the assistance of automated tools. As discussed in this blog post by Cedric (and I love the title).