<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom">
    <title>darron schall</title>
    <link rel="alternate" type="text/html" href="http://www.darronschall.com/weblog/" />
    
    <id>tag:www.darronschall.com,2008-10-24:/weblog/1</id>
    <updated>2009-02-04T14:01:19Z</updated>
    <subtitle>application developer specializing in the flash platform</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.23-en</generator>

<link rel="self" href="http://feeds.feedburner.com/darronschall" type="application/atom+xml" /><entry>
    <title>DelegateInvoker for the Mate Flex Framework</title>
    <link rel="alternate" type="text/html" href="http://www.darronschall.com/weblog/2009/02/delegateinvoker-for-the-mate-flex-framework.cfm" />
    <id>tag:www.darronschall.com,2009:/weblog//1.276</id>

    <published>2009-02-02T16:15:00Z</published>
    <updated>2009-02-04T14:01:19Z</updated>

    <summary><![CDATA[I've been using the Mate Flex Framework a lot in recent history.&nbsp;&nbsp; I think it's a solid framework that does a lot of things right and it's very lightweight and easy to use.&nbsp; If you haven't used it yet, it's...]]></summary>
    <author>
        <name>darron</name>
        
    </author>
    
        <category term="Flex" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="flex" label="Flex" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="framework" label="Framework" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="mate" label="Mate" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="opensource" label="Open Source" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-US" xml:base="http://www.darronschall.com/weblog/">
        <![CDATA[<p>I've been using the <a href="http://mate.asfusion.com/">Mate Flex Framework</a> a lot in recent history.&nbsp;&nbsp; I think it's a solid framework that does a lot of things right and it's very lightweight and easy to use.&nbsp; If you haven't used it yet, it's at least <a href="http://www.insideria.com/2009/01/frameworkquest-2008-part-6-the.html">worth looking into</a>.</p>

<p>That said, I was recently confronted with a situation in which the current service invokers were insufficient.&nbsp; By service invokers, I mean specifically the <a href="http://mate.asfusion.com/page/documentation/tags/services/remoteobjectinvoker">RemoteObjectInvoker</a>, <a href="http://mate.asfusion.com/page/documentation/tags/services/httpserviceinvoker">HTTPServiceInvoker</a>, and <a href="http://mate.asfusion.com/page/documentation/tags/services/webserviceinvoker">WebServiceInvoker</a> classes.&nbsp; Let me explain.</p>

<p>When you use the Web Service code generation tools from <a href="http://labs.adobe.com/technologies/gumbo/">FlexBuilder Gumbo MAX Preview</a>, you end up with a service class that wraps a web service and provides a well defined public interface.&nbsp; Each method in the class returns an <a href="http://livedocs.adobe.com/flex/3/langref/mx/rpc/AsyncToken.html">AsyncToken</a> that allows you to add a responder to be notified of success/failure when the remote method call comes back.&nbsp; The generated code looks something like this:</p>

<pre name="code" class="js">
public class MyService extends WebServiceWrapper
{
    public function myRemoteMethod(param1:String, param2:int) : AsyncToken
    {
        loadWSDLIfNecessary();
        var operation:AbstractOperation = _serviceControl.getOperation("myRemoteMethod");
        var token:AsyncToken = operation.send(param1, param2);
        return token;
    }
}
</pre>

<p>If you've used <a href="http://opensource.adobe.com/wiki/display/cairngorm/Cairngorm">Cairngorm</a> before, this code should look very familiar.&nbsp; It's the same type of code that you would normally see in the Delegate layer.<br /><br />How do we use this type of delegate class in Mate?&nbsp; My first approach was to try and use a WebServiceInvoker, but the delegate class is not a WebService.&nbsp; My second approach was to try and leverage <a href="http://mate.asfusion.com/api_docs/com/asfusion/mate/actions/builders/AsyncMethodInvoker.html">AsyncMethodInvoker</a>, but that had a few other problems.&nbsp; The biggest was that the success/failure listeners respond to the class itself and not the token returned by the method.&nbsp; Additionally, the AsyncMethodInvoker doesn't integrate with the UnhandledFaultEvent approach to <a href="http://mate.asfusion.com/page/documentation/tags/services/handling-a-service-result-or-fault">application-wide service fault handling</a>.</p>

<p>So, I decided the best approach was to create a new kind of invoker, DelegateInvoker, specifically to handle calling these types of delegate classes.  Usage is essentially the same as the other Mate service invokers:</p>

<pre name="code" class="js">
&lt;DelegateInvoker instance="{ services.myService }" method="myRemoteMethod"
	arguments="{ [ 'param1', 12 ] }"
	showBusyCursor="true"&gt;
			
	&lt;resultHandlers&gt;
		...
	&lt;/resultHandlers&gt;
			
	&lt;faultHandlers&gt;
		...
	&lt;/faultHandlers&gt;
&lt;/DelegateInvoker&gt;
</pre>

<p>If no faultHandlers are defined, then an UnhandledFaultEvent is generated.  This allows the DelegateInvoker to integrate with the application-wide service fault handler.</p>

<p>The DelegateInvoker can be used with any method that returns an AsyncToken.  Behind the scenes, the DelegateInvoker attaches a responder to the AsyncToken returned by the method.  The responder listens for success/failure and triggers the inner handlers when the method call returns.  If the method does not return an AsyncToken to attach a responder to a runtime error is logged.</p>

<p>I've spoken with Nahuel about getting this new DelegateInvoker class incorporated into the Mate core.  He will be adding it into the <a href="http://mate-framework.googlecode.com/svn/branches/in_development/">Mate in_development branch</a>.  <strike>It should be available for download in the next day or so, and I'll update this entry when the class is posted.</strike></p>

<p>The DelegateInvoker class is available as of <a href="http://code.google.com/p/mate-framework/source/detail?r=93">revision 93 in Mate's SVN</a>.  It's currently in the in_development branch, but will eventually be moved to the trunk in a future release.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Flex 2.0.1 SDK is dying</title>
    <link rel="alternate" type="text/html" href="http://www.darronschall.com/weblog/2009/01/flex-201-sdk-is-dying.cfm" />
    <id>tag:www.darronschall.com,2009:/weblog//1.275</id>

    <published>2009-01-26T14:39:21Z</published>
    <updated>2009-01-26T15:20:00Z</updated>

    <summary><![CDATA[If you have a project that still uses the Flex 2.0.1 hotfix 3 SDK, now is a good time to consider upgrading.&nbsp; When the new version of FlexBuilder is released (presumably in the second half of 2009), you will no...]]></summary>
    <author>
        <name>darron</name>
        
    </author>
    
        <category term="Flex" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="flexsdk" label="Flex SDK" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="flexbuilder" label="FlexBuilder" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-US" xml:base="http://www.darronschall.com/weblog/">
        <![CDATA[If you have a project that still uses the Flex 2.0.1 hotfix 3 SDK, now is a good time to consider upgrading.&nbsp; When the new version of FlexBuilder is released (presumably in the <a href="http://opensource.adobe.com/wiki/display/flexsdk/Gumbo">second half of 2009</a>), you will no longer be able to build your Flex 2.0.1 projects using FlexBuilder.<br /><br />When you try to build a project with the Flex 2.0.1 SDK using the FlexBuilder Gumbo MAX Preview build, you'll encounter an error indicating that the flex-compiler-oem.jar is missing from the classpath.&nbsp; I've logged this as the following issue: <a href="https://bugs.adobe.com/jira/browse/FB-15688">https://bugs.adobe.com/jira/browse/FB-15688</a>.&nbsp; The issue was resolved as <i>Not a Bug</i> with the comment <i>Flex Builder 4 will not support Flex SDK 2</i>. <br /><br />I'll repeat that.&nbsp; On a separate line.&nbsp; In Bold.&nbsp; Pay attention.<br /><br /><b>FlexBuilder 4 will not support Flex SDK 2.</b><br /><br />Of course, ANT scripts and command-line compiles will continue to
work.&nbsp; However, losing IDE support should be a pretty compelling reason
to look into the upgrade process.<br /><br />Flex 3.0 was released February 25, 2008.&nbsp; Since release the SDK has been updated to Flex 3.1 on August 15 and Flex 3.2 on October 29.<br /><br />To learn more about the Flex SDK and download new versions, visit <a href="http://opensource.adobe.com/wiki/display/flexsdk/Flex+SDK">http://opensource.adobe.com/wiki/display/flexsdk/Flex+SDK</a>.<br /><br />For those of you looking to upgrade from Flex 2 to Flex 3, check out the <a href="http://labs.adobe.com/wiki/index.php/Flex_3:Release_Notes#Compatibility_Issues">compatibility issues</a> in the Flex 3 release notes.<br /><br />And now, I leave you with <a href="http://www.youtube.com/watch?v=dGFXGwHsD_A">Monty Python's "Bring Out Your Dead"</a>.&nbsp; Flex 2.0.1, you'll be stone dead in a moment.<br /> ]]>
        
    </content>
</entry>

<entry>
    <title>AS3 JSON library now a little less strict</title>
    <link rel="alternate" type="text/html" href="http://www.darronschall.com/weblog/2008/12/as3-json-library-now-a-little-less-strict.cfm" />
    <id>tag:www.darronschall.com,2008:/weblog//1.274</id>

    <published>2008-12-23T15:16:02Z</published>
    <updated>2008-12-23T15:38:01Z</updated>

    <summary><![CDATA[I've just checked in revision 83 of as3corelib that adds a strict flag to the AS3 JSON library.&nbsp; In the past the library would generate an error if the JSON string was deemed invalid according to the syntax rules.&nbsp; Now,...]]></summary>
    <author>
        <name>darron</name>
        
    </author>
    
        <category term="ActionScript" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="actionscript" label="ActionScript" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="json" label="JSON" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-US" xml:base="http://www.darronschall.com/weblog/">
        <![CDATA[I've just checked in <a href="http://code.google.com/p/as3corelib/source/detail?r=83">revision 83 of as3corelib</a> that adds a <i>strict</i> flag to the AS3 JSON library.&nbsp; In the past the library would generate an error if the JSON string was deemed invalid according to the syntax rules.&nbsp; Now, based on the strict flag setting, the parser does a better job at allowing "valid" input even if the input doesn't match the <a href="http://www.json.org/">JSON spec</a>.<br /><br />I've actually had this code completed since <a href="http://max.adobe.com/">MAX 2008</a>.&nbsp; I wrote it on my flight from San Fransisco to Harrisburg, but haven't had the time to get it ready for check-in until now.<br /><br />Here is the commit message:<br /><br /><blockquote><ul><li>Added throwing error if entire string cannot be consumed (when there are remaining characters left in the input stream)</li><li>Added "strict" flag to decoding process.&nbsp; Default is true for backwards compatibility.&nbsp; When false, relaxes input format rules.&nbsp; Fixes <a href="http://code.google.com/p/as3corelib/issues/detail?id=34">#34</a>, Fixes <a href="http://code.google.com/p/as3corelib/issues/detail?id=41">#41</a>, Fixes <a href="http://code.google.com/p/as3corelib/issues/detail?id=71">#71</a>:</li><ul><li>Allows for hex specification for numbers, ex: { "myNum": 0xFFCC33 }</li><li>Allows for NaN to be parsed as a number, ex: { "myNum": NaN }</li><li>Allows for trailing commas in arrays, ex: [1,2,]</li><li>Allows for trailing commas in objects, ex: { "p1":true, "p2":false, }</li><li>Does not throw error if there were characters left in the input string</li></ul><li>Added tests for strict flag</li><li>Added tests to better exercise comments</li><li>Updated tests to use proper assert types</li><li>Some minor cosmetic code cleanup</li></ul></blockquote>Usage is exactly the same as before, with the additional option of specifying the strict flag as part of the <i>JSON.decode(&nbsp;string,&nbsp;strict&nbsp;)</i> call.&nbsp; Example:<br /><br />

<pre name="code" class="js">// Set strict mode to false to allow for trailing commas to not throw an error
var o:Array = JSON.decode( "[0,1,]", false ) as Array;
assertEquals( 0, o[0] );
assertEquals( 1, o[1] );

// Same usage as before, strict mode will throw a runtime error if the string is not valid
var a:Array = JSON.decode( "[0,1,]" ) as Array;
</pre>
<br />I still need to address <a href="http://code.google.com/p/as3corelib/issues/detail?id=35">#35</a> to allow for unquoted keys in objects to be parsed in non-strict mode.&nbsp; This is a bit more complicated of a change because it changes how the tokenizer recognizes what is in the input stream.&nbsp; It's coming though!<br /><br />Note that a new .swc file was not yet posted.&nbsp; If you want to experiment with these changes, you'll have to pull the latest from source.&nbsp; I'll work with <a href="http://www.mikechambers.com/blog/">Mike</a> to get the download .swc updated soon.<br />]]>
        
    </content>
</entry>

<entry>
    <title>Hello World 2.0</title>
    <link rel="alternate" type="text/html" href="http://www.darronschall.com/weblog/2008/12/hello-world-20.cfm" />
    <id>tag:www.darronschall.com,2008:/weblog//1.273</id>

    <published>2008-12-08T15:00:00Z</published>
    <updated>2008-12-08T17:10:10Z</updated>

    <summary><![CDATA[It's been about a year since I've last posted something.&nbsp; Pardon the dust...&nbsp; it's not that I haven't had anything to say, it's more that I just haven't had the time to say it.In fact, I've neglected my weblog so...]]></summary>
    <author>
        <name>darron</name>
        
    </author>
    
    
    <content type="html" xml:lang="en-US" xml:base="http://www.darronschall.com/weblog/">
        <![CDATA[It's been about a year since I've last posted something.&nbsp; Pardon the dust...&nbsp; it's not that I haven't had anything to say, it's more that I just haven't had the time to say it.<br /><br />In fact, I've neglected my weblog so much that I had to upgrade through not just one but two major versions of MovableType.&nbsp; It was interesting upgrading from 2.6 to 3.35 to 4.21 then finally to the latest 4.23.&nbsp; The upgrade from 2.6 to 3.35 was smooth, but 3.35 to 4.21 was an <b>epic fail</b>.<br /><br />Years and years ago when I first created my weblog I chose Berkeley DB as my database option.&nbsp; I would've chosen MySQL but at the time either my host didn't support it or MT didn't support it, I don't really remember.&nbsp; Today, it turns out that Brekeley DB is no longer supported in modern versions of MT.<br /><br />I lost basically everything during the 3.35 to 4.21 upgrade when my database became unreadable.&nbsp; I had some backups that I was able to use to import all of my old entries and comments without too much issue, but I wasn't able to recover the site design.&nbsp; I had customized the default MT templates to leverage my ColdFusion custom tag templating system that I createad for my website, but the MT templates have radically changed over the years.&nbsp; Also, the CSS and page structure were too structurally different and I wasn't able to quickly/easily modify the default MT template to work with my past site design.&nbsp; I'm not a huge fan of the default design I'm using now so I'm still working on getting my old site design back (but I expect that it's going to take quite a bit time).<br /><br />Not only that, but I also lost my code coloring plugin.&nbsp; In the past I've used MTCodeBeautifier but this no longer works with the MT4.&nbsp; I've started using <a href="http://code.google.com/p/syntaxhighlighter/">SyntaxHighlighter</a> which is a completely JavaScript-based solution and should be future-proof, however, I haven't been through all of my old entries to convert them.&nbsp; I'm still working on that, too...<br /><br />Anyway, what I have been up to lately?<br /><br />Well... I've been up to my elbows in Flex development.&nbsp; It's been a great year and I've worked on some really interesting and challenging projects.&nbsp; Perhaps the biggest news, though, is that my employment situation has changed.<br /><br />I'm now officially employed by <a href="http://www.universalmind.com/">Universal Mind</a> as a Principal Architect (and have been since the summer).&nbsp; It feels great to be part of such an elite and passionate team.&nbsp; I'm really excited about what the future holds for both myself and the company, and I'm especially happy to see the immense positive reaction that <a href="http://www.spatialkey.com/">SpatialKey</a> has been getting.<br /><br />Now that I'm back up and running, in the future I hope to get through the backlog of weblog ideas that I've been meaning to post for... well... over a year now.&nbsp; I'm just as busy as always but now that I actually have modern weblog software that can do things like schedule entry posting dates, it should be easier for me to stay on top of things.<br /><br />Stay tuned...<br /><br />Oh, one final note, my RSS feed link has changed to <a href="http://feedproxy.google.com/darronschall">http://feedproxy.google.com/darronschall</a>.&nbsp; The old rdf link is no longer being updated.<br />]]>
        
    </content>
</entry>

<entry>
    <title>Creating Default, Cancelable Event Handlers</title>
    <link rel="alternate" type="text/html" href="http://www.darronschall.com/weblog/2008/01/creating-default-cancelable-event-handlers.cfm" />
    <id>tag:www.darronschall.com,2008:/darron_schall//1.269</id>

    <published>2008-01-29T14:15:27Z</published>
    <updated>2008-11-22T20:58:21Z</updated>

    <summary>Today I'm going to show you how to create a default event handler that performs an operation, and what steps are needed to cancel that default behavior to prevent it from happening.</summary>
    <author>
        <name>darron</name>
        
    </author>
    
    
    <content type="html" xml:lang="en-US" xml:base="http://www.darronschall.com/weblog/">
        <![CDATA[<p>Events play a key role in Flex-based RIAs so it's important to have a solid understanding of them when building applications.  Today I'm going to show you how to create a default event handler that performs an operation, and what steps are needed to cancel that default behavior to prevent it from happening.</p>

<p>A default event handler is a method of a component that handles the same event it dispatches and performs some default action.  This happens a lot in component development.  A component can dispatch an event, but also act on that event with some default behavior.  You don't have to explicitly listen for the event because the default action happens automatically within the component itself.</p>

<p>For example, let's think about a "closeable" tab navigator.  When you click on the "x" to close a tab, a "closeTab" event might be dispatched to signal that a tab is intended to be closed.  The tab navigator itself listens for the "closeTab" event and provides a default behavior of removing the tab that was intended to be closed.</p>

<p>But what if you want to present the user with a confirm dialog first before the tab gets removed?  In this situation, you don't want the default behavior to occur because the tab will be removed before the user has a chance to respond to the confirm dialog.  So, you need a way to prevent the tab from being removed by the component.</p>

<p>There are 4 things associated with creating default event handlers and allowing them to be canceled.  They are:</p>

<ul>
<li>Creating the event with the "cancelable" flag set to true.  This is the third parameter in the <a href="http://livedocs.adobe.com/flex/201/langref/flash/events/Event.html#Event()">Event constructor</a>.</li>

<li>Creating the default event listener with an priority of <a href="http://livedocs.adobe.com/flex/201/langref/mx/core/EventPriority.html#DEFAULT_HANDLER">EventPriority.DEFAULT_HANDLER</a>.</li>

<li>Calling <a href="http://livedocs.adobe.com/flex/201/langref/flash/events/Event.html#preventDefault()">event.preventDefault()</a> in your own event handler to signal that you don't want the default behavior to occur.</li>

<li>In the default event handler, checking if <a href="http://livedocs.adobe.com/flex/201/langref/flash/events/Event.html#isDefaultPrevented()">event.isDefaultPrevented()</a> to know whether or not you should actually carry out the default behavior.</li>

</ul>

<p>Rather than elaborating on these pieces with a few paragraphs of text, I think a code sample illustrates this best.  Here's a sample component that has an "alarm" event with a default behavior of just showing an Alert dialog to let you know the default behavior has happened:</p>

<pre name="code" class="js">
package
{

import flash.events.Event;

import mx.controls.Alert;
import mx.core.EventPriority;
import mx.core.UIComponent;	

[Event( name="alarm", type="flash.events.Event" )]

public class MyComponent extends UIComponent
{

	public function MyComponent()
	{
		// Assign a default event listener for the "alarm" event.  The key here
		// is the event priority of DEFAULT_HANDLER.  This is a low priority and 
		// allows normal listeners to execute first, giving them a chance to call
		// event.preventDefault() to cancel the event's default behavior
		addEventListener( "alarm", handleAlarm, false, EventPriority.DEFAULT_HANDLER, true );
	}
	
	/***
	 * Silly method here just to have the component dispatch an event that it
	 * has a default behavior for.
	 */
	public function triggerAlarm():void
	{
		// Create a new event of type alarm.  The key here is the third
		// parameter which signals that the event is allowed to be canceled
		// via event.preventDefault();
		dispatchEvent( new Event( "alarm", false, true ) ); 
	}
	
	/**
	 * The default behavior for handling the "alarm" event
	 */
	protected function handleAlarm( event:Event ):void
	{
		// Check to see whether or not the event had it's default behavior prevented
		// by another event listener
		if ( !event.isDefaultPrevented() )
		{
			// The event has NOT been canceled, so continue with
			// the default behavior
			Alert.show( "handleAlarm default handler executed from MyComponent" );
		}
	}
	
} // end class
} // end package
</pre>

<p>Here's a sample Flex application using this component.  I add a listener for the "alarm" event, and if the user wants to cancel the default event behavior I call event.preventDefault() in my alarm listener:</p>

<pre name="code" class="js">
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" xmlns:local="*"&gt;
	
	&lt;mx:Script&gt;
		&lt;![CDATA[
			
			protected function handleAlarm( event:Event ):void
			{
				// Just for example purposes, we have a flag in the UI to indicate
				// if we want to prevent the default event handler from executing
				// or not...
				if ( preventToggle.selected )
				{
					trace( "Default behavior is prevented" );
					event.preventDefault();
				}
				else
				{
					trace( "We didn't prevent the default behavior, so we'll see the alert from MyComponent." );
				}
			}
			
		]]&gt;
	&lt;/mx:Script&gt;
	
	&lt;mx:Button label="Trigger Event" click="myComp.triggerAlarm();" /&gt;
	
	&lt;mx:CheckBox id="preventToggle" label="Prevent default behavior?" selected="true" /&gt;
	
	&lt;local:MyComponent id="myComp" alarm="handleAlarm( event );" /&gt;
	
&lt;/mx:Application&gt;
</pre>

<p>So, there you have it!  There's not much to it really, but it's a pretty useful technique.  I'd actually like to see this covered a bit more in the  <a href="http://livedocs.adobe.com/flex/201/html/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Book_Parts&file=events_054_16.html">Events </a> portion of the livedocs site.  Creating cancelable default event behaviors is a key part of Flex component development.  Having a solid understanding of events will go a long way when it comes to building Flex applications.</p>

<p>Enjoy!</p>]]>
        
    </content>
</entry>

<entry>
    <title>Launching Firefox from ANT on OSX</title>
    <link rel="alternate" type="text/html" href="http://www.darronschall.com/weblog/2007/12/launching-firefox-from-ant-on-osx.cfm" />
    <id>tag:www.darronschall.com,2007:/darron_schall//1.268</id>

    <published>2007-12-20T19:40:13Z</published>
    <updated>2008-11-23T01:40:18Z</updated>

    <summary>I've been a happy Linux user for quite some time, but I recently switched to OSX after getting a new Macbook laptop.  After the switch, one of the first things I've noticed was that my ANT tasks to launch a web browser would no longer work as expected.</summary>
    <author>
        <name>darron</name>
        
    </author>
    
    
    <content type="html" xml:lang="en-US" xml:base="http://www.darronschall.com/weblog/">
        <![CDATA[<p>I've been a happy Linux user for quite some time, but I recently switched to OSX after getting a new Macbook laptop.  After the switch, one of the first things that caught my attention was that my ANT tasks to launch a web browser would no longer work as expected.</p>

<p>Let's take a look at a quick example.  I was launching Firefox with the following technique:</p>

<pre name="code" class="js">
// In linux.properties
browser = firefox

// In win.properties
browser = C:/Program Files/Mozilla Firefox/firefox.exe
</pre>

<pre name="code" class="xml">
&lt;!-- Launch the browser via the exec ANT task --&gt;
&lt;exec executable="${browser}" spawn="yes"&gt;
	&lt;arg line="${output.index.html}" /&gt;
&lt;/exec&gt;
</pre>

<p>Naturally, since this worked on Linux and Windows I figured it would work on OSX just fine as long as I got the path to the browser correct.  The first thing that I tried was this:</p>

<pre name="code" class="js">
browser = /Applications/Firefox.app/Contents/MacOS/firefox
</pre>

<p>When I tested this it <i>almost</i> worked.  If I didn't have Firefox already open, it would open the browser correctly and display my target output file.  However, things broke down if I already had an instance of Firefox open.</p>

<p>Rather than open the target output file in a new tab (which was the Linux/Win behavior), I would get an error dialog saying that Firefox was already in use and that I was only allowed to launch one instance of it at a time.  It asked me to quit Firefox first, and then try again.  Since I almost always have a browser window open to keep tabs on my webmail, obviously this wasn't a workable solution for me.</p>

<p>After a bit of digging and experimenting, I came up with the idea of using the "open" command and passing it the Firefox application as a parameter.  This has been working great so far and only required a slight modification to the script:</p>

<pre name="code" class="js">
// In mac.properties
#browser = open -a Firefox  #Does not work, need to pass -a Firefox as args to exec

browser = open
browser.args = -a Firefox
</pre>

<pre name="code" class="xml">
&lt;!-- Updated the exec tag to use additional arguments --&gt;
&lt;exec executable="${browser}" spawn="yes"&gt;
	&lt;arg line="${browser.args}" /&gt;
	&lt;arg line="${output.index.html}" /&gt;
&lt;/exec>
</pre>

<p>I know this really isn't new or groundbreaking information here.  But, I couldn't find an easy answer trying to google for my problem.  I'm posting this to try and save someone else some time in the future who might be running into the same problem that I did.  Enjoy!</p>

<p>P.S.  I'm starting to like OSX, but I still prefer Linux.  I'd consider myself somewhat of a power-user, and there's just too many things Linux has that OSX doesn't.  However, I can't get my external monitor xinerama display to work in Linux (doh!) so I think I'm an official OSX user for the time being until I can get my xorg.conf configured right...  </p>]]>
        
    </content>
</entry>

<entry>
    <title>ActionScript 3 Singleton Redux</title>
    <link rel="alternate" type="text/html" href="http://www.darronschall.com/weblog/2007/11/actionscript-3-singleton-redux.cfm" />
    <id>tag:www.darronschall.com,2007:/darron_schall//1.267</id>

    <published>2007-11-29T16:20:29Z</published>
    <updated>2008-11-23T01:42:55Z</updated>

    <summary>Not to beat a dead horse, but....</summary>
    <author>
        <name>darron</name>
        
    </author>
    
        <category term="Flex" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en-US" xml:base="http://www.darronschall.com/weblog/">
        <![CDATA[<p>Not to beat a dead horse, but....</p>

<p>Ever since developers have been using ActionScript 3 the quest for the perfect Singleton has been underway.  The heart of the issue is that there are no private constructors in ActionScript 3.  Thus, it's been a tricky road trying to find the best way to prevent other developers from inadvertently invoking a Singleton's constructor and creating an additional (and erroneous) instance.</p>

<p>For example, a quick google search yields quite a few results.  Here are a handful of them that I've tried to place in chronological order:</p>

<ul>
<li>
<a href="http://www.tink.ws/blog/stricter-singletons/">http://www.tink.ws/blog/stricter-singletons/</a>
</li>

<li>
<a href="http://www.gskinner.com/blog/archives/2006/07/as3_singletons.html">http://www.gskinner.com/blog/archives/2006/07/as3_singletons.html</a>
<li>

<li>
<a href="http://www.ericfeminella.com/blog/as3-model-view-controller-implementation/">http://www.ericfeminella.com/blog/as3-model-view-controller-implementation/</a>
</li>

<li>
<a href="http://skovalyov.blogspot.com/2006/12/there-are-some-ways-to-create-singleton.html">http://skovalyov.blogspot.com/2006/12/there-are-some-ways-to-create-singleton.html</a>
</li>

<li>
<a href="http://tomschober.blogspot.com/2007/01/singleton-pattern-in-cairngorm-21-with.html">http://tomschober.blogspot.com/2007/01/singleton-pattern-in-cairngorm-21-with.html</a>
</li>

<li>
<a href="http://blog.pixelbreaker.com/flash/as30-better-singletons/">http://blog.pixelbreaker.com/flash/as30-better-singletons/</a>
</li>

</ul>

<p>What do I think?  My initial reaction was to not worry about it.  Seriously, what does it matter?  Do we really need compile time checking?  Isn't runtime checking and unit testing enough?  If a developer uses the class wrong, is that the class author's fault?  As long as there is documentation as to what the class is and how it's used, then this is really a non-issue at best and trivial at worst.</p>

<p>Admittedly that's a bit of a naive attitude.  However, in over a year of not caring about the private constructor issue I can honestly say that I've never run into a problem with singletons, or had any of my team members accidentally use them the wrong way.</p>

<p>It was actually a combination of other factors (and personal preference) that made me revisit the singleton pattern.  The singleton technique that I prefer was developed to address the other issues I was running into and to reflect my personal coding style.  While I was at it, I figured I might as well address the private constructor issue too.  After all, we all love being smacked around by the compiler sometimes.</p>

<p>The technique I prefer has the following highlights:</p>

<ul>

<li><b>Usage of static <i>instance</i> read-only property instead of a static <i>getInstance()</i> function</b>.  This is somewhat a matter of style and personal preference, but I prefer the succinctness of the read-only property.  This is especially obvious when the singleton is used in binding expressions.  Plus, getInstance() is <i>so</i> 1990s Java which ActionScript is most definitely not.  I kid, I kid.  But seriously, ".instance" is cooler.</li>

<li><b>Usage of a private lock class to prevent outside construction</b>.  While this is a common theme in the above links, my approach is slightly different.  Instead of passing an instance of the private locking class to the constructor, I just pass the Class reference itself.  This does two things.  First, it clarifies the conditional check in the constructor.  The test for the proper locking Class reference communicates the code's intent better than the traditional check for not null.  Second, it encapsulates the private locking class itself.  The constructor's argument is simply <i>lock:Class</i> which doesn't expose the name of the private locking class to the outside world, but still communicates that the constructor is locked. </li>

<li><b>Removal of 'Unable to bind' warnings in Flex 2.</b>  When you use a singleton in a binding expression, it's typical to have the Console log flooded with warning messages indicating that binding to the instance property will not be able to detect updates.  My singleton version fixes these warnings.</li>

<li><b>Use of <i>const</i> instead of <i>var</i> for the instance storage</b>.  This one is pretty obvious, but using const here communicates intent better.   The variable storing the singleton instance is not allowed to change so const is the better choice.</li>

</ul>

<p>So, with that said, I thought it was worth throwing my singleton version into the ring.  This is the method I prefer.  If you like it, great.  If not, that's fine too.  No hard feelings.  Really.</p>

<p>Sample code is after the jump.</p>]]>
        <![CDATA[<pre name="code" class="js">
package someProject.model
{

// This import is required for Flex 2
//import flash.events.EventDispatcher;	

[Bindable]
public class Model
	// To avoid binding warnings to "instance" in Flex 2 we need to
	// explicitly extends EventDispatcher and add [Bindable] to the
	// static instance getter. 
	//extends EventDispatcher
{
	
	/** Sample model property.  The name of the currently logged in user. */
	public var userName:String;
	
	// =======================================
	//  Singleton instance
	// =======================================
	
	/** Storage for the singleton instance. */
	private static const _instance:Model = new Model( SingletonLock );
	
	/** Provides singleton access to the instance. */
	// We can use the Bindable metadata with an event name to prevent
	// Flex from reporting that "instance is not bindable".  We have to
	// use a custom event name because you cannot just use [Bindable]
	// with a static function (it's a compiler error).
	//
	// Since we never actually change the instance, we never need to 
	// dispatch an event, so there is no negative side effects here.  If 
	// you're  getting warnings in the console log, try uncommenting the line
	// below.  This isn't necessary with recent Flex 3 builds, but it is for
	// Flex 2.
	//[Bindable( "instanceChange" )]
	public static function get instance():Model
	{
		return _instance;
	}
	
	/**
	 * Constructor
	 * 
	 * @param lock The Singleton lock class to pevent outside instantiation.
	 */
	public function Model( lock:Class )
	{
		// Verify that the lock is the correct class reference.
		if ( lock != SingletonLock )
		{
			throw new Error( "Invalid Singleton access.  Use Model.instance." );
		}
		
		// Normal construction can continue here
		userName = "sample user";
	}
	
} // end class
} // end package

/**
 * This is a private class declared outside of the package
 * that is only accessible to classes inside of the Model.as
 * file.  Because of that, no outside code is able to get a
 * reference to this class to pass to the constructor, which
 * enables us to prevent outside instantiation.
 */
class SingletonLock
{
} // end class
</pre>

<p>This still doesn't feel right to me.  I don't like the private locking class as I think it's a bit of a hack.  But, the compile time and runtime checking is a nice feature to help prevent mistakes.  Additionally, the singleton related code in the class takes away from the actual meat of the class itself.  I want the class to be a Singleton, but I don't want to have to wade through the Singleton code when I'm working on it. I'm also tempted to remove the <i>get instance</i> and just make it <i>public static const instance</i>.  The compiler will prevent assignment to const so the read-only property is a little redundant.</p>

<p>I think my ideal situation would be to introduce new [Singleton] metadata that would automatically take care of the implementation details.  The metadata is self documenting as it clearly indicates that the class is intended to be a singleton.  The compiler would be able to write the singleton related code for us automatically so that we don't have to do it ourselves and so that it doesn't get lost in the actual meat of the class.</p>

<p>Here's an example of what I envision:</p>

<pre name="code" class="js">
[Singleton( "get instance" )]
// or, if you really want to use getInstance() instead...
//[Singleton( "getInstance()" )]
[Bindable]
public class Model
{
	
	/** Sample model property.  The name of the currently logged in user. */
	public var userName:String;
	
	/**
	 * Constructor
	 */
	public function Model()
	{
		userName = "sample user";
	}
	
} // end class
} // end package
</pre>

<p>How cool is that?  We clearly mark the class as a singleton and provide the mechanism we want to use to access the singleton instance (either a read-only property, or a static accessor).  Then, we let the compiler do the work behind the scenes.  I think this ends up being a really clean and elegant solution.</p>

<p>Obviously this doesn't work today because it would need modifications to the mxmlc compiler.  I've submitted this as enhancement request <a href="https://bugs.adobe.com/jira/browse/ASC-3033">ASC-3033</a>.  However, since Flex is going open source this is something we could build in our own if we really wanted to, in theory.  Food for thought...</p>

<p>Anyway, enjoy!</p>]]>
    </content>
</entry>

<entry>
    <title>Hooking dispatchEvent for Cairngorm Events</title>
    <link rel="alternate" type="text/html" href="http://www.darronschall.com/weblog/2007/10/hooking-dispatchevent-for-cairngorm-events.cfm" />
    <id>tag:www.darronschall.com,2007:/darron_schall//1.266</id>

    <published>2007-10-11T16:36:41Z</published>
    <updated>2008-11-23T01:45:14Z</updated>

    <summary>Gone are the days of cairngormEvent.dispatch(); and CairngormEventDispatcher.getInstance().dispatchEvent( cairngormEvent );.  Say hello to dispatchEvent( cairngormEvent );!</summary>
    <author>
        <name>darron</name>
        
    </author>
    
    <category term="cairngorm" label="Cairngorm" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-US" xml:base="http://www.darronschall.com/weblog/">
        <![CDATA[<p>Gone are the days of <i>cairngormEvent.dispatch();</i> and <i>CairngormEventDispatcher.getInstance().dispatchEvent( cairngormEvent );</i>.  Say hello to <i>dispatchEvent( cairngormEvent );</i>!</p>

<p>A downside of using Cairngorm is that you need to remember that Cairngorm events are "special".  Because of how the controller registers listeners, you need to dispatch Cairngorm events through the CairngormEventDispatcher instance in order for the associated commands to execute.   Self-dispatching events were <a href="http://weblogs.macromedia.com/amcleod/archives/2007/05/cairngorm_22_-.cfm">added in Cairngorm 2.2</a> to make things a little easier, but that addition still doesn't address the fact that these events are "different" from other events:</p>

<pre name="code" class="js">
public function doLogin():void
{
	var event:LoginEvent = new LoginEvent( username.text, password.text );
	// Dispatch through the dispatcher directly
	CairngormEventDispatcher.getInstance().dispatchEvent( event );
	// Or, have the event dispatch itself using Cairngorm 2.2+
	event.dispatch();
}
</pre>

<p>A better approach, I think, is to remove the "special"-ness of Cairngorm events and treat them the same as any other regular event.  Rather than having to remember that Cairngorm events get dispatched a special way, doesn't it make sense to simply use the standard <a href="http://livedocs.adobe.com/flex/2/langref/flash/events/EventDispatcher.html#dispatchEvent()">dispatchEvent</a> function?</p>

<p>In order to accomplish this, we need to abstract the Cairngorm event dispatching logic further up the chain.  We still need to to dispatch Cairngorm events through the CairngormEventDispatcher instance, but we can create an abstraction that allows us to not have to know this extra information.  This abstraction allows us to treat Cairngorm events as regular events and just dispatchEvent() them.</p>

<p>So how do we create this abstraction?  Simple.  We hook dispatchEvent at the UIComponent level.  Example code after the jump.</p>]]>
        <![CDATA[<pre name="code" class="js">
/** Create the dispatch event hook when the Application is created. */
private static dispatchEventHooked:Boolean = hookDispatchEvent();

/**
 * Add a hook into dispatchEvent high up in the inheritance chain.  Any
 * subclass of UIComponent is now "CairngormEvent-aware" and no longer
 * needs separate event dispatching code for Cairngorm events.
 */
private static function hookDispatchEvent():Boolean
{
	UIComponent.mx_internal::dispatchEventHook = cairngormDispatchEventHook;

	return true;
}

/**
 * The event hook itself.  Any time we encounter a CairngormEvent, we
 * dispatch it through the centralized CairngormEventDispatcher.  This
 * abstraction prevents subclasses from having to know how to deal with
 * Cairngorm events.
 */
private static function cairngormDispatchEventHook( event:Event, uic:UIComponent ):void
{
	if ( event is CairngormEvent )
	{
		CairngormEventDispatcher.getInstance().dispatchEvent( event as CairngormEvent );
	}
}
</pre>

<p>The beauty of this approach is that it allows you to use <i>dispatchEvent( cairngormEvent )</i> from any view in your application.  This includes nested child views, popup windows, etc.  Additionally, it doesn't interfere with regular events and normal event dispatching.  The hook simply allows some code to be run before the regular dispatchEvent is called.  Cairngorm events make it to the controller via the hook, and regular events still get dispatched as normal.</p>

<p>That said, there are a few downsides to this technique.</p>

<ul>
<li>Since the dispatchEventHook function is scoped as <i>mx_internal</i>, the usual caveats apply (e.g. it may be removed in future versions, etc.)</li>

<li>I couldn't find any documentation on dispatchEventHook in UIComponent or anywhere online for that matter.  In fact, it was by complete accident that I even stumbled across it in the first place.  I've searched the Flex SDK code (both versions 2 and 3) to see if it's in use but I couldn't find any references to it.  It seems to not be in use for now, but naturally, this is subject to change in the future.</li>

<li>Since the hook itself is a reference to a function, it can easily be overwritten somewhere else without you knowing it.  So far I haven't found this to be the case, but you never know...</li>

<li>A side effect here is that even though Cairngorm events get dispatched correctly through the CairngormEventDispatcher instance, the regular dispatchEvent() is called on the event instance as well.  I haven't found this to be a problem, but it's something to be aware of.  You might need to manually stop the propagation of the event in the hook if you run into issues.</li>

</ul>

<p>That said, I've been using this on my current project without any issues to speak of so far.  It's been great to have a consistent event dispatching mechanism, and finally cleans up one of the "messy" aspects of Cairngorm.</p>]]>
    </content>
</entry>

<entry>
    <title>Do you use the public Flex bug base?</title>
    <link rel="alternate" type="text/html" href="http://www.darronschall.com/weblog/2007/09/do-you-use-the-public-flex-bug-base.cfm" />
    <id>tag:www.darronschall.com,2007:/darron_schall//1.265</id>

    <published>2007-09-21T17:30:11Z</published>
    <updated>2008-11-23T01:47:19Z</updated>

    <summary>If you're not familiar with the Flex Bug and Issue Management System, you need to do yourself a favor and get involved.</summary>
    <author>
        <name>darron</name>
        
    </author>
    
        <category term="Flex" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="flex" label="Flex" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="opensource" label="Open Source" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-US" xml:base="http://www.darronschall.com/weblog/">
        <![CDATA[<p>If you're not familiar with the <a href="http://bugs.adobe.com/flex/">Flex Bug and Issue Management System</a>, you need to do yourself a favor and get involved.</p>

<p>As I've <a href="http://www.darronschall.com/weblog/archives/000265.cfm">spoken about before</a>, when the Open Source Flex initiative was first announced one of the things I was most excited about was the opening of a publicly accessible issue management system.  I've touched on a little bit of my reasoning <a href="http://www.darronschall.com/weblog/archives/000270.cfm">here</a>, but wanted to call attention to how awesome a system like this truly is.</p>

<p>If you use Flex day in and day out like I do, chances are you're going to run into issues or things that you think can be improved.  That's just the nature of software development.  Having access to the public bugbase allows you to be actively involved in identifying issues and helping to improve the product for other developers.  Better yet, when you encounter a problem it allows you to defer the work of fixing or working around the issue to Adobe.</p>

<p>Let me share an example to demonstrate what I mean.</p>

<p>Earlier this summer I ran into a strange issue with the DateChooser component.  Code that should have worked was failing for no apparent reason.</p>

<p>I opened up a web browser to the Flex bugbase, <a href="http://bugs.adobe.com/flex/">http://bugs.adobe.com/flex/</a>, and searched for the issue.    There are a lot of search options here, but I just used the "Quick Search" to get started looking, and then narrowed down via the extended options.</p>

<p>After searching for my specific issue, I didn't see anything related to the problem I was having.  This meant that <i>Adobe was not aware of a potential issue</i>.  So, I created a new issue describing my problem.</p>

<p>The process for creating a new issue is really straightforward.  Use the "Create New Issue" link and just describe the problem your encountering.  Having sample code to reproduce the problem really helps well.  When you're done creating the issue it gets assigned an id.</p>

<p>For my particular issue, it was assigned <a href="https://bugs.adobe.com/jira/browse/SDK-12004">SDK-12004</a>.  Since this issue was affecting my ability to complete some code I was working on, I was really interested to find out what Adobe thought and I wanted to be notified if anything changed on the issue.  I clicked the "Watch it" link so that any changes to the issue would be emailed to me.</p>

<p>By watching the issue I was able to see it move through the Adobe QA system.  I knew who was looking at it and what their thoughts where.  I was emailed anytime someone commented on the issue, and ultimately I knew when it was fixed.  In this case, another bug was found that was related to my original report but not quite the same, so <a href="https://bugs.adobe.com/jira/browse/SDK-12008">SDK-12008</a> was opened as well.  I opted to watch that issue too since it also affected what I was working on at the time.</p>

<p>When I saw that the issue was resolved as fixed, I found the comment with the associated build number of the fix.  Here's where things get really interesting.  The particular issue was listed as working fine in build 179224.  Sweet, but where's the code for that?</p>

<p>Did you know there are <a href="http://labs.adobe.com/technologies/flex/sdk/flex3sdk.html">nightly builds of the Flex SDK</a>?</p>

<p>Did you know that when an issue in the bug system is fixed, you can grab the code for the fix from the nightly SDK having a build number greater than or equal to the issue's "fixed in build" number?  You have to agree to the terms of the early build access license, but once you click the checkbox for that there is a matrix at the bottom of the page that populates with links to download the nightly build.  Even better, there's a change log for each version.</p>

<p>I scanned the change logs looking for the change set that related to my SDK-12004 and SDK-12008 issues.  When I found it, I made note of the files that were changed.  Then, I downloaded that particular nightly build that contained the fix.</p>

<p>I should note here that the nightly builds are actually for the upcoming Flex 3 SDK, but my current project is still using the Flex 2.0.1 hotfix 3 SDK.  </p>

<p>I used the "underriding" technique that <a href="http://dougmccune.com/blog/2007/08/17/my-360flex-slides-and-code/">Doug described here</a> to apply the changes to my current SDK.  Essentially, I took the code for the files that have changed and created versions of them in my local project.   My project now has an "mx.controls.DateChooser" class defined that contains the code from the nightly build.  Because it has the same fully qualified name as the default DateChooser in my Flex 2.0.1 hf 3 SDK, the version in my project takes greater precedence and it is what gets compiled into the ptoject and used.  </p>

<p>This allowed me to apply only the the relevant changes from the nightly build without affecting the rest of my installed SDK.  It took a little bit of effort to remove some of the "Flex 3" features from the updated code to downgrade it to work with the Flex 2.0.1 hf 3 SDK, but it wasn't a difficult process.</p>

<p>If you're already using Flex 3, it's even easier to apply a nightly build.  In fact, you can just add the nightly build as a new installed SDK in FlexBuilder 3 and simply recompile your project with that SDK to incorporate the changes.  It was only because I'm using an older SDK that I had to go through the process of manually applying the changes.</p>

<p>To summarize:</p>

<p>1.  I ran into a bug<br />
2.  I looked to see if it was a known issue or already fixed<br />
3.  It wasn't, so I told Adobe about it<br />
4.  I watched the bug to keep informed of its progress<br />
5.  Adobe developed a fix for me<br />
6.  I downloaded the nightly SDK that included the code for the fix<br />
7.  I applied the fix in my project<br />
8.  All is well</p>

<p>A positive side effect here is that the fix now goes out to all developers who will be using the Flex 3 SDK going forward.  By identifying issues and being involved you not only help yourself by getting Adobe to do the work for you, but you also help the entire Flex community by allowing Adobe to continually improve an already amazing product.</p>

<p>This process isn't limited to just bugs.  If you think something could be done better, log an issue for it.  It will get prioritized, and Adobe might even take your advice and build the enhancement into a future version.</p>

<p>So, if you haven't been using the <a href="http://bugs.adobe.com/flex/">Flex bug base</a>, isn't it about time you start?</p>]]>
        
    </content>
</entry>

<entry>
    <title>On [Transient], ObjectUtil.copy(), and Casting</title>
    <link rel="alternate" type="text/html" href="http://www.darronschall.com/weblog/2007/08/on-transient-objectutilcopy-and-casting.cfm" />
    <id>tag:www.darronschall.com,2007:/darron_schall//1.264</id>

    <published>2007-08-13T15:20:49Z</published>
    <updated>2008-11-23T01:51:34Z</updated>

    <summary>I ran into an interesting situation not too long ago where ObjectUtil.copy wasn't working quite as I had expected.  The solution that I came up with was to rely on [Transient] metadata.  Confused?  Let me explain...</summary>
    <author>
        <name>darron</name>
        
    </author>
    
    <category term="amf" label="AMF" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="transient" label="Transient" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-US" xml:base="http://www.darronschall.com/weblog/">
        <![CDATA[<p>I ran into an interesting situation not too long ago where <a href="http://livedocs.adobe.com/flex/201/langref/mx/utils/ObjectUtil.html#copy()">ObjectUtil.copy</a> wasn't working quite as I had expected.  The solution that I came up with was to rely on [Transient] metadata.  Confused?  Let me explain...</p>

<p>ObjectUtil.copy is a wonderful utility method to perform a <a href="http://en.wikipedia.org/wiki/Deep_copy">deep copy</a> of an object.  Its implementation is also amazingly simple:</p>

<pre name="code" class="js">
var buffer:ByteArray = new ByteArray();
buffer.writeObject(value);
buffer.position = 0;
var result:Object = buffer.readObject();
return result;
</pre>

<p>Rather than using introspection and recursively copying properties from one object to another, the entire object is serialized into a array of bytes.  When the bytes are deserialized, a brand new object is created copying all of the original contents.  </p>

<p>Simple, but effective.  Instead of writing a custom deep copy algorithm , the copy() method uses the built in Flash Player AMF capabilities.  This is the same serialization that Flash Remoting uses.  When you send an object to the server via Flash Remoting (&lt;mx:RemoteObject/&gt;), you send an AMF array of bytes describing the object that the server deserializes to create an identical object on the server.</p>

<p>Because of using AMF behind the scenes to perform object copies, a few interesting things happen:</p>

<ul>
<li>If you try to cast the results of a copy to a class, the cast might fail.</li>
<li>Using the [Transient] metadata tag affects the output of copy().</li>
</ul>

<p>When an object is deserialized from AMF, it does not automatically get created as a class instance.  The object might have all of the properties of a class instance, but it will not be a true class instance unless the AMF packet includes type information about the object.  The type information gets added to AMF in one of two ways:</p>

<ul>
<li>Using the <a href="http://livedocs.adobe.com/livecycle/es/sdkHelp/programmer/lcds/serialize_data_3.html">[RemoteClass] metadata</a> tag.</li>
<li>Using the <a href="http://livedocs.adobe.com/flex/201/langref/flash/net/package.html#registerClassAlias()">registerClassAlias()</a> method.</li>
</ul>

<p>If you're using [RemoteClass] metadata on a class instance being copied, then it is safe to cast the result as that particular class instance:</p>

<pre name="code" class="js">
// The works if Book has [RemoteClass] metadata
var bookCopy:Book = Book( ObjectUtil.copy( book ) );
</pre>

<p>If you're not using [RemoteClass], before performing the copy you need to register the class against a string alias.  The alias is written to the AMF packet so that when the object is deserialized, it can be created as the proper type.  For example:</p>

<pre name="code" class="js">
// Book doesn't have [RemoteClass] metadata, so associate the my.package.Book string
// with a reference to the Book class.
registerClassAlias( "my.package.Book", Book );

// Now we can cast the result of the copy without errors.
var bookCopy:Book = Book( ObjectUtil.copy( book ) );
</pre>

<p>So, what about [Transient], and how is this related to the issue I ran into where the copy wasn't working as I had expected?  Now that you know how copy works behind the scenes, let's talk about [Transient].</p>

<p>The [Transient] metadata tag is not very well documented in Flex 2 or 2.0.1.  If you look in some of the LiveCycle Data Services documentation you can see mentions of it, but there isn't a dedicated page on the subject.  In the beta Flex 3 documentation, <a href="http://livedocs.adobe.com/labs/flex/3/html/metadata_066_15.html">[Transient] is finally explained</a>.  There is also some documentation gathered on <a href="http://nondocs.blogspot.com/2007/04/metadatatransient.html">The Flex Non-Docs weblog</a>.</p>

<p>Essentially, what it comes to is that <b>using [Transient] on a property removes that property from the AMF packet during serialization</b>.  This is important.  The reason [Transient] properties are not sent over the wire via Flash Remoting is because, again, they're not included in the AMF packet.</p>

<p>With the background information explained, onto the problem I ran into.  Here's a small class that doesn't copy correctly (after the jump):</p>]]>
        <![CDATA[<pre name="code" class="js">
package
{

public class Example
{
	
	/** Constant for when the flag value indicates option 1. */
	public static const OPTION_1:String = "1";
	
	/** Constant for when the flag value indicates option 2. */
	public static const OPTION_2:String = "2";
	
	/** Constant for when th flag vlaue indicates no option. */
	public static const OPTION_NONE:String = "0";

	/** One of the option constants, determines what value is used for. */
	public var flag:String;
	
	/** The numeric value for whatever option the flag indicates. */
	public var value:int;
	
	// ================================
	//  option1 property
	// ================================
	
	/** 
	 * Helper method to get/set the value of option 1.  Returns -1 if option 1
	 * is not the flag value.
	 */
	public function get option1():int
	{
		return flag == OPTION_1 ? value : -1;
	}
	
	public function set option1( value:int ):void
	{
		// Anytime the option1 setter is called, set the flag and save the value
		flag = OPTION_1;
		this.value = value;
	}
	
	// ================================
	//  option2 property
	// ================================
	
	/** 
	 * Helper method to get/set the value of option 2.  Returns -1 if option 2
	 * is not the flag value.
	 */
	public function get option2():int
	{
		return flag == OPTION_2 ? value : -1;
	}
	
	public function set option2( value:int ):void
	{
		// Anytime the option2 setter is called, set the flag and save the value
		flag = OPTION_2;
		this.value = value;
	}

} // end class
} // end package
</pre>

<p>What's important about this class is that there are really only two values that we care about - <i>flag</i>, and <i>value</i>.  I'm using option1 and option2 as helper getter/setters to read and manipulate those properties.</p>

<p>Trying to copy this class yields some interesting behavior:</p>

<pre name="code" class="js">
// Create an object and assign a value
var example:Example = new Example();
example.option2 = 123;
				
// Register the class so deserialization preserves the type information
registerClassAlias( "Example", Example );
				
// Make a copy of the original object
var copy:Example = Example( ObjectUtil.copy( example ) );
				
trace( "example: " + example.option2 ); // example: 123
trace( "copy: " + copy.option2 ); 		// copy: -1

trace( example.flag );  // 2
trace( copy.flag );		// 1
</pre>

<p>Since <i>example</i> and <i>copy</i> have different option2 values, obviously the copy didn't complete as expected.  Where did we go wrong?</p>

<p>When the copy() method serialized the data as AMF, Flash Player not only wrote the flag and value properties and their values, but it <i>also</i> wrote the option1 and option2 values.  When the deserialization happened, all 4 properties were read back in.  The option1 property was read in <i>after</i> option2.  This means the option1 setter was called and changed the values of both flag and value incorrectly.  Oops!</p>

<p>The solution, now that we know how [Transient] relates to AMF, is to tag the option1 and option2 helper properties as transient.  This excludes them from the AMF serialization and prevents errors when the setters would be called during deserialization:</p>

<pre name="code" class="js">
// Flag option1 as transient so it is not included as part
// of the object when copied or sent to the server
[Transient]
public function get option1():int
// ...
// ...likewise with option2
</pre>

<p>After adding [Transient], when the example code is run again only <i>flag</i> and <i>value</i> are serialized (and therefore deserialized and copied).  This corrects the original behavior and the copy's option2 value is the same as example's value.</p>

<p>I hope this helps in your understanding of AMF, how it relates to class instances and casting, and what kind of effect the [Transient] metadata actually has behind the scenes.  Even if a class is never meant to be sent to the server, [Transient] can still be useful.</p>]]>
    </content>
</entry>

<entry>
    <title>Flex 2.0.1 Hotfix 3 - The WebService Fix</title>
    <link rel="alternate" type="text/html" href="http://www.darronschall.com/weblog/2007/07/flex-201-hotfix-3---the-webservice-fix.cfm" />
    <id>tag:www.darronschall.com,2007:/weblog//1.263</id>

    <published>2007-07-24T12:38:01Z</published>
    <updated>2008-11-23T01:52:45Z</updated>

    <summary>...and it couldn't have come at a better time for me.</summary>
    <author>
        <name>darron</name>
        
    </author>
    
        <category term="Flex" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="flex" label="Flex" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-US" xml:base="http://www.darronschall.com/weblog/">
        <![CDATA[<p>...and it couldn't have come at a better time for me.</p>

<p>I've been hard at work on a large Flex 2 application that utilizes Web Services to communicate with the back-end.  I've run into a number of issues that had to be worked around, all of which appear to be fixed by <a href="http://www.adobe.com/go/kb402381">Flex 2.0.1 Hotfix 3</a>.</p>

<p>It looks like Hotfix 3's main focus has been the Web Service classes, adding more stability and fixing lingering issues.  This should be a welcome update to anyone who's been banging their head against a wall using Web Services.</p>

<p>One of the issues in particular, using a secure wsdl switches useProxy to true which breaks applications, was quite a pain to deal with.  This is where the <a href="http://www.darronschall.com/weblog/archives/000265.cfm">Open Source Flex announcement</a> really pays dividends.  I was able to <a href="https://bugs.adobe.com/jira/browse/SDK-11194">find the issue in the public facing bugbase</a> and monitor progress.  I was happy to see that the issue was already reported, that it already had a valid workaround, and that it was going to be fixed in an upcoming Hotfix 3 release.  Kudos to Adobe for having transparency here.</p>

<p>As with any Hotfix release, if you're not experiencing any of the issues that were fixed then it is not recommend that you upgrade.  As they say... if it ain't broke...</p>

<p>However, if you're using Web Services you might want to consider the Hotfix 3 upgrade at <a href="http://www.adobe.com/go/kb402381">http://www.adobe.com/go/kb402381</a>.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Parse errors with ActionScript 3's JSON library</title>
    <link rel="alternate" type="text/html" href="http://www.darronschall.com/weblog/2007/07/parse-errors-with-actionscript-3s-json-library.cfm" />
    <id>tag:www.darronschall.com,2007:/darron_schall//1.262</id>

    <published>2007-07-05T15:02:22Z</published>
    <updated>2008-11-23T01:55:06Z</updated>

    <summary>I've had a few people ping me recently about unexpected parse errors they've encountered while decoding JSON strings using the ActionScript 3 JSON library (part of as3corelib).  The fix is easy, but not entirely obvious.</summary>
    <author>
        <name>darron</name>
        
    </author>
    
        <category term="Flex" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="json" label="JSON" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="ruby" label="Ruby" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-US" xml:base="http://www.darronschall.com/weblog/">
        <![CDATA[<p>I've had a few people ping me recently about unexpected parse errors they've encountered while decoding JSON strings using the <a href="http://as3corelib.googlecode.com/svn/trunk/docs/com/adobe/serialization/json/JSON.html">ActionScript 3 JSON library</a> (part of <a href="http://code.google.com/p/as3corelib/">as3corelib</a>).  The fix is easy, but not entirely obvious.</p>

<p>It turns out that in all of the cases where erroneous parse errors were reported, the JSON string looked something like this:</p>

<pre name="code" class="js">
{ prop1: 12, prop2: "hello, world" }
</pre>

<p>Can you spot the problem?</p>

<p>According to the <a href="http://json.org/">JSON spec</a>, the above snippet is not actually valid JSON.  The reason?  It's because the object property identifiers are not string literals.  It may be valid JavaScript/ActionScript for creating an object via a literal, but JSON objects contain pairs of <i>string : value</i> and strings are always enclosed in double quotes.</p>

<p>The ActionScript 3 JSON parser I made is a bit on the strict side, I guess.  From what I can gather, a lot of JSON decoders will accept the above snippet as valid JSON.  Even worse, a lot of JSON encoders will produce JSON in the above format.  That is, when you create a JSON string, behind the scenes the JSON string might not actually be valid.  Typically the libraries that produce snippets without quotes around object identifiers will also accept those as valid input, so it's usually not a problem.</p>

<p>So, if you're running into parse errors when trying to decode JSON strings in ActionScript 3... make sure the JSON string is actually valid.  The first place to look is for quoted identifiers in objects.</p>

<p>If you're using Ruby on Rails and running into this problem, a simple configuration change on the server end will fix the problem:</p>

<pre name="code" class="js">
>> ActiveSupport::JSON::unquote_hash_key_identifiers=false
=> false
</pre>

<p>Thanks to Richard Wallace for pointing out the Rails configuration change necessary to produce valid JSON for the ActionScript 3 JSON decoder.</p>]]>
        
    </content>
</entry>

<entry>
    <title>How I Debug with Flex Modules</title>
    <link rel="alternate" type="text/html" href="http://www.darronschall.com/weblog/2007/06/how-i-debug-with-flex-modules.cfm" />
    <id>tag:www.darronschall.com,2007:/darron_schall//1.261</id>

    <published>2007-06-14T16:52:53Z</published>
    <updated>2008-11-23T01:57:27Z</updated>

    <summary>When you create modular application in Flex 2.0.1, you lose the ability to debug within the loaded modules.  This can be overcome by using a simple technique that a friend encouraged me to post after I shared it with him.</summary>
    <author>
        <name>darron</name>
        
    </author>
    
        <category term="Flex" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="debugging" label="Debugging" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="modules" label="Modules" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-US" xml:base="http://www.darronschall.com/weblog/">
        <![CDATA[<p>When you <a href="http://livedocs.adobe.com/flex/201/html/modular_083_1.html">create modular application in Flex 2.0.1</a>, you lose the ability to debug within the loaded modules.  This can be overcome by using a simple technique that <a href="http://www.simb.net/">a friend</a> encouraged me to post after I shared it with him.</p>

<p>Essentially, modules are loaded into an application via the <a href="http://livedocs.adobe.com/flex/201/langref/mx/modules/ModuleLoader.html">ModuleLoader</a> class.  A typical example looks like this:</p>

<pre name="code" class="xml">
&lt;mx:ModuleLoader id="moduleLoader" url="myModule.swf" /&gt;
</pre>

<p>The problem with this approach is that the URL is hard-coded to always load the non-debug version of the module .swf file.  Whenever you create an application/module in FlexBuilder, two .swf files are generated: the release version which just ends in ".swf", and the debug version which ends in "-debug.swf").  When you launch a debug session, the debug .html file launches which instructs Flash Player to load the debug .swf file.  The debug .swf contains additional information to help the debugger along so you can examine the running application in detail.</p>

<p>In the case of debugging with modules, when you debug the debug version of the main application is loaded and the debugger launches, but the release version of the modules are loaded because of the hard-coded reference to the module's URL.  This means that you can't get debugging information from your modules because the release .swf which loads does not contain the debugging information.</p>

<p>The fix is pretty straightforward.  When you need to debug the application you have to load the "-debug.swf" module, and when you want to create a release version you have to load the normal .swf file.  Rather than constantly changing the URL on each ModuleLoader instance, I've been using a static getter "constant" that makes the process transparent:</p>

<pre name="code" class="js">
public final class Constants
{
	/** The path to the swf file for my module. */
	public static function get MY_MODULE_SWF():String
	{
		// Check to see if the application is the debug version, and if
		// so then use the debug module...
		if ( Application( Application.application ).url.indexOf( "debug" ) >= 0 )
		{
			return "MyModule-debug.swf";
		}
		
		// ...otherwise use the release module
		return "MyModule.swf";
	}
}
</pre>

<p>The ModuleLoader then needs to have the url property set via ActionScript.  If you try to use binding in the MXML tag itself, you'll get a warning about not being able to detect changes in the { } binding syntax, and trying to make the getter [Bindable] will complain that you can't create bindable static functions.  It's a minor annoyance, but I hardly notice it since I control module loading via ActionScript anyway:</p>

<pre name="code" class="js">
moduleLoader.url = Constants.MY_MODULE_SWF;

// Load the module
var module:IModuleInfo = ModuleManager.getModule( Constants.MY_MODULE_SWF );
module.load();
</pre>

<p>A nice side effect of using this simple technique is being able to use a "constant" to reference the module from anywhere via the ModuleManager.getModule method.</p>

<p>Now, no matter if you run or debug, the correct version of the module gets loaded and the fact that you're using modules becomes transparent.  I believe this is an area that Adobe is hoping to improve upon in <a href="http://labs.adobe.com/wiki/index.php/Flex_3">Flex 3 (Moxie)</a> and in the future as well, but the above is a good workaround in the near term.</p>

<p>I've been using modules quite a bit for the past few months on my current project.  Hopefully I'll have some time in the future to share a few more tips and tricks like this for creating modular architectures in Flex RIAs.</p>]]>
        
    </content>
</entry>

<entry>
    <title>New Chart Annotation added to FlexLib</title>
    <link rel="alternate" type="text/html" href="http://www.darronschall.com/weblog/2007/05/new-chart-annotation-added-to-flexlib.cfm" />
    <id>tag:www.darronschall.com,2007:/darron_schall//1.260</id>

    <published>2007-05-24T13:45:46Z</published>
    <updated>2008-11-23T01:59:38Z</updated>

    <summary>I've added a new chart annotation, HorizontalAxisDataSelector, to the FlexLib project.</summary>
    <author>
        <name>darron</name>
        
    </author>
    
        <category term="ActionScript" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Flex" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="annotation" label="Annotation" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="chart" label="Chart" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="component" label="Component" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="flexlib" label="FlexLib" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-US" xml:base="http://www.darronschall.com/weblog/">
        <![CDATA[<p>I've added a new chart annotation, <a href="http://flexlib.googlecode.com/svn/trunk/docs/flexlib/charts/HorizontalAxisDataSelector.html">HorizontalAxisDataSelector</a>, to the <a href="http://code.google.com/p/flexlib/">FlexLib</a> project.</p>

<p>The HorizontalAxisDataSelector is a relatively simple chart annotation that allows a user to select a value along the horizontal axis of the chart.  When the uses mouses down on the chart, the selector dispatches a change event and draws a vertical line at the nearest data point along the x-axis.</p>

<p>The selector contains a <b>dataValues</b> property that is an array containing the y value of each chart series at the given x-axis location.  You can use these values to present a clear view to the user of all of the y-values for a given x-value rather than forcing them to rely on mousing over data tip points.</p>

<p>You can <a href="http://flexlib.googlecode.com/svn/trunk/examples/HorizontalAxisDataSelector/HorizontalAxisDataSelector_Sample.swf">view the example here</a>, along with the <a href="http://flexlib.googlecode.com/svn/trunk/examples/HorizontalAxisDataSelector/HorizontalAxisDataSelector_Sample.mxml">example source code</a>.</p>

<p>Integrating the chart annotation basically just involves adding the following to your chart:</p>

<pre name="code" class="xml">
&lt;mx:annotationElements&gt;
	&lt;flexlib:HorizontalAxisDataSelector id="dataSelector"
		change="updateDetails();"
		selectorColor="0x000000" /&gt;
&lt;/mx:annotationElements&gt;
</pre>

<p>This is something I wrote a really long time ago, probably on the order of 6 months or so (6 months is like an eon or two in internet-time).  It's nothing special by any means, and is still rough around the edges.  I had wanted to re-visit it and make some improvements, but just haven't found the time to work on it.  As such, I figured it was best to just publish it since it's actually proven itself useful a few times, rather than hold on to it waiting until I have the time to get around to updating it.</p>

<p>In its current form, you can only use this annotation on horizontal axes that are numeric (or date-driven), and that are in ascending order.  Kind of a bummer, I know.  If you need to use this on a category axis, feel free to modify the <a href="http://flexlib.googlecode.com/svn/trunk/src/flexlib/charts/HorizontalAxisDataSelector.as">source</a> and contribute it back into FlexLib once you get it working!</p>

<p><b>Note:</b> Right now this is only available in <a href="http://flexlib.googlecode.com/svn//trunk/">SVN</a>.  <a href="http://www.dougmccune.com/blog/">Doug</a> and I are still sorting out when the best time is to create new packaged <a href="http://code.google.com/p/flexlib/">FlexLib</a> .swc releases.</p>

<p>On a related note, this annotation isn't nearly as cool as some of the <a href="http://www.quietlyscheming.com/blog/2006/04/03/custom-chart-annotations/">annotations Ely has come up with</a>.  His <a href="http://www.quietlyscheming.com/blog/charts/chart-sampler/">Chart Sampler</a> is amazing.  My meager annotation barely scratches the surface of what is possible in the charting framework.  To this day I'm still amazed at just how flexible and extensible the charting framework is...</p>]]>
        
    </content>
</entry>

<entry>
    <title>FlexBuilder Quick Tip: Not all errors lead to Rome.</title>
    <link rel="alternate" type="text/html" href="http://www.darronschall.com/weblog/2007/05/flexbuilder-quick-tip-not-all-errors-lead-to-rome.cfm" />
    <id>tag:www.darronschall.com,2007:/darron_schall//1.259</id>

    <published>2007-05-04T13:59:28Z</published>
    <updated>2008-11-23T02:01:08Z</updated>

    <summary>A friend of mine was getting an error in FlexBuilder that, quite frankly, didn't make any sense.  Here's the rundown of how we fixed it.</summary>
    <author>
        <name>darron</name>
        
    </author>
    
        <category term="Flex" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="flexbuilder" label="FlexBuilder" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en-US" xml:base="http://www.darronschall.com/weblog/">
        <![CDATA[<p>A friend of mine was getting an error in FlexBuilder that, quite frankly, didn't make any sense.  Here's the rundown of how we fixed it.</p>

<p><font color="red"><b>Friend:</b></font> Would you happen to have any idea why when i include 'import flash.external.ExternalInterface;' i can't use it, like 'ExternalInterface.available' gives me 'Access of possibly undefined property available through a reference with static type Class.'<br />
<font color="blue"><b>Me:</b></font> hmm, smells fishy.<br />
<font color="red"><b>Friend:</b></font> yeah i'm thinking something is hosed with my fbuilder or something<br />
<font color="blue"><b>Me:</b></font> I wonder if it's one of the .swc library files, like playerglobal.swc, in the framework lib directory<br />
<font color="blue"><b>Me:</b></font> Have you installed something that might've overwritten that, like apollo?<br />
<font color="red"><b>Friend:</b></font> yeah, apollo<br />
<font color="blue"><b>Me:</b></font>  maybe it just got overwritten by a bad version then, check to see when it was last modified<br />
<font color="red"><b>Friend:</b></font> i don't think that's it, same date as the others<br />
<font color="blue"><b>Me:</b></font>  hmm, ok, nevermind then<br />
<font color="red"><b>Friend:</b></font> when I  i do ExternalInterface. something<br />
<font color="red"><b>Friend:</b></font> nothing comes up<br />
<font color="blue"><b>Me:</b></font> are you sure its the EI class that the error is coming from?<br />
<font color="blue"><b>Me:</b></font> and not a different compiler error?<br />
<font color="blue"><b>Me:</b></font> sometimes that happens when you have a syntax error in the file<br />
<font color="red"><b>Friend:</b></font> oo maybe<br />
<font color="blue"><b>Me:</b></font> like, FB can't process the code hints because of a previous error (previous meaning in time, not necessarily earlier in the file)<br />
<font color="red"><b>Friend:</b></font> let me try something<br />
<font color="blue"><b>Me:</b></font> if you're not getting code hints, check to make sure you have matching {}'s, ()'s, etc.<br />
<font color="red"><b>Friend:</b></font> that's it, it works now<br />
<font color="blue"><b>Me:</b></font> I'm going to blog this quickly :-)<br />
<font color="red"><b>Friend:</b></font> haha, i work with this clown that can't write code that compiles and asks me why it doesn't work<br />
<font color="blue"><b>Me:</b></font> nah, I won't mention you by name, unless you want me too.. haha<br />
<font color="red"><b>Friend:</b></font> oo the problem was that my project was named ExternalInterface as well</p>

<p>Moral of the story: I have multiple personalities, and I'm really just talking to myself.  Wait.. no....</p>

<p>Moral of the story: If you ping me on IM be aware that I just might make an example of you on my weblog!  Wait.. that's not it either!</p>

<p><b>Real</b> moral of the story: Sometimes the error you're getting from FlexBuilder is misleading.  If all of a sudden something stops working such as code hints, or you get an error message that just doesn't make sense, check to make sure the rest of the file has correct syntax.  Sometimes there are situations where FlexBuilder erroneously reports one error when it should've reported something else.  </p>

<p>Also, check to make sure that you don't have an mxml file with the same name as another class you're trying to use.  Remember, all mxml files are compiled into ActionScript 3.0 classes behind the scenes.  You might have to use a fully-qualified name for a class if you have a conflicting mxml file that shares the same name.  For example, use flash.external.ExternalInterface.available if you already have an ExternalInterface.mxml file.</p>

<p>These types of errors don't happen often, but when they do hopefully the above information will help you to fix them!</p>]]>
        
    </content>
</entry>

</feed>
