PackageInfo: Declarative Categorization of Squeak Code
The PackageInfo system is a simple, lightweight way of organizing
Smalltalk source: it is nothing more than a naming convention, which
uses (or abuses) the existing categorization mechanisms to group
related code. Let me give you an example: say that you are developing
a framework named SqueakLink to facilitate using relational databases
from Squeak. You will probably have a series of system categories to
contain all of your classes, eg,
('SqueakLink-Connections' OracleConnection MySQLConnection
PostgresConnection)
('SqueakLink-Model' DBTable DBRow DBQuery)
and so on. But not all of your code will reside in these classes - you
may also have, for example, a series of methods to convert objects
into an SQL friendly format:
Object>>asSQL
String>>asSQL
Date>>asSQL
These methods belong in the same package as the classes in
'SqueakLink-Connections' and 'SqueakLink-Model'. You mark this by
placing those methods in a method category (of Object, String, Date,
and so on) named '*squeaklink' (note the initial star). The
combination of the 'SqueakLink-...' system categories and the
'*squeaklink' method categories forms a package named "SqueakLink".
The rules, to be precise, are this: a package named "Foo" contains
* All class definitions of classes in the system category "Foo",
or in system categories with names starting with "Foo-".
* All method definitions in any class in method categories named
"*foo" or with names starting with "*foo-".
* All methods in classes in the system category "Foo", or in
system categories with names starting with "Foo-", except those
in method categories with names starting with "*" (which must
belong to other modules).
To get a feel for this, try filing both PackageInfo and the
Refactoring Browser into a Squeak 3.2 image. The Refactoring Browser
code uses PackageInfo's naming conventions, using "Refactory" as the
package name. In a workspace, create a model of this package with
refactory := PackageInfo named: 'Refactory'.
It is now possible to introspect on this package; for example,
refactory classes will return the long list of classes that make up
the Refactoring Browser. refactory coreMethods will return a list of
MethodReferences for all of the methods in those classes. refactory
extensionMethods is perhaps one of the most interesting queries: it
will return a list of all methods contained in the Refactory package
but not contained within a Refactory class. This includes, for
example, String>>expandMacrosWithArguments: and
Behavior>>parseTreeFor:.
Since the PackageInfo naming conventions are based on those used
already by Squeak, it is possible to use it to perform analysis even
of code that has not explicitly adapted to work with it. For example,
(PackageInfo named: 'Collections') externalSubclasses will return a
list of all Collection subclasses outside the Collections categories.
As another example, if you're willing to wait for a bit, you can try
(PackageInfo named: 'Network-Url') browseExternalReferences, which
will bring up a view of all of the users of the Network-Url classes.
You can send #fileOut to an instance of PackageInfo to get a changeset
of the entire package. For more sophisticated source code management,
however, you can use the DVS system, which uses PackageInfo to
integrate with CVS. A pure-Squeak version control system based on
PackageInfo is also in the works.