From: ara.t.howard@... Date: 2006-01-07T14:59:38+09:00 Subject: Re: Iterator Fu Failing Me On Sat, 7 Jan 2006, James Edward Gray II wrote: > I have a group of classes, all implementing a parse?() class method. Calling > parse?(token) will return the constructed object, if it can be parsed by this > class, or false otherwise. > > I want to run a bunch of tokens through these classes, grabbing the first > fit. For example: > > elements = tokens.map do |token| > ClassA.parse?(token) or > ClassB.parse?(token) or > ClassC.parse?(token) > end > > That works. Now can anyone give me a version of the middle section that > doesn't require I call parse?() 50 times? I want something close to: > > elements = tokens.map do |token| > [ClassA, ClassB, ClassC].find { |kind| kind.parse?(token) } > end > > Except that I want the return result of parse?(), instead of the class that > took it. harp:~ > cat a.rb module Parser module ClassMethods def parse tokens, klasses tokens.map{|token| catch('parse!'){ klasses.each{|klass| klass.parse! token}; nil}} end def parse! token ret = parse?(token) and throw 'parse!', ret end def parse? token return "<#{ token }> parsed by <#{ self }>" if token =~ self::RE end end module InstanceMethods end def self::included other other.module_eval{ extend ClassMethods and include InstanceMethods } end extend ClassMethods and include InstanceMethods end class ClassA include Parser RE = /a/ end class ClassB include Parser RE = /b/ end class ClassC include Parser RE = /c/ end elements = Parser::parse %w( a b c d ), [ClassA, ClassB, ClassC] p elements harp:~ > ruby a.rb [" parsed by ", " parsed by ", " parsed by ", nil] you can probably come up with something shorter - but using catch/throw with parsers is very useful to break of conditions like these. cheers. -a -- =============================================================================== | ara [dot] t [dot] howard [at] noaa [dot] gov | all happiness comes from the desire for others to be happy. all misery | comes from the desire for oneself to be happy. | -- bodhicaryavatara ===============================================================================