From: David Simmons Date: 2001-10-24T23:11:53+09:00 Subject: [ruby-talk:23190] Re: Bruce Eckel's opinion of Ruby [SmallScript/AOS Selector Namespaces] "Rich Kilmer" wrote in message news:NDBBKPEKEKOELOHKPCNOAEGNCHAA.rich@infoether.com... > > -----Original Message----- > > From: David Simmons [mailto:pulsar@qks.com] > > Sent: Wednesday, October 24, 2001 3:09 AM > > To: ruby-talk ML; undisclosed-recipients: > > Subject: [ruby-talk:23145] Re: Bruce Eckel's opinion of Ruby > > [SmallScript/AOS Selector Namespaces] > > > > [deleted David's incredibly cool explanation] > > > > so...in Ruby it could be explained as: > > module A > class Foo > def bar > "The bar is for drinking" > end > def bar2 > "More drinking!" > end > end > end > > module B > include A > class Foo > def bar > "The bar is for beer nuts" > end > end > end > > module C > include A > class Foo > def bar > "The bar is for picking up da' ladies" > end > end > end > > #Now, if you enter the namespace of B > include B > #and build a Foo > f = Foo.new > print f.bar # => "The bar is for beer nuts" > print f.bar2 # => Exception...no method found > ^--This does not work today! > > TODAY: In the namespace identified by module B, f.bar2 does not exist because in B when you define class Foo you are not just replacing the module A Foo class method "bar", but creating a whole new class Foo in B. > > TOMORROW: With David's selector namespaces, when in the scope of module B your definition of class Foo would modify Foo (from module A) in the context of module B, and module C would modify Foo (from module A) in the context of C and "bar2" would exist in all (three) namespace instances of Foo, but each would have a different "bar" method. > > Whew! > > Is that right David? Basically. But I probably should make sure we really are saying the same thing. It is important to recognize that the described in all my prior examples is and always remains (as these prior examples were written) a member of the namespace A defined by module A. What is happening is that methods are being added to . These methods, however, belong to module B and are scoped to module B [where ownership and scoping are distinct notions of module and namespace]. When module B is loaded, the methods it owns will be registered within their appropriate namespaces and behavior/class contexts. When code which has access to moduleB is executed, it will then have access to the "set" of available methods that were defined in moduleB. ------ What I'm going to say next, upon first reading, may create more confusion than it resolves. I want to be clear the referred to in all the examples is the defined in the namespace A of module A. The B and/or C modules are just defining additional/alternate methods on . It is still entirely possible for module B to define [within the B namespace] a class it called , as could module C within the C namespace. Such a class would be entirely unrelated to the module A's . They could all be distinguished by explicit use of their full paths, , , . Obviously this would be confusing, and is not a good idea. But the compiler and the underlying object model would not be confused by these three distinct classes have the same name. ---- Here's a File System Analogy [assuming this analogy helps to clarify the point]: To the compiler/object-model this is no different than (by analogy) you as a human being examining three directories (\A, \B, \C) on your disk drive, each of which happens to contain a file called "Foo.txt". In the file example, we can readily understand that the three "Foo.txt" files within the (\A, \B, \C) folders/directories do not have to have anything in common [they may each contain entirely different text, written by different people at different times]. ---- Good names for things, are good names because they describe/fit the things role. So it is realistic to assume that different people may well decide (independently) to use the same name to describe unrelated classes. Thus, as a language designer, planning for naming conflicts is an important issue. So SmallScript (and its ancestor QKS Smalltalk) provide support for renaming/importing explicit members of other namespaces. In SmallScript, if we wanted to rename to be when referenced from within module B's namespace, we could do so as follows. "" w/other module attribute decls ignored for this example Module name: B shared-fields: alias[A.Foo] Bar. This would allow us to write the modifications to A.Foo, using the name . Method class: Bar scope: B [myPrivateX ...]. Which is really identical to writing: Method class: A.Foo scope: B [myPrivateX ...]. Such capabilities can prove to be convenient/invaluable in the following kind of scenario: ======== Module name: B shared-fields: alias[A.Foo] Bar default-scope: B. Class name: Foo. "" Some function or code defined within module B Function [ someFn ^{Foo new, Bar new}. ]. ========= In the above example, we have used the renaming to allow us to avoid prefixing the references to module A's with "A.". Note: the {...} brace operator returns a list containing its comma [or period] delimited arguments. "" This code is identical to the example using shown above: Function [someFn ^{Foo new, A.Foo new}]. There are actually far more things happening here (from a dynamic language implementation viewpoint) than I am explaining. But for this example, I think the surface explanation of straightforward import/renaming will suffice. [If I've left you hanging, here is one clue: We could make a single change to the definition of in module B and not need to recompile any code that referenced ]. -- Dave S. [www.smallscript.org] > > -Rich