On Tue, 28 Mar 2006 parisnight / gmail.com wrote:

> Passing in the parent instance to the child is a nice approach.  In the
> end they still seem like separate entities though.  That is, the parent
> is an object that the child can look at but the child hasn't actually
> become the parent.  I'd like the child to become the parent including
> all its previous attributes, good or otherwise.
>
> You read a header and it says, I'm a shape at position (4,5).  So you
> instantiate a shape at position (4,5).  Now you read further and it
> says it is a square.  You'd now like the shape to change its class to
> become a square with its additional attributes.
>
> The way I've always followed is just to wait until later in the parsing
> until knowing exactly what kind of an object you want to instantiate
> and than using mmap or other ways to expose previously read data.  But
> what if there is a lot of data in the header and what if the unions are
> nested.  What about a more complex example like an animal or plant
> phyla or taxon where there are many levels.  It seems there should be a
> way to refine an object's classification as more detail is discovered
> about it, and it seems that each level of classification should only
> need to know about the next level below it.  The knowledge for
> classification is contained within the class structure and
> instantiation rather than in something external to the classes.
>
> Kind regards,
> Bob Anderson

use mixins:

       harp:~ > cat.rb
       class K
         module A
           def parse buf
             buf.each do |line|
               more =
                 case buf
                   when /b/i
                     extend B
                 end
               more ? parse(buf) : break
             end
           end
         end
         module B
           def parse buf
             buf.each do |line|
               more =
                 case buf
                   when /c/i
                     extend C
                   else
                     false
                 end
               more ? parse(buf) : break
             end
           end
         end
         module C
           def parse buf
             nil
           end
         end

         def parse buf
           buf.each do |line|
             more =
               case buf
                 when /a/i
                   extend A
                 when /b/i
                   extend B
                 when /c/i
                   extend C
                 else
                   false
               end
             more ? parse(buf) : break
           end
         end
         alias_method "initialize", "parse"
       end


       require "yaml"

       k = K.new <<-buf
         a
       buf
       y "K::A === k" => K::A === k
       y "K::B === k" => K::B === k
       y "K::C === k" => K::C === k
       puts


       k = K.new <<-buf
         a
         b
       buf
       y "K::A === k" => K::A === k
       y "K::B === k" => K::B === k
       y "K::C === k" => K::C === k
       puts

       k = K.new <<-buf
         a
         b
         c
       buf
       y "K::A === k" => K::A === k
       y "K::B === k" => K::B === k
       y "K::C === k" => K::C === k
       puts




       harp:~ > ruby a.rb
       ---
       K::A === k: true
       ---
       K::B === k: false
       ---
       K::C === k: false

       ---
       K::A === k: true
       ---
       K::B === k: true
       ---
       K::C === k: false

       ---
       K::A === k: true
       ---
       K::B === k: true
       ---
       K::C === k: true


food for thought.


-a
-- 
share your knowledge.  it's a way to achieve immortality.
- h.h. the 14th dali lama