Geek Blog for Little Red String

Geek stuff, amature programming, Linux, Ruby, open source

Ruby — Inject

I’ve done a little bit of programming (as a hobby) in a few languages (C, C++, Java and Scheme) and Ruby stands out to me as both “easy” and “fun”. One of Ruby’s strongest points is it’s readability. Phrases like

3.times{ puts "Good Morning" } unless sun.down? 

are often touted in introductory lessons. The Java equivalent is

if (! sun.down) {
   for (int c=0; c<3; c++) {
      System.out.println( "Good Morning" );
   }
}

I really gave Java a break here because in order to run that program I had to wrap it in a class and use the classic Java idiom “public static void main()”. Idioms like Java’s and other’s “for (int c=0; c<num; c++){}” get annoying after you get a good taste of Ruby. Once Ruby starts catching on in your mind you’ll make all kinds of excuses for it like when your hot, new girlfriend drops an F-bomb in front of your mother.

Ruby’s F-bomb in this post is “inject”. I just learned about inject today and despite being confusing and unreadable I still find it charming. I recently wrote a quick script to search for people’s names in text files. If this script finds someone in a text file it puts the name of the text file next to the person’s name. Part of this script builds a String (like: “John Johnson, list_of_users1.txt, list_of_users2.txt”) before putting it in a csv file.

def check_presence_of_user( user )
   s = user.to_s
   files_to_check.each do |file|
      s << (',' + file.name) if file.has_user(user)
   end
   return s
end

This code takes each users and adds them to a String. Then we run through each check file and, if the user is in a file, we add that filename to the string. Finally we return the string. Refactoring this simple piece of code with inject is fun.

def check_presence_of_user( user )
   files_to_check.inject(user.to_s) do |s, file|
      s << (',' + file.name) if file.has_user(user)
   end
end

Basically we just eliminated “setting up” the string, which is where I find myself using inject most often; when building strings. This code seems readable to me in a Why The Lucky Stiff sort of way where you imaging a syringe that starts with “user.to_s” in it and keeps sucking up the output of the block and squirting it back in for another round. However I’ve also seen some inject snippets that that make my head explode.