On Jan 7, 2006, at 1:08 PM, Robert Klemme wrote:
>>
>> You mean #detect or #select?
>
> #detect - because it stops as soon as it has a hit while #select  
> will return an array.  We need just the first hit.
>
>>> [nil,nil,nil,"w",2,3].find {|x|puts x;x}
> nil
> nil
> nil
> w
> => "w"
>>> [nil,nil,nil,"w",2,3].select {|x|puts x;x}
> nil
> nil
> nil
> w
> 2
> 3
> => ["w", 2, 3]
>

The trouble is that detect returns the 'x' not the result of  
processing x successfully (or, in terms of the original post, the  
class that accepts the token not the result of the #parse? method).  
That's why you have to capture the result in the block. Map returns  
the result of processing.

>> elements = tokens.select do |token|
>>   result = nil
>>   [ClassA, ClassB, ClassC].find { |kind| results << kind.parse?
>> (token) }
>>   result
>> end
>
> You don't define results and you never assign result another value  
> than nil...

Sorry, I've 'corrected' myself in a mail I just sent out. (My email  
is suffering long delays today, and my mind isn't working all that  
quickly either I think)

This is what I had intended with the "<< results" is:

results = []
tokens.each do |token|
   # use find over the collection of classes to find the one that  
successfully parses the
   # token. Find will return the class, not the result of #parse?, so  
capture that result
   # by using a closure on result (Note: result must appear outside  
of and before the block.
   # Collect each result in results.
   result = nil
   [ClassA, ClassB, ClassC].find { |kind| result = kind.parse?(token)}
   results << result if result
end

If you also want the nil results then you can use:

elements = tokens.map do |token|
   result = nil
   [ClassA, ClassB, ClassC].find { |kind| result = kind.parse?(token)}
   result
end


> Say what you want, find/detect is the most elegant solution.
>

Only they return the wrong things.

>    robert
>
>

----
Bob Hutchison                  -- blogs at <http://www.recursive.ca/ 
hutch/>
Recursive Design Inc.          -- <http://www.recursive.ca/>
Raconteur                      -- <http://www.raconteur.info/>
xampl for Ruby                 -- <http://rubyforge.org/projects/xampl/>