# Iterator Fu Failing Me

**URL:** <https://rubytalk.org/t/iterator-fu-failing-me/23918>\
**Category:** ruby-talk\
**Created:** [7 January 2006 04:36 UTC](https://rubytalk.org/t/iterator-fu-failing-me/23918 "2006-01-07T04:36:30Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![James\_Edward\_Gray\_II](https://avatars.discourse-cdn.com/v4/letter/j/ea5d25/32.png) [@James\_Edward\_Gray\_II](https://rubytalk.org/u/James_Edward_Gray_II)\
**Post date:** [7 January 2006 04:36 UTC](https://rubytalk.org/t/iterator-fu-failing-me/23918/1 "2006-01-07T04:36:30Z")

</div>

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:

&nbsp;&nbsp;&nbsp;elements = tokens.map do |token|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ClassA.parse?(token) or  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ClassB.parse?(token) or  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ClassC.parse?(token)  
&nbsp;&nbsp;&nbsp;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:

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

Except that I want the return result of parse?(), instead of the class that took it.

Thanks for any tips you can offer.

James Edward Gray II

---

<div class="post-metadata">

**Author:** ![Marcel\_Molina\_Jr](https://avatars.discourse-cdn.com/v4/letter/m/edb3f5/32.png) [@Marcel\_Molina\_Jr](https://rubytalk.org/u/Marcel_Molina_Jr)\
**Post date:** [7 January 2006 04:39 UTC](https://rubytalk.org/t/iterator-fu-failing-me/23918/2 "2006-01-07T04:39:27Z")

</div>

do/end doesn't bind tightly enough for the assignment to 'elements'. Using {}  
should work.

marcel

> **···**
>
> On Sat, Jan 07, 2006 at 01:36:30PM +0900, 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:
> > 
> > &nbsp;&nbsp;elements = tokens.map do |token|  
> > &nbsp;&nbsp;&nbsp;&nbsp;ClassA.parse?(token) or  
> > &nbsp;&nbsp;&nbsp;&nbsp;ClassB.parse?(token) or  
> > &nbsp;&nbsp;&nbsp;&nbsp;ClassC.parse?(token)  
> > &nbsp;&nbsp;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:
> > 
> > &nbsp;&nbsp;elements = tokens.map do |token|  
> > &nbsp;&nbsp;&nbsp;&nbsp;[ClassA, ClassB, ClassC].find { |kind| kind.parse?(token) }  
> > &nbsp;&nbsp;end
> > 
> > Except that I want the return result of parse?(), instead of the  
> > class that took it.
> 
> --  
> Marcel Molina Jr. \<marcel@vernix.org\>

---

<div class="post-metadata">

**Author:** ![Mike\_Harris1](https://avatars.discourse-cdn.com/v4/letter/m/e5b9ba/32.png) [@Mike\_Harris1](https://rubytalk.org/u/Mike_Harris1)\
**Post date:** [7 January 2006 05:38 UTC](https://rubytalk.org/t/iterator-fu-failing-me/23918/3 "2006-01-07T05:38:01Z")

</div>

Are "Write a new Enumerable method that mimics find but returns the  
block result instead" or "do a less elegant solution involving  
assignment" not acceptable solutions?

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:
> > 
> > &nbsp;&nbsp;&nbsp;elements = tokens.map do |token|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ClassA.parse?(token) or  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ClassB.parse?(token) or  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ClassC.parse?(token)  
> > &nbsp;&nbsp;&nbsp;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:
> > 
> > &nbsp;&nbsp;&nbsp;elements = tokens.map do |token|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ClassA, ClassB, ClassC].find { |kind| kind.parse?(token) }  
> > &nbsp;&nbsp;&nbsp;end
> > 
> > Except that I want the return result of parse?(), instead of the  
> > class that took it.
> > 
> > Thanks for any tips you can offer.
> > 
> > James Edward Gray II

---

<div class="post-metadata">

**Author:** ![Ara.T.Howard6](https://avatars.discourse-cdn.com/v4/letter/a/958977/32.png) [@Ara.T.Howard6](https://rubytalk.org/u/Ara.T.Howard6)\
**Post date:** [7 January 2006 05:59 UTC](https://rubytalk.org/t/iterator-fu-failing-me/23918/4 "2006-01-07T05:59:38Z")

</div>

harp:~ \> cat a.rb

&nbsp;&nbsp;&nbsp;module Parser  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;module ClassMethods  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def parse tokens, klasses  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tokens.map{|token| catch('parse!'){ klasses.each{|klass| klass.parse! token}; nil}}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def parse! token  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret = parse?(token) and throw 'parse!', ret  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def parse? token  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return "\<#{ token }\> parsed by \<#{ self }\>" if token =~ self::RE  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;module InstanceMethods  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def self::included other  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;other.module\_eval{ extend ClassMethods and include InstanceMethods }  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;extend ClassMethods and include InstanceMethods  
&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;class ClassA  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;include Parser  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RE = /a/  
&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;class ClassB  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;include Parser  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RE = /b/  
&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;class ClassC  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;include Parser  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RE = /c/  
&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;elements = Parser::parse %w( a b c d ), [ClassA, ClassB, ClassC]

&nbsp;&nbsp;&nbsp;p elements

&nbsp;&nbsp;&nbsp;harp:~ \> ruby a.rb  
&nbsp;&nbsp;&nbsp;["\<a\> parsed by \<ClassA\>", "\<b\> parsed by \<ClassB\>", "\<c\> parsed by \<ClassC\>", 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

> **···**
>
> 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|  
> > &nbsp;&nbsp;&nbsp;ClassA.parse?(token) or  
> > &nbsp;&nbsp;&nbsp;ClassB.parse?(token) or  
> > &nbsp;&nbsp;&nbsp;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|  
> > &nbsp;&nbsp;&nbsp;[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.
> 
> # --
> 
> > 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
> 
> ===============================================================================

---

<div class="post-metadata">

**Author:** ![Anonymous\_Coward](https://avatars.discourse-cdn.com/v4/letter/a/94ad74/32.png) [@Anonymous\_Coward](https://rubytalk.org/u/Anonymous_Coward)\
**Post date:** [7 January 2006 06:15 UTC](https://rubytalk.org/t/iterator-fu-failing-me/23918/5 "2006-01-07T06:15:49Z")

</div>

> 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:
> 
> &nbsp;&nbsp;elements = tokens.map do |token|  
> &nbsp;&nbsp;&nbsp;&nbsp;ClassA.parse?(token) or  
> &nbsp;&nbsp;&nbsp;&nbsp;ClassB.parse?(token) or  
> &nbsp;&nbsp;&nbsp;&nbsp;ClassC.parse?(token)  
> &nbsp;&nbsp;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:
> 
> &nbsp;&nbsp;elements = tokens.map do |token|  
> &nbsp;&nbsp;&nbsp;&nbsp;[ClassA, ClassB, ClassC].find { |kind| kind.parse?(token) }  
> &nbsp;&nbsp;end

&nbsp;&nbsp;# Not tested  
&nbsp;&nbsp;elements = tokens.map {|token|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[A, B, C].each {|kind|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result = kind.parse?(token) and break result  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

> Except that I want the return result of parse?(), instead of the  
> class that took it.
> 
> Thanks for any tips you can offer.
> 
> James Edward Gray II

E

> **···**
>
> On 2006.01.07 13:36, James Edward Gray II wrote:

---

<div class="post-metadata">

**Author:** ![Michael\_Q\_Harris](https://avatars.discourse-cdn.com/v4/letter/m/ba8739/32.png) [@Michael\_Q\_Harris](https://rubytalk.org/u/Michael_Q_Harris)\
**Post date:** [7 January 2006 08:13 UTC](https://rubytalk.org/t/iterator-fu-failing-me/23918/6 "2006-01-07T08:13:01Z")

</div>

Are "Write a new Enumerable method that mimics find but returns the  
block result instead" or "do a less elegant solution involving  
assignment" not acceptable solutions?

---

<div class="post-metadata">

**Author:** ![Henrik\_Martensson](https://avatars.discourse-cdn.com/v4/letter/h/e95f7d/32.png) [@Henrik\_Martensson](https://rubytalk.org/u/Henrik_Martensson)\
**Post date:** [7 January 2006 10:33 UTC](https://rubytalk.org/t/iterator-fu-failing-me/23918/7 "2006-01-07T10:33:21Z")

</div>

I am not certain if this solution fits, but...

There is a refactoring named Replace Conditional with Polymorphism that  
might solve your problem. The idea is that when you have a conditional,  
you can create a class hierarchy with one subclass for each leg in the  
conditional. (See  
[Replace Conditional with Polymorphism](http://www.refactoring.com/catalog/replaceConditionalWithPolymorphism.html) for a slightly better explanation.)

You already have several different parser classes, and of course you  
don't need to bother with a class hierarchy, so you could do something  
like:

parser = ParserFactory.create(parser\_type)  
...  
elements = tokens.map do |token|  
&nbsp;&nbsp;parser.parse?(token)  
end

Note that 'parser\_type' may well be the class of a token in tokens.

This works assuming that all tokens in 'tokens' are of the same type.  
For example, you have one parser for handling CSV data, another for XML,  
a third for SGML, a fourth for non-compliant HTML, etc.

On the other hand, if each parser class handles a subset of the tokens  
you get from one type of input, for example you have tokenized an XML  
file, and have one parser for elements, another for processing  
instructions, a third for text nodes, etc., you will need something  
different. A case statement would do the trick:

elements = tokens.map do |token|  
&nbsp;&nbsp;case token  
&nbsp;&nbsp;&nbsp;&nbsp;when Element  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ElementParser.parse?(token)  
&nbsp;&nbsp;&nbsp;&nbsp;when Text  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TextParser.parse?(token)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...  
&nbsp;&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise "Unknown token type"  
&nbsp;&nbsp;end  
end

You can then factor out the case statement into a method named parse?,  
move the parse? method to a class of it's own, and be back to:

elements = tokens.map do |token|  
&nbsp;&nbsp;ParseEverything.parse?(token)  
end

A while ago I wrote a CSV parser in Java for a talk on Test Driven  
Design. The Java code got horribly complex, but it struck me that in  
Ruby I could do this:

class Parser  
&nbsp;&nbsp;def parse(reader, writer)  
&nbsp;&nbsp;&nbsp;&nbsp;tokenize(reader) { |type| |value|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;write(type, value, writer)  
&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;end  
end

By mixing in tokenize and write methods, it would be possible to build  
parsers that handle most formats.

I hope this helps.

/Henrik

> **···**
>
> On Sat, 2006-01-07 at 05:36, 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:
> > 
> > &nbsp;&nbsp;&nbsp;elements = tokens.map do |token|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ClassA.parse?(token) or  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ClassB.parse?(token) or  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ClassC.parse?(token)  
> > &nbsp;&nbsp;&nbsp;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
> 
> --
> 
> [http://www.henrikmartensson.org/](http://www.henrikmartensson.org/) - Reflections on software development

---

<div class="post-metadata">

**Author:** ![Brian\_Mitchell](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Brian\_Mitchell](https://rubytalk.org/u/Brian_Mitchell)\
**Post date:** [7 January 2006 11:03 UTC](https://rubytalk.org/t/iterator-fu-failing-me/23918/8 "2006-01-07T11:03:56Z")

</div>

How about:

elements = tokens.map do |token|  
&nbsp;&nbsp;[ClassA, ClassB, ClassC].inject(false) {|m, kind| m or kind.parse?(token)}  
end

It isn't perfectly efficient but it is short.

Brian.

> **···**
>
> On 1/6/06, James Edward Gray II \<james@grayproductions.net\> 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:
> > 
> > &nbsp;&nbsp;&nbsp;elements = tokens.map do |token|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ClassA.parse?(token) or  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ClassB.parse?(token) or  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ClassC.parse?(token)  
> > &nbsp;&nbsp;&nbsp;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:
> > 
> > &nbsp;&nbsp;&nbsp;elements = tokens.map do |token|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ClassA, ClassB, ClassC].find { |kind| kind.parse?(token) }  
> > &nbsp;&nbsp;&nbsp;end

---

<div class="post-metadata">

**Author:** ![Robert](https://avatars.discourse-cdn.com/v4/letter/r/e95f7d/32.png) [@Robert](https://rubytalk.org/u/Robert)\
**Post date:** [7 January 2006 13:33 UTC](https://rubytalk.org/t/iterator-fu-failing-me/23918/9 "2006-01-07T13:33:00Z")

</div>

elements = tokens.map do |tok|  
&nbsp;&nbsp;parsers.inject(false) {|a,par| a=par.parse(tok) and break a}  
end

alternative using a method definition

def parse(token)  
&nbsp;&nbsp;parsers.each {|par| a=par.parse(token) and return a}  
&nbsp;&nbsp;false  
end

But the best solution is

elements = tokens.map do |tok|  
&nbsp;&nbsp;parsers.detect {|par| par.parse(tok)}  
end

🙂

Kind regards

&nbsp;&nbsp;&nbsp;&nbsp;robert

> **···**
>
> James Edward Gray II \<james@grayproductions.net\> 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:
> > 
> > &nbsp;&nbsp;elements = tokens.map do |token|  
> > &nbsp;&nbsp;&nbsp;&nbsp;ClassA.parse?(token) or  
> > &nbsp;&nbsp;&nbsp;&nbsp;ClassB.parse?(token) or  
> > &nbsp;&nbsp;&nbsp;&nbsp;ClassC.parse?(token)  
> > &nbsp;&nbsp;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:
> > 
> > &nbsp;&nbsp;elements = tokens.map do |token|  
> > &nbsp;&nbsp;&nbsp;&nbsp;[ClassA, ClassB, ClassC].find { |kind| kind.parse?(token) }  
> > &nbsp;&nbsp;end
> > 
> > Except that I want the return result of parse?(), instead of the  
> > class that took it.
> > 
> > Thanks for any tips you can offer.
> > 
> > James Edward Gray II

---

<div class="post-metadata">

**Author:** ![Bob\_Hutchison1](https://avatars.discourse-cdn.com/v4/letter/b/9e8a1a/32.png) [@Bob\_Hutchison1](https://rubytalk.org/u/Bob_Hutchison1)\
**Post date:** [7 January 2006 16:04 UTC](https://rubytalk.org/t/iterator-fu-failing-me/23918/10 "2006-01-07T16:04:13Z")

</div>

Why not:

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

> **···**
>
> On Jan 6, 2006, at 11:36 PM, James Edward Gray II wrote:
> 
> > 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:
> > 
> > &nbsp;&nbsp;elements = tokens.map do |token|  
> > &nbsp;&nbsp;&nbsp;&nbsp;[ClassA, ClassB, ClassC].find { |kind| kind.parse?(token) }  
> > &nbsp;&nbsp;end
> > 
> > Except that I want the return result of parse?(), instead of the class that took it.
> 
> ----  
> Bob Hutchison -- blogs at \<[http://www.recursive.ca/hutch/&gt](http://www.recursive.ca/hutch/&gt);  
> Recursive Design Inc. -- \<[http://www.recursive.ca/&gt](http://www.recursive.ca/&gt);  
> Raconteur -- \<[http://www.raconteur.info/&gt](http://www.raconteur.info/&gt);  
> xampl for Ruby -- \<[http://rubyforge.org/projects/xampl/&gt](http://rubyforge.org/projects/xampl/&gt);

---

<div class="post-metadata">

**Author:** ![jwesley](https://avatars.discourse-cdn.com/v4/letter/j/74df32/32.png) [@jwesley](https://rubytalk.org/u/jwesley)\
**Post date:** [9 January 2006 00:58 UTC](https://rubytalk.org/t/iterator-fu-failing-me/23918/11 "2006-01-09T00:58:01Z")

</div>

Perhaps I'm missing the point, but wouldn't the following work: (?)

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

Justin

---

<div class="post-metadata">

**Author:** ![James\_Edward\_Gray\_II](https://avatars.discourse-cdn.com/v4/letter/j/ea5d25/32.png) [@James\_Edward\_Gray\_II](https://rubytalk.org/u/James_Edward_Gray_II)\
**Post date:** [7 January 2006 04:47 UTC](https://rubytalk.org/t/iterator-fu-failing-me/23918/12 "2006-01-07T04:47:01Z")

</div>

> > &nbsp;&nbsp;elements = tokens.map do |token|  
> > &nbsp;&nbsp;&nbsp;&nbsp;[ClassA, ClassB, ClassC].find { |kind| kind.parse?(token) }  
> > &nbsp;&nbsp;end
> > 
> > Except that I want the return result of parse?(), instead of the  
> > class that took it.
> 
> do/end doesn't bind tightly enough for the assignment to 'elements'. Using {}  
> should work.

Sure it does:

\>\> numbers = (1..3).map do |n|  
?\> n \* 2  
\>\> end  
=\> [2, 4, 6]

My problem is not syntax. It's that I can't find a way to iterate to the result of parse?().

James Edward Gray II

> **···**
>
> On Jan 6, 2006, at 10:39 PM, Marcel Molina Jr. wrote:
> 
> > On Sat, Jan 07, 2006 at 01:36:30PM +0900, James Edward Gray II wrote:

---

<div class="post-metadata">

**Author:** ![Ara.T.Howard6](https://avatars.discourse-cdn.com/v4/letter/a/958977/32.png) [@Ara.T.Howard6](https://rubytalk.org/u/Ara.T.Howard6)\
**Post date:** [7 January 2006 14:49 UTC](https://rubytalk.org/t/iterator-fu-failing-me/23918/13 "2006-01-07T14:49:15Z")

</div>

fails when no kind parses. in this case the result will be

&nbsp;&nbsp;&nbsp;[[A,B,C]] (the return of each...)

regards.

-a

> **···**
>
> On Sat, 7 Jan 2006, Eero Saynatkari wrote:
> 
> > On 2006.01.07 13:36, 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:
> > > 
> > > &nbsp;&nbsp;elements = tokens.map do |token|  
> > > &nbsp;&nbsp;&nbsp;&nbsp;ClassA.parse?(token) or  
> > > &nbsp;&nbsp;&nbsp;&nbsp;ClassB.parse?(token) or  
> > > &nbsp;&nbsp;&nbsp;&nbsp;ClassC.parse?(token)  
> > > &nbsp;&nbsp;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:
> > > 
> > > &nbsp;&nbsp;elements = tokens.map do |token|  
> > > &nbsp;&nbsp;&nbsp;&nbsp;[ClassA, ClassB, ClassC].find { |kind| kind.parse?(token) }  
> > > &nbsp;&nbsp;end
> > 
> > # Not tested  
> > elements = tokens.map {|token|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[A, B, C].each {|kind|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result = kind.parse?(token) and break result  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
> 
> # --
> 
> > ara [dot] t [dot] howard [at] noaa [dot] gov  
> > strong and healthy,  
> > who thinks of sickness until it strikes like lightning?  
> > preoccupied with the world,  
> > who thinks of death, until it arrives like thunder?  
> > -- milarepa
> 
> ===============================================================================

---

<div class="post-metadata">

**Author:** ![Ara.T.Howard6](https://avatars.discourse-cdn.com/v4/letter/a/958977/32.png) [@Ara.T.Howard6](https://rubytalk.org/u/Ara.T.Howard6)\
**Post date:** [7 January 2006 15:29 UTC](https://rubytalk.org/t/iterator-fu-failing-me/23918/14 "2006-01-07T15:29:33Z")

</div>

nice.

-a

> **···**
>
> On Sat, 7 Jan 2006, Robert Klemme wrote:
> 
> > elements = tokens.map do |tok|  
> > parsers.inject(false) {|a,par| a=par.parse(tok) and break a}  
> > end
> 
> # --
> 
> > ara [dot] t [dot] howard [at] noaa [dot] gov  
> > strong and healthy,  
> > who thinks of sickness until it strikes like lightning?  
> > preoccupied with the world,  
> > who thinks of death, until it arrives like thunder?  
> > -- milarepa
> 
> ===============================================================================

---

<div class="post-metadata">

**Author:** ![Robert](https://avatars.discourse-cdn.com/v4/letter/r/e95f7d/32.png) [@Robert](https://rubytalk.org/u/Robert)\
**Post date:** [7 January 2006 16:13 UTC](https://rubytalk.org/t/iterator-fu-failing-me/23918/15 "2006-01-07T16:13:00Z")

</div>

Because this won't return the proper value from the block. You need at least to add a line with "result" after the #find. 🙂 And then it's much more inelegant than using #detect. 🙂

Kind regards

&nbsp;&nbsp;&nbsp;&nbsp;robert

> **···**
>
> Bob Hutchison \<hutch@recursive.ca\> wrote:
> 
> > On Jan 6, 2006, at 11:36 PM, James Edward Gray II wrote:
> > 
> > > 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:
> > > 
> > > &nbsp;&nbsp;elements = tokens.map do |token|  
> > > &nbsp;&nbsp;&nbsp;&nbsp;[ClassA, ClassB, ClassC].find { |kind| kind.parse?(token) }  
> > > &nbsp;&nbsp;end
> > > 
> > > Except that I want the return result of parse?(), instead of the  
> > > class that took it.
> > 
> > Why not:
> > 
> > elements = tokens.map do |token|  
> > &nbsp;&nbsp;result = nil  
> > &nbsp;&nbsp;[ClassA, ClassB, ClassC].find { |kind| result = kind.parse?(token) }  
> > end

---

<div class="post-metadata">

**Author:** ![Barbier\_de\_Reuille\_P](https://avatars.discourse-cdn.com/v4/letter/b/ea5d25/32.png) [@Barbier\_de\_Reuille\_P](https://rubytalk.org/u/Barbier_de_Reuille_P)\
**Post date:** [7 January 2006 16:23 UTC](https://rubytalk.org/t/iterator-fu-failing-me/23918/16 "2006-01-07T16:23:01Z")

</div>

ara.t.howard@noaa.gov a écrit :

> **···**
>
> > 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|  
> > > &nbsp;&nbsp;&nbsp;ClassA.parse?(token) or  
> > > &nbsp;&nbsp;&nbsp;ClassB.parse?(token) or  
> > > &nbsp;&nbsp;&nbsp;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|  
> > > &nbsp;&nbsp;&nbsp;[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.
> > 
> > &nbsp;&nbsp;harp:~ \> cat a.rb
> > 
> > &nbsp;&nbsp;module Parser  
> > &nbsp;&nbsp;&nbsp;&nbsp;module ClassMethods  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def parse tokens, klasses  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tokens.map{|token| catch('parse!'){ klasses.each{|klass|  
> > klass.parse! token}; nil}}  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def parse! token  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret = parse?(token) and throw 'parse!', ret  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def parse? token  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return "\<#{ token }\> parsed by \<#{ self }\>" if token =~ self::RE  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;module InstanceMethods  
> > &nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;def self::included other  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;other.module\_eval{ extend ClassMethods and include InstanceMethods }  
> > &nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;extend ClassMethods and include InstanceMethods  
> > &nbsp;&nbsp;end
> 
> Could you explain this module ?
> 
> I think I can understand why you defined a module ClassMethods : to  
> include class methods and not only instace methods.
> 
> However, I don't understant why the InstanceMethods module ? What do you  
> expect with this module ? Is it just for symetry ?
> 
> Thanks !

---

<div class="post-metadata">

**Author:** ![James\_Edward\_Gray\_II](https://avatars.discourse-cdn.com/v4/letter/j/ea5d25/32.png) [@James\_Edward\_Gray\_II](https://rubytalk.org/u/James_Edward_Gray_II)\
**Post date:** [7 January 2006 18:53 UTC](https://rubytalk.org/t/iterator-fu-failing-me/23918/17 "2006-01-07T18:53:31Z")

</div>

> elements = tokens.map do |tok|  
> parsers.inject(false) {|a,par| a=par.parse(tok) and break a}  
> end

That's what I was looking for. Thank you.

> But the best solution is
> 
> elements = tokens.map do |tok|  
> parsers.detect {|par| par.parse(tok)}  
> end

That's not equivalent. It's actually the same example I showed in my original question message that didn't work. See that post for details, but the short story is that it finds the parsers that did the conversion, not the parsed elements I was looking for.

James Edward Gray II

> **···**
>
> On Jan 7, 2006, at 7:33 AM, Robert Klemme wrote:

---

<div class="post-metadata">

**Author:** ![James\_Edward\_Gray\_II](https://avatars.discourse-cdn.com/v4/letter/j/ea5d25/32.png) [@James\_Edward\_Gray\_II](https://rubytalk.org/u/James_Edward_Gray_II)\
**Post date:** [9 January 2006 01:09 UTC](https://rubytalk.org/t/iterator-fu-failing-me/23918/18 "2006-01-09T01:09:23Z")

</div>

It works just fine, yes. Just doesn't feel very Rubyish to me. \<shrugs\>

James Edward Gray II

> **···**
>
> On Jan 8, 2006, at 6:58 PM, jwesley wrote:
> 
> > Perhaps I'm missing the point, but wouldn't the following work: (?)
> > 
> > &nbsp;&nbsp;&nbsp;elements = tokens.map do |token|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;val = nil  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ClassA, ClassB, ClassC].find { |kind| val = kind.parse?(token) }  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;val  
> > &nbsp;&nbsp;&nbsp;end

---

<div class="post-metadata">

**Author:** ![Robert](https://avatars.discourse-cdn.com/v4/letter/r/e95f7d/32.png) [@Robert](https://rubytalk.org/u/Robert)\
**Post date:** [7 January 2006 15:43 UTC](https://rubytalk.org/t/iterator-fu-failing-me/23918/19 "2006-01-07T15:43:01Z")

</div>

Yeah, but #detect is better here. And if \*I\* say that another solution is bettern than an inject solution... 🙂

&nbsp;&nbsp;&nbsp;&nbsp;robert

> **···**
>
> ara.t.howard@noaa.gov wrote:
> 
> > On Sat, 7 Jan 2006, Robert Klemme wrote:
> > 
> > > elements = tokens.map do |tok|  
> > > parsers.inject(false) {|a,par| a=par.parse(tok) and break a}  
> > > end
> > 
> > nice.

---

<div class="post-metadata">

**Author:** ![Barbier\_de\_Reuille\_P](https://avatars.discourse-cdn.com/v4/letter/b/ea5d25/32.png) [@Barbier\_de\_Reuille\_P](https://rubytalk.org/u/Barbier_de_Reuille_P)\
**Post date:** [7 January 2006 16:28 UTC](https://rubytalk.org/t/iterator-fu-failing-me/23918/20 "2006-01-07T16:28:00Z")

</div>

Robert Klemme a écrit :

> **···**
>
> > Bob Hutchison \<hutch@recursive.ca\> wrote:
> > 
> > > On Jan 6, 2006, at 11:36 PM, James Edward Gray II wrote:
> > > 
> > > > 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:
> > > > 
> > > > &nbsp;&nbsp;elements = tokens.map do |token|  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;[ClassA, ClassB, ClassC].find { |kind| kind.parse?(token) }  
> > > > &nbsp;&nbsp;end
> > > > 
> > > > Except that I want the return result of parse?(), instead of the  
> > > > class that took it.
> > > 
> > > Why not:
> > > 
> > > elements = tokens.map do |token|  
> > > &nbsp;&nbsp;result = nil  
> > > &nbsp;&nbsp;[ClassA, ClassB, ClassC].find { |kind| result = kind.parse?(token) }  
> > > end
> > 
> > Because this won't return the proper value from the block. You need at  
> > least to add a line with "result" after the #find. 🙂 And then it's  
> > much more inelegant than using #detect. 🙂
> > 
> > Kind regards
> > 
> > &nbsp;&nbsp;&nbsp;robert
> 
> Well, looking at the documentation of ruby1.8, detect and find are  
> aliases ... is it specific to ruby1.8 or some newer/older version ?
> 
> Pierre

[Next page](https://rubytalk.org/t/iterator-fu-failing-me/23918.md?page=2)
