My favourite Ruby feature
Friday, March 31st, 2006It’s not a Rails thing. It’s not even a Ruby thing.
I was just writing a bit of code and trying to force it to pass its test and I realised I was going about it all the wrong way. What I needed to do was something that I used to do all the time in Smalltalk and had forgotten about.
It was this:
column_names = MyClass.content_columns.collect do | column | column.nameend
or
columnNames:= MyClass contentColumns collect: [ | column | column name.].
if you prefer.
It doesn’t look like much but the Smalltalk style iterators and collectors for collections make dealing with arrays and lists and the like so much simpler. Consider the equivalents (if Delphi or Java had an equivalent to ActiveRecord):
List columnNames = new LinkedList();Iterator i = MyClass.getContentColumns().iterator();while (i.hasNext()) { Column column = (Column)i.next(); columnNames.add(column.getName());}
or even worse
var I: Integer; S: TStringList; C: TColumn;begin S:= TStringList.Create; try for I:= 0 to MyClass.ContentColumns.Count - 1 do begin C:= MyClass.ContentColumns[I] as TColumn; S.Add(C.Name); end; // do something with the list of names finally S.Free; end;end;
OK, the Java doesn’t look too bad (and I’ve not used Java 1.5 so I don’t know about generics), but it reads, to me at least, like “go through the columns and do something with them” whereas the Ruby (Smalltalk) reads like “collect the column names“. And easier to read means easier to understand means easier to maintain.