Class Builder V0.1
Coldwave Programs Ltd, coldwave@bigfoot.com

Class builder is a subproject that allows a developer to make changes to class source and have them take effect in a running program without having to re-link it. It works by temporarily turning the class implementation file into a category and then dynamically loading this file using a simple distributed object. This works because implementations of the most recently loaded category take precedence over those of the statically loaded class.

To use ClassBuilder simply add the ClassBuilder subproject to the project you wish to develop incrementally and rebuild it. This should bring the necessary support classes into you application, copy the builder.csh file into your ~/Unix/bin directory and add the class builder services to your terminal services. In order to develop a class as a run-time loadable category use the service "Terminal/Class Categorise" to turn the class source file into a category and it will be added automatically into the stand alone ClassCategories.bproj subproject. Each time you change the class source, build this project and the new method implementations will be loaded into the application while it is running. Once you have finished modifying the class use the service "Terminal/Class Uncategorise" to return the source back to it's original position. You will need to manually remove the class from the ClassCategories subproject.

In order to work the application must be running and have an instance of the class CategoryLoader registered under that name as a distributed object. In order to ensure this happens without having to modify the main project the ClassBuilder subproject includes a slightly dodgy category of application that intercepts the [Application new] call that all next applications call at application startup.

Each time the ClassCategories subproject is built the program "reload" is called to message the CategoryLoader instance in the application to load in the newly built bundle. To avoid multiple definitions if the bundle has been loaded previously it is unloaded then a new NXBundle instance created to load in the bundle project's categories. These are then linked into the running classes superseding their code.

One limitation it is worth keeping in mind is that dynamic loading on NeXT operates as a stack so in order to be able to unload the previous version of a bundle loaded it must have been the last bundle that was loaded by the application. This means if you want to use ClassBuilder to load a bundle of class categories more than once it must be loaded after all other bundles required by the application have been loaded. Also remember that any global variables in a class (tut tut) must be bracketed by #ifndef LOADABLE_CATEGORY in order to avoid clashing with their original definitions in the main application. In order for categorised classes to be able to find included headers all header files in the project are linked into ClassBuilder.subproj/sym directory. This is a useful trick for projects in general. Check out the "links:" rule in Makefile.postamble if you have problems. Finally ClassBuilder attempts to make sure that your project's PB.gdbinit file always contains a "directory" entry for the ClassBuidler.subproj/BundleProjects/ClassCategories.subproj subproject so gdb is able to find the correct source for the method implementation being used.

There is also a ClassBuilderPalettte Interface Builder Palette that allows you to develop Palettes inside IB the same way without having to restart it all the time.

Feel free to email bug reports but please no support. Best of luck.

John H.
johnh@bigfoot.com