<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>JonnyReeves.co.uk &#187; ActionScript 3</title>
	<atom:link href="http://www.jonnyreeves.co.uk/tag/actionscript-3/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.jonnyreeves.co.uk</link>
	<description>Actionscript, Flash, PHP and stuff</description>
	<lastBuildDate>Mon, 19 Jul 2010 15:36:14 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Logging in ActionScript 3</title>
		<link>http://www.jonnyreeves.co.uk/2010/02/logging-in-actionscript-3/</link>
		<comments>http://www.jonnyreeves.co.uk/2010/02/logging-in-actionscript-3/#comments</comments>
		<pubDate>Mon, 22 Feb 2010 20:27:36 +0000</pubDate>
		<dc:creator>Jonny</dc:creator>
				<category><![CDATA[ActionScript 2]]></category>
		<category><![CDATA[ActionScript 3]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[logging]]></category>

		<guid isPermaLink="false">http://www.jonnyreeves.co.uk/?p=169</guid>
		<description><![CDATA[Logging is a fundamental part of any mid to large scale application, your application needs to be able to talk to other developers and Q&#038;A engineers to help diagnose problems and gain insight into what&#8217;s going on under the hood.  Jesse Warden recently wrote an excellent article on logging, however, my own implementation of [...]]]></description>
			<content:encoded><![CDATA[<p>Logging is a fundamental part of any mid to large scale application, your application needs to be able to talk to other developers and Q&#038;A engineers to help diagnose problems and gain insight into what&#8217;s going on under the hood.  Jesse Warden recently wrote <a href="http://jessewarden.com/2010/02/consulting-chronicles-3-preventing-fire-drills-crises-by-removing-land-mines-and-using-diagnostic-tools.html">an excellent article on logging</a>, however, my own implementation of logging AS3 apps differs so much that I thought it warranted a blog post.</p>
<h3>The Problems</h3>
<p>One of the most important things in OOP is to ensure that you avoid tight coupling; Jesse&#8217;s approach of using a static logger leaves your code scattered with a dependency on it.  </p>
<p>Another point that Jesse makes is how important it is to include the name of the enclosing class when writing a log message,</p>
<blockquote><p>&#8230; all log messages start with &#8220;ClassName::methodName&#8221; where ClassName is the name of the class you are in, and methodName is the current method the log message is in.  It seems a major pain at first, but I guarantee you when you start removing them 2 months later, you know EXACTLY where to find it vs. that one trace that stays there for weeks because no one found where the bastard is.
</p></blockquote>
<p>I couldn&#8217;t agree more with this, having come from working on a massive application with thousands of log messages, not knowing where a message was originating from would have been a nightmare.  However, Jesse&#8217;s approach is very manual and relies on your entire team being disciplined; not to mention the fact that as soon as you start refactoring that &#8220;ClassName::methodName&#8221; identifier is quickly going to get out of sync.</p>
<h3>A Commons Solution</h3>
<p>I feel that there is a simple solution to both the above problems in the form of the <a href="http://code.google.com/p/as3-commons/">AS3 Commons Logging Framework</a>.  The framework provides an abstraction of logging which means your code is not dependant on any one implementation, plus it has the added benefit of automatically adding the name of the Class when writing a log message; winner!</p>
<p>Usage is pretty straight forward, but requires a little more setup than Jesse&#8217;s static helper approach; first of all your request a static ILogger instance from the LoggerFactory at the top of your class and then you are free to use it throughout the Class to write log messages, for example:</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
package uk.<span class="me1">co</span>.<span class="me1">jonnyreeves</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">public</span> <span class="kw2">class</span> MyClass<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Request an ILogger instance for this Class.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">public</span> <span class="kw3">static</span> const LOGGER : ILogger = LogFactory.<span class="me1">getClassLogger</span><span class="br0">&#40;</span>MyClass<span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">public</span> <span class="kw2">function</span> MyClass<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Write a log message using the Logger instance.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LOGGER.<span class="me1">info</span><span class="br0">&#40;</span><span class="st0">&quot;Created instance of MyClass&quot;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
&nbsp;</div>
<p>Using the TraceLogger implementation which the AS3 Commons Logger will default to, you would receive the following in your <a href="http://yourpalmark.com/2005/07/01/trace-from-the-browser-using-standard-trace/">Flash TraceLog</a>:</p>
<pre>
Sun Feb 21 10:33:29 GMT+0000 2010 [INFO]  uk.co.jonnyreeves.MyClass - Created instance of MyClass
</pre>
<p>The beauty of this approach is that the actual implementation of the ILogger interface is left to the LoggerFactory which means it can be switched at runtime.  Another neat benfit is that the name of the Logger is taken from the encolosing Class which created it (via <a href="http://code.google.com/p/as3-commons/source/browse/tags/as3-commons-logging/1.1/src/main/actionscript/org/as3commons/logging/LoggerFactory.as">LoggerFactory.getClassLogger()</a>).  This mean that is you rename the Class as part of a refactoring effort, all the log messages contained in said class will automatically update.</p>
<h3>Getting More Specific</h3>
<p>So I&#8217;ve mentioned that your can decide the ILogger implementation at runtime, let&#8217;s see an example of that in action.  My current Logging implementation of choice is the excellent DeMonsters Monster Debugger which reminds me a lot of the AS2 classic, LumnicBox in that it allows you to fully inspect the Object Graph at run time.</p>
<p>The first thing we need is to create an implementation of LogFactory which will return our ILogger instances upon request:</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
package uk.<span class="me1">co</span>.<span class="me1">jonnyreeves</span>.<span class="me1">logging</span>.<span class="me1">util</span>.<span class="me1">monsterdebugger</span> <br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">import</span> nl.<span class="me1">demonsters</span>.<span class="me1">debugger</span>.<span class="me1">MonsterDebugger</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">import</span> org.<span class="me1">as3commons</span>.<span class="me1">logging</span>.<span class="me1">ILogger</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">import</span> org.<span class="me1">as3commons</span>.<span class="me1">logging</span>.<span class="me1">ILoggerFactory</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Provides a bridge between the AS3Commons Logging Framework and MonsterDebugger.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @author John Reeves<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">public</span> <span class="kw2">class</span> MonsterDebuggerLoggerFactory <span class="kw3">implements</span> ILoggerFactory <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Initialises MonsterDebugger<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @param target&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; The Base Object you wisht to start graphing from (usually you will supply the<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Display Root DisplayObject).<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @param clearConsole&nbsp; Clears MonsterDebugger&#8217;s Trace Console when the initial connection is made.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">public</span> <span class="kw2">function</span> MonsterDebuggerLoggerFactory<span class="br0">&#40;</span><span class="kw3">target</span> : <span class="kw3">Object</span>, clearConsole : <span class="kw3">Boolean</span> = <span class="kw2">true</span><span class="br0">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">new</span> MonsterDebugger<span class="br0">&#40;</span><span class="kw3">target</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>clearConsole<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MonsterDebugger.<span class="me1">clearTraces</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Factory Method, used to return an instance of ILogger to the AS3Commons Logging Framework.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">public</span> <span class="kw2">function</span> getLogger<span class="br0">&#40;</span><span class="kw3">name</span> : <span class="kw3">String</span><span class="br0">&#41;</span> : ILogger<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">new</span> MonsterDebuggerLogger<span class="br0">&#40;</span><span class="kw3">name</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
&nbsp;</div>
<p>Now all that&#8217;s left to do is to create the MonsterDebuggerLogger implementation of the ILogger interface; this will re-write all the LOGGER.info(), etc calls through to MonsterDebugger.</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
package uk.co.jonnyreeves.logging.util.monsterdebugger <br />
{<br />
&nbsp; &nbsp; &nbsp; &nbsp; import org.as3commons.logging.util.MessageUtil;<br />
&nbsp; &nbsp; &nbsp; &nbsp; import nl.demonsters.debugger.MonsterDebugger;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; import org.as3commons.logging.LogLevel;<br />
&nbsp; &nbsp; &nbsp; &nbsp; import org.as3commons.logging.impl.AbstractLogger;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; /**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Provides a bridge between the AS3 Commons Logging implementation and Monster Debugger; it&#8217;s not perfect but it <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* works for the most part.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* The Target of the log message will always be the name of the logger.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* The Object of the log message will vary depending on the parameters passed. &nbsp;If the message string is empty<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* then the params Array will be logged. &nbsp;If the message string is not empty, the params Array will be used to<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* tokenise the message string.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Usage:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; LOGGER.debug(&quot;Hello World&quot;);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Outputs message: &quot;(String) Hello World&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; LOGGER.debug(&quot;Hello {0} {1}, &quot;Jonny&quot;, &quot;Reeves&quot;);&nbsp; &nbsp; &nbsp; &nbsp; // Outputs message: &quot;(String) Hello Jonny Reeves&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; LOGGER.debug(&quot;&quot;, [ 1, 2, 3 ]);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Outputs message: &quot;(Array)&#8230;&quot; (which can then be inspected)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Incorrect usage:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; LOGGER.debug(&quot;Some Array&quot;, [1, 2, 3]);&nbsp; // Outputs message: &quot;(String) Some Array&quot; (which can&#8217;t be inspected)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @author John Reeves<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/<br />
&nbsp; &nbsp; &nbsp; &nbsp; public class MonsterDebuggerLogger extends AbstractLogger <br />
&nbsp; &nbsp; &nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public var level : int = LogLevel.DEBUG;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public function MonsterDebuggerLogger(name : String) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; super(name);<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; override protected function log(level : uint, message : String, params : Array) : void<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (level &gt;= this.level)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var target : Object = name;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var object : Object = getLogObject(message, params);<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var colour : uint = getLogMessageColour(level);<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MonsterDebugger.trace(target, object, colour);<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; private function getLogObject(message : String, params : Array) : Object <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (message == &quot;&quot;)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // If the user only supplied a single param to log, we remove the params array which is enclosing it.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return (params.length == 1) ? params.pop() : params;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return MessageUtil.toString(message, params);<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; private function getLogMessageColour(level : int) : uint <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var colour : int;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; switch (level)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case LogLevel.FATAL:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case LogLevel.ERROR:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; colour = MonsterDebugger.COLOR_ERROR;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case LogLevel.WARN:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; colour = MonsterDebugger.COLOR_WARNING;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; colour = MonsterDebugger.COLOR_NORMAL;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return colour;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; override public function get debugEnabled() : Boolean<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return LogLevel.DEBUG &gt;= level;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; override public function get errorEnabled() : Boolean<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return LogLevel.ERROR &gt;= level;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; override public function get infoEnabled() : Boolean<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return LogLevel.INFO &gt;= level;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; override public function get warnEnabled() : Boolean<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return LogLevel.WARN &gt;= level;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; override public function get fatalEnabled() : Boolean<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return LogLevel.FATAL &gt;= level;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; &nbsp; &nbsp; }<br />
}<br />
&nbsp;</div>
<p>The code here is fairly self documenting with the protected log() method proxying all the logging requests through to MonsterDebugger.  Because the creators of the AS3Commons Logging Project specified the message param to have a datatype of String, we are forced to do a little bit of a workaround when we want to dump Objects out to the MonsterDebugger console.  There is an <a href="http://code.google.com/p/as3-commons/issues/detail?id=3">open ticket</a> on the AS3Commons project page should you wish to request a change.</p>
<p>The last piece of the puzzle is to swap the AS3Commons LoggingFactory implementation, this is very straight forward and requires a single line of code during your application&#8217;s startup routine (preferably before any logging takes place).</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
package &nbsp;<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">import</span> uk.<span class="me1">co</span>.<span class="me1">jonnyreeves</span>.<span class="me1">logging</span>.<span class="me1">util</span>.<span class="me1">MonsterDebuggerLoggerFactory</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">import</span> flash.<span class="me1">display</span>.<span class="me1">Sprite</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Application Entry Point.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @author John Reeves<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">public</span> <span class="kw2">class</span> MyApp <span class="kw3">extends</span> Sprite <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">public</span> <span class="kw2">function</span> MyApp<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LoggerFactory.<span class="me1">loggerFactory</span> = <span class="kw2">new</span> MonsterDebuggerLoggerFactory<span class="br0">&#40;</span><span class="kw3">this</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
&nbsp;</div>
<p>Once this is done you are free to start using the LoggingFactory as per the example further up the page.  Your log messages should now show up in the MonsterDebugger logging console.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jonnyreeves.co.uk/2010/02/logging-in-actionscript-3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Sorting Values Stored in a Dictionary</title>
		<link>http://www.jonnyreeves.co.uk/2009/06/sorting-values-stored-in-a-dictionary/</link>
		<comments>http://www.jonnyreeves.co.uk/2009/06/sorting-values-stored-in-a-dictionary/#comments</comments>
		<pubDate>Mon, 15 Jun 2009 06:59:11 +0000</pubDate>
		<dc:creator>Jonny</dc:creator>
				<category><![CDATA[ActionScript 3]]></category>
		<category><![CDATA[dictionary]]></category>
		<category><![CDATA[sort]]></category>

		<guid isPermaLink="false">http://www.jonnyreeves.co.uk/?p=93</guid>
		<description><![CDATA[Looking through my incoming seaches from Google I&#8217;ve noticed that a lot of visitors to my site are trying to figure out how to sort values stored in a Dictionary.  The short and simple answer is that you can&#8217;t as Dictionary&#8217;s in AS3 are meant to represent un-ordered HashMaps, however, there&#8217;s nothing to stop [...]]]></description>
			<content:encoded><![CDATA[<p>Looking through my incoming seaches from Google I&#8217;ve noticed that a lot of visitors to my site are trying to figure out how to sort values stored in a Dictionary.  The short and simple answer is that you can&#8217;t as Dictionary&#8217;s in AS3 are meant to represent un-ordered HashMaps, however, there&#8217;s nothing to stop you moving the un-ordered data out of the Dictionary and into an Array:</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
package <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">import</span> flash.<span class="me1">display</span>.<span class="me1">Sprite</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">import</span> flash.<span class="me1">utils</span>.<span class="me1">Dictionary</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @author Jonny Reeves<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">public</span> <span class="kw2">class</span> DictionarySort <span class="kw3">extends</span> Sprite <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">function</span> DictionarySort<span class="br0">&#40;</span><span class="br0">&#41;</span> : <span class="kw3">void</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> myDictionary : Dictionary = <span class="kw2">new</span> Dictionary<span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Provide some values to sort.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; myDictionary<span class="br0">&#91;</span><span class="nu0">500</span><span class="br0">&#93;</span> = <span class="st0">&quot;Five Hundred&quot;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; myDictionary<span class="br0">&#91;</span><span class="nu0">55</span><span class="br0">&#93;</span> = <span class="st0">&quot;Fifty Five&quot;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; myDictionary<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span> = <span class="st0">&quot;One&quot;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; myDictionary<span class="br0">&#91;</span><span class="nu0">231</span><span class="br0">&#93;</span> = <span class="st0">&quot;Two Hundred and Thirty One&quot;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> myKeys : <span class="kw3">Array</span> = <span class="kw3">this</span>.<span class="me1">extractKeysFrom</span><span class="br0">&#40;</span>myDictionary<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">trace</span><span class="br0">&#40;</span><span class="st0">&quot;myKeys Array before sort: &quot;</span> + myKeys<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Apply a Numeric sort to the Array.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; myKeys.<span class="kw3">sort</span><span class="br0">&#40;</span><span class="kw3">Array</span>.<span class="me1">NUMERIC</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">trace</span><span class="br0">&#40;</span><span class="st0">&quot;myKeys Array after sort: &quot;</span> + myKeys<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// You can now use the extracted Keys to read from the Dictionary in</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// the required order.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> each <span class="br0">&#40;</span><span class="kw2">var</span> thisKey : * <span class="kw1">in</span> myKeys<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Will trace out the number followed by the english words.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">trace</span><span class="br0">&#40;</span>thisKey + <span class="st0">&quot; = &quot;</span> + myDictionary<span class="br0">&#91;</span>thisKey<span class="br0">&#93;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Helper method to extract the Keys from a Dictionary Object and return<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* them in an Array.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*/</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">private</span> <span class="kw2">function</span> extractKeysFrom<span class="br0">&#40;</span>source : Dictionary<span class="br0">&#41;</span> : <span class="kw3">Array</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> output : <span class="kw3">Array</span> = <span class="br0">&#91;</span><span class="br0">&#93;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Note that Dictionary&#8217;s Keys are untyped as they can contain</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// any value.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw2">var</span> prop : * <span class="kw1">in</span> source<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; output.<span class="kw3">push</span><span class="br0">&#40;</span>prop<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> output;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
&nbsp;</div>
]]></content:encoded>
			<wfw:commentRss>http://www.jonnyreeves.co.uk/2009/06/sorting-values-stored-in-a-dictionary/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
