Jun 24, 2007 @ 11:56 pm

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.

  1. def manage_ducks(ducks)
  2.   if ducks == nil
  3.     ducks = fetch_some_champions
  4.   else
  5.     unless ducks.won_stanley_cup?   
  6.       ducks = fetch_some_champions
  7.     end
  8.   end
  9.   ducks.beat_random_opponent
  10. 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?

Bookmark this post : These icons link to social bookmarking sites where readers can share and discover new web pages.
  • DZone
  • Reddit
  • del.icio.us
  • Digg
  • Furl
  • Technorati
  • StumbleUpon
Rate this post :
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...
Posted under : short & sweet
13 Comments
MyAvatars 0.2

Here is an alternative to get the idea rolling.

def manage_ducks(ducks)
  if ducks.nil? || !ducks.won_stanley_cup?
    ducks = fetch_some_champions
  end
  ducks.beat_random_opponent
end
Comment by : Gerry
— June 25, 2007 @ 12:41 am

MyAvatars 0.2

it doesn’t appear that wrapping in tags works.

Comment by : Gerry
— June 25, 2007 @ 12:42 am

MyAvatars 0.2

ducks = fetch_some_champions unless ducks and ducks.won_stanley_cup?
ducks.beat_random_opponent

Comment by : Alpha Chen
— June 25, 2007 @ 1:02 am

MyAvatars 0.2

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.

Comment by : Jbosss
— June 25, 2007 @ 7:13 am

MyAvatars 0.2

Here it is:

def manage_ducks(ducks)
  ducks = ducks.fetch_some_champions unless ducks.nil? || ducks.won_stanley_cup?
  ducks.beat_random_opponent
end
Comment by : Nando Vieira
— June 25, 2007 @ 8:15 am

MyAvatars 0.2
def manage_ducks(ducks)
  ducks = fetch_some_champions if ducks.nil? || !ducks.won_stanley_cup?
  ducks.beat_random_opponent
end
Comment by : Casey Winans
— June 25, 2007 @ 8:52 am

MyAvatars 0.2

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:

def manage_ducks(ducks)
  ducks = ducks.fetch_some_champions if ducks.nil? || !ducks.won_stanley_cup?
  ducks.beat_random_opponent
end
Comment by : Silvio Fonseca
— June 25, 2007 @ 9:06 am

MyAvatars 0.2

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.

# Verbose
def manage_ducks(ducks)
  unless ducks and ducks.won_stanley_cup?
    fetch_some_champions
  else
    ducks
  end.beat_random_opponent
end

# Superterse, if Perl-y
def manage_ducks(ducks)
  ((ducks && ducks.won_stanley_cup?) ? ducks : fetch_some_champions).beat_random_opponent
end
Comment by : RSL
— June 25, 2007 @ 11:18 am

MyAvatars 0.2

Also, you don’t have to ask “if ducks.nil?” when “if ducks” works just fine and is perfectly idiomatic Ruby.

Comment by : RSL
— June 25, 2007 @ 11:20 am

MyAvatars 0.2

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”.

Comment by : Frank
— June 25, 2007 @ 6:33 pm

MyAvatars 0.2

Sorry… my bad! ;)
I posted it without reviewing just to be fast.. huahahuahuau. :P

Comment by : Nando Vieira
— June 25, 2007 @ 7:14 pm

MyAvatars 0.2

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.

Comment by : RSL
— June 25, 2007 @ 11:24 pm

MyAvatars 0.2

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.

Comment by : Matt Jones
— June 27, 2007 @ 10:10 pm




Leave a comment
Name (required)
Email (will not be publish) (required)
Website