Elliott's Blog | Life Through Math, Algorithms and Code

Mar/07

25

ActionSctipt 3.0 Array Access Woes

With the recent launch of Apollo Beta I thought I’d look into Flex again for some fun and decided I’d write plist api so that Apollo applications could read and modify OS X plists in a sane maner.

PList XML is particularly problematic because of how its structured:

    <dict>
        <key>Foods</key>
        <array>
            <dict>
               <key>Chocolate</key>
               <true/>
            </dict>
        </array>
    </dict>

While this example is contrived we can see that keys are associated with the following element in dict[tionaries] and that array elements are just the elements inside array blocks. This makes tools like XPath less than stellar since nodes don’t have real ids and makes working with E4X awkward.

Instead I decided a layer of transparency would be best, so the previous structure could be represented as:

    Dictionary { 
        "Foods" => Array [
              Dictionary {
                   "Chocolate" => true
              }
         ]
    }

The goal being that in the actionscript I can do myPlist.Foods[0].Chocolate and get true, and allow simple assignments so myPlist.Foods[0] = "foo" should automatically wrap that string in a PListString. Simple right?

Well in a language like ruby, yes, but AS3 makes it more complicated than it needs to be (in part due to the way ECMAScript works) and requires flash.utils.Proxy to be able to override the Array Access operator.

This is problematic as it means that PListArray cannot actually extend the Array class and still override the Array Access operator at the same time! Doh!. To add insult to injury the array access operator definition on the Array class doesn’t call a method that we can override.

This means making a Typed array that handles all input and output to allow wrapping is impossible, instead we’d need to resort to get() and set() methods which means you can’t actually use the PListArray in any method that requires an array in transparent manner.

This makes me question why Adobe chose to force a fragile base class on us for overriding the existing object operators like delete or the Array Access Operator.

Instead they should have used an interface, flash.utils.IProxy which allowed implementing methods for calling performing those actions. Then again we’re still in a bind since interface methods must all be public these new override methods would clutter the public API.

Seems to me the best solution would be a little syntax addition for array access such as:

function object get():*
function object set( key:*, value:* ):void
function object delete( key:* ):void

And so on…

This would allow defining proper getters and setters for the array access and let users redefine the getter and setter methods on superclasses to implement proper Arrays without the need to extend a super class which may or may not be an option. Sweet too since we can do this without even extending the language by adding an “object” namespace. :)

No tags

No comments yet.

Leave a Reply

<<

>>

Theme Design by devolux.nh2.me