From: jweirich@... Date: 2000-11-07T10:49:08+09:00 Subject: [ruby-talk:6087] detect:ifNone: in Ruby I was recently converting a bit of Smalltalk code to Ruby. The code was written by Ron Jeffries to demonstrate Test First programming in the XP mailing list. (BTW, Dave Thomas was working on it as well and posted his version at http://www.egroups.com/message/extremeprogramming/15261?source=1 ... you can find Ron's Smalltalk version in the book "Extreme Programming Installed"). One of Ron's methods used detect:ifNone: ... matchingSum: aSum ^summary detect: [:each| each name = aSum name] ifNone: [summary add: (Sum name: aSum name amount: 0)] I went digging through the Ruby documentation and found "detect", but nothing that matched detect:ifNone:. No problem, I wrote the Ruby version as follows ... def matching_sum (aSum) result = @summary.detect { |each| each.name == aSum.name } if result == nil then result = Sum.new (aSum.name, 0) @summary << result end result end Because Ruby only allows a single code block to follow a method call, it is difficult to write methods that expect two separate code blocks. After a bit of thought, I realized that Smalltalk's detect:ifNone: method really combined two separate algorithms ... (1) Search for a value and (2) provide an alternative value. If we capture (2) in the following code ... def if_none (value) if value then value else yield end end Then we can rewrite matching_sum into ... def matching_sum (aSum) if_none (@summary.detect {|each| each.name == aSum.name}) do result = Sum.new (aSum.name, 0) @summary << result result end end There, that captures some of the flavor of the Smalltalk version. Is it worthwhile? Is it clearer? I'm not sure, but I thought it was interesting and that this list might enjoy it. -- -- Jim Weirich jweirich@one.net http://w3.one.net/~jweirich --------------------------------------------------------------------- "Beware of bugs in the above code; I have only proved it correct, not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)