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