Archive for December, 2009

Get the Full Version of Google Tasks on Your Desktop

I started using Google Tasks about a month ago in order to make it easier for me to use multiple computers and multiple operating systems. Google Tasks is a nice, simple, straightforward application with one small shortcoming: it’s tied to the browser.

Continue reading…

Four New Properties Added to Socket

In response to feedback from the AIR 2 public beta, it looks like we’re going to be adding four new properties to the flash.net.Socket class:

  • Socket.localAddress: The local IP address of this Socket if it has been bounded locally — otherwise null.
  • Socket.localPort: The local port of this Socket if it has been bounded locally — otherwise 0.
  • Socket.remoteAddress: The remote IP address of this Socket if it has been connected — otherwise null.
  • Socket.remotePort: The remote port of this Socket if it has been connected — otherwise 0.

They’re not yet available in the current public beta build, but I would expect them to be in the next one. As always, thanks for the feedback!

(I’ve added these properties to Exhaustive List of Everything That’s New in AIR 2, so that’s still the definitive list.)

Labels in ActionScript 3

There’s a little-known feature of ActionScript 3 called labels which can give you better control over nested loops. In particular, labels give you control over the depth of your continue and break statements.

Consider the following piece of code which compares two arrays to find which elements exist in outerArray that do not exist in innerArray:

var outerArray:Array = ["coffee", "juice", "water", "beer"];
var innerArray:Array = ["liquor", "beer", "wine", "juice"];

for each (var foo:String in outerArray)
{
    var found:Boolean = false;
    for each (var bar:String in innerArray)
    {
        if (foo == bar)
        {
            found = true;
        }
    }
    if (!found)
    {
        trace(foo);
    }
}

(Note: I know there are better ways of doing this particular comparison; this technique is for demonstration purposes only.)

The same code could be written using labels like this:

var outerArray:Array = ["coffee", "juice", "water", "beer"];
var innerArray:Array = ["liquor", "beer", "wine", "juice"];

outerLoop: for (var i:uint = 0; i < outerArray.length; ++i)
{
    var foo:String = outerArray[i];
    innerLoop: for (var j:uint = 0; j < innerArray.length; ++j)
    {
        var bar:String = innerArray[j];
        if (foo == bar)
        {
            continue outerLoop;
        }
    }
    trace(foo);
}

Notice how the labels outerLoop and innerLoop precede my for loops, and how I can reference the outerLoop label in my continue statement. Without specifying a label, continue would have continued from the top of innerLoop rather than outerLoop.

Labels will also work with break statements, and can even be used to create their own blocks as in the following example:

dateCheck:
{
    trace("Good morning.");
    var today:Date = new Date();
    if (today.month == 11 && today.date == 24)  // Christmas!
    {
        break dateCheck;
    }
    trace("Time for work!");
}

Some things to keep in mind about labels:

  • You can’t use a continue statement in the context of a labeled code block since the result would be an infinite loop. This will be caught by the compiler.
  • You obviously can’t reference labels that don’t exist. The compiler will catch your mistake and let you know that the target wasn’t found.
  • In using labels yesterday for new application I’m working on, I discovered that they don’t play well with for each..in loops. If you’re going to use labels, you’ll want to make sure you’re using regular for or while loops. (A bug has been filed and will hopefully be fixed soon.)