Reflective programming is a very common, powerful, yet expensive software development practice. In most modern programming languages reflection can not be utilized to modify private members of an object, which is to be expected. However in certain circumstances, such as when developing very high level frameworks and automation APIs it may be beneficial at times to be have the ability to access private members of an object from outside of the public API of the class.
For instance, consider the following class definition:
The above class defines two private members: _username and _password. The public API of this class exposes these properties via the read-only accessors get username and get password. Per design assignments to these properties can only be made via the instance constructor.
So how can these values be modified once the object has been instantiated? More importantly, should this be allowed as the properties have not been publicly exposed? Theoretically they can not, philosophically they shouldn’t. All of this is debatable; however as a dynamic programming language ActionScript can easily accomplish accessing and modifying private members of an object which have not been exposed.
To do so is simple: define a method which provides an interface into the private members of the class instance, as in the following example:
The above example is pretty straightforward. It is simply a static method which requires 3 arguments. The first being the instance of the class, the second is the property in which to assign a new value, and the third is the value to assign to the property. This static method can be defined in any class and will work fine – you only need to change the type of the instance argument and error message to match the type of the class in which the method is defined. All methods in a class definition have access to any member of the class therefore assignments can be made to an instance of the class via a static method. This is possible in most object oriented languages such as C# and Java, however ActionScript takes this approach into the dynamic realm thus making it much more robust as the actual properties which are to be modified can be specified at runtime.
This approach can just as easily be accomplished on the instance level as well via an instance method, as in the following:
A client implementation for each would be as follows:
This approach is best suited for assigning values to simple types, or for pointing reference types to other object instances. This does not allow nested properties of a member to be accessed or modified (although it could easily be refactored to do so). Most importantly, (as you may be thinking) this breaks encapsulation and violates information hiding; therefore I do not recommend utilizing this approach for general use, however it is a convenient and efficient way to modify objects when developing complex APIs which use reflection and also for implementing Unit Tests directly against private members.
Initially I was introduced to the static implementation of this technique by a .Net developer on my team, and admittedly I was somewhat skeptical at first, however given the dynamic nature of ActionScript I realized this could open up some interesting possibilities under unique circumstances, similar to how mixins open up many possibilities – when used with discretion in a good design they both provide powerful advantages over other languages.
Food for thought. Enjoy.
In AS3 this only works if the function is declared in the same class in which the private member is declared. Otherwise you’ll get a runtime exception. I thought that by setting a handful of compiler flags (-es=true -as3=false -strict=false) you could get around this but I just tested it and the exception still occurs.
Hey Paul,
The error you are getting is to be expected as methods declared outside of the class which defines the private members will never be able to access those members. The method which modifies private members must be defined in the class in which the members are defined, otherwise the method would not have access to those members. This applies to all languages, not just AS3.
Think of it like this, private members are only accessible from within the class in which they are defined, therefore if the method which modifies these members is also defined in the same class then that method has access to those members as well.
Hope that is clear.
Thanks,
Eric
Hi
if you define your class as dynamic “dynamic public class..” , the you can access private methods and attributes using dynamic addressing like in AS2 …
If you conclude during design time that the class you are going to write needs its private methods and attributes accessed then you should be using dynamic, thats just my view.
Hi Eric,
sorry if I missing something here but if the methods need to be defined inside the actual class (in your example the User class) then why would or should this approach be used? Would it not be easier to simple add some setters?
Cheers
Stefan
Hey Stefan,
This approach is intended as an alternative to exposing setters. It is typically used for automation APIs in which you may need to modify specific properties at runtime but you do not want to expose those members publicly. The properties which are to be modified would only be known within the API that modifies them. I also recommend using a custom namespace in order to help prevent potential misuse.
– Eric
Hey Rodney,
This approach is intended to modify members of sealed classes, not add members to dynamic classes. There is a big difference: This approach does not add or remove members to the prototype object of a Class, rather it makes assignments to sealed private members defined on the traits object of a Class which would otherwise be inaccessible.
– Eric
Hi Eric,
Is it possible to reflectively call functions in AS3 as well or is this confined to modifying member variables? If possible, how would one go about doing this?