Ruby Idioms, Part 3
Written on 7:32:00 PM by S. Potter
Now, probably the biggest difference after the syntax, and the non-static nature of Ruby for Java heads to get used to is that Ruby is an "expressionist" language. Meaning almost all statements in Ruby evaluates to a value, i.e. everything that reasonably can be is an expression in Ruby is. This is definitely not the way Java thinks or works. So this will take some adjusting to. Don't worry I will show you an example. Now the Javafied Ruby code we will optimize is shown below:
user_id = nil if comments if comments.first if comments.first.user user_id = comments.first.user.id end end endNow that is some ugly code, but sometimes doing something equivalent to that in Java is very necessary. So how would a true Rubyist write that code:
user_id = comments && comments.first && comments.first.user && comments.first.user.idNow let us walk through what this really does.
comments
is evaluated, if it isnil
, then the valuenil
is returned, the boolean expression is exited out of (because it is all &&'s and fails at the first condition, thus the whole boolean expression fails) andnil
, which was the last value evaluated in that expression is set touser_id
. This is the same outcome that would have occurred in the first code snippet.- We repeat the process of the previous step for
comments.first
,comments.first.user
and finallycomments.first.user.id
until eithernil
is encountered and set as the value of user_id or the final part of the boolean expression evaluates to a non-nil value and that value is set to the value of user_id.

hi,
do you know about method "defined?" ?
user_id = comments.first.user.id if defined? comments.first.user
the method defined? returns nil if
its argument is not defined
The defined? operator returns nil if its argument (which can be an arbitrary expression)
is not defined; otherwise it returns a description of that argument. If the argument
is yield, defined? returns the string “yield” if a code block is associated with the
current context.
defined? 1 # => "expression"
defined? dummy # => nil
defined? printf # => "method"
defined? String # => "constant"
defined? $_ # => "globalvariable"
defined? Math::PI # => "constant"
defined? a = 1 # => "assignment"
defined? 42.abs # => "method"
Hi Ed,
Yes, of course I know defined?. I am glad you brought this up.
defined? is used in a different problem context to the context of the problem I use in this blog entry. It is a way to determine the type of object passed in rather than determining its value.
In the problem scenario in this blog entry we wish to determine whether it is nil or not.
I understand the approach you are suggesting to aid in the solution of this problem, however I do not find it more readable than the short-cut idiom that I propose, even though the it is not that elegant. I am not a fan of using defined? except for what it is intended for. Also the defined? solution would be slightly less terse, in addition to less readable (in my opinion). The vocabulary (i.e. "defined") is more codish than natural. That is my personal persuasion though. Others, I am sure, will have different opinions on this.
So, thanks for suggesting an alternative for other Ruby developers that may not object to using defined? in a solution to this problem.
SP
I should correct myself. The "defined?" approach may or may not be terser. It depends on mostly the length of variable names and number of constituents, for the purely terse inclined (not me).