Looking at the E4X implementation in ActionScript, it occurs to me that they had to figure out how to do three things that I am not sure can be done within ActionScript regularly:
Properties/Getters prefixed with @:
var myAttribute = xmlPerson.@name;
Nameless functions for filtering:
xmlData.person.(/* predicate */)
lambda syntax for predicates:
xmlData.person.(@name == "Brian")
So here is my question: Are these just one-off capabilities (much like Vector.<>
) they put in just for E4X, therefore keeping out of reach for us? Or do we, as ActionScript developers, have access to these features?
More specifically, I'd love to get access t开发者_高级运维o the expression tree of that lambda predicate for my own code (not tied to the XML classes in any way).
I figured out that this is called the "filter operator"... but I am not sure how to harness it. Not sure I can... since ActionScript does not allow for operator overloading :(
As far as I know, it's not possible to harness the E4X syntax for other types of objects. It's really sad, because there's a lot of potential in it; especially the lamdba syntax.
I think what you need is the Proxy class. The mechanism of this class is quite interesting, allowing you to handle dynamic access to non-existent but algorithmically definable properties. In order to do this, you subclass the flash.utils.Proxy class.
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/utils/Proxy.html
The dynamic getter / setter logic is easy to implement. However attribute (@) access and the lambda syntax are tricky. Proxy getters do not see the @ character for some reason and filter methods result in runtime errors. You can see them below:
package {
import flash.display.Sprite;
public class ProxyTest extends Sprite {
public function ProxyTest() {
var obj:ProxyObject = new ProxyObject();
trace(obj.testingDefault); // Invokes default logic.
trace(obj.@testingAttributes); // Invokes default logic. :(
trace(obj["(@testingLambda == 'testing')"]); // Invokes lambda logic.
trace(obj.filter("@testing == 'testing'")); // Just an idea
trace(obj.(@testing = "testing")); // Throws Error #1123: Filter operator not supported
}
}
}
import flash.utils.Proxy;
import flash.utils.flash_proxy;
dynamic class ProxyObject extends Proxy {
public function ProxyObject() {
}
override flash_proxy function callProperty(propName:*, ... args):* {
var name:String = propName.toString();
switch (name.charAt(0)) {
case '(':
trace("Lambda logic.");
break;
case '@':
trace("Attribute logic.");
break;
default:
trace("Default logic.");
break;
}
return "CALL: " + propName;
}
override flash_proxy function getProperty(propName:*):* {
var name:String = propName.toString();
switch (name.charAt(0)) {
case '(':
trace("Lambda logic.");
break;
case '@':
trace("Attribute logic.");
break;
default:
trace("Default logic.");
break;
}
return "GET: " + propName;
}
override flash_proxy function setProperty(propName:*, value:*):void {
}
}
I know I'm late, but Brain, it appears that filter operators ARE supported in AS3!!
Checkout this error I got:
TypeError: Error #1123: Filter operator not supported on type XYZ
On this line of code:
object.(getChildByName("image") as Sprite).addChild(img);
Well.. I suppose we figure out the rest ...
精彩评论