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/>