Thursday, March 11, 2010

Debugging private variables in Flex

Introduction
Proudly brought to you from the dept of thuggery, buggery and skullduggery, here is a bit of a hack which enables you to access another classes private variables in a semi-controlled manner.

You want to do what?!?
Many out there should be shaking their heads right now. Yes, I agree, a belligerant attitude towards breaking a canonical axiom in Object Oriented programming rarely ends well, however, given the right situations, and preventative steps, it can be a useful way to get around certain... how shall we say... issues..

As always with dirty rotten hacks, let's investigate the rule we are breaking, followed by when you definitely should not break it.

Why private variables are good
Private variables help in preventing an anti-pattern known as Action at a Distance. If you just let any old programmer from any old class, access any old variable, and change it, you are opening yourself up for a real world of hurt.

Why private variables are bad
Most programmers follow Test Driven Development and a good Separation of Concerns philosophy. These two requirements can be at loggerheads at times, as although you want to shield your application from becoming a mess of spaghetti with a good selection of private and protected variables, when it comes to testing, the same protections that keep programmers out, keep your test framework out as well.

When, where and why you want to break encapsulation
My first year lecturer was a pretty cool dude who always wore a sarong, no shoes, and more than one occasion rode into our lecture theatre on his motor cycle.

We once asked him why you should not be able to access private variables from the outside, even from instances of the same class. His response, was for us to imagine that we are all instances of the class of students. We definitely should not be able to just start messing with each others privates. The discussion abruptly ended there.

But when would it be acceptable to access a private variable? The answer is, whenever your are performing diagnostics. It isn't a bad thing for your doctor to have access to private areas in the process of diagnosing a problem, is it? It is the same for your code.


Let's get down to code
We'll start off with the ArgumentFunctionPair object. This is basically an argument chain, followed by a function that's invoked outside passing the value out.
public class ArgumentFunctionPair
{
public var argument:String;
public var functionVar:Function;
public function ArgumentFunctionPair(argument:String, functionVar:Function)
{
this.argument=argument;
this.functionVar=functionVar;
}
}

Here we have the visitInternal function that gets attached to your class that you wish to allow to have the visitor.
//reflective function to test properties and values for unit testing purposes
protected function visitInternal(errorFunction:Function, argFunctionPair:ArgumentFunctionPair):Boolean
{
var integrityOK:Boolean=false;
var returnObj:Object;
try
{
returnObj = this[argFunctionPair.argument];
}
catch(e:Error)
{
errorFunction("ERROR: " + argFunctionPair.argument + " was not found.");
}
finally
{
argFunctionPair.functionVar(returnObj);
return integrityOK;
}
}


So why go throught this elaborate ruse?
It's all about preventing a visitor from changing a private internal. You never know when you'll get some sort of clever programming getting in there and thinking he can just sneak a change in when you're not looking.

With this sort of methodology, it makes it quite a bit harder to turn the function into a method to access the classes private variables.

1 comment: