[Modules] Upper case message names for accessing modules

Doug Way dway at riskmetrics.com
Mon Feb 18 07:27:30 UTC 2002


Hannes Hirzel wrote:
> 
> On the swiki page
> http://minnow.cc.gatech.edu/squeak/2252
> Creating and accessing modules in code
> 
> where it is explained how to access modules:
> Module @ path
> Module fromPath: path
> Module @ #(Squeak VMConstruction)
> 
> a new way of accessing submodules was added
> <citation>
> You can also send uppercase messages to a module to access its
> submodules. So if moduleA has a submodule named ModuleB:
> 
>     moduleA ModuleB
> This will return the submodule. Ie. the message is the exact name of the
> submodule.
> </citation>
> 
> I don't like this idea. It sacrifies regularity of the syntax for a tiny
> benefit.

I suppose it's not really essential to have, but it does have some good aspects along with the bad.

One good thing is that it doesn't technically change any Smalltalk syntax... they're just message sends.  So, the compiler/parser is unaffected, as opposed to something like VisualWorks namespaces.

However, allowing upper-case message sends is a pretty big change in Smalltalk syntax *convention*, which could be weird.

Let's say you're writing some code in a module, and you need to access the EllipseMorph class (to create an instance), which is in a different module.  Let's say for some reason you haven't imported (via #uses:) the module containing EllipseMorph, so your code needs to specify the path for EllipseMorph.  You might do something like this:  (this example works in a workspace in 3.3alpha)

"example 1"
ellipse := Squeak Morphic Core Basic EllipseMorph new.
ellipse extent: 200 at 300.
ellipse openInWorld.

Executing this with "debug it" is interesting... it shows that the #Morphic message is handled via doesNotUnderstand:.

Or, if you don't want to use the uppercase message stuff, you could do this instead:

"example 2"
ellipse := (Module @ #(Squeak Morphic Core Basic) at: #EllipseMorph) new.
ellipse extent: 200 at 300.
ellipse openInWorld.

Anyway, "Squeak Morphic Core Basic EllipseMorph" in example 1 is quite a bit more concise and arguably more readable than example 2, even if it's a bit odd looking at first.  It reads a bit more like a single unit, kind of like Squeak-Morphic-Core-Basic-EllipseMorph or Squeak.Morphic.Core.Basic.EllipseMorph might, which seems like a good thing IMHO.

(I'm assuming the typical use of module paths in people's code will involve getting at classes, not modules.  I don't think you'd commonly need to do much with module instances, unless you're writing something (e.g. a Modules browser) that needs to work with modules directly...?)

Of course, there's always the third and best option:

"example 3"
ellipse := EllipseMorph new.
ellipse extent: 200 at 300.
ellipse openInWorld.

This would require that your module imports ("uses") the Morphic-Core-Basic module.  I tend to think that this is probably the best practice of the three... assuming there's some sort of reasonable UI for easily making modules import other modules, etc, in as automated a fashion as possible.

In fact, I'd go as far to say that I would always import modules (like example 3) when writing code, and never use explicit paths in my code, the *only* exception being when there's an actual class name clash in my imported modules, and then of course I would need an explicit path in the code.  (I'd be curious to hear other opinions on this, though.)

Anyway, I haven't messed around with modules too much yet, so hopefully I haven't misrepresented anything in this message. :)

- Doug Way
  dway at riskmetrics.com



More information about the Squeak-dev mailing list