Adobe Flex 3 Help

Performing object introspection

Object introspection is a technique for determining the elements of a class at run time, such as its properties and methods. There are two ways to do introspection in ActionScript:

  • Using for..in loops
  • Using the introspection API

You might find object introspection a useful technique when debugging your application. For example, you might write a method that takes a generic object of type Object as an argument. You can use introspection to output all of the properties and methods of the Object to determine exactly what your application passed to it.

Using for..in loops

You can use a for..in loop to iterate over objects and output their properties and their values. A for..in loop enumerates only dynamically added properties. Declared variables and methods of classes are not enumerated in for..in loops. This means that most classes in the ActionScript API will not display any properties in a for..in loop. However, the generic type Object is still a dynamic object and will display properties in a for..in loop.

The following example creates a generic Object, adds properties to that object, and then iterates over that object when you click the button to inspect its properties:

<?xml version="1.0"?>
<!-- usingas/IntrospectionForIn.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="initApp()">
  <mx:Script><![CDATA[
     private var obj:Object = new Object();
     
     private function initApp():void {
        // Create the object.
        obj.a = "Schotten Totten";
        obj.b = "Taj Majal";
        obj.c = "Durche die Wuste";     
     }
     
     public function dumpObj():void {
        for (var p:String in obj) {
           ta1.text += p + ":" + obj[p] + "\n";
        }
     }
  ]]></mx:Script>
  <mx:TextArea id="ta1" width="400" height="200"/>
  <mx:Button label="Dump Object" click="dumpObj()"/>
</mx:Application>

The executing SWF file for the previous example is shown below:

You can also use the mx.utils.ObjectUtil.toString() method to print all the dynamically added properties of an object, for example:

<?xml version="1.0"?>
<!-- usingas/ObjectUtilToString.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="initApp()">
  <mx:Script><![CDATA[
     import mx.utils.ObjectUtil;

     private var obj:Object = new Object();
     
     private function initApp():void {
        // Create the object.
        obj.a = "Schotten Totten";
        obj.b = "Taj Majal";
        obj.c = "Durche die Wuste";     
     }
     
     public function dumpObj():void {
        ta1.text = ObjectUtil.toString(obj);
     }
  ]]></mx:Script>
  <mx:TextArea id="ta1" width="400" height="200"/>
  <mx:Button label="Dump Object" click="dumpObj()"/>
</mx:Application>

The executing SWF file for the previous example is shown below:

The mx.utils.ObjectUtil class has other useful methods such as compare(), copy(), and isSimple(). For more information, see the Adobe Flex Language Reference.

Using the introspection API

If you want to list all the public properties and methods of a nondynamic (or sealed) class or class instance, use the describeType() method and parse the results using the E4X API. The describeType() method is in the flash.utils package. The method's only parameter is the target object that you want to introspect. You can pass it any ActionScript value, including all available ActionScript types such as object instances, primitive types such as uint, and class objects. The return value of the describeType() method is an E4X XML object that contains an XML description of the object's type.

The describeType() method returns only public members. The method does not return private members of the caller's superclass or any other class where the caller is not an instance. If you call describeType(this), the method returns information only about nonstatic members of the class. If you call describeType(getDefinitionByName("MyClass")), the method returns information only about the target's static members.

The following example introspects the Button control and prints the details to TextArea controls:

<?xml version="1.0"?>
<!-- usingas/IntrospectionAPI.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="getDetails()">
    <mx:Script><![CDATA[
        import flash.utils.*;

        public function getDetails():void { 
            // Get the Button control's E4X XML object description.
            var classInfo:XML = describeType(button1);

            // Dump the entire E4X XML object into ta2.
            ta2.text = classInfo.toString();

            // List the class name.
            ta1.text = "Class " + classInfo.@name.toString() + "\n";

            // List the object's variables, their values, and their types.
            for each (var v:XML in classInfo..variable) {
                ta1.text += "Variable " + v.@name + "=" + button1[v.@name] + 
                    " (" + v.@type + ")\n";
            }

            // List accessors as properties.
            for each (var a:XML in classInfo..accessor) {
                // Do not get the property value if it is write only.
                if (a.@access == 'writeonly') {
                    ta1.text += "Property " + a.@name + " (" + a.@type +")\n";
                }
                else {
                    ta1.text += "Property " + a.@name + "=" + 
                        button1[a.@name] +  " (" + a.@type +")\n";
                }
            } 

            // List the object's methods.
            for each (var m:XML in classInfo..method) {
                ta1.text += "Method " + m.@name + "():" + m.@returnType + "\n";
            }
        }
    ]]></mx:Script>

    <mx:Button label="This Button Does Nothing" id="button1"/>
    <mx:TextArea id="ta1" width="400" height="200"/>
    <mx:TextArea id="ta2" width="400" height="200"/>
</mx:Application>

The executing SWF file for the previous example is shown below:

The output displays accessors, variables, and methods of the Button control, and appears similar to the following:

Class mx.controls::Button
...
Variable id=button1 (String)
Variable __width=66 (Number)
Variable layoutWidth=66 (Number)
Variable __height=22 (Number)
Variable layoutHeight=22 (Number)
...
Property label=Submit (String)
Property enabled=true (Boolean)
Property numChildren=2 (uint)
Property enabled=true (Boolean)
Property visible=true (Boolean)
Property toolTip=null (String)
...
Method dispatchEvent():Boolean
Method hasEventListener():Boolean
Method layoutContents():void
Method getInheritingStyle():Object
Method getNonInheritingStyle():Object

Another useful method is the ObjectUtil's getClassInfo() method. This method returns an Object with the name and properties of the target object. The following example uses the getClassInfo() and toString() methods to show the properties of the Button control:

<?xml version="1.0"?>
<!-- usingas/IntrospectionObjectUtil.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
  <mx:Script><![CDATA[
     import mx.controls.Alert;
     import mx.utils.ObjectUtil;
     private function showProps(b:Button):void {
        var o:Object = ObjectUtil.getClassInfo(b);
        ta1.text = ObjectUtil.toString(o);
     }
  ]]></mx:Script>
  <mx:Button id="b1" label="Show Properties" click="showProps(b1)"/>
  <mx:TextArea id="ta1" width="300" height="500"/>
</mx:Application>

The executing SWF file for the previous example is shown below:

For more information about using E4X, see Programming ActionScript 3.0.