-
Ruby Idioms & Shortcuts: Or Equals
I was recently looking for a Ruby authorization solution for the Platform app I’m developing. I had already settled on using Authlogic for authentication and session management, and wanted something that would play nice with what I had so far. Lockdown was one of the authorization libraries that I considered, but unfortunately it was unsuitable for my requirements.
For those interested in Lockdown there is a sample Rails app on GitHub. It was something I considered to make my decision whether to use Lockdown or not. During my examination of the App I noticed code in the ApplicationController that made me shudder:
class ApplicationController < ActionController::Base … def current_user_session if defined?(@current_user_session) && !@current_user_session.nil? return @current_user_session end @current_user_session = UserSession.find end endExtremely long winded.
What this method is doing is checking if the instance variable is defined i.e. has a value been assigned to it? Even assigning it nil is sufficient. If it has, it returns a string description of the object being checked, in this case “instance-variable”, which of course evaluates as true in Ruby, so the second half of the if condition is evaluated. This is checking that the instance variable does not have a nil value in an extremely backwards way, i.e. is the object not nil? SMH. If both conditions evaluate as true the instance variable is returned, if not, it is assigned the result of the find class method on the UserSession model.
As alluded to before, everything other than nil or false evaluates as true in Ruby, also if an object is undefined, the defined? operator will actually return nil, so if one was so inclined as to use an if block, all that would be necessary would be:
class ApplicationController < ActionController::Base … def current_user_session if @current_user_session return @current_user_session end @current_user_session = UserSession.find end endIf @current_user_session is undefined or has a nil value, the block will not evaluate and @current_user_session will be assigned using the class method of the UserSession model. Immediately we have trimmed some cruft off of this, but this is Ruby, and as is often the case, there is a better way.
Enter the equals or operator:
class ApplicationController < ActionController::Base … def current_user_session @current_user_session ||= UserSession.find end endHoly S*** Batman! We just took that down to one line and it is functionally equivalent!
Ok, what is this equals or operator? How does it work? It checks the left hand side and if it evaluates as true, the left hand side is returned, otherwise the result of the right hand side is assigned to the left hand side of the operator and returned.
I duly patched the app and sent a pull request to the maintainer, because this sort of code belies a poor understanding of Ruby and immediately dissuaded me from seriously considering Lockdown further. If the example app is written in such a style, I might reasonably infer that the library is written as such too. I thought others might come to the same conclusion.
The equals or operator: So short, so sweet, so necessary!
Thu24Dec