Aleksi Niemel<zak / ale.cx> wrote:
>
>On Sun, 4 Feb 2001, Guy N. Hurst wrote:
>
> > "Hal E. Fulton" wrote:
> > > ...
> > > Also, I don't really remember seeing any discussion
> > > here of nested classes... though apparently they
> > > exist. Are they ever Really Useful or just a mild
> > > curiosity?
> > >
> >
> > I have not yet seen an answer to this question, and
> > I am also interested in understanding this.
> >
> > I find nested modules and nested classes,
> > as well as nested classes inside nested modules.
> >
> > Nowhere have I seen this documented, yet I see it
> > used.  What is the scoop?
>
>Nested modules are definitely useful as nested namespaces.
>
>Nested classes are not that useful in my experience. In Java you would
>use them for a substitute for blocks (procs) or (not so) anonymous
>routines. In Ruby they could be used in a same way, but as we have
>blocks already there's hardly any need for them used in that way.

Cool, Ruby does this?  I have a good use for using nested
classes right now in a learning project I am doing!

>There's good use for nested classes. If you need a class carrying some
>data and methods, but feel that it's not important enough for the
>others to use or know about it, it might be beneficial to "localize"
>the definition, thus place it inside and near the code which uses it.
>
>     - Aleksi
>
>
>   module MyPackage
>
>     module InnerPackage
>
>       class TheWorker
>
>         def initialize(foo)
>           @foo = WorkersHelper.new(foo)
>         end
>
>         def foo
>           @foo.calculate
>         end
>
>         class WorkersHelper
>           def initialize(value)
>             @value = value
>           end
>           def calculate
>             @value ** 2
>           end
>         end
>       end
>     end
>   end
>
>   puts MyPackage::InnerPackage::TheWorker.new(10).foo
>
Real life example of another valid use.

One parsing technique is recursive descent.  The key
difference between recursive descent and the lex
approach is that you try out alternative rules in
order (recursive descent) rather than in parallel.
(Quite similar, not surprisingly, to the difference
between an NFA and a DFA.)

So suppose we want a class for a parser that parses
text using RecDescent.  Within our grammar we will
have many rules (named and unnamed) of specific
forms.  For instance, "Try these rules in order."
"Match a token."  "Match these rules in turn."
"Match this rule 0 or more times."  And so on.

Well with the above technique I can easily do the
following:

    class RecDescent

      # Try these rules in order
      class Alt
        atr_accessor :rules

        def initialize (*rules)
          @rules = rules
        end

        def parse (str, pos=0)
          for rule in rules
            out, next_pos = rule.parse str, pos
            if not out.nil?
              return out, next_pos
            end
          end
          return nil, nil
        end
      end

      # Match all rules in turn
      class InOrder
        atr_accessor :rules

        def initialize (*rules)
          @rules = rules
        end

        def parse (str, pos=0)
          output = ''
          for rule in rules
            out, next_pos = rule.parse str, pos
            if out.nil?
              return nil, nil
            else
              output << out
              pos = next_pos
            end
          end
          return output, pos
        end
      end


      # And so on, more classes for each type of rule

    end

Each rule is now an object, and each type of rule is
a class.  Now you can build a parser for a complex
grammar by combining objects from its private classes
in the right way.  Classes which it needs but the
outside world should not care about.

Of course right now what I have doesn't do this, nor am
I trying to get there right now.  I just have a
collection of different types of rules, and I am
trying to use them in a configurable interface that
creates a highly specialized processor for scanning a
slightly marked up HTML document, passes through strictly
checked html (eg only specified tags, for each tag only
specified attributes), reports errors, has room for
custom escapes, etc, and then just does a standard html
escape for everything it doesn't have specific rules for.
Appropriate for use in a web bulletin board.

But anyways, nested class definitions will *definitely*
be the right way to hide away all of these private
classes which are required in the internals of my
parser...

Cheers,
Ben
_________________________________________________________________
Get your FREE download of MSN Explorer at http://explorer.msn.com