February 2006 Archives

ActionScript 3 JSON Library Now Available

| 4 Comments | No TrackBacks

I'm happy to announce that my JSON library has been made publicly available through labs. JSON stands for "JavaScript Object Notation" and is a lightweight data exchange format, sort of like WDDX on a diet.

You can download the JSON library as part of the core ActionScript 3 library.

Usage is as follows:

// import the JSON library from the core serialization package
import com.macromedia.serialization.json.JSON;

// Encode a native ActionScript object as a JSON string
var jsonString:String = JSON.encode( someValue );

// Decode a JSON string into a native ActionScript object
var value:* = JSON.decode( jsonString ); 

If you run into any problems with it, let me know. It passed all of the unit tests, but there's always a chance that a test case is missing and there's a hidden bug somewhere. I'm interested in hearing any feedback you may have!

Tags: , , , , , ,

Both E4X and Regular Expressions are powerful on their own, but by combining them you can really do some amazing stuff - especially in relation to data filtering...

Manish Jethani outlined data filtering with E4X, but I just wanted to expand on that and show a technique I've been using that combines E4X Predicate Filtering with Regular Expressions.

Consider the following code snippet:

I see this question a lot: "How can I select nodes that contain a certain attribute using E4X? I keep getting a reference error saying the variable doesn't exist..." The answer is to use the hasOwnProperty method in predicate filtering.

The hasOwnProperty method checks to see if a string property name is present, and returns a boolean value. By using "@" as the first character in the property name, hasOwnProperty will check to see if an XML object has a particular attribute.

Using hasOwnProperty instead of just looking for "@hex == " something or other will avoid the error ReferenceError: Error #1065: Variable @hex is not defined on the nodes that don't have the hex attribute. This is because the predicate filtering loops over all of the nodes in the previous XMLList to try to match the expression, and if @hex doesn't exist on the current node being inspected, the error is generated. Switching to hasOwnProperty will gracefully handle the "not found" cases.

The code below shows hasOwnProperty in action, using predicate filtering to select specific nodes.

// Create an XML object that contains two types of color nodes:
// One type with a hex attribute, and another with red, green
// and blue attributes.
var colors:XML = <colors>
		<color hex="0xFF0000" />
		<color hex="0x00FF00" />
		<color hex="0x0000FF" />
		<color red="255" green="0" blue="0" />
		<color red="0" green="255" blue="0" />
		<color red="0" green="0" blue="255" />
	</colors>;

// Use the hasOwnProperty method in predicate filtering
// to find the nodes that have a certain attribute - hasOwnProperty
// will return true if the hex attribute (denoted via @) is found
// on the node.
var colorsWithHexAttribute:XMLList = colors.color.( hasOwnProperty( "@hex" ) );

// Outputs:
// <color hex="0xFF0000"/>
// <color hex="0x00FF00"/>
// <color hex="0x0000FF"/>
trace( colorsWithHexAttribute );
			
// By looking for a false result of hasOwnProperty we can successfully
// select all of the nodes that do NOT contain the hex attribute
var colorsWithoutHexAttribute:XMLList = colors.color.( hasOwnProperty( "@hex" ) == false );
			
// Outputs:
// <color red="255" green="0" blue="0"/>
// <color red="0" green="255" blue="0"/>
// <color red="0" green="0" blue="255"/>
trace( colorsWithoutHexAttribute );

Unfortunately, due to a compiler bug the above code will not compile in strict compilation mode. You'll need to turn off the strict flag if you want to use this code in the current beta of Flex 2.

To turn off strict compilation mode, open the project properties (Select properties from the Project menu on the menu bar). Select ActionScript compiler on the left, and uncheck the "enable compile-time type checking" option.

I much prefer to compile with strict mode on, but to use this approach it's a necessary evil to leave it off. I can say for certain that there's a bug logged already for this. I'm hoping it gets fixed soon!

Tags: , , ,

More Proof that Unit Testing is Good

| 6 Comments | No TrackBacks

I thought I'd share a positive experience I had today with unit testing.

If you don't know what unit testing is, essentially it's an automated process used to ensure that your code actually does what you think it does. It's a fundamental rule of extreme programming, has an active cult following, and has spawned test-driven development.

Without getting into an essay on the background of unit testing, how it's useful, or how to set it up with Flash or Flex, I just wanted to relay my experience this afternoon.

Someone had contacted me about a possible bug in a piece of software that I wrote. Naturally, I assumed this was nonsense (after all, who writes buggy code anyway?). It turns out there was an edge case that I never thought would occur and it was causing erroneous results. I was given the steps to consistently reproduce the problem, and immediately went to work.

ActionScript 3 Casting

| 3 Comments | 3 TrackBacks

If you're anything like me, you're not a fan of how ActionScript 2 handles casting. Luckily, ActionScript 3 introduces a new operator to make casting more intuitive.

The syntax for casting a from one datatype to another is Type( expression ) - see About casting objects. There are a few reasons why this syntax is confusing:

Using the new * DataType in ActionScript 3

| 7 Comments | 1 TrackBack

The Flex 2.0 beta available from Adobe labs introduces a special new datatype in ActionScript 3, the * type. So what is the *, and when should you use it?

Essentially, the * datatype mans "any type." Declaring a variable as type * is functionally the same as leaving it untyped. That is, the following two blocks of code are equivalent:

var x;
var x:*;

Both declare a variable x and will allow it to take on any type. At first glance, it may seem that the * datatype is pretty useless. All it does is add clutter to your code, and make you type more. Omitting the type is easier anyway, right?

I've seen this question a few times: How do I make an mx:Panel with a transparent background color? The white just isn't doing it for me...

By default, the mx:Panel has a white background:

panel-white.jpg

In order to remove the white background, the secret is the backgroundAlpha attribute of the mx:Panel tag. By setting the backgroundAlpha to ".4", the default white background will not be displayed and will look transparent instead:

panel.jpg

The following MXML demonstrates setting the backgroundAlpha:

<mx:Panel width="200" height="200" title="Example" backgroundAlpha=".4" />

Remember that the alpha properties you may be used to using ranged from 0-100 and were interpreted as the straight % (where 100 = 100%). In Flex 2, the alpha values range from 0-1 (where 1 is 100%). Therefore, setting the alpha to a value of .4 actually means 40% alpha.

Reminder: Central Penn CFUG meeting tonight

| No Comments | No TrackBacks

The Central Pennsylvania ColdFusion User's Group will be holding a meeting tonight, right down the street from me in Hershey, PA. Nic Tunney is the guest speaker, and will be covering Application.cfc.

More information can be found here. The meeting will be held at the Country Meadows offices located at 830 Cherry Drive, Hershey, PA 17033. The meeting start time on the website is 6:30, but the email announcement that went out said 6. I would err on the side of caution and say be there at 6.

This will be my first time attending the CPCFUG since moving to the area from Baltimore last year. I don't really do a lot of ColdFusion development anymore, but I'm hoping to meet some new people and support the local user group. If you're planning on attending, be sure to RSVP at info@centralpenncfug.org in order for refreshments to be planned properly.

Local user groups are a great way to learn technology, make new contacts, meet new friends, share good times, and usually get some free pizza. Check out this page to find a list of user groups in your area, and get involved!

There's a reason that you shouldn't rely on undocumented features. The for..in loop's behavior has changed from ActionScript 2 to ActionScript 3. It's a subtle change, but it might break your code.

The for..in loop iterates over the properties of an object. In previous versions of ActionScript, the for..in loop was known to iterate over the properties backwards, in a predictable order. It has been said many times that the order is not guaranteed, but in practice it was always the same, and predictable.

For example, the following code creates an object in ActionScript 2, adds some properties to the object, and then iterates over the properties with for..in. The order of the trace output is always the same:

var o:Object = new Object();
o.prop1 = 1;
o.prop2 = 2;
o.prop3 = 3;
o.prop4 = "four";

for ( var i:String in o ) {
	trace( i + ":" + o[i] );	
}

/* Always Displays:
prop4:four
prop3:3
prop2:2
prop1:1
*/

As an aside, in this type of situation I'd build the object with an object literal (using { prop1:1, prop2:2 ..etc.. }) instead of adding properties like the preceding code block, but the code was written this way for clarity. You can cleary see that the last item added is always the first one found by the for..in loop.

Because the order was always the same, you may have tried to use this to your advantage. However, in ActionScript 3 the same code does not produce the same results. The order of for..in is no longer predictable:

var o:Object = new Object();
o.prop1 = 1;
o.prop2 = 2;
o.prop3 = 3;
o.prop4 = "four";

for ( var i:String in o ) {
	trace( i + ":" + o[i] );	
}

/* Displays:
prop2:2
prop4:four
prop1:1
prop3:3
*/

/* Or, could Display:
prop3:3
prop2:2
prop1:1
prop4:four
*/

As you can see, if you used the undocumented feature of the for..in loop iterating backwards through an object, your code will not work the same in ActionScript 3. This demonstrates another good reason why undocumented features should be used with caution, as future versions are free to change functionality without warning.

I've made a few changes to my solitaire game, and I'm proud to say it's showcased on labs! Here's a few of the migration issues I've had:

  • Void is now void - This was a minor but very welcome change. A simple find/replace is all you need.
  • [Embed(source="someImage.jpg")] broken? - No, this still works. The problem is that the Embed instructs the compiler to create a class that extends SkinSprite or SkinBitmap, and by default these are not included in ActionScript-only projects in FlexBuilder. The solution is to add the framework.swc to the build path, like this:
    1. Open the project properties and select ActionScript Build Path and then the Libraries tab.
    2. Click the Add SWC button and use "${FRAMEWORKS}\framework.swc" as the location.
  • Event constants no longer have their own "Type" classes for the constants. That is, "EventType.OPEN" is now "Event.OPEN"

These are the main things that I ran into. Of course, there are other migration issues from alpha 1 to beta 1, and I highly recommend you read the release notes as well.

All that being said, you can play the updated game here (requires Flash Player Alpha 3)



About this Archive

This page is an archive of entries from February 2006 listed from newest to oldest.

January 2006 is the previous archive.

March 2006 is the next archive.

Find recent content on the main index or look in the archives to find all content.

Archives

OpenID accepted here Learn more about OpenID
Powered by Movable Type 5.02