I have a problem. It turns out that I'm really not the good of a programmer/architect. I make mistakes. Often. I'm good proof of the adage "it takes 3 times to get it right." I try. Hard. I really do. But try as I might, it always seems that my initial versions of software require future revising and improvements.
Oh, I could shoot for some "self confidence." I might suppose I actually do OK, that my first cuts are OK for a while, but that software needs change. Software evolves and adapts.
Either way, the outcome is the same, eventually my code is outdated and obsolete. No problem though! We have the modern miracle of the Refactoring engine. I can improve code. Keep it alive. Rename things. Refactor. Remove. Polish. Keep it all well oiled and clean. Works great. Unless... I have to share my code. Key Technology has a set of logging tools that hook into SUnitToo. When I used to modify SUnitToo, those tools got modified. But I'm not there anymore, I don't have that code in my image. So they've had to modify the code to keep up with the change. Unfortunately, they basically have to find the mismatch through trial and error, through unhandled exception.
I might venture to claim that I'm not so alone. That every person who writes software to be consumed by others has the same problem. If I was in a really bold mood (just conjecture here, I'm having a low moment here as the title says), I'd proclaim vehemenently that this is a very big problem for my employer. That one of our largest handicaps with keeping the Smalltalk object library alive and vibrant and robust and lean and mean are the demands of backwards compatibility.
This has percolated in the back of my mind for a while now. Being on the vendor side, it's suddenly become that much more important to me to find some thing that at least improves the situation a little. So I've sat down and started my humble attempt at a tool to help with the problem. The package Deprecation has just been published to the Open Repository. It's package comment states:
A framework for deprecating methods and classes (namespaces & shares too).
**Methods**
Marking methods as deprecated involves one of two methods located on Object:
deprecated
simply place this method in a given method, and when that method is invoked, Deprecated actions will be taken
deprecated: anArray
same, but allows you to specify meta data about the deprecation. It is expected that the array contains alternating symbol/string pairs which represent the tag/parameter pieces of metadata. The intent is that the array be a literal array, so that it can be used to "filter" subsets of tagged deprecations by tools
"Deprecated actions" are controlled by Shared Value flags located on Deprecated. Currently supported are:
LogToTranscript
RaiseException
**Classes and other Global Variables**
Marking a Variable reference as deprecated involves the actual VariableBinding object. To create a deprecated reference to a current binding one sends something like:
Histogram fullyQualifiedReference binding deprecateAs: #Bag in: Histogram environment (after we had renamed Bag to Histogram probably).
This message returns the newly DeprecatedVariableBinding. One can optionally send extraInfo: anArray to that binding. The expectation is that it is the same as anArray used when a deprecated: message is found in a method.
There MAY be/PROBABLY is issues if you try to Deprecate the Deprecation system itself. In particular the bindings defined by it. My guess is that it would go recursive? Maybe. Doctor it hurts when I do that?
There is a DeprecationTests as well. And in my image, but not published is a DeprecationTools. If this is even a viable approach, I believe the tools are a very necessary part of the picture. For example, the ability to select a Class/Share/Namespace and invoke a Deprecate & Rename. Or the ability to find references to any deprecated references in a given package. So on.
I guess it is my hope that some of the other Open Repository projects might consider using this tool as they evolve forward, hopefully helping the people using their code have an easier time of tracking the evolution, and thus allowing the packages to continue to evolve, and not get stuck. And that if enough people try to use it, they can help vet out the issues with this very modest first cut at a solution.