AS3 | Programming

Setting private property values of a cloned ActionScript 3 object

Sometimes when cloning an object it is desirable to set a private or read-only property on the clone. Since these properties aren’t writable from outside the class itself, how can their values be changed?

Drawing from the ideas of Grant Skinner’s post on Singletons the same internal class technique can be used to set properties on an object through its constructor, but only if it is instantiated within the class itself, such as through a clone() method.

The following is an example of a simple class that has a clone() method and the clone has a read-only property that is set when it is instantiated:

package
{
	public class Cloner
	{
		/*----------------------------------------------------------------------
		* properties
		*---------------------------------------------------------------------*/
		private var _isClone_:Boolean = false;
 
		/*----------------------------------------------------------------------
		* constructor
		*---------------------------------------------------------------------*/
		public function Cloner( allow:AllowConstructorArguments = null , prop:Boolean = false ) 
		{
		  	if ( allow is AllowConstructorArguments ) 
		  	{
		  		_isClone_ = prop;
		  	}
		}
 
		/*----------------------------------------------------------------------
		* public methods
		*---------------------------------------------------------------------*/
		/**
		* Whether this object was created from the clone method.
		*/
		public function get isClone() : Boolean{ return _isClone_; }
 
		/**
		* Create a clone of this object
		*/
		public function clone() : Cloner
		{
			return new Cloner(new AllowConstructorArguments() , true);
		}
	}
}
 
 
/**
* Internal class for allowing arguments in the constructor if this class is 
* instantiated from within this class.
*/
internal class AllowConstructorArguments{}

Alternatively, if you would not like the constructor to have a long list of parameters. The … (rest) parameter could be used in the constructor, like so:

...
		public function Cloner( ... args:Array ) 
		{
		  	if ( args[0] is AllowConstructorArguments ) 
		  	_secretSwitch = Boolean(args[1]);
		}
...

The class can be tested with the following:

			var c:Cloner = new Cloner();
			var d:Cloner = c.clone();
 
			// outputs: false true
			trace( c.isClone , d.isClone );