On Mon, 29 Jan 2001, David Alan Black wrote:

> Hello --
> 
> I'm trying to hone my skills at manipulating classes and methods.  The
> following example/question is taken in isolation from a current
> project.
> 
> The idea is to pass a string to FirstStage#new, and get back a Class
> object.  Instances of that second class then do things (#showstuff)
> which have knowledge of the words in that original string.
> 
> The way I'm doing it right now feels a bit awkward.  I'm wondering if
> there's a nicer way to get a dynamically-created class to be able to
> see and use variables from the instance that's creating it (as opposed
> to using class variables in a quasi-global-variable way, which is what
> I'm currently doing).

To answer my own question:

You can use constants (courtesy of const_set()) to "talk" to a class
across a visibility barrier.  I remembered something like this from a
recent post by Dave Thomas, and tracked it down ([ruby-talk:9848]) --
and sure enough, it helped.  (Thanks, Dave!)

The new version looks like this:

   class FirstStage

     attr_accessor :words

     def initialize(s)
       @words = s.split
     end

     def second_class
       c = Class.new
       c.const_set(:WORDS, @words)
       c.class_eval <<-EOE

       attr_accessor :stuff

       def initialize
         self.stuff = WORDS      # instead of jumping through a
       end                       # variety of hoops.... 

       def showstuff
         self.stuff.each do |t|
           puts t.upcase
         end
       end

       EOE

       return c
     end

   end


# Test run

   f = FirstStage.new("These are some words")
   s = f.second_class
   p = s.new
   p.showstuff  #  THESE\nARE\nSOME\nWORDS\n


David

-- 
David Alan Black
home: dblack / candle.superlink.net
work: blackdav / shu.edu
Web:  http://pirate.shu.edu/~blackdav