However, I think that both Ruby and Ruby on Rails take the principle of brevity to an unreasonable extreme. Here are a few examples.
First, Ruby (the language) does not require parentheses around conditions or method arguments. So, you can write
instead offoo.bar baz, thud
In the second form, isn't it much more obvious that we're calling a method, and that baz and thud are the arguments?foo.bar( baz, thud )
As an even simpler (and more ambiguous) example, say that you see this code in a Ruby method:
A bare identifier does not really provide any clue that would suggest to the reader how the identifier is being used. In this case, it will be interpreted as a method call with no arguments. Wouldn't it be much more clear like this?blat
I think the general lack of visual cues in Ruby code makes it difficult to read.blat()
Rails code (at least in the books and on-line tutorials I have read) tends to opt for the same kind of extreme brevity. For example, consider the following code:
I found this code in an implementation of user authentication using something called Confluence4r. The code specifies what should happen when a privileged action is attempted without the proper credentials being present in the user's session. It's reasonably clear that a request is being redirected. However, an options hash is being used to specify the details of the redirection.redirect_to :action => :login, \
:destination => request.request_uri \
and return false
I guess that options hashes are good in the sense that unnecessary information can be omitted. However, I think options hashes are overused in Rails. An options hash is basically a "magic bag of goodies" that a method will use to carry out some behavior. However, the specification of the options hash at the call site does very little to inform the reader how the contents of the hash will influence the behavior of the called method. In the case above, it's reasonably clear that :action => :login will redirect to the login action. However, what is going on the :destination key? As far as I can tell, it simply puts request.request_uri in the query parameters of the redirected request, but I fail to see how that behavior is even hinted at in the text of the method call. Wouldn't something like the following be much clearer?
Sure, we replaced 1 line of code with 5, but the reader would have a much better chance of figuring out what is going on.next_request = Request.new()
next_request,set_action( :login )
next_request.add_param( :destination, request.request_uri() )
redirect_to( next_request )
return false
Sacrificing a bit of brevity in order to get self-documenting code seems like a good tradeoff to me.
No comments:
Post a Comment