January 30th, 2014

Mutable, Immutable, My Black Hen

At some point late this morning, I came to the horrible realization that the absence of the "const" keyword in Java, coupled with the absence of operator overloading, meant that all of the code that I was porting across from C++ had an ugly, ugly hole in it.

I have ID classes that I use to locate several types of objects in the C++ code. In C++, I would write code like:

const CPdID& id = pPd->GetID();
PdID modifiableID = pPd->GetID();

The first case wouldn't make a copy of the const reference that GetID() returns and I wouldn't be allowed to change it, while the second line would assign the contents of the const reference to my new PdID, since I'd overloaded operator=. And all was right with the world.

Except when I converted that to Java, I ended up with:

PdID id = pPd.GetID();
PdID modifiableID = pPd.GetID();

Now in this case, I have taken the reference that pPd.GetID() has returned that I did not want to modify and am happily going to modify it, because I didn't -- and couldn't -- define the function return as const. Ick.

So I have now made PdID immutable by removing all of the mutators that belong to the class. And I've added a MutablePdID which extends PdID and contains all of the mutators that are no longer in PdID. Add toMutable() and toImmutable() methods to each class that will create new objects as required, and my IDs Formerly Known As Const are now safe from the ravages of clueless coding.

The result looks like:

PdID id = pPd.GetID();
MutablePdID modifiableID = new MutablePdID( pPd.GetID());
// The case below is not preferred (by me), because if GetID() returned a MutablePdID,
// I could change the returned object without intending to. Oops.
//MutablePdID modifiableID = pPd.GetID().toMutable();

This was an exciting way to spend a day of work...