It’s not a secret, Ruby syntax offers many possibilities. One thing I enjoy doing once in a while is to take some code I have written a few days before and improve it to make it look more rubyish (read : short, expressive and readable).
I thought it could be fun to make a little game out of it. I’ll put a chunk of code that needs some improvement. Try to analyze and rubyize it.
Be warned though, the code snippet of today is quite stupid. It has been written by Fleebie, the red slime with a trumpet piston shaped mouth.
def manage_ducks(ducks)
if ducks == nil
ducks = fetch_some_champions
else
unless ducks.won_stanley_cup?
ducks = fetch_some_champions
end
end
ducks.beat_random_opponent
end
That’s it. How would you rubyize this piece of code?
#UPDATE : It seems that the PRE tag tip I talked about doesn’t work. WordPress strips the pre tags when you are not an administrator. I may have to hack some php files to make it work. Someone knows a wordpress plugin that let the users write nice and indented code snippets?
Here is an alternative to get the idea rolling.
it doesn’t appear that wrapping in tags works.
ducks = fetch_some_champions unless ducks and ducks.won_stanley_cup?
ducks.beat_random_opponent
The code is ugly indeed. I agree with Aplha Chen’s suggestion, its the same I have came up with. Pretty and still nice and readable.
Here it is:
Nando and Alpha Chen solutions were exactly what I had in mind. IMHO, Nando’s solutions is a bit better, using the “nil?” method, which is easier to understand. Just a minor correction on the logic:
One thing I noticed no one was doing is taking advantage of Ruby returning an object from assignment. The whole ducks.beat_random_opponent thing can do without the ducks.
Also, you don’t have to ask “if ducks.nil?” when “if ducks” works just fine and is perfectly idiomatic Ruby.
Thanks everyone for commenting in this first edition of Rubyize this (seeing it was quite popular there will be some more).
My favorite solution is without a doubt the one by Nando (once you remove the logic mistake like Silvio has pointed out) and Casey. In this situation I prefer the if over unless because it feels more natural. (unless ducks and ducks.won_stanley_cup? can be a bit confusing when you read it).
I’d also like to talk about RSL suggestions which I find very interesting (the second one is a bit cryptic… but still pretty nice). Although the first solution looks awkward at first, I find it extremely readable and clean. I’ll try to include some of this stuff in my applications in the future.
RSL, however I don’t understand your last comment. “if ducks.nil?” is definitely not the same as “if ducks”. I guess you wanted to say “unless ducks”.
Sorry… my bad! 😉
I posted it without reviewing just to be fast.. huahahuahuau. 😛
Woops. You’re right. I did have that backwards. I guess I shouldn’t post comments [especially not ones containing _code_] before I’ve finished my morning coffee.
A little late, but this is an interesting approach:
def manage_ducks(ducks)
throw(nil) unless ducks.won_stanley_cup? rescue ducks = fetch_some_champions
ducks.beat_random_opponent
end
A little weird, but it works. If ducks is nil, the unless clause will throw an exception; if
won_stanley_cup? is false, it throws a nil exception.