Some time ago I'd written about how Twitter's descriptions of their own codebase made my hackles rise.
I wasn't alone in this, and one discussion thread on the internal ThoughtWorks dev list later we had some hard numbers extracted from all the Ruby work we've done or are doing.
Martin's put them up on his bliki - take a look. There are the numbers to back the talk - you don't need type checks all over your codebase in Ruby (or any other dynamic language), Alex Payne's opinion notwithstanding.
Showing posts with label darkness. Show all posts
Showing posts with label darkness. Show all posts
Collections, each and the violation of encapsulation
Every so often I come across a bit of code which looks something like this:
Yeah, I know you language punters are looking at this and going 'yech'; but folks new to blocks and used to
Here's the deal: when using blocks with collections in Ruby, always respect the sanctity of a block passed to a collection. Never misuse the closure created with the block to manipulate objects outside the scope of the block - in this example using
There are a couple of smells you always come across in such situations:
The (trivial) example I've given would be better solved using
def upcase_collection(collection)
array = []
collection.each{|item| array << item.upcase}
array
end
Yeah, I know you language punters are looking at this and going 'yech'; but folks new to blocks and used to
for loops aren't likely see the problem.Here's the deal: when using blocks with collections in Ruby, always respect the sanctity of a block passed to a collection. Never misuse the closure created with the block to manipulate objects outside the scope of the block - in this example using
array as an accumulator. There are always better ways to do this without violating encapsulation, the other collection methods available in Enumerable being a case in point.There are a couple of smells you always come across in such situations:
- The presence of objects whose states are changed from within a block in a different scope
- The fact that you need a temporary variable at all in the first place
- The availability of methods like
collect,partitionorinjectwhich do exactly what you need - for free.
The (trivial) example I've given would be better solved using
collect.
Subscribe to:
Posts (Atom)