<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>HD DVD / Randomness... : Script</title><link>http://blogs.msdn.com/ptorr/archive/tags/Script/default.aspx</link><description>Tags: Script</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Fun Friends for Functions, Part 2: Handling Exceptions</title><link>http://blogs.msdn.com/ptorr/archive/2008/02/01/fun-friends-for-functions-part-2-handling-exceptions.aspx</link><pubDate>Sat, 02 Feb 2008 04:24:40 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7380450</guid><dc:creator>ptorr</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/7380450.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=7380450</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=7380450</wfw:comment><description>&lt;p&gt;Previously we looked at how you can &lt;a href="http://blogs.msdn.com/ptorr/archive/2008/01/29/fun-friends-for-functions.aspx"&gt;bind a function to a set of arguments&lt;/a&gt; and then call the resultant function at some time in the future. This technique is very powerful, but as-is it is a ticking bomb. As Amy points out in her &lt;a href="http://blogs.msdn.com/amyd/archive/2007/12/07/exception-handling.aspx"&gt;blog post on exception handling&lt;/a&gt;, you always need to be prepared to handle an exception in your code. Failure to catch an exception usually leads to playback stopping and an error diagnostic from your player.
&lt;/p&gt;&lt;p&gt;The trouble is that when you start using bound functions, you don't always have an easy way to deal with exceptions. Typically, a bound function is used as part of an asynchronous callback, and in those cases you don't have any functions further up the stack to save you from unhandled errors. Simple, you might think, I'll just wrap the contents of my function in a try-catch and be done with it.
&lt;/p&gt;&lt;p&gt;Not so fast.
&lt;/p&gt;&lt;p&gt;Let's look at the example function we were using in the previous blog post:
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;
 &lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// function to set a backgroundImage&lt;br/&gt;&lt;/span&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; SetBackgroundImage(markupId, url)&lt;br/&gt;{&lt;br/&gt;  document[markupId].style.backgroundImage = url;&lt;br/&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
 &lt;/p&gt;&lt;p&gt;This could throw for several reasons – for example, an element with the &lt;strong&gt;markupId&lt;/strong&gt; doesn't exist, or &lt;strong&gt;url&lt;/strong&gt; isn't a correctly-formatted property value. Simply wrapping this up in a try-catch would result in something like this:
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;
 &lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// function to set a backgroundImage&lt;br/&gt;&lt;/span&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; SetBackgroundImage(markupId, url)&lt;br/&gt;{&lt;br/&gt;  &lt;span style="color:blue"&gt;try&lt;br/&gt;&lt;/span&gt;  {&lt;br/&gt;    document[markupId].style.backgroundImage = url;&lt;br/&gt;  }&lt;br/&gt;  &lt;span style="color:blue"&gt;catch&lt;/span&gt;(ex)&lt;br/&gt;  {&lt;br/&gt;    &lt;span style="color:green"&gt;// What do we do here?!?&lt;br/&gt;&lt;/span&gt;  }&lt;br/&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
 &lt;/p&gt;&lt;p&gt;But there's a problem – what do we do when we catch the exception? I don't know. And that's a key thing about exception handling:
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;strong&gt;Functions should only handle exceptions if they are &lt;em&gt;actually prepared to deal with them&lt;/em&gt;. If a function doesn't know what to do in an error condition, it should let its caller figure it out. The exception [groan] to this rule is that your top-level code should &lt;em&gt;always&lt;/em&gt; swallow exceptions (unless of course things are so out of whack that you think the player should stop immediately).
&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;In this case, the &lt;strong&gt;SetBackgroundImage&lt;/strong&gt; function has no idea what a failure means. It might be perfectly OK if the background image can't be set correctly, or it could be totally disastrous. It all depends on the context, so the &lt;strong&gt;SetBackgroundImage&lt;/strong&gt; function should remain silent on the topic of exceptions and let the calling function figure out what (if anything) to do with them.
&lt;/p&gt;&lt;p&gt;In our particular case, let's say that the exception is benign; we are simply updating some eye-candy graphics and it doesn't matter if they fail to appear. So then: maybe we should write a wrapper function, &lt;strong&gt;SafeSetBackgroundImage&lt;/strong&gt;, that does this for us?
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;
 &lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// function to set a backgroundImage, ignoring exceptions&lt;br/&gt;&lt;/span&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; SafeSetBackgroundImage(markupId, url)&lt;br/&gt;{&lt;br/&gt;  &lt;span style="color:blue"&gt;try&lt;br/&gt;&lt;/span&gt;  {&lt;br/&gt;    SetBackgroundImage(markupId, url);&lt;br/&gt;  }&lt;br/&gt;  &lt;span style="color:blue"&gt;catch&lt;/span&gt;(ex) { }&lt;br/&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
 &lt;/p&gt;&lt;p&gt;I actually like to use this approach if I am going to be calling the 'Safe' version in a lot of different places, but if it is only in one or two places that seems like too much overhead to someone lazy like me. Anytime you update the parameter list of the wrapped function, you have to update the wrappers, too. It can also hide the intent of your code by sprinkling endless wrapper functions all over the place, and this also has the productivity-reducing effect of polluting IntelliSense with unnecessary function names. Instead, we can use the same kind of nested-function trick we used in the argument-binding case to get a "safe" version of any function:
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;
 &lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// return a version of a function that is wrapped in try-catch&lt;br/&gt;// you can optionally provide an errorFunc, which will be&lt;br/&gt;// called with the 'tag' parameter in case of an exception&lt;br/&gt;&lt;/span&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; Function_WrapInTryCatch(errorFunc, tag)&lt;br/&gt;{&lt;br/&gt;  &lt;span style="color:green"&gt;// stash the target function&lt;br/&gt;&lt;/span&gt;  &lt;span style="color:blue"&gt;var&lt;/span&gt; func = &lt;span style="color:blue"&gt;this&lt;/span&gt;;
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;  &lt;span style="color:green"&gt;// return the nested function&lt;br/&gt;&lt;/span&gt;  &lt;span style="color:blue"&gt;return&lt;/span&gt; wrappedFunction;
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;  &lt;span style="color:blue"&gt;function&lt;/span&gt; wrappedFunction()&lt;br/&gt;  {&lt;br/&gt;    &lt;span style="color:green"&gt;// wrap the original function in a try-catch&lt;br/&gt;&lt;/span&gt;    &lt;span style="color:blue"&gt;try&lt;br/&gt;&lt;/span&gt;    {&lt;br/&gt;      func();&lt;br/&gt;    }&lt;br/&gt;    &lt;span style="color:blue"&gt;catch&lt;/span&gt; (ex)&lt;br/&gt;    {&lt;br/&gt;      &lt;span style="color:green"&gt;// call the errorFunc if it was provided&lt;br/&gt;&lt;/span&gt;      &lt;span style="color:green"&gt;// note this MUST be resilient to errors; if it throws&lt;br/&gt;&lt;/span&gt;      &lt;span style="color:green"&gt;// then it is game over.&lt;br/&gt;&lt;/span&gt;      &lt;span style="color:blue"&gt;if&lt;/span&gt; (&lt;span style="color:blue"&gt;typeof&lt;/span&gt; errorFunc == &lt;span style="color:#a31515"&gt;"function"&lt;/span&gt;)&lt;br/&gt;      {&lt;br/&gt;        errorFunc(ex, tag);&lt;br/&gt;      }&lt;br/&gt;    }&lt;br/&gt;  }&lt;br/&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;Function.prototype.WrapInTryCatch = Function_WrapInTryCatch;
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
 &lt;/p&gt;&lt;p&gt;In this example, we also allow the caller of the &lt;strong&gt;WrapInTryCatch&lt;/strong&gt; function to provide an optional error-handling function that will be called if an error occurs. This allows you to do things like channel all your async exceptions to the same error handling function, which can figure out what to do based on the value of the &lt;strong&gt;tag&lt;/strong&gt; parameter. Now we can re-write the last couple of lines of the example as:
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;
 &lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// Call the download function, passing in the set-image function as the callback handler&lt;br/&gt;&lt;/span&gt;&lt;span style="color:blue"&gt;var&lt;/span&gt; setBackgroundHandler = SetBackgroundImage.BindToArguments(&lt;span style="color:#a31515"&gt;"button1"&lt;/span&gt;, &lt;span style="color:#a31515"&gt;"file:///filecache/bar.png"&lt;/span&gt;);&lt;br/&gt;&lt;span style="color:blue"&gt;var&lt;/span&gt; wrappedHandler = setBackgroundHandler.WrapInTryCatch();&lt;br/&gt;DownloadFile(&lt;span style="color:#a31515"&gt;"http://foo/bar.png"&lt;/span&gt;, &lt;span style="color:#a31515"&gt;"file:///filecache/bar.png"&lt;/span&gt;, wrappedHandler);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
 &lt;/p&gt;&lt;p&gt;This helper has the same limitations as the &lt;strong&gt;BindToArguments&lt;/strong&gt; function (specifically: you can't pass any arguments to the returned function, and any tracing information is lost if 'errorFunc' is called) but this is also a solvable problem.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7380450" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ptorr/archive/tags/Script/default.aspx">Script</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/iHD/default.aspx">iHD</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/HDi/default.aspx">HDi</category></item><item><title>Why the ‘arguments’ object is bad, Exhibit #3,745</title><link>http://blogs.msdn.com/ptorr/archive/2008/01/30/why-the-arguments-object-is-bad-exhibit-3-745.aspx</link><pubDate>Thu, 31 Jan 2008 00:46:52 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7334659</guid><dc:creator>ptorr</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/7334659.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=7334659</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=7334659</wfw:comment><description>&lt;p&gt;Having just written a post with an &lt;a href="http://blogs.msdn.com/ptorr/archive/2008/01/29/fun-friends-for-functions.aspx"&gt;example of how to use the arguments object&lt;/a&gt;, you might question my choice of title for this blog post. In my not-so-humble opinion, the 'arguments' object in ECMAScript is only useful for one thing:
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;strong&gt;The 'arguments' object should only be used by infrastructure functions that simply perform book-keeping on behalf of other functions. Any function that actually operates on its arguments in a meaningful way should never access the 'arguments' object. 
&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;The reason for this is plain and simple: code should be easy to &lt;em&gt;read&lt;/em&gt;, easy to &lt;em&gt;debug&lt;/em&gt;, and easy to &lt;em&gt;maintain&lt;/em&gt;. Saving yourself a small amount of effort while &lt;em&gt;writing&lt;/em&gt; code is a very bad trade-off if it negatively impacts these other three important tasks. Using the 'arguments' object in any normal function might save you a few keystrokes in the short-term, but will come back to bite you later on.
&lt;/p&gt;&lt;p&gt;The most obvious problem with the arguments object is this: You have some code you wrote a few [days|weeks|years] ago and now you have to go and update it. You see some function calls like this in source code:
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;
 &lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;SomeBadFunction(42);&lt;br/&gt;&lt;span style="color:green"&gt;// ...
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;SomeBadFunction(i, current);&lt;br/&gt;&lt;span style="color:green"&gt;// ...
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;SomeBadFunction(next, data, OtherFunction(), moreData);&lt;br/&gt;&lt;span style="color:green"&gt;// ...
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
 &lt;/p&gt;&lt;p&gt;You think the problem might be related to one of the parameters being passed to &lt;strong&gt;SomeBadFunction&lt;/strong&gt;, so you decide you need to check it out:
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;
 &lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; SomeBadFunction()&lt;br/&gt;{&lt;br/&gt;  &lt;span style="color:green"&gt;// 200 lines of code&lt;br/&gt;&lt;/span&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
 &lt;/p&gt;&lt;p&gt;Oh dear. The definition of &lt;strong&gt;SomeBadFunction&lt;/strong&gt; gives us &lt;em&gt;absolutely no idea&lt;/em&gt; how many parameters it expects, what order they should be in, nor what values they might represent. &lt;em&gt;Maybe&lt;/em&gt; there's a comment at the top of the function that explains what you should pass it, but we all know that comments get out of date very quickly and the code is the only real way to know what is going on. So now you have to trawl through several hundred lines of code, trying to reverse-engineer what kind of parameters the function expects. This could take a long time, and you might get it wrong.
&lt;/p&gt;&lt;p&gt;Let's imagine that the real intent of &lt;strong&gt;SomeBadFunction&lt;/strong&gt; is to update an internal table. The first parameter is the index of the item in the table to update, and the second parameter is the value to place in the table. The function supports rudimentary format strings (like &lt;strong&gt;printf()&lt;/strong&gt; in C) and so if the value contains a format-specifier like "%d" or "%s" then the remaining parameters are used to fill in the blanks. Finally, if the value is omitted then the table entry is removed.
&lt;/p&gt;&lt;p&gt;In this case, I would define the function something like this:
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;
 &lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; SomeBadFunction(index, value, formatArgs)&lt;br/&gt;{&lt;br/&gt;  &lt;span style="color:green"&gt;// probably fewer than 200 lines of code&lt;br/&gt;&lt;/span&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
 &lt;/p&gt;&lt;p&gt;Now it is clear that &lt;strong&gt;SomeBadFunction&lt;/strong&gt; expects three arguments, the first should probably be a number, the second should be some generic value, and the third should be an array of values (by using the naming convention &lt;strong&gt;...Args&lt;/strong&gt;; you could also call it &lt;strong&gt;formatArgArray&lt;/strong&gt; or &lt;strong&gt;paramarray&lt;/strong&gt; or &lt;strong&gt;varargs&lt;/strong&gt; or something else if you feel that is clearer). 
&lt;/p&gt;&lt;p&gt;ECMAScript already allows for omitting function arguments, and code is typically written to have some "obvious" behaviour if parameters end up being &lt;strong&gt;undefined&lt;/strong&gt;, so simply dropping &lt;strong&gt;value&lt;/strong&gt; or &lt;strong&gt;formatArgs&lt;/strong&gt; from a function call is quite OK. Now the only thing you need to change when you call the function is that if – &lt;em&gt;if&lt;/em&gt; – you want to use the special format-string ability of &lt;strong&gt;SomeBadFunction&lt;/strong&gt;, you simply encase the trailing arguments in square brackets to put them in an Array:
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;
 &lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;SomeBadFunction(next, data, [OtherFunction(), moreData]);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
 &lt;/p&gt;&lt;p&gt;Anyway, I promised you an exhibit of why 'arguments' is bad – a bona-fide bug in ECMAScript, not just the rambling opinions of some Microsoft fuddy-duddy. Take this code:
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;
 &lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; foo(x, y)&lt;br/&gt;{&lt;br/&gt;  print(&lt;span style="color:#a31515"&gt;"x: "&lt;/span&gt; + x + &lt;span style="color:#a31515"&gt;", y: "&lt;/span&gt; + y);&lt;br/&gt;  Array.prototype.shift.call(arguments);&lt;br/&gt;  print(&lt;span style="color:#a31515"&gt;"x: "&lt;/span&gt; + x + &lt;span style="color:#a31515"&gt;", y: "&lt;/span&gt; + y);&lt;br/&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;foo(42, 123);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
 &lt;/p&gt;&lt;p&gt;What do you expect&lt;em&gt;
		&lt;/em&gt;it to display? Don't ruin the fun by running it and posting the &lt;em&gt;actual&lt;/em&gt; answer – just post what you &lt;em&gt;think&lt;/em&gt; it is.
&lt;/p&gt;&lt;p&gt;I say this is a bug in ECMAScript – rather than a bug in JScript – because section 10.1.8 of the ECMA 262 spec doesn't &lt;em&gt;completely&lt;/em&gt; define how the arguments object interacts with the parameters of the function, and so you get some strange results. Note that both IE and Firefox give you the same result (replace 'print' with 'alert') but I doubt both companies independently came up with the same unexcpected result. I don't know if this is a case of IE being bug-compatible with the original Netscape Navigator code, or Firefox being bug-compatible with IE code, or a bit of both. I wasn't around when this was happening :-)&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7334659" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ptorr/archive/tags/Script/default.aspx">Script</category></item><item><title>Fun Friends For Functions</title><link>http://blogs.msdn.com/ptorr/archive/2008/01/29/fun-friends-for-functions.aspx</link><pubDate>Wed, 30 Jan 2008 03:45:34 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7315751</guid><dc:creator>ptorr</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/7315751.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=7315751</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=7315751</wfw:comment><description>&lt;p&gt;And now for a more techy post. In ECMAScript, functions are considered first-class objects. "What," you might ask, "differentiates a 'first-class' object from a merely 'economy-class' object?" Well, the main thing is that functions in ECMAScript are treated just like any other type of data (strings, numbers, arrays, etc.) in that they can be assigned to variables, they can be passed as function arguments, and they can have properties and methods of their own. They also have a prototype object, just like all other ECMAScript objects. The upshot of this is that you can do fun things with functions in ECMAScript that you can't do in other languages such as C or Java.
&lt;/p&gt;&lt;p&gt;In this entry I will introduce four types of "helper" functions that are ideally suited to HDi development. They are:
&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Binding a function to a set of arguments and / or a 'this' object
&lt;/li&gt;&lt;li&gt;Wrapping an existing function in an exception handler
&lt;/li&gt;&lt;li&gt;Chaining function calls together one after the other
&lt;/li&gt;&lt;li&gt;Calling a function after a specified period of time
&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;In all cases, you write the actual function (the one that does the interesting work) just as you normally would, but when it comes time to call that function you do something funky with it to make some magic happen. Exactly why you might want to do this will become clearer soon, but it mostly comes down to how you write event handlers and callbacks.
&lt;/p&gt;&lt;p&gt;A common theme in this post will be that you want to &lt;a href="http://blogs.msdn.com/ptorr/archive/2007/08/29/using-timers-effectively-in-hdi.aspx"&gt;avoid closures&lt;/a&gt; as much as possible, and using these helpers should get you a long way to doing that (even though these helper functions rely on closures, they do so in a "safe" manner). And although there are various ad-hoc ways to accomplish the same tasks, generally these require writing specialised wrapper functions or following ugly coding practices (which I might blog about in the future) when what I would prefer to focus on is writing highly readable, highly re-usable code and utilising some clever, general-purpose helper functions to take care of all the tricky dirty work.
&lt;/p&gt;&lt;h3&gt;Binding to arguments
&lt;/h3&gt;&lt;p&gt;Many operations in HDi use a callback function to notify you when a specific task is completed (such as a File I/O operation or an event handler). Oftentimes you will want to associate more information with your callback than the HDi API actually allows for, and there are a couple of ways to accomplish this. But first, an example: 
&lt;/p&gt;&lt;p&gt;Say you have an application where you want to dynamically download some images from the network and display them inside a markup page. The basic code you want to write is probably like this (the code is simplified for clarity; obviously there is some additional code to convert the &lt;strong&gt;onStateChange&lt;/strong&gt; callback into a single "the download is complete" call, etc.):
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;
 &lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// function to download an image&lt;br/&gt;&lt;/span&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; DownloadImage(src, dest)&lt;br/&gt;{&lt;br/&gt;  &lt;span style="color:blue"&gt;var&lt;/span&gt; httpClient = Network.createHttpClient(src, dest);&lt;br/&gt;  httpClient.onStateChange = SetBackgroundImage;&lt;br/&gt;  httpClient.send();&lt;br/&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// function to set a backgroundImage&lt;br/&gt;&lt;/span&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; SetBackgroundImage(markupId, url)&lt;br/&gt;{&lt;br/&gt;  document[markupId].style.backgroundImage = url;&lt;br/&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// call the download function... but what next?&lt;br/&gt;&lt;/span&gt;DownloadImage(&lt;span style="color:#a31515"&gt;"http://foo/bar.png"&lt;/span&gt;, &lt;span style="color:#a31515"&gt;"file:///filecache/bar.png"&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
 &lt;/p&gt;&lt;p&gt;Note that both functions have been written to be "highly readable, highly re-usable" and do one thing in a very straight-forward manner. The problem, of course, is that this code won't work because there is no way for the callback to &lt;strong&gt;SetBackgroundImage&lt;/strong&gt; to communicate what &lt;strong&gt;markupId&lt;/strong&gt; or the final download &lt;strong&gt;url&lt;/strong&gt; is supposed to be. 
&lt;/p&gt;&lt;p&gt;One common way of solving this problem is to use a nested function, like this:
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;
 &lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// function to download an image and set it as the background URL&lt;br/&gt;&lt;/span&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; DownloadBackgroundImage(src, dest, markupId)&lt;br/&gt;{&lt;br/&gt;  &lt;span style="color:blue"&gt;var&lt;/span&gt; httpClient = Network.createHttpClient(src, dest);&lt;br/&gt;  httpClient.onStateChange = SetBackgroundImage;&lt;br/&gt;  httpClient.send();
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;  &lt;span style="color:green"&gt;// nested function to set a backgroundImage&lt;br/&gt;&lt;/span&gt;  &lt;span style="color:blue"&gt;function&lt;/span&gt; SetBackgroundImage()&lt;br/&gt;  {&lt;br/&gt;    document[markupId].style.backgroundImage = dest;
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;    &lt;span style="color:green"&gt;// Clean up the memory&lt;br/&gt;&lt;/span&gt;    httpClient = &lt;span style="color:blue"&gt;null&lt;/span&gt;;&lt;br/&gt;  }&lt;br/&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// call the download function and update the element 'button1'&lt;br/&gt;&lt;/span&gt;DownloadBackgroundImage(&lt;span style="color:#a31515"&gt;"http://foo/bar.png"&lt;/span&gt;, &lt;span style="color:#a31515"&gt;"file:///filecache/bar.png"&lt;/span&gt;, &lt;span style="color:#a31515"&gt;"button1"&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
 &lt;/p&gt;&lt;p&gt;Note that even though we've done work to ensure the closure won't memory leak memory, there is still at big problem in that neither the download function nor the background setting function are generic any more. If you want to (eg) download an XML file, or if you want to set the backgroundImage to a file on persistent storage, you will need to either add some more hacks to this function (making it less readable and less maintainable) or you will need to duplicate the code into a similar-but-not-entirely-the-same function.
&lt;/p&gt;&lt;p&gt;The solution I prefer is to use the fact that functions are first-class objects and solve this problem using "argument binding." In this case, the code would be re-written as follows:
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;
 &lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// function to download a file and then call 'handler' when it is done&lt;br/&gt;&lt;/span&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; DownloadFile(src, dest, handler)&lt;br/&gt;{&lt;br/&gt;  &lt;span style="color:blue"&gt;var&lt;/span&gt; httpClient = Network.createHttpClient(src, dest);&lt;br/&gt;  httpClient.onStateChange = handler;&lt;br/&gt;  httpClient.send();&lt;br/&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// function to set a backgroundImage&lt;br/&gt;&lt;/span&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; SetBackgroundImage(markupId, url)&lt;br/&gt;{&lt;br/&gt;  document[markupId].style.backgroundImage = url;&lt;br/&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// Call the download function, passing in the set-image function as the callback handler&lt;br/&gt;&lt;/span&gt;&lt;span style="color:blue"&gt;var&lt;/span&gt; setBackgroundHandler = SetBackgroundImage.BindToArguments(&lt;span style="color:#a31515"&gt;"button1"&lt;/span&gt;, &lt;span style="color:#a31515"&gt;"file:///filecache/bar.png"&lt;/span&gt;);&lt;br/&gt;DownloadFile(&lt;span style="color:#a31515"&gt;"http://foo/bar.png"&lt;/span&gt;, &lt;span style="color:#a31515"&gt;"file:///filecache/bar.png"&lt;/span&gt;, setBackgroundHandler);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
 &lt;/p&gt;&lt;p&gt;Now both the download function and the set-image function are still written in a clear, simple, re-usable fashion, but we can easily chain them together to get the desired result. Even the call that makes this possible (the &lt;strong&gt;BindToArguments&lt;/strong&gt; call) is straight-forward and understandable. All that is missing is the magic &lt;strong&gt;BindToArguments&lt;/strong&gt; helper function... which looks like this:
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;
 &lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// helper function to return a copy of the target function, but&lt;br/&gt;// bound to the original arguments&lt;br/&gt;&lt;/span&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; Function_BindToArguments()&lt;br/&gt;{&lt;br/&gt;  &lt;span style="color:green"&gt;// store a reference to the target function and its arguments&lt;br/&gt;&lt;/span&gt;  &lt;span style="color:blue"&gt;var&lt;/span&gt; storedFunction = &lt;span style="color:blue"&gt;this&lt;/span&gt;;&lt;br/&gt;  &lt;span style="color:blue"&gt;var&lt;/span&gt; storedArguments = arguments;
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;  &lt;span style="color:green"&gt;// return the nested function&lt;br/&gt;&lt;/span&gt;  &lt;span style="color:blue"&gt;return&lt;/span&gt; boundFunction;
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;  &lt;span style="color:green"&gt;// nested function simply invokes the stashed values&lt;br/&gt;&lt;/span&gt;  &lt;span style="color:blue"&gt;function&lt;/span&gt; boundFunction()&lt;br/&gt;  {&lt;br/&gt;    storedFunction.apply(&lt;span style="color:blue"&gt;null&lt;/span&gt;, storedArguments);&lt;br/&gt;  }&lt;br/&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// make the helper available to all functions&lt;br/&gt;&lt;/span&gt;Function.prototype.BindToArguments = Function_BindToArguments;
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
 &lt;/p&gt;&lt;p&gt;As noted in the comments, this helper function simply stores a reference to the "target" function and the arguments that are passed to the &lt;strong&gt;BindToArguments&lt;/strong&gt; call. Then it returns a nested function, which when called will invoke the stored function (&lt;strong&gt;SetBackgroundImage&lt;/strong&gt;) with the stored arguments (&lt;strong&gt;"button1"&lt;/strong&gt; and &lt;strong&gt;"file:///filecache/bar.png"&lt;/strong&gt;). Note that the &lt;strong&gt;apply&lt;/strong&gt; function is a built-in function of ECMAScript Function objects that invokes a given function with the specified 'this' object and arguments array.
&lt;/p&gt;&lt;p&gt;This is the most basic form of a "binding" helper, and the resultant function is one that has no 'this' object and that cannot take any arguments of its own. It also can't participate in a typical &lt;a href="http://blogs.msdn.com/ptorr/archive/2007/06/27/helpful-tracing-routines.aspx"&gt;logging infrastructure&lt;/a&gt; because much of the required metadata (original function name, number of expected arguments, etc.) is missing. The good news is that all this can be added with the help of more code, and hopefully that's something I'll be posting soon. 
&lt;/p&gt;&lt;p&gt;As usual, this is longer (and took longer) to write, so I'll have to save the other "friends" for later. The depressing thing is that actually writing the code is the easy part (and it's all done already); it's wrapping it all up in a post and explaining how things work that take forever!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7315751" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ptorr/archive/tags/Script/default.aspx">Script</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/iHD/default.aspx">iHD</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/HDi/default.aspx">HDi</category></item><item><title>Maintaining Callback Semantics</title><link>http://blogs.msdn.com/ptorr/archive/2007/10/24/maintaining-callback-semantics.aspx</link><pubDate>Wed, 24 Oct 2007 21:29:55 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5655276</guid><dc:creator>ptorr</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/5655276.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=5655276</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=5655276</wfw:comment><description>&lt;p&gt;One of the key programming concepts in HDi is the use of asynchronous processing with callback functions. The HDi platform exposed to title authors is not multi-threaded (which helps reduce the complexity of writing applications), but many of the functions of the player are asynchronous in nature. For example, all the I/O in HDi (both local and network) is asynchronous so that the on-screen experience isn't degraded while the script waits for a long I/O call to complete. Instead, the script asks the player for a resource and then just keeps on plugging away. At some future point in time the resource will become available, the player will notify the script via a callback function, and the script can act on the resource without any further waiting.
&lt;/p&gt;&lt;p&gt;As is common in any programming environment, many developers have built "helper functions" around some of the built-in HDi functions in order to centralise error handling, simplify high-level tasks, or for other various reasons. This is all well and good, but I have seen some developers use a programming pattern for these helpers that will lead to bugs down the road. I'm going to show an example of this bad pattern (and how to avoid it), but first here's an example of many people's first attempt at asynchronous programming:
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// Global variables to hold state&lt;br/&gt;&lt;/span&gt;&lt;span style="color:blue"&gt;var&lt;/span&gt; done = &lt;span style="color:blue"&gt;false&lt;/span&gt;;&lt;br/&gt;&lt;span style="color:blue"&gt;var&lt;/span&gt; result = 0;
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// Copy a file and return when it is done&lt;br/&gt;&lt;/span&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; CopyFileHelper(src, dest)&lt;br/&gt;{&lt;br/&gt;  &lt;span style="color:green"&gt;// Copy the file, providing a simple callback function&lt;br/&gt;&lt;/span&gt;  FileIO.copy(src, dest, &lt;span style="color:blue"&gt;true&lt;/span&gt;, IOFinishedHandler);
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;  &lt;span style="color:green"&gt;// Wait until the callback is called&lt;br/&gt;&lt;/span&gt;  &lt;span style="color:blue"&gt;while&lt;/span&gt; (!done)&lt;br/&gt;    ; &lt;span style="color:green"&gt;// nothing
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;  &lt;span style="color:blue"&gt;return&lt;/span&gt; result;&lt;br/&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// Function to handle the callback and stop the loop&lt;br/&gt;// inside CopyFileHelper&lt;br/&gt;&lt;/span&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; IOFinishedHandler(errorInfo)&lt;br/&gt;{&lt;br/&gt;  result = errorInfo;&lt;br/&gt;  done = &lt;span style="color:blue"&gt;true&lt;/span&gt;;&lt;br/&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;
 &lt;/p&gt;&lt;p&gt;This code will never work, so luckily nobody has ever shipped a title like this (that I know of!). Nevertheless, it is interesting to learn &lt;em&gt;why&lt;/em&gt; it doesn't work. The basic idea is to have a sentinel value (in this case, &lt;strong&gt;done&lt;/strong&gt;) that is initially &lt;strong&gt;false&lt;/strong&gt;. The &lt;strong&gt;FileIO&lt;/strong&gt; operation is called and is provided a callback handler that will (i) stash the result of the I/O function for later use; and (ii) set the sentinel to &lt;strong&gt;true&lt;/strong&gt;. The main function then performs a &lt;a href="http://en.wikipedia.org/wiki/Busy_wait"&gt;busy wait&lt;/a&gt; until the &lt;strong&gt;done&lt;/strong&gt; variable is set to &lt;strong&gt;true&lt;/strong&gt; by the callback, at which point the &lt;strong&gt;while&lt;/strong&gt; loop ends and the function returns.
&lt;/p&gt;&lt;p&gt;Although this kind of programming might work on a natively multi-threaded platform like .NET or Java, it won't work in HD DVD because of the way application time is scheduled. (Note it would also still be a bad idea on .NET or Java, but that's another story). In HD DVD, application code (including markup timing and script execution) is executed in a tick-based fashion. At the start of a tick, the necessary script code &lt;em&gt;for that tick&lt;/em&gt; is executed (including event handlers, timers, and other callbacks) and then execution is passed to the markup layer. The markup layer performs timing and layout operations, and then the script is given another chance to run if it needs to handle any markup events. Finally, the markup page is generated and the system starts over again on a new tick. This all happens on a single thread. At the same time, other operations like A/V decoding and the &lt;strong&gt;FileIO&lt;/strong&gt; APIs are happening on different threads.
&lt;/p&gt;&lt;p&gt;What happens in this case is that the &lt;strong&gt;FileIO.copy&lt;/strong&gt; function is called, a new thread is created to handle the copy operation, and then the script goes into the busy-wait loop. At some point in the future, the copy operation will finish and player will schedule the callback to happen &lt;em&gt;on the next tick&lt;/em&gt;. But because the script code is busy waiting for &lt;strong&gt;done&lt;/strong&gt; to become &lt;strong&gt;true&lt;/strong&gt;, &lt;em&gt;the current tick never ends&lt;/em&gt; and so your player's menu appears to hang. This is why nobody actually ships this code :-)
&lt;/p&gt;&lt;p&gt;OK, so that's the impossibly-bad way of doing async IO. Here's the promised programming pattern that you should look out for and fix:
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// Copy a file and do some common logging, etc&lt;br/&gt;&lt;/span&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; CopyFileHelper(src, dest, clientCallbackHandler)&lt;br/&gt;{&lt;br/&gt;  &lt;span style="color:green"&gt;// Perform some common, useful stuff...&lt;br/&gt;&lt;/span&gt;  &lt;span style="color:green"&gt;// ...&lt;br/&gt;&lt;/span&gt;  &lt;span style="color:green"&gt;// ...
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;  &lt;span style="color:green"&gt;// Copy the file, providing the caller's callback handler&lt;br/&gt;&lt;/span&gt;  &lt;span style="color:green"&gt;// so they can continue when it is done&lt;br/&gt;&lt;/span&gt;  &lt;span style="color:blue"&gt;try&lt;br/&gt;&lt;/span&gt;  {&lt;br/&gt;    FileIO.copy(src, dest, &lt;span style="color:blue"&gt;true&lt;/span&gt;, clientCallbackHandler);&lt;br/&gt;  }&lt;br/&gt;  &lt;span style="color:blue"&gt;catch&lt;/span&gt; (ex)&lt;br/&gt;  {&lt;br/&gt;    &lt;span style="color:green"&gt;// Oops! Got an exception, so log it, convert to a FAILED result,&lt;br/&gt;&lt;/span&gt;    &lt;span style="color:green"&gt;// and let the caller know via their callback&lt;br/&gt;&lt;/span&gt;    &lt;br/&gt;    LogError(&lt;span style="color:#a31515"&gt;"Exception while copying "&lt;/span&gt; + src + &lt;span style="color:#a31515"&gt;" to "&lt;/span&gt; + dest, ex);&lt;br/&gt;    clientCallbackHandler(FileIO.FAILED);&lt;br/&gt;  }&lt;br/&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;
 &lt;/p&gt;&lt;p&gt;In this case, at least we're not trying to break the laws of physics. In most cases, this code will work fine. If the &lt;strong&gt;copy&lt;/strong&gt; operation doesn't throw an exception, the client's callback is called and everyone is happy. If the &lt;strong&gt;copy&lt;/strong&gt; operation &lt;em&gt;does&lt;/em&gt; throw, we log the error and convert it into a failed result for their callback. This makes programming much easier for the client since they don't have to worry about exceptions anymore; they just treat all failures the same way... right?
&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Wrong.
&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Although it looks like you've made life simpler, you've just introduced a subtle bug that may not bite you until sometime in the future. The problem is that you've broken the semantics of the client's callback, which is that &lt;em&gt;callbacks are always called asynchronously&lt;/em&gt;.&lt;strong&gt;
			&lt;em&gt;You should never call a callback synchronously because the client code may not be expecting it&lt;/em&gt;. 
&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Imagine the client has code like this:
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// Perform a sequence of operations involving a file copy&lt;br/&gt;&lt;/span&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; ClientCode()&lt;br/&gt;{&lt;br/&gt;  DoFirstThing();
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;  CopyFileHelper(src, dest, DoThirdThing);
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;  DoSecondThing();&lt;br/&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; DoFirstThing() { &lt;span style="color:green"&gt;/* ... */&lt;/span&gt; }&lt;br/&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; DoSecondThing() { &lt;span style="color:green"&gt;/* ... */&lt;/span&gt; }&lt;br/&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; DoThirdThing(result) { &lt;span style="color:green"&gt;/* ... */&lt;/span&gt; }
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;
 &lt;/p&gt;&lt;p&gt;Under normal circumstances (no exceptions), the order of function calls will be &lt;strong&gt;DoFirstThing&lt;/strong&gt;, &lt;strong&gt;DoSecondThing&lt;/strong&gt;, and then at some future tick, &lt;strong&gt;DoThirdThing.&lt;/strong&gt; Even if there is an error while copying, the code will progress in this sequence and the client can happily deal with any copy failures in &lt;strong&gt;DoThirdThing&lt;/strong&gt;, secure in the knowledge that &lt;strong&gt;DoSecondThing&lt;/strong&gt; has already completed. But what happens when there is an exception (which may not have happened during testing)? Now the order of execution is &lt;strong&gt;DoFirstThing&lt;/strong&gt;, &lt;strong&gt;DoThirdThing&lt;/strong&gt;, &lt;strong&gt;DoSecondThing&lt;/strong&gt;, all in the same tick. &lt;em&gt;You have reversed the order of the last two steps!&lt;/em&gt;
	&lt;/p&gt;&lt;p&gt;If &lt;strong&gt;DoSecondThing&lt;/strong&gt; performs a critical task that is needed before &lt;strong&gt;DoThirdThing&lt;/strong&gt; can succeed, the code is now broken and won't operate properly even though &lt;strong&gt;DoThirdThing&lt;/strong&gt; may be coded robustly to deal with the &lt;strong&gt;copy&lt;/strong&gt; error. The solution is to simply schedule the client's callback to happen at a later time, thus preserving the execution order of the client's code. This is easily done with a single-frame, non-repeating timer. Here's an example of how you might do it:
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;  &lt;span style="color:green"&gt;// ... same code as before ...&lt;br/&gt;&lt;/span&gt;  &lt;span style="color:blue"&gt;catch&lt;/span&gt; (ex)&lt;br/&gt;  {&lt;br/&gt;    &lt;span style="color:green"&gt;// Oops! Got an exception, so log it, convert to a FAILED result,&lt;br/&gt;&lt;/span&gt;    &lt;span style="color:green"&gt;// and let the caller know via their callback&lt;br/&gt;&lt;/span&gt;    &lt;br/&gt;    LogError(&lt;span style="color:#a31515"&gt;"Exception while copying "&lt;/span&gt; + src + &lt;span style="color:#a31515"&gt;" to "&lt;/span&gt; + dest, ex);&lt;br/&gt;    ScheduleCallback(ExceptionCallback);&lt;br/&gt;  }
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;  &lt;span style="color:green"&gt;// Closure used to pass arguments to the callback &lt;br/&gt;&lt;/span&gt;  &lt;span style="color:blue"&gt;function&lt;/span&gt; ExceptionCallback()&lt;br/&gt;  {&lt;br/&gt;    &lt;span style="color:blue"&gt;try&lt;br/&gt;&lt;/span&gt;    {&lt;br/&gt;      clientCallbackHandler(FileIO.FAILED);&lt;br/&gt;    }&lt;br/&gt;    &lt;span style="color:blue"&gt;catch&lt;/span&gt; (ex)&lt;br/&gt;    {&lt;br/&gt;      &lt;span style="color:green"&gt;// Client callback failed; nowhere to go from here&lt;br/&gt;&lt;/span&gt;      LogError(&lt;span style="color:#a31515"&gt;"Fatal exception while calling client callback"&lt;/span&gt;, ex);&lt;br/&gt;    }&lt;br/&gt;  }&lt;br/&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// Call the function on the next tick. If you need to pass arguments to&lt;br/&gt;// the function, then pass a closure (nested function) to do the work&lt;br/&gt;&lt;/span&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; ScheduleCallback(callback)&lt;br/&gt;{&lt;br/&gt;  &lt;span style="color:blue"&gt;var&lt;/span&gt; t = createTimer(&lt;span style="color:#a31515"&gt;"00:00:00:01"&lt;/span&gt;, 1, callback);&lt;br/&gt;  t.autoReset = &lt;span style="color:blue"&gt;false&lt;/span&gt;;&lt;br/&gt;  t.enabled = &lt;span style="color:blue"&gt;true&lt;/span&gt;;&lt;br/&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;
 &lt;/p&gt;&lt;p&gt;In this new code, if an exception occurs then rather than calling the callback directly, we schedule it to be called on the next tick via a couple of helper functions. We need the &lt;strong&gt;ExceptionCallback&lt;/strong&gt; helper function in order to pass arguments to the callback (timers never pass arguments themselves), and we use the &lt;strong&gt;ScheduleCallback&lt;/strong&gt; helper to &lt;a href="http://blogs.msdn.com/ptorr/archive/2007/08/29/using-timers-effectively-in-hdi.aspx"&gt;avoid closures&lt;/a&gt;. This ensures that the client's code always executes in the order expected, and thus reduces your chances of having weird bugs in the future.
&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5655276" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ptorr/archive/tags/Script/default.aspx">Script</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/HDi/default.aspx">HDi</category></item><item><title>Sliced bread ain’t got nuthin’ on this!</title><link>http://blogs.msdn.com/ptorr/archive/2007/10/02/sliced-bread-ain-t-got-nuthin-on-this.aspx</link><pubDate>Tue, 02 Oct 2007 21:49:21 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5246358</guid><dc:creator>ptorr</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/5246358.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=5246358</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=5246358</wfw:comment><description>&lt;p&gt;Forget being the best thing &lt;em&gt;since&lt;/em&gt; sliced bread – this is the best thing &lt;em&gt;ever&lt;/em&gt;. Well maybe not &lt;em&gt;quite &lt;/em&gt;that good, but it's still darn cool!
&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:14pt"&gt;Finally – &lt;span style="color:red"&gt;&lt;strong&gt;FINALLY!&lt;/strong&gt;&lt;/span&gt; – you can get &lt;a href="http://blogs.msdn.com/webdevtools/archive/2007/03/02/jscript-intellisense-in-orcas.aspx"&gt;decent IntelliSense for JScript inside Visual Studio&lt;/a&gt;! 
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Holy hotcakes, Batman! This is so awesome you have to &lt;a href="http://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx"&gt;download Visual Studio 2008 Beta 2&lt;/a&gt;
		&lt;strong&gt;right now&lt;/strong&gt; and try it out. 
&lt;/p&gt;&lt;p&gt;Back when I was on the script team, we couldn't get any features into Visual Studio (much to the chagrin of our customers) because all the hype was around ASP.NET. The rich client was dead. It was all about the server. Nobody needed client-side script any more. Everything was a web form post-back.
&lt;/p&gt;&lt;p&gt;But now that AJAX and Silverlight and all these other buzzwords are suddenly important, people taking notice of the little script language that could. 
&lt;/p&gt;&lt;p&gt;Congrats and thanks to the Visual Web Developer and JScript teams – at last, JScript is getting some of the respect it has always deserved! :-)&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5246358" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ptorr/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/Script/default.aspx">Script</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/HDi/default.aspx">HDi</category></item><item><title>Using Timers Effectively in HDi</title><link>http://blogs.msdn.com/ptorr/archive/2007/08/29/using-timers-effectively-in-hdi.aspx</link><pubDate>Thu, 30 Aug 2007 05:21:47 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4638148</guid><dc:creator>ptorr</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/4638148.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=4638148</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=4638148</wfw:comment><description>&lt;p&gt;The use of timers in HDi applications is very common, and there are a few things you should keep in mind when using them to avoid performance issues when playing back your title. 
&lt;/p&gt;&lt;p&gt;I will categorise these as:
&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The autoReset problem
&lt;/li&gt;&lt;li&gt;The closure problem
&lt;/li&gt;&lt;li&gt;The re-use problem
&lt;/li&gt;&lt;li&gt;The general-abuse problem
&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;
 &lt;/p&gt;&lt;h2&gt;The AutoReset Problem
&lt;/h2&gt;&lt;p&gt;This problem stems from the fact that, by default, timers created in HDi are &lt;em&gt;repeating timers&lt;/em&gt;, meaning that they will fire over and over and over again until you tell them to stop. Sometimes this is what the content author wants, but more often than not what they really need is a single notification after the timeout period has elapsed (what we call a "one-shot" timer). It's essentially the difference between &lt;a href="http://msdn2.microsoft.com/en-us/library/ms536753.aspx"&gt;setTimeout&lt;/a&gt; and &lt;a href="http://msdn2.microsoft.com/en-us/library/ms536749.aspx"&gt;setInterval&lt;/a&gt; in the browser DOM.
&lt;/p&gt;&lt;p&gt;If you want a one-shot timer, the following pattern should be avoided:
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// Create a timer; note it auto-repeats by default&lt;br/&gt;&lt;/span&gt;&lt;span style="color:blue"&gt;var&lt;/span&gt; t = createTimer(TIME, CLOCK, callback);&lt;br/&gt;t.enabled = &lt;span style="color:blue"&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; callback()&lt;br/&gt;{&lt;br/&gt;  &lt;span style="color:green"&gt;// do stuff...
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;  &lt;span style="color:green"&gt;// Now disable the timer; sometimes people forget this step!&lt;br/&gt;&lt;/span&gt;  t.enabled = &lt;span style="color:blue"&gt;false&lt;/span&gt;;&lt;br/&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Instead, consider the more straightforward (and less bug-prone) version:
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// Create a timer and make sure it only fires once&lt;br/&gt;&lt;/span&gt;&lt;span style="color:blue"&gt;var&lt;/span&gt; t = createTimer(TIME, CLOCK, callback);&lt;br/&gt;t.autoReset = &lt;span style="color:blue"&gt;false&lt;/span&gt;;&lt;br/&gt;t.enabled = &lt;span style="color:blue"&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; callback()&lt;br/&gt;{&lt;br/&gt;  &lt;span style="color:green"&gt;// do stuff...&lt;br/&gt;&lt;/span&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Sometimes, the problem is compounded because the author &lt;em&gt;assumes&lt;/em&gt; the timer is a one-shot timer, and that in order to get repeating semantics they need to re-create the timer every time. That results in code like this:
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// Create a timer; note it auto-repeats by default&lt;br/&gt;&lt;/span&gt;&lt;span style="color:blue"&gt;var&lt;/span&gt; t = createTimer(TIME, CLOCK, callback);&lt;br/&gt;t.enabled = &lt;span style="color:blue"&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; callback()&lt;br/&gt;{&lt;br/&gt;  &lt;span style="color:green"&gt;// do stuff...
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;  &lt;span style="color:green"&gt;// Now re-create the timer to ensure we get called again&lt;br/&gt;&lt;/span&gt;  t = createTimer(TIME, CLOCK, callback);&lt;br/&gt;  t.enabled = &lt;span style="color:blue"&gt;true&lt;/span&gt;;&lt;br/&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Now what happens is that every time the timer fires, a new timer is created to fire on the same schedule! So after the first callback, there are two timers. After the second callback, there are four timers. After the third callback, there are eight timers, and so on. Eventually the old timers will get garbage collected by the script engine (and stop firing), but this could take a long time to happen depending on what else your script is doing. This is clearly a waste of resources and should be avoided; if you need a repeating timer, leave &lt;strong&gt;autoReset&lt;/strong&gt; at its default value and don't re-create the timer later on (although I prefer explicitly setting &lt;strong&gt;autoReset&lt;/strong&gt; to &lt;strong&gt;true&lt;/strong&gt; to convey the intent that it really should repeat). Otherwise, set &lt;strong&gt;autoReset&lt;/strong&gt; to &lt;strong&gt;false&lt;/strong&gt; at the time you create the timer, and you will be happy. 
&lt;/p&gt;&lt;h2&gt;The Closure Problem
&lt;/h2&gt;&lt;p&gt;In ECMAScript, a "closure" is a geeky name for a nested function. The reason we call them closures is to do with the way they affect the lifetime of other objects. I don't want to go into great detail now, but essentially a nested function maintains a reference to all the local variables of its containing function, thereby "closing them off" from being released by the garbage collector. Normally this isn't a problem for ECMAScript, because sooner or later the closure will die and thus the other objects it has been keeping references to will also die. 
&lt;/p&gt;&lt;p&gt;For example:
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; MakeAClosure()&lt;br/&gt;{&lt;br/&gt;  &lt;span style="color:green"&gt;// Gobble up some memory&lt;br/&gt;&lt;/span&gt;  &lt;span style="color:blue"&gt;var&lt;/span&gt; bigObj = CreateECMAScriptObjectThatUsesLotsOfMemory();
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;  &lt;span style="color:green"&gt;// Deliberately set up a circular reference&lt;br/&gt;&lt;/span&gt;  bigObj.circularReference = Closure;
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;  &lt;span style="color:green"&gt;// Return the closure&lt;br/&gt;&lt;/span&gt;  &lt;span style="color:blue"&gt;return&lt;/span&gt; Closure;
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;  &lt;span style="color:green"&gt;// Define the nested function (closure)&lt;br/&gt;&lt;/span&gt;  &lt;span style="color:blue"&gt;function&lt;/span&gt; Closure()&lt;br/&gt;  {&lt;br/&gt;    &lt;span style="color:green"&gt;// doesn't really matter what Closure does;&lt;br/&gt;&lt;/span&gt;    &lt;span style="color:green"&gt;// it still keeps a referenceto bigObj&lt;br/&gt;&lt;/span&gt;  }&lt;br/&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; foo()&lt;br/&gt;{&lt;br/&gt;  &lt;span style="color:green"&gt;// Get the closure&lt;br/&gt;&lt;/span&gt;  &lt;span style="color:blue"&gt;var&lt;/span&gt; closure = MakeAClosure();&lt;br/&gt;  &lt;span style="color:green"&gt;// maybe use it, maybe not...&lt;br/&gt;&lt;/span&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// Call foo&lt;br/&gt;&lt;/span&gt;foo();
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;In this example, we have an outer function (&lt;strong&gt;MakeAClosure&lt;/strong&gt;), a nested function (&lt;strong&gt;Closure&lt;/strong&gt;), another global function (&lt;strong&gt;foo&lt;/strong&gt;), and some global code that calls &lt;strong&gt;foo&lt;/strong&gt;. Here's what happens during execution:
&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;foo&lt;/strong&gt; gets called
&lt;/li&gt;&lt;li&gt;&lt;strong&gt;foo&lt;/strong&gt; calls &lt;strong&gt;MakeAClosure&lt;/strong&gt;
		&lt;/li&gt;&lt;li&gt;&lt;div&gt;&lt;strong&gt;MakeAClosure&lt;/strong&gt; creates a large object that uses up some memory, and stashes it in &lt;strong&gt;bigObj&lt;/strong&gt;
			&lt;/div&gt;&lt;ul&gt;&lt;li&gt;The nested function&lt;strong&gt; Closure&lt;/strong&gt; gets a reference to &lt;strong&gt;bigObj&lt;/strong&gt; for reasons that I won't get in to here (check sections 10.2.3, 13, and 13.2 of ECMA-262 for technical details... or I can post more later :-)) 
&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;MakeAClosure&lt;/strong&gt; explicitly makes &lt;strong&gt;bigObj&lt;/strong&gt; hold a reference to &lt;strong&gt;Closure&lt;/strong&gt; so they both refer to each other – a classic &lt;a href="http://en.wikipedia.org/wiki/Reference_counting"&gt;circular reference problem&lt;/a&gt;
		&lt;/li&gt;&lt;li&gt;&lt;div&gt;&lt;strong&gt;MakeAClosure&lt;/strong&gt; returns the &lt;strong&gt;Closure&lt;/strong&gt;
				&lt;strong&gt;Function&lt;/strong&gt; object back to &lt;strong&gt;Foo&lt;/strong&gt;
			&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Note that this includes the reference to &lt;strong&gt;bigObj&lt;/strong&gt;
				&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;foo&lt;/strong&gt; stores the &lt;strong&gt;Function&lt;/strong&gt; object inside the &lt;strong&gt;closure&lt;/strong&gt; variable 
&lt;/li&gt;&lt;li&gt;&lt;strong&gt;foo&lt;/strong&gt; exits
&lt;/li&gt;&lt;li&gt;Sooner or later, the garbage collector runs and sees that &lt;strong&gt;bigObj&lt;/strong&gt; is used by &lt;strong&gt;closure&lt;/strong&gt;, and &lt;strong&gt;closure&lt;/strong&gt; is used by &lt;strong&gt;bigObj&lt;/strong&gt;, but there is no way to access either of them (they are not "reachable") so it can safely kill both of them
&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Here everything is fine and dandy. But if &lt;strong&gt;bigObj&lt;/strong&gt; where a &lt;em&gt;non&lt;/em&gt;-ECMAScript object (eg, a Host object), the memory would never be reclaimed in Step 8 because the garbage collector cannot prove that &lt;strong&gt;bigObj&lt;/strong&gt; is unreachable – maybe some other part of the system still relies on it – and so it has to assume that &lt;strong&gt;closure&lt;/strong&gt; is still reachable, too. And since &lt;strong&gt;closure&lt;/strong&gt; holds on to &lt;strong&gt;bigObj&lt;/strong&gt;, the native object is never going to release itself, and the memory is leaked. 
&lt;/p&gt;&lt;p&gt;Perhaps it's clearer with an example.... using Timers, of course :-)
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// Perform two animations, one after the other&lt;br/&gt;&lt;/span&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; DoTwoPartAnimation()&lt;br/&gt;{&lt;br/&gt;  &lt;span style="color:green"&gt;// Perform some animation over 1 second&lt;br/&gt;&lt;/span&gt;  document.foo.animateProperty(&lt;span style="color:#a31515"&gt;"y"&lt;/span&gt;, &lt;span style="color:#a31515"&gt;"0px;100px"&lt;/span&gt;, 1);
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;  &lt;span style="color:green"&gt;// Setup a callback to do the other animation after the first is done&lt;br/&gt;&lt;/span&gt;  &lt;span style="color:blue"&gt;var&lt;/span&gt; t = createTimer(&lt;span style="color:#a31515"&gt;"00:00:01:00"&lt;/span&gt;, 1, DoPartTwo);&lt;br/&gt;  t.autoReset = &lt;span style="color:blue"&gt;false&lt;/span&gt;;&lt;br/&gt;  t.enabled = &lt;span style="color:blue"&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;  &lt;span style="color:blue"&gt;function&lt;/span&gt; DoPartTwo()&lt;br/&gt;  {&lt;br/&gt;    &lt;span style="color:green"&gt;// Perform second part of animation&lt;br/&gt;&lt;/span&gt;    document.bar.animateProperty(&lt;span style="color:#a31515"&gt;"x"&lt;/span&gt;, &lt;span style="color:#a31515"&gt;"0px;100px"&lt;/span&gt;, 1);&lt;br/&gt;  }&lt;br/&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;This simple example illustrates a common pattern in HDi – chaining together two or more script-based animations by having a timer fire after the first animation is complete (this is unnecessary with markup animations, but they're not always practical). 
&lt;/p&gt;&lt;p&gt;In this case, &lt;strong&gt;DoTwoPartAnimation&lt;/strong&gt; creates a local &lt;strong&gt;Timer&lt;/strong&gt; variable, &lt;strong&gt;t&lt;/strong&gt;, and gives it a reference to the nested function &lt;strong&gt;DoPartTwo&lt;/strong&gt; as the callback function. As we learnt above, &lt;strong&gt;DoPartTwo&lt;/strong&gt; maintains a reference to all of &lt;strong&gt;DoTwoPartAnimation&lt;/strong&gt;'s variables, including the timer &lt;strong&gt;t&lt;/strong&gt;. So even after the timer has fired, and &lt;strong&gt;DoPartTwo&lt;/strong&gt; has executed, we will leak the timer object (and the &lt;strong&gt;Function&lt;/strong&gt; object for &lt;strong&gt;DoPartTwo&lt;/strong&gt;) because the circular reference can't be broken.
&lt;/p&gt;&lt;p&gt;The good news is that there are at least three ways to solve this problem:
&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Avoid closures altogether
&lt;/li&gt;&lt;li&gt;Explicitly break the cycle
&lt;/li&gt;&lt;li&gt;Avoid making the timer a local variable
&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The first is the simplest, and in the case above we can solve the problem by simply making &lt;strong&gt;DoPartTwo&lt;/strong&gt; another global function instead of a nested function. Then although the timer &lt;strong&gt;t&lt;/strong&gt; has a reference to &lt;strong&gt;DoPartTwo&lt;/strong&gt;, &lt;strong&gt;DoPartTwo&lt;/strong&gt; does not have a reference back to &lt;strong&gt;t&lt;/strong&gt; and so the timer will be garbage collected sooner or later (which in turn will release &lt;strong&gt;DoPartTwo&lt;/strong&gt;). The problem here is that often you &lt;em&gt;need&lt;/em&gt; to use a nested function in order to correctly perform the callback operation – for example, the callback needs to know some of the parameters that were originally passed to the containing function in order to complete its task. 
&lt;/p&gt;&lt;p&gt;In that case, another simple solution is to explicitly break the cycle by manually releasing the reference to the timer. For example, we could change the &lt;strong&gt;DoPartTwo&lt;/strong&gt; function slightly to look like this:
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;  &lt;span style="color:blue"&gt;function&lt;/span&gt; DoPartTwo()&lt;br/&gt;  {&lt;br/&gt;    document.bar.animateProperty(&lt;span style="color:#a31515"&gt;"x"&lt;/span&gt;, &lt;span style="color:#a31515"&gt;"0px;100px"&lt;/span&gt;, 1);
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;    &lt;span style="color:green"&gt;// Explicitly break the circular reference&lt;br/&gt;&lt;/span&gt;    t = &lt;span style="color:blue"&gt;null&lt;/span&gt;;&lt;br/&gt;  }
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Now, as with the 1&lt;sup&gt;st&lt;/sup&gt; work-around, the script engine can eventually garbage collect &lt;strong&gt;t&lt;/strong&gt;, which in turn will release &lt;strong&gt;DoPartTwo&lt;/strong&gt;. Nevertheless, the problem with this solution – as with all solutions that require that the programmer religiously follow some strict rules all the time – is that you might forget to add this line to your callback, or you might have a &lt;strong&gt;return&lt;/strong&gt; statement near the top of the function, or you might throw an exception, or... there are various ways your program might miss this opportunity to break the cycle.
&lt;/p&gt;&lt;p&gt; So that leaves us with... my preferred approach, which is simply to make your own helper function – much like the web's &lt;strong&gt;setTimeout&lt;/strong&gt; – that will create the timer for you. Here's a simple example:
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// Call callback after timecode has elapsed&lt;br/&gt;&lt;/span&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; SetTimeout(timecode, callback)&lt;br/&gt;{&lt;br/&gt;  &lt;span style="color:blue"&gt;var&lt;/span&gt; t = createTimer(timecode, 1, callback);&lt;br/&gt;  t.autoReset = &lt;span style="color:blue"&gt;false&lt;/span&gt;;&lt;br/&gt;  t.enabled = &lt;span style="color:blue"&gt;true&lt;/span&gt;;&lt;br/&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Now you can simply replace all the pesky &lt;strong&gt;createTimer&lt;/strong&gt; / &lt;strong&gt;autoReset&lt;/strong&gt; / &lt;strong&gt;enabled&lt;/strong&gt; code with a single call to &lt;strong&gt;SetTimeout&lt;/strong&gt;, and avoid all the closure issues, too! 
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// Perform two animations, one after the other&lt;br/&gt;&lt;/span&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; DoTwoPartAnimation()&lt;br/&gt;{&lt;br/&gt;  &lt;span style="color:green"&gt;// Perform some animation over 1 second&lt;br/&gt;&lt;/span&gt;  document.foo.animateProperty(&lt;span style="color:#a31515"&gt;"y"&lt;/span&gt;, &lt;span style="color:#a31515"&gt;"0px;100px"&lt;/span&gt;, 1);
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;  &lt;span style="color:green"&gt;// Setup a callback to do the other animation after 1s&lt;br/&gt;&lt;/span&gt;  SetTimeout(&lt;span style="color:#a31515"&gt;"00:00:01:00"&lt;/span&gt;, DoPartTwo);
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;  &lt;span style="color:blue"&gt;function&lt;/span&gt; DoPartTwo()&lt;br/&gt;  {&lt;br/&gt;    &lt;span style="color:green"&gt;// Perform second part of animation&lt;br/&gt;&lt;/span&gt;    document.bar.animateProperty(&lt;span style="color:#a31515"&gt;"x"&lt;/span&gt;, &lt;span style="color:#a31515"&gt;"0px;100px"&lt;/span&gt;, 1);&lt;br/&gt;  }&lt;br/&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;The closure issues are avoided because &lt;strong&gt;DoPartTwo&lt;/strong&gt; has zero knowledge of the Timer object &lt;strong&gt;t&lt;/strong&gt;, which is a local variable of the &lt;strong&gt;SetTimeout&lt;/strong&gt; function. Although the timer has a reference to &lt;strong&gt;DoPartTwo&lt;/strong&gt;, the opposite is not true and so there is no circular reference.
&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Note about HTTPClient
&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Note that this "closure problem" also exists with &lt;strong&gt;HTTPClient&lt;/strong&gt; objects and the &lt;strong&gt;onStateChange&lt;/strong&gt; function. The same solutions exist for breaking the circular reference though – avoid closures, null out the object once it is finished (eg, &lt;strong&gt;STATE_COMPLETED&lt;/strong&gt;, &lt;strong&gt;STATE_ERROR&lt;/strong&gt;, or &lt;strong&gt;STATE_ABORT&lt;/strong&gt;), or use a helper to create the object.
&lt;/p&gt;&lt;p&gt;In general it doesn't affect other callback-based APIs like &lt;strong&gt;FileIO.openTextStream&lt;/strong&gt; or &lt;strong&gt;XMLParser.parse&lt;/strong&gt; because these are global objects, not local instances created by the enclosing function. The API will release the callback function as soon as it has been used (so it won't leak), and it doesn't really matter how many references there are to global objects; they will always exist.
&lt;/p&gt;&lt;h2&gt;The Re-Use Problem
&lt;/h2&gt;&lt;p&gt;Timer re-use is something that can be done correctly, but is often done incorrectly. Sometimes this is done by mistake (eg, forgetting to put &lt;strong&gt;var&lt;/strong&gt; in front of a variable declaration, making it global), but other times it is deliberately done and leads to brittle code. 
&lt;/p&gt;&lt;p&gt;Here's a canonical example:
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:green"&gt;// Create timer; assume it is enabled&lt;br/&gt;&lt;/span&gt;&lt;span style="color:blue"&gt;var&lt;/span&gt; timer = createTimer(TIME, CLOCK, CALLBACK);
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; EventHandler()&lt;br/&gt;{&lt;br/&gt;  &lt;span style="color:green"&gt;// Clobber global timer; assume it is enabled&lt;br/&gt;&lt;/span&gt;  timer = createTimer(TIME2, CLOCK2, CALLBACK2);&lt;br/&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:10pt"&gt;&lt;span style="color:blue"&gt;function&lt;/span&gt; CancelTheTimer()&lt;br/&gt;{&lt;br/&gt;  &lt;span style="color:green"&gt;// Which timer are you cancelling?&lt;br/&gt;&lt;/span&gt;  timer.enabled = &lt;span style="color:blue"&gt;false&lt;/span&gt;;&lt;br/&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;The code is pretty much self explanatory:
&lt;/p&gt;&lt;ol&gt;&lt;li&gt;A global &lt;strong&gt;timer&lt;/strong&gt; is created
&lt;/li&gt;&lt;li&gt;An event handler clobbers the first &lt;strong&gt;timer&lt;/strong&gt; and creates a new one
&lt;/li&gt;&lt;li&gt;A cancel function disables the &lt;strong&gt;timer&lt;/strong&gt;
		&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The problem is that depending on the order in which &lt;strong&gt;EventHandler&lt;/strong&gt; and &lt;strong&gt;CancelTheTimer&lt;/strong&gt; are called, different things may happen. If &lt;strong&gt;CancelTheTimer&lt;/strong&gt; is called before &lt;strong&gt;EventHandler&lt;/strong&gt;, it will cancel the global timer, but if the order is reversed then the global timer will fire and the event-handler timer will be disabled instead! 
&lt;/p&gt;&lt;p&gt;Even if you &lt;em&gt;think&lt;/em&gt; you know the order in which events will occur, they may not always fire in exactly the same order – especially if they rely on user input or some asynchronous processes such as the progression of the title timeline. Better to always assume that the worst will happen, and program accordingly.
&lt;/p&gt;&lt;p&gt;The simple solution here is to always use a unique name for your timers, or ensure they are local variables that won't conflict with other timers. (I would say to use the &lt;strong&gt;SetTimeout&lt;/strong&gt; function from above, but that won't allow you to cancel the timer). 
&lt;/p&gt;&lt;h2&gt;The General-Abuse Problem
&lt;/h2&gt;&lt;p&gt;The "general abuse" category basically covers any use of a timer that is unnecessary given the feature set of HDi. Sometimes authors abuse timers because they are not aware of HDi's built-in features (in which case it is generally easy to change from an abusive timer to use the right feature), or sometimes it is because the application's design has been built around timers rather than some more elegant solution (in which case it can be much harder to re-work the code to use fewer timers).
&lt;/p&gt;&lt;p&gt;Two prime examples of the former include:
&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Performing many &lt;strong&gt;set&lt;/strong&gt; operations on a repeating 1-frame timer, rather than using the &lt;strong&gt;&amp;lt;animate&amp;gt;&lt;/strong&gt; element in markup or the &lt;strong&gt;animateProperty&lt;/strong&gt; API
&lt;/li&gt;&lt;li&gt;Constantly polling &lt;strong&gt;currentTitle.elapsedTime&lt;/strong&gt; to check for a specific timecode, rather than using an &lt;strong&gt;&amp;lt;event&amp;gt;&lt;/strong&gt; in markup or a &lt;strong&gt;PauseAt&lt;/strong&gt; in the playlist
&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Examples of the latter are harder to come by, but (with no intention of bashing the other format) we have seen authors trying to replicate the behaviour of BD-J applications on HD DVD by an over-zealous use of timers, since they don't necessarily realise that the HDi system will do a lot of the heavy lifting for them.
&lt;/p&gt;&lt;h2&gt;Final Thought
&lt;/h2&gt;&lt;p&gt;An astute observer might ask the question "what happens if a timer is garbage-collected &lt;em&gt;before&lt;/em&gt; it fires?" Good question. It is entirely possible that the local variable &lt;strong&gt;t&lt;/strong&gt; used in these examples will be collected before the timer fires, especially if the timeout is quite long (say, several minutes). The answer is that the HD DVD specification requires timers to fire &lt;em&gt;at least once&lt;/em&gt;, even if the script engine has released all references to them.
&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4638148" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ptorr/archive/tags/Script/default.aspx">Script</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/HDi/default.aspx">HDi</category></item><item><title>Simple ACA dumper</title><link>http://blogs.msdn.com/ptorr/archive/2007/07/05/simple-aca-dumper.aspx</link><pubDate>Fri, 06 Jul 2007 00:36:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:3713342</guid><dc:creator>ptorr</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/3713342.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=3713342</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=3713342</wfw:comment><description>&lt;P&gt;Quick one today – if you have an ACA with some files in it, you can use the &lt;STRONG&gt;createaca&lt;/STRONG&gt; tool (provided as part of the &lt;A href="http://blogs.msdn.com/amyd/archive/2007/04/11/getting-started-with-hd-dvd.aspx" mce_href="http://blogs.msdn.com/amyd/archive/2007/04/11/getting-started-with-hd-dvd.aspx"&gt;Jumpstart Kit&lt;/A&gt;) to list the files inside it. Trouble is that the output is not very helpful; it contains too much information. &lt;/P&gt;
&lt;P&gt;So here is a simple JScript file you can run on the output of &lt;STRONG&gt;createaca -r&lt;/STRONG&gt; to just dump the filenames (and it checks for duplicates, too!). Just copy to &lt;STRONG&gt;dumpaca.js&lt;/STRONG&gt; (or the file of your choice) and run it from a command prompt. It expects a file named &lt;STRONG&gt;filelist.txt&lt;/STRONG&gt; to exist in the same folder. Modifications to do whatever you want to do should be trivial... &lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: green"&gt;// Open file named "filelist.txt"&lt;BR&gt;‎&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; fso = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; ActiveXObject(&lt;SPAN style="COLOR: #a31515"&gt;"Scripting.FileSystemObject"&lt;/SPAN&gt;);&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; stream = fso.OpenTextFile(&lt;SPAN style="COLOR: #a31515"&gt;"filelist.txt"&lt;/SPAN&gt;);&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; contents = stream.ReadAll(); &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: green"&gt;// Regular expression to search for DATA_FNAME followed by a name&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; re =/DATA_FNAME : ((?:\w|\.)+)/g; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: green"&gt;// Lists of result data&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; names = {};&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; nameList = [];&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; result;&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; dupes = []; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: green"&gt;// Search for every instance of the regular expression&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;while&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt; != (result = re.exec(contents)))&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; name = result[1]; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: green"&gt;// Record dupes&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (names[name] != &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;)&lt;BR&gt;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dupes.push(name);&lt;BR&gt;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: green"&gt;// else record new values&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;else&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;names[name] = nameList.length;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;nameList.push(name);&lt;BR&gt;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;} &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: green"&gt;// Print results&lt;BR&gt;&lt;/SPAN&gt;print(&lt;SPAN style="COLOR: #a31515"&gt;"---------- Complete file list ----------"&lt;/SPAN&gt;); &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;for&lt;/SPAN&gt; (&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; i &lt;SPAN style="COLOR: blue"&gt;in&lt;/SPAN&gt; nameList)&lt;BR&gt;&amp;nbsp;&amp;nbsp;print(nameList[i]); &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: green"&gt;// Print dupes&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (dupes.length &amp;gt; 0)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;print(&lt;SPAN style="COLOR: #a31515"&gt;"---------- Duplicate file names ----------"&lt;/SPAN&gt;); &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;for&lt;/SPAN&gt; (&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; j &lt;SPAN style="COLOR: blue"&gt;in&lt;/SPAN&gt; dupes)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(dupes[j]);&lt;BR&gt;} &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: green"&gt;// Helper&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt; print(s) { WScript.Echo(String(s)); }&lt;BR&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=3713342" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ptorr/archive/tags/Script/default.aspx">Script</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/iHD/default.aspx">iHD</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/HDi/default.aspx">HDi</category></item><item><title>Helpful Tracing Routines</title><link>http://blogs.msdn.com/ptorr/archive/2007/06/27/helpful-tracing-routines.aspx</link><pubDate>Wed, 27 Jun 2007 11:37:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:3561879</guid><dc:creator>ptorr</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/3561879.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=3561879</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=3561879</wfw:comment><description>&lt;P&gt;Last time we looked at &lt;A class="" title="Open blog post on conditional compilation" href="http://blogs.msdn.com/ptorr/archive/2007/06/01/using-conditional-compilation-in-hdi.aspx" mce_href="http://blogs.msdn.com/ptorr/archive/2007/06/01/using-conditional-compilation-in-hdi.aspx"&gt;conditional compilation&lt;/A&gt;, and how using it with HDiSim could aid with interactive debugging of runtime exceptions. But as useful as interactive debugging is, there are three major cases where it is impractical or impossible: &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;When the bug is timing related, and using a debugger masks the bug; or &lt;/LI&gt;
&lt;LI&gt;Reproducing the bug requires running a large amount of code it's impractical or laborious to step through by hand; or &lt;/LI&gt;
&lt;LI&gt;You're trying to track down an issue on a real player (which you can't debug on). &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;In these cases, it is very useful to have some robust tracing primitives built in to your code to give you a trace (or log) of everything that the player is doing up until the time the bug occurs. I already posted a while back on &lt;A class="" title="Open blog on red-box debugging" href="http://blogs.msdn.com/ptorr/archive/2007/02/01/red-box-debugging.aspx" mce_href="http://blogs.msdn.com/ptorr/archive/2007/02/01/red-box-debugging.aspx"&gt;red box debugging&lt;/A&gt;, and how that relates to &lt;STRONG&gt;printf&lt;/STRONG&gt; debugging; now we're going to add some more &lt;STRONG&gt;printf&lt;/STRONG&gt;-like tracing to our HDi toolkit to help diagnose issues on retail players or to trace errors through the system in critical timing sections. &lt;/P&gt;
&lt;P&gt;The general approach is to pepper our code with calls to a &lt;STRONG&gt;trace()&lt;/STRONG&gt; function that will either write the trace info to a log file, or display it on the screen, or both. Usually the trace function will be called when execution enters a new function, when an exception is handled, and at any other point in time where it is useful to know the result of a test or the value of a particular variable or property. Now, the key to any good trace log is the ability to identify the &lt;EM&gt;function&lt;/EM&gt; that was active at the time a given log entry was made. Whilst it is possible to hard-code the name of the function into the trace call (for example, &lt;STRONG&gt;trace("Inside function 'foo'")&lt;/STRONG&gt;), this is problematic because any time you re-name a function (or copy-and-paste it to a new function) you need to update the function name in the script. It would be much better if you could somehow automatically get the function name... &lt;/P&gt;
&lt;P&gt;Enter the &lt;STRONG&gt;GetFunctionName&lt;/STRONG&gt; function, defined like this: &lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: Lucida Console"&gt;// Returns the name of a function &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt; GetFunctionName(func)&lt;BR&gt;{&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp; try&lt;BR&gt;&lt;/SPAN&gt;&amp;nbsp; {&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var&lt;/SPAN&gt; re = /&lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt;\s+(\w+)/;&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var&lt;/SPAN&gt; s = re.exec(func.toString())[1]; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: green"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Based on naming convention of 'object_FunctionName'&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&lt;/SPAN&gt; (s.indexOf(&lt;SPAN style="COLOR: maroon"&gt;"_"&lt;/SPAN&gt;) &amp;gt;= 0)&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/SPAN&gt; s.substring(s.indexOf(&lt;SPAN style="COLOR: maroon"&gt;"_"&lt;/SPAN&gt;)); &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/SPAN&gt; s;&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp; catch&lt;/SPAN&gt;(ex) { ; } &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp; return&lt;/SPAN&gt; &lt;SPAN style="COLOR: maroon"&gt;"AnonymousOrUnknownFunction"&lt;/SPAN&gt;;&lt;BR&gt;} &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Given a &lt;STRONG&gt;Function&lt;/STRONG&gt; object as its only argument, this function will return the name of the function (or the string &lt;STRONG&gt;"AnonymousOrUnknownFunction"&lt;/STRONG&gt; if the function name is not available – for example, you pass in a function expression or a native method). It does this by creating a Regular Expression &lt;STRONG&gt;re&lt;/STRONG&gt; that looks for the word &lt;STRONG&gt;"function"&lt;/STRONG&gt; followed by some whitespace &lt;STRONG&gt;\s+&lt;/STRONG&gt; and then a word &lt;STRONG&gt;(\w+)&lt;/STRONG&gt;. If the word is found, it is "captured" (because it is in parentheses) and returned by the expression &lt;STRONG&gt;re.exec(...)[1]&lt;/STRONG&gt;. The &lt;STRONG&gt;toString&lt;/STRONG&gt; call inside of &lt;STRONG&gt;exec&lt;/STRONG&gt; simply converts the &lt;STRONG&gt;Function&lt;/STRONG&gt; object into an implementation-defined representation of the function body, but ECMA 262 defines that at a minimum this contains the function name (ie, it is a &lt;EM&gt;FunctionDeclaration&lt;/EM&gt;). &lt;/P&gt;
&lt;P&gt;OK, that's kind of useful, but how do you get the right &lt;STRONG&gt;Function&lt;/STRONG&gt; object to pass to the &lt;STRONG&gt;GetFunctionName&lt;/STRONG&gt; function? Good question. The answer is that you use the &lt;STRONG&gt;arguments&lt;/STRONG&gt; object, and in particular the &lt;STRONG&gt;callee&lt;/STRONG&gt; property; it holds a reference to the function being called. Neato, eh? &lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;I want to take a quick detour here to say that I &lt;EM&gt;personally&lt;/EM&gt; think that &lt;SPAN style="TEXT-DECORATION: underline"&gt;relying on the &lt;STRONG&gt;arguments&lt;/STRONG&gt; object as a way of passing parameters to a function is a bad programming practice&lt;/SPAN&gt; and should be avoided for normal development; I won't bore you with all the details, but basically it makes your code harder to read (and thus harder to understand) if all the expected parameters aren't immediately obvious from the function's declaration. Nevertheless, the &lt;STRONG&gt;arguments&lt;/STRONG&gt; object is great for &lt;EM&gt;tracing&lt;/EM&gt;, and so we shall use it for this. &lt;/P&gt;
&lt;P&gt;So while we're on the subject of the &lt;STRONG&gt;arguments&lt;/STRONG&gt; object, it's also worth noting that it's a great way to trace the arguments passed to a function in a generic way (again, avoiding the copy-and-paste problem, or having to keep up with added or removed parameters). To do this, we'll write another function (and a little helper) that can be used to generate a string holding the value of all the arguments passed to a function. It looks like this: &lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: green"&gt;// Returns a string representing the arguments list of a function&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt; GetArgumentsString(args) &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;{&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp; var&lt;/SPAN&gt; s = &lt;SPAN style="COLOR: maroon"&gt;"("&lt;/SPAN&gt;;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp; var&lt;/SPAN&gt; first = &lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp; for&lt;/SPAN&gt; (&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; i = 0; i &amp;lt; args.length; i++)&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&amp;nbsp; {&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&lt;/SPAN&gt; (first != &lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;)&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; s += &lt;SPAN style="COLOR: maroon"&gt;", "&lt;/SPAN&gt;; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; first = &lt;SPAN style="COLOR: blue"&gt;false&lt;/SPAN&gt;; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var&lt;/SPAN&gt; arg = args[i];&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; s += ObjectToString(arg);&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&amp;nbsp; } &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&amp;nbsp; s += &lt;SPAN style="COLOR: maroon"&gt;")"&lt;/SPAN&gt;;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp; return&lt;/SPAN&gt; s;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;} &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: Lucida Console"&gt;// Returns a string representation of an object;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt; ObjectToString(obj)&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;{&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp; try&lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&amp;nbsp; {&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(obj) == &lt;SPAN style="COLOR: maroon"&gt;"function"&lt;/SPAN&gt;)&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/SPAN&gt; &lt;SPAN style="COLOR: maroon"&gt;"function "&lt;/SPAN&gt; + GetFunctionName(obj); &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: blue"&gt;typeof&lt;/SPAN&gt;(obj) == &lt;SPAN style="COLOR: maroon"&gt;"string"&lt;/SPAN&gt;)&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/SPAN&gt; &lt;SPAN style="COLOR: maroon"&gt;"\""&lt;/SPAN&gt; + obj + &lt;SPAN style="COLOR: maroon"&gt;"\""&lt;/SPAN&gt;; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/SPAN&gt; String(obj);&amp;nbsp;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&amp;nbsp; }&amp;nbsp;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp; catch&lt;/SPAN&gt;(ex)&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&amp;nbsp; {&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/SPAN&gt; &lt;SPAN style="COLOR: maroon"&gt;"[native Object]"&lt;/SPAN&gt;;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&amp;nbsp; }&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;} &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Together these two functions will take an &lt;STRONG&gt;arguments&lt;/STRONG&gt; object and return a string that contains all their values, including special handling for functions and native (host) objects. Now we can build a simple function that is used to trace function entry like this: &lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: Lucida Console"&gt;// Global to define whether to do tracing or not; &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: Lucida Console"&gt;// Tracing can be expensive so you might not want to do it on a released title &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; _DO_TRACE = &lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: Lucida Console"&gt;// Trace function name and argument list &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt; TraceFunctionEntry(args)&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;{&lt;BR&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: green"&gt;// Bail immediately if tracing is not desired&lt;/SPAN&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp; if&lt;/SPAN&gt; (_DO_TRACE != &lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;)&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/SPAN&gt;; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp; var&lt;/SPAN&gt; name = GetFunctionName(args.callee);&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp; var&lt;/SPAN&gt; argString = GetArgumentsString(args);&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&amp;nbsp; TraceString(name + argString);&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;} &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;And we can use the &lt;STRONG&gt;TraceFunctionEntry&lt;/STRONG&gt; function like this: &lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt; MyFunction(a, b, c)&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;{&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&amp;nbsp; TraceFunctionEntry(arguments); &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: green"&gt;&amp;nbsp; // Do some actual work...&lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;} &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Now we just need to define the &lt;STRONG&gt;TraceString&lt;/STRONG&gt; function; but that's the easy part ;-) &lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: Lucida Console"&gt;// Global startup code to open the diagnostics file, if necessary.&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (_DO_TRACE)&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;{&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp; try&lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&amp;nbsp; {&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Diagnostics.listeners.add(&lt;SPAN style="COLOR: maroon"&gt;"file"&lt;/SPAN&gt;);&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Diagnostics.trace.autoFlush = &lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&amp;nbsp; } &lt;SPAN style="COLOR: blue"&gt;catch&lt;/SPAN&gt; (ex) { }&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;} &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: Lucida Console"&gt;// Function to trace a message to the diagnostics log and, if available,&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: green"&gt;// an on-screen input.&lt;/SPAN&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt; TraceString(msg)&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;{&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp; if&lt;/SPAN&gt; (_DO_TRACE != &lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;)&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/SPAN&gt;; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: green"&gt;&amp;nbsp; // Write out the message to the diagnostics log&lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp; try&lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&amp;nbsp; {&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Diagnostics.trace.writeLine(msg, &lt;SPAN style="COLOR: maroon"&gt;"Trace"&lt;/SPAN&gt;, 1);&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&amp;nbsp; } &lt;SPAN style="COLOR: blue"&gt;catch&lt;/SPAN&gt; (ex) { } &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: green"&gt;&amp;nbsp; // Try to add the message to an &amp;lt;input&amp;gt; named 'trace', if one exists&lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp; try&lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&amp;nbsp; {&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var&lt;/SPAN&gt; node = document.trace;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&lt;/SPAN&gt; (node != &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt; &amp;amp;&amp;amp; node.nodeName == &lt;SPAN style="COLOR: maroon"&gt;"input"&lt;/SPAN&gt;)&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; node.state.value = node.state.value + &lt;SPAN style="COLOR: maroon"&gt;" | "&lt;/SPAN&gt; + msg; &lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;&amp;nbsp;&amp;nbsp;} &lt;SPAN style="COLOR: blue"&gt;catch&lt;/SPAN&gt; (ex) { }&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Lucida Console"&gt;} &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;And there you have it! I have &lt;A class="" title="Download tracing sample" href="http://blogs.msdn.com/ptorr/attachment/3561879.ashx" mce_href="http://blogs.msdn.com/ptorr/attachment/3561879.ashx"&gt;attached a sample project&lt;/A&gt; that includes a couple of other helpful tracing aids (one for errors, one for informational tracing). As usual, you need to copy a file named &lt;STRONG&gt;font.ttf&lt;/STRONG&gt; into the &lt;STRONG&gt;ADV_OBJ&lt;/STRONG&gt; folder in order for it to work (I use the "Kooteny" sample font from the HDiSim download). &lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=3561879" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/ptorr/attachment/3561879.ashx" length="4237" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/ptorr/archive/tags/Script/default.aspx">Script</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/HD+DVD/default.aspx">HD DVD</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/iHD/default.aspx">iHD</category></item><item><title>Using Conditional Compilation in HDi </title><link>http://blogs.msdn.com/ptorr/archive/2007/06/01/using-conditional-compilation-in-hdi.aspx</link><pubDate>Sat, 02 Jun 2007 05:40:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:3034398</guid><dc:creator>ptorr</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/3034398.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=3034398</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=3034398</wfw:comment><description>&lt;P&gt;One of the cardinal rules for developing HD DVD applications is, &lt;EM&gt;"let no exception go unhandled." &lt;/EM&gt;The reason for this is simple – if you fail to handle an exception, the player will kill your application and stop the disc. This leads many developers to wrap entire functions in &lt;STRONG&gt;try / catch&lt;/STRONG&gt; blocks, which solves the problem but introduces some of its own. &lt;/P&gt;
&lt;P&gt;To me, one of the biggest problems with using &lt;STRONG&gt;try / catch&lt;/STRONG&gt; during development is that it makes debugging script with Visual Studio virtually impossible. For a start, you can't rely on "just-in-time" (JIT) debugging to work because you never have any unhandled exceptions. Additionally, even if you manually attach the debugger and step through your code line by line, as soon as there is an exception it will dump you out at the &lt;STRONG&gt;catch&lt;/STRONG&gt; handler, losing all the context information you might need to fix the bug (stack trace, local variables, even the location in the source file). &lt;/P&gt;
&lt;P&gt;As an example, try this script (run it under WSH with the command-line &lt;STRONG&gt;cscript //x test.js&lt;/STRONG&gt;) and step through each line by hitting F11. Step over the &lt;STRONG&gt;PretendThisIsAPlatformAPI&lt;/STRONG&gt; function by hitting F10 instead. &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: Courier New"&gt;// Hit F11 to step INTO each line &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Courier New"&gt;try &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;{ &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;nbsp; foo(1) &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;} &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;catch&lt;/SPAN&gt;(ex) &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;{&amp;nbsp;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;WScript.Echo(ex) &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;} &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt; foo(x) &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;{&amp;nbsp;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: green"&gt;// Imagine lots of complex code here...&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; y = x - 1 &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;nbsp; bar(y) &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;} &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt; bar(x) &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;{&amp;nbsp;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: green"&gt;// More complex code here...&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; y = x / 2&amp;nbsp;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: green"&gt;// Hit F10 to step OVER this function&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;PretendThisIsAPlatformAPI(y) &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;} &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt; PretendThisIsAPlatformAPI(x) &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;{&amp;nbsp;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (x &amp;lt;= 0)&amp;nbsp;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;nbsp;&amp;nbsp;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;throw&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"bad parameter value"&lt;/SPAN&gt;) &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;} &lt;/SPAN&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Note that everything is fine until you call that fake platform API. Then you are dumped back into the &lt;STRONG&gt;catch&lt;/STRONG&gt; block of the global code with a message saying "bad parameter value." But what &lt;EM&gt;was&lt;/EM&gt; the parameter value I passed to the function? I can't find out, because all the context (the stack frames for &lt;STRONG&gt;bar&lt;/STRONG&gt; and &lt;STRONG&gt;foo&lt;/STRONG&gt;) has been removed. &lt;/P&gt;
&lt;P&gt;Is the solution to remove the &lt;STRONG&gt;try / catch&lt;/STRONG&gt; block during development, then add it back at the last minute before shipping? &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;NO! &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;That is a recipe for disaster for at least two reasons: &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;You might forget to put it back in &lt;/LI&gt;
&lt;LI&gt;You will never have tested your exception-handling code &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;There's a better approach, and it relies on a feature of Microsoft's JScript implementation that lets you "hide" parts of the script from JScript whilst making it clearly visible to normal ECMAScript engines. This allows you to toggle exception handling on or off during development (with HDiSim), whilst never risking having it turned off when you ship. &lt;/P&gt;
&lt;P&gt;This feature is called &lt;A href="http://msdn2.microsoft.com/en-us/library/ahx1z4fs(VS.80).aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ahx1z4fs(VS.80).aspx"&gt;conditional compilation&lt;/A&gt;, and here's how we use it: &lt;/P&gt;
&lt;P&gt;The first thing to do is to activate conditional compilation. We do that like this – note how it is in an ECMAScript comment, so that other script engines will ignore the command: &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: Courier New"&gt;//@cc_on &lt;/SPAN&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Next, we define a conditional-compilation variable that will determine whether or not we want exception handling (note: you can name the variable anything you want; this isn't some magic value): &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: Courier New"&gt;//@set @enable_exceptions = true &lt;/SPAN&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Perhaps obviously, we set this to &lt;STRONG&gt;true&lt;/STRONG&gt; if we want to handle exceptions with &lt;STRONG&gt;try / catch&lt;/STRONG&gt;, and &lt;STRONG&gt;false&lt;/STRONG&gt; if we do not. &lt;/P&gt;
&lt;P&gt;Finally, we wrap our &lt;STRONG&gt;try&lt;/STRONG&gt; and &lt;STRONG&gt;catch&lt;/STRONG&gt; blocks with a conditional statement: &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: Courier New"&gt;&lt;A&gt;//@if(@enable_exceptions&lt;/A&gt;) &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Courier New"&gt;try &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;{ &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: Courier New"&gt;&lt;A&gt;//@end&lt;/A&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;foo(1) &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: Courier New"&gt;&lt;A&gt;//@if(@enable_exceptions&lt;/A&gt;) &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;} &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;catch&lt;/SPAN&gt;(ex) &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;{&amp;nbsp;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;WScript.Echo(ex) &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;} &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: Courier New"&gt;//@end &lt;/SPAN&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Now, depending on the value of &lt;STRONG&gt;@enable_exceptions&lt;/STRONG&gt;, JScript either sees this source code (when &lt;STRONG&gt;true&lt;/STRONG&gt;): &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Courier New"&gt;try &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;{&amp;nbsp;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;nbsp; &lt;/SPAN&gt;foo(1) &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;} &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;catch&lt;/SPAN&gt;(ex) &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;{&amp;nbsp;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;WScript.Echo(ex) &lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;} &lt;/SPAN&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Or this source code (when &lt;STRONG&gt;false&lt;/STRONG&gt;): &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&amp;nbsp; &lt;/SPAN&gt;foo(1) &lt;/SPAN&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Non-JScript engines will &lt;EM&gt;always&lt;/EM&gt; see the former source code, because they simply treat the &lt;STRONG&gt;@if&lt;/STRONG&gt; statements as comments. That means they will always have &lt;STRONG&gt;try / catch&lt;/STRONG&gt; turned on, and is why I say it is impossible to "forget" to turn exception handling back on when you ship. &lt;/P&gt;
&lt;P&gt;During normal testing and development, you should leave &lt;STRONG&gt;@enable_exceptions&lt;/STRONG&gt; set to &lt;STRONG&gt;true&lt;/STRONG&gt;, because you &lt;EM&gt;need&lt;/EM&gt; to test your exception-handling code. But when you are trying to debug a problem caused by a thrown exception, you can set it to &lt;STRONG&gt;false&lt;/STRONG&gt; and use the JIT feature of Visual Studio to jump right to the line that is throwing the exception. &lt;EM&gt;You should then turn it back to &lt;STRONG&gt;true&lt;/STRONG&gt; again after you've finished debugging&lt;/EM&gt;, because it is possible that some players on Windows might use the JScript engine. Even then, this approach is better than manually adding and removing the exception-handling code from your applications since there's only one place in your code to do it, rather than every single location where you use &lt;STRONG&gt;try / catch&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;You can try this out now, by running the sample script again with exception handling turned on and off. In this case, instead of stepping through the file with F11, just hit F5 to run the program. When exception handling is turned on, you don't get any help from the VS debugger. When it's turned off, VS will break at the offending line so you can investigate the problem and determine the right fix. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Marvellous! &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Typically I have a single file, &lt;STRONG&gt;cc.js&lt;/STRONG&gt;, that I always include as the first &lt;STRONG&gt;&amp;lt;Script&amp;gt;&lt;/STRONG&gt; element in my manifest. It contains the &lt;STRONG&gt;@cc_on&lt;/STRONG&gt; statement and the &lt;STRONG&gt;@enable_exceptions&lt;/STRONG&gt; variable, along with any others I might decide to use. As part of your shipping process, you could decide to always remove this file (or replace it with one that forces &lt;STRONG&gt;@enable_exceptions &lt;/STRONG&gt;to &lt;STRONG&gt;true&lt;/STRONG&gt;) "just in case"...&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=3034398" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ptorr/archive/tags/Script/default.aspx">Script</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/iHD/default.aspx">iHD</category></item><item><title>A Game of Chance that Pirates like to Play</title><link>http://blogs.msdn.com/ptorr/archive/2007/05/16/a-game-of-chance-that-pirates-like-to-play.aspx</link><pubDate>Thu, 17 May 2007 01:52:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2682093</guid><dc:creator>ptorr</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/2682093.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=2682093</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=2682093</wfw:comment><description>&lt;P&gt;Ahoy there me laddies! Yarrrr you better be readin' this blog then matey, or you'll be feelin' the lick o' the cat come nightfall! &lt;/P&gt;
&lt;P&gt;No, it's not &lt;A href="http://en.wikipedia.org/wiki/International_Talk_Like_a_Pirate_Day" mce_href="http://en.wikipedia.org/wiki/International_Talk_Like_a_Pirate_Day"&gt;&lt;EM&gt;Talk Like a Pirate Day&lt;/EM&gt;&lt;/A&gt;; it's &lt;EM&gt;Let's Post Another HDi Game Day&lt;/EM&gt;. The other week I &lt;A href="http://blogs.msdn.com/ptorr/archive/2007/04/02/coloured-blocks-advancing-on-a-moving-block.aspx" mce_href="http://blogs.msdn.com/ptorr/archive/2007/04/02/coloured-blocks-advancing-on-a-moving-block.aspx"&gt;posted an HDi sample&lt;/A&gt; based of the old arcade game &lt;A href="http://en.wikipedia.org/wiki/Space_Invaders" mce_href="http://en.wikipedia.org/wiki/Space_Invaders"&gt;&lt;EM&gt;Space Invaders&lt;/EM&gt;&lt;/A&gt;. Today it's a (somewhat prettier) example that implements the old game &lt;A href="http://en.wikipedia.org/wiki/Liar's_Dice" mce_href="http://en.wikipedia.org/wiki/Liar's_Dice"&gt;Liar's Dice&lt;/A&gt;. Some of you may wonder how I chose these two games to demo as HDi applications; the rest of you already know this is to show just how easy it is to get great interactivity on a next-generation high-definition optical disc &lt;EM&gt;without&lt;/EM&gt; expensive replication, &lt;EM&gt;without&lt;/EM&gt; expensive programmers, and &lt;EM&gt;without&lt;/EM&gt; an expensive games console to play it on. This was all written by little old me in a couple of hours, is about 130k in size (most of which are PNGs), and will play on any &lt;A href="http://www.amazon.com/dp/B000IJV4BC/" mce_href="http://www.amazon.com/dp/B000IJV4BC/"&gt;sub-$300 HD DVD player&lt;/A&gt; without first running through a &lt;A href="http://www.blueboard.com/bluray/movie_review_chickenlittle.htm" mce_href="http://www.blueboard.com/bluray/movie_review_chickenlittle.htm"&gt;performance test application&lt;/A&gt;. &lt;EM&gt;[Ed: I am currently travelling without access to a real player so have been unable to test it properly; it works on HDiSim and if there are any issues with up-to-date players I will resolve them next week]&lt;/EM&gt; &lt;/P&gt;
&lt;P&gt;Here's a screenshot of the game: &lt;/P&gt;
&lt;P&gt;&lt;IMG alt="Screenshot of the Liar's Dice game" src="http://blogs.msdn.com/photos/ptorr/images/2681862/original.aspx"&gt;&lt;/P&gt;
&lt;P&gt;As with the last game, this was thrown together very quickly and doesn't necessarily represent "best practices" (I know, I know, I should be demonstrating those too). Nevertheless the concepts should be pretty easy to understand. If not, post a comment! :-) &lt;/P&gt;
&lt;P&gt;The download is &lt;A class="" title="Download the ADV_OBJ ZIP" href="http://blogs.msdn.com/ptorr/attachment/2682093.ashx" mce_href="http://blogs.msdn.com/ptorr/attachment/2682093.ashx"&gt;here&lt;/A&gt;. Enjoy. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2682093" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/ptorr/attachment/2682093.ashx" length="202482" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/ptorr/archive/tags/Script/default.aspx">Script</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/iHD/default.aspx">iHD</category></item><item><title>Red Box Debugging</title><link>http://blogs.msdn.com/ptorr/archive/2007/02/01/red-box-debugging.aspx</link><pubDate>Thu, 01 Feb 2007 23:07:01 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1575033</guid><dc:creator>ptorr</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/1575033.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=1575033</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=1575033</wfw:comment><description>&lt;p&gt;Today I have a simple debugging tip.
&lt;/p&gt;&lt;p&gt;Sometimes when you have an obscure bug, you need to answer the question &lt;em&gt;"is my code even getting executed?"&lt;/em&gt; Often you can find that really obscure bugs are caused simply by a bad conditional, a typo, an unexpected exception, or some other flow-control issue that bypasses your code altogether.
&lt;/p&gt;&lt;p&gt;Whilst you can use an interactive debugger such as Microsoft Visual Studio for tracking down some of these things, debuggers aren't always available (eg, if you are on a hardware emulator), and if the bug is timing-related then they hamper your ability to reproduce the problem. Worse still, if your bug is in a declarative timing section (rather than in a script file) there's currently no way to debug that at all.
&lt;/p&gt;&lt;p&gt;So you need something a bit less impactful.
&lt;/p&gt;&lt;p&gt;In the good old days of C programming, people used to use "printf debugging" to display a message on the console indicating that a particular line of code had executed, and possibly to show the value of a variable. In the web world, this was changed to "alert debugging" where a popup window was used to the same effect.
&lt;/p&gt;&lt;p&gt;For HD DVD, I like to use "red box debugging". Basically I create a big red &lt;strong&gt;div&lt;/strong&gt; in my markup file and set &lt;strong&gt;style:display="none"&lt;/strong&gt;. Then at the point in my script where I want to "prove" that it gets executed or not, I simply say &lt;strong&gt;document.whateverTheIdIs.style.display = "auto"&lt;/strong&gt; and see if the red box appears. And if your bug is timing related, you simply has a cue that does a &lt;strong&gt;&amp;lt;set style:display="auto" /&amp;gt;&lt;/strong&gt; and similarly proves (or disproves...) that your program is working as planned.
&lt;/p&gt;&lt;p&gt;That's all &lt;span style="font-family:Wingdings"&gt;J&lt;/span&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1575033" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ptorr/archive/tags/Script/default.aspx">Script</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/iHD/default.aspx">iHD</category></item><item><title>Simple Pre-Processor for HDi</title><link>http://blogs.msdn.com/ptorr/archive/2007/01/10/simple-pre-processor-for-hdi.aspx</link><pubDate>Wed, 10 Jan 2007 11:07:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1443007</guid><dc:creator>ptorr</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/1443007.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=1443007</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=1443007</wfw:comment><description>&lt;P&gt;Hope you all had a good break. I haven't blogged for a while due to travel (both business and pleasure) and laziness… but I thought I'd start off today with simple pre-processor for HDi. &lt;/P&gt;
&lt;P&gt;One of the things that is missing from HD DVD is a good pre-processor; anyone familiar with C will know of all the good (and evil) things you can do with a few &lt;STRONG&gt;#define&lt;/STRONG&gt; macros. Anyone not familiar with C, well, you don't know what you're missing out on :-) &lt;/P&gt;
&lt;P&gt;Anyway, what I am basically talking about is the ability to define &lt;STRONG&gt;macros&lt;/STRONG&gt; (symbolic constants; shortcuts; expansions; whatever) that you can use in your markup files and script files to simplify development. &lt;/P&gt;
&lt;P&gt;Here's a common problem scenario (at least for me): &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Lay out some simple markup &lt;/LI&gt;
&lt;LI&gt;Create a button &lt;STRONG&gt;foo&lt;/STRONG&gt; with (eg) an &lt;STRONG&gt;x&lt;/STRONG&gt; position of &lt;STRONG&gt;100px&lt;/STRONG&gt; &lt;/LI&gt;
&lt;LI&gt;Write some animation that moves &lt;STRONG&gt;foo&lt;/STRONG&gt; from &lt;STRONG&gt;100px&lt;/STRONG&gt; to &lt;STRONG&gt;200px&lt;/STRONG&gt; (this could be in script or markup) &lt;/LI&gt;
&lt;LI&gt;Realise you need to shift &lt;STRONG&gt;foo&lt;/STRONG&gt; to &lt;STRONG&gt;110px&lt;/STRONG&gt; to accommodate a stylistic change &lt;/LI&gt;
&lt;LI&gt;Now figure out all the places where you need to change &lt;STRONG&gt;100px&lt;/STRONG&gt; to &lt;STRONG&gt;110px&lt;/STRONG&gt;, noting that you can't do a global search-and-replace because &lt;STRONG&gt;100px&lt;/STRONG&gt; could refer to other things as well &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Traditionally this kind of problem (known as a "magic number") is solved by using a symbolic constant – we define a placeholder value named (eg) &lt;STRONG&gt;FOO_X&lt;/STRONG&gt; and we define it to be &lt;STRONG&gt;100px&lt;/STRONG&gt;. Then everywhere we want to refer to the &lt;STRONG&gt;x&lt;/STRONG&gt; location of &lt;STRONG&gt;foo&lt;/STRONG&gt;, we use &lt;STRONG&gt;FOO_X&lt;/STRONG&gt; rather than &lt;STRONG&gt;100px&lt;/STRONG&gt;. Then if we want to update &lt;STRONG&gt;foo&lt;/STRONG&gt; to be at &lt;STRONG&gt;110px&lt;/STRONG&gt; later on, we simply change the definition of &lt;STRONG&gt;FOO_X&lt;/STRONG&gt; to be &lt;STRONG&gt;110px&lt;/STRONG&gt; and our work is done. &lt;/P&gt;
&lt;P&gt;This is easily done in script (where you have variables) but not so easily done in markup. So, I have written a very simple pre-processor that will take a bunch of macro definitions and replace them in your markup files AND give you a nice script file containing matching declarations to go along with it. &lt;/P&gt;
&lt;P&gt;In addition to simple text expansion (&lt;STRONG&gt;FOO_X = 100px&lt;/STRONG&gt;) you can also do arithmetic (&lt;STRONG&gt;FOO_X = BAR_X + 100&lt;/STRONG&gt;) and indeed perform any kind of processing in your macros because they are all &lt;STRONG&gt;eval&lt;/STRONG&gt;-ed at "compile" time. This has made my life a lot easier, especially when I am just testing things out and I need to re-lay-out stuff over and over again. &lt;/P&gt;
&lt;P&gt;&lt;A class="" title="Download the sample" href="http://blogs.msdn.com/ptorr/attachment/1443007.ashx" mce_href="http://blogs.msdn.com/ptorr/attachment/1443007.ashx"&gt;Attached is a simple project&lt;/A&gt;, along with &lt;STRONG&gt;preprocess.js&lt;/STRONG&gt;. You run &lt;STRONG&gt;preprocess.js&lt;/STRONG&gt; like this: &lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;STRONG&gt;cscript.exe preprocess.js &amp;lt;defs&amp;gt; &amp;lt;infile&amp;gt; &amp;lt;outfile&amp;gt; [-d] &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;where: &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&amp;lt;defs&amp;gt; is the name of the definitions file, eg "my_definitions.ini" &lt;/LI&gt;
&lt;LI&gt;&amp;lt;infile&amp;gt; is the name of the input file, eg "markup_with_symbolic_names.xmu" &lt;/LI&gt;
&lt;LI&gt;&amp;lt;outfile&amp;gt; is the name of the output file to create, eg "markup.xmu" &lt;/LI&gt;
&lt;LI&gt;The optional –d switch produces a .JS file with the same base name as &amp;lt;defs&amp;gt; containing JScript declarations for all the macros &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The definitions file is a simple text file that contains four types of lines: &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Empty lines or lines beginning with a semi-colon are ignored (eg, use for comments) &lt;/LI&gt;
&lt;LI&gt;Lines of the format &lt;EM&gt;NAME &amp;lt;space&amp;gt; TEXT&lt;/EM&gt; define &lt;EM&gt;NAME&lt;/EM&gt; to be exactly &lt;EM&gt;TEXT&lt;/EM&gt; &lt;/LI&gt;
&lt;LI&gt;Lines of the format &lt;EM&gt;NAME &amp;lt;space&amp;gt; '=' CODE&lt;/EM&gt; define &lt;EM&gt;NAME&lt;/EM&gt; to be the evaluation of &lt;EM&gt;CODE&lt;/EM&gt;, which can contain references to functions or other &lt;EM&gt;NAME&lt;/EM&gt;s &lt;/LI&gt;
&lt;LI&gt;Lines of the format '#' &lt;EM&gt;CODE&lt;/EM&gt; run &lt;EM&gt;CODE&lt;/EM&gt; directly without creating any new names (it is assumed the function being called adds names implicitly) &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;If a macro definition looks like a number, the system will automatically create an additional macro with the same name with "_PX" on the end that has the same value with "px" on the end. An example of a simple file: &lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&lt;STRONG&gt;; Here is a simple file &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&lt;STRONG&gt;; These lines are ignored &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&lt;STRONG&gt;; This creates two macros &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&lt;STRONG&gt;; The first is called "BUTTON_X" and has the value 100 &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&lt;STRONG&gt;; The second is called "BUTTON_X_PX" and has the value "100px" &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&lt;STRONG&gt;BUTTON_X&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;100 &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&lt;STRONG&gt;; This also creates two macros by doing simple arithmetic &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&lt;STRONG&gt;; Given the definition of BUTTON_X above, this will produce &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&lt;STRONG&gt;; both "BUTTON_Y" with a value of 200 &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&lt;STRONG&gt;; and "BUTTON_Y_PX" with a value of "200px" &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&lt;STRONG&gt;BUTTON_Y&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;= BUTTON_X + 100 &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&lt;STRONG&gt;; This runs the theoretical function DoSomethingCool, which you &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&lt;STRONG&gt;; could add to preprocess.js &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-FAMILY: Courier New"&gt;&lt;STRONG&gt;#DoSomethingCool() &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Note that &lt;STRONG&gt;preprocess.js&lt;/STRONG&gt; is not necessarily the best code in the world, nor is it a secure application (it will &lt;STRONG&gt;eval&lt;/STRONG&gt; arbitrary input code, so DO NOT USE IT on untrusted definition files!). It was something I threw together and have been iterating on in the normal hacker fashion. It was an itch that needed scratching, not a well-designed and thought-out application. &lt;/P&gt;
&lt;P&gt;Also note that whilst using the –d switch will output a script file, &lt;EM&gt;it is not big-endian as the HD DVD spec requires&lt;/EM&gt;! This is due to a limitation in the &lt;STRONG&gt;FileSystemObject&lt;/STRONG&gt;. You need to open the JS file in Notepad and re-save it with Big Endian encoding. That's why it isn't generated by default… &lt;/P&gt;
&lt;P&gt;So, on to &lt;A class="" title="Download the sample" href="http://blogs.msdn.com/ptorr/attachment/1443007.ashx" mce_href="http://blogs.msdn.com/ptorr/attachment/1443007.ashx"&gt;the enclosed example HDi program&lt;/A&gt;, it is very simple and very ugly. All it shows you is a simple defs file and a simple input markup file. Running the batch file will create the output markup file and then run the result (assuming HdiSim.exe is in your PATH). Clicking on the blue square makes it grow larger. &lt;/P&gt;
&lt;P&gt;&lt;EM&gt;AMAZING! &lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;But what is "cool" about this is that if you edit the defs.ini file and change (eg) the &lt;STRONG&gt;SMALL_W_ANIMATED&lt;/STRONG&gt; value to &lt;STRONG&gt;500&lt;/STRONG&gt; (to make the blue button grow larger) and re-run the batch file, the red button will automatically shift as well. No need to go and tweak its values to compensate for changes in the blue button. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;EM&gt;AMAZING! &lt;/EM&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Well, not so much, but in more complicated projects this is a real time-saver. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1443007" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/ptorr/attachment/1443007.ashx" length="6276" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/ptorr/archive/tags/Script/default.aspx">Script</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/iHD/default.aspx">iHD</category></item><item><title>Script Execution Order in HD DVD</title><link>http://blogs.msdn.com/ptorr/archive/2006/11/08/script-execution-order-in-hd-dvd.aspx</link><pubDate>Thu, 09 Nov 2006 00:28:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1040084</guid><dc:creator>ptorr</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/1040084.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=1040084</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=1040084</wfw:comment><description>&lt;P&gt;An HDi application can use multiple script files so that you can better manage your code (more manageable files; easier source control; etc.). You do this simply by listing the files inside &lt;STRONG&gt;&amp;lt;Script&amp;gt;&lt;/STRONG&gt; elements inside the manifest (and of course add the appropriate &lt;STRONG&gt;&amp;lt;Resource&amp;gt;&lt;/STRONG&gt; elements if they're not all in an ACA file). Whether or not script code in one file can "see" the script in another file is a common question that I'll address here. &lt;/P&gt;
&lt;H2&gt;Spec Behaviour &lt;/H2&gt;
&lt;P&gt;The HD DVD specification says that you take all the script files, load them in the order they are listed in the manifest, and then start running the script engine. This means that you really have one big "virtual file" that is the concatenation of all the individual files, and so all the code can "see" all the other code. &lt;/P&gt;
&lt;P&gt;This doesn't mean you're &lt;A href="http://www.amazon.com/Home-Dry-Pt-Shop-Boys/dp/B00005YWP7/sr=1-2/qid=1163021217/" mce_href="http://www.amazon.com/Home-Dry-Pt-Shop-Boys/dp/B00005YWP7/sr=1-2/qid=1163021217/"&gt;home and dry&lt;/A&gt;, of course, because there are some other things to be wary of that we'll get to soon. &lt;/P&gt;
&lt;H2&gt;HDiSim Behaviour &lt;/H2&gt;
&lt;P&gt;The spec behaviour was clarified in a fairly recent supplemental change, and so HDiSim currently uses a different approach – it loads each script file and executes it in the order listed in the manifest, similar to how a web browser would load and execute multiple &lt;STRONG&gt;&amp;lt;script&amp;gt;&lt;/STRONG&gt; blocks. What this means is that in HDiSim, code can only "see" code in the files that were listed before it in the manifest. &lt;/P&gt;
&lt;P&gt;Note that this only applies to "global code" that executes as soon as the script is loaded; basically any code outside of any functions (and the code that it calls, etc.) is subject to this rule, but because ECMAScript is a late-bound language, once all your script files have been loaded and your &lt;STRONG&gt;setMarkupLoadedHandler&lt;/STRONG&gt; has been called, all your code can "see" all the other code anyway. &lt;/P&gt;
&lt;P&gt;So it's only during initial startup that you have this problem. &lt;/P&gt;
&lt;H2&gt;Caveats &lt;/H2&gt;
&lt;P&gt;There are still several things to think about though. First let's look at what happens when an ECMAScript interpreter gets hold of a script. It basically does the following: &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Scan the file for variable declarations, and make them available (but with the initial value &lt;STRONG&gt;undefined&lt;/STRONG&gt;) &lt;/LI&gt;
&lt;LI&gt;Scan the file for function declarations, and make the &lt;STRONG&gt;Function&lt;/STRONG&gt; objects available &lt;/LI&gt;
&lt;LI&gt;Start running program code &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;This means that you can always call functions declared in the same file, and you can always access variables declared in the same file, but if you access variables before they are initialised you get &lt;STRONG&gt;undefined&lt;/STRONG&gt;. &lt;/P&gt;
&lt;P&gt;Here's a quick example, using &lt;STRONG&gt;Windows Script Host&lt;/STRONG&gt; as an example: &lt;/P&gt;
&lt;P style="MARGIN-LEFT: 36pt"&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; above = &lt;SPAN style="COLOR: maroon"&gt;"you see this"&lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;print(above) &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;print(below) &lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; below = &lt;SPAN style="COLOR: maroon"&gt;"you don't see this" &lt;BR&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt; print(s) { WScript.Echo(String(s)) } &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Running this program will print &lt;STRONG&gt;"you see this"&lt;/STRONG&gt; and &lt;STRONG&gt;"undefined"&lt;/STRONG&gt; on the screen. Note that if you comment out the line &lt;STRONG&gt;"var below=..."&lt;/STRONG&gt; you will get a runtime error because &lt;STRONG&gt;below&lt;/STRONG&gt; is not declared. ECMAScript lets you &lt;EM&gt;assign&lt;/EM&gt; values to undeclared variables, but you cannot &lt;EM&gt;read&lt;/EM&gt; undeclared variables (in broad terms, they can be &lt;A href="http://msdn2.microsoft.com/en-us/library/bkbs2cds.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/bkbs2cds.aspx"&gt;l-values but not r-values&lt;/A&gt;). &lt;/P&gt;
&lt;P&gt;Another HD DVD-specific caveat is that the &lt;STRONG&gt;document&lt;/STRONG&gt; object is not available when your script first executes; it doesn't become valid until the markup document has loaded and your &lt;STRONG&gt;setMarkupLoadedHandler&lt;/STRONG&gt; function has been called. Because of this, you probably want to avoid running too much code at startup anyway; sooner or later you're going to try and access &lt;STRONG&gt;document&lt;/STRONG&gt;, and crash. &lt;/P&gt;
&lt;P&gt;Finally, ECMAScript lets you re-define functions (since they are just objects like anything else). Within the same file, the lexically last definition will win, but in the case where you load multiple files independently (ala HDiSim) you could end up running one version of the function from global code inside one file, then re-defining it in a later file and running different code. Don't do that. &lt;/P&gt;
&lt;H2&gt;The Long and the Short of it &lt;/H2&gt;
&lt;P&gt;So basically what this means is that for maximum compatibility with the spec and with HDiSim, you should just make sure that your script files are listed in a "reasonable" order in the manifest, and that you don't try to do too much work before &lt;STRONG&gt;setMarkupLoadedHandler&lt;/STRONG&gt; is called. At that stage, everything will be available to you. &lt;/P&gt;
&lt;P&gt;Also, never re-define functions unless you &lt;EM&gt;really&lt;/EM&gt; know what you are doing. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1040084" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ptorr/archive/tags/Script/default.aspx">Script</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/HD+DVD/default.aspx">HD DVD</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/iHD/default.aspx">iHD</category></item><item><title>How do I get started with iHD?</title><link>http://blogs.msdn.com/ptorr/archive/2006/07/17/668845.aspx</link><pubDate>Tue, 18 Jul 2006 00:50:03 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:668845</guid><dc:creator>ptorr</dc:creator><slash:comments>8</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/668845.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=668845</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=668845</wfw:comment><description>
    &lt;div class="Section1"&gt;
      &lt;p&gt;
        &lt;span&gt;Many DVD authoring professionals may be wondering how they can get started with HD DVD. Probably the first thing to do is to &lt;a style="text-decoration:none;" href="http://www.microsoft.com/downloads/details.aspx?familyid=994accae-1591-4cc0-9d5b-03b0494686a4&amp;amp;displaylang=en"&gt;&lt;span class="Hyperlink-H" style="text-decoration:none underline;"&gt;download the iHD Jumpstart kit&lt;/span&gt;&lt;/a&gt; and get yourself a good XML editor (like the &lt;a style="text-decoration:none;" href="http://msdn.microsoft.com/vstudio/express/vwd/"&gt;&lt;span class="Hyperlink-H" style="text-decoration:none underline;"&gt;free Visual Studio Web Developer edition&lt;/span&gt;&lt;/a&gt;) and a graphics program like Photoshop or the &lt;a style="text-decoration:none;" href="http://www.microsoft.com/products/expression/en/graphic_designer/default.mspx"&gt;&lt;span class="Hyperlink-H" style="text-decoration:none underline;"&gt;Microsoft Expressions beta&lt;/span&gt;&lt;/a&gt;. This will allow you to create iHD content and play it back on your PC.&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;But the tools aren't much good if you don't know how to use them. You can look at the very basic samples in the iHD download, or look at some of the samples on my blog, but the best way to go from zero to hero (*cringe*) is to get a good book on HTML programming for the web. &lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;iHD's concepts are very similar to those used on the web -- you have some content elements (like divs, buttons, and paragraphs) and then you make them look pretty by giving them styles (like CSS -- Cascading Style Sheets). You then make things happen by writing small blocks of script code, just like a web page. The only thing that doesn't have a good parallel with web programming is the XPath-based timing engine, but hopefully I will be writing more about that in the not-too-distant future. You don't really need to know much about XML to write iHD; learning HTML is probably enough to get started, and any decent XML editor will help write the correct XML syntax for you (or, at least, tell you where you went wrong :-) ).&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;So if you know nothing about web development, or if you haven't really learnt anything new since 1995, I would suggest picking up a book on HTML programming -- just make sure it covers CSS and some basic JavaScript! Don't pick up one of those really thick books that contain a full reference to every DHTML object, property, and method, since that will not do you any good. You want to know about the basics of HTML structure, the basics of CSS and styling, and a little bit about script (which you might be better off getting a different book for -- again, just make sure it isn't full of HTML object references, because that's a waste of your time).&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;There are also lots of references on the web for HTML, CSS, and Script... unfortunately I don't have any personal recommendations right now; let me know if you find something particularly good!&lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        &lt;span&gt;  &lt;/span&gt;
      &lt;/p&gt;
    &lt;/div&gt;
  &lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=668845" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ptorr/archive/tags/Script/default.aspx">Script</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/HD+DVD/default.aspx">HD DVD</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/iHD/default.aspx">iHD</category></item><item><title>Inheritance in JavaScript - Part 2</title><link>http://blogs.msdn.com/ptorr/archive/2006/06/19/638195.aspx</link><pubDate>Tue, 20 Jun 2006 05:38:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:638195</guid><dc:creator>ptorr</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/ptorr/comments/638195.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ptorr/commentrss.aspx?PostID=638195</wfw:commentRss><wfw:comment>http://blogs.msdn.com/ptorr/rsscomments.aspx?PostID=638195</wfw:comment><description>&lt;P&gt;&lt;A href="http://blogs.msdn.com/ptorr/archive/2006/06/13/630208.aspx"&gt;Last time&lt;/A&gt; we took a (very) long-winded look at a simple JavaScript program that used basic inheritance. This time, we'll expand on that a little bit and improve on the techniques. &lt;/P&gt;
&lt;P&gt;
&lt;H2&gt;Calling the Constructor Directly &lt;/H2&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;First of all, let's look back at the &lt;STRONG&gt;Point&lt;/STRONG&gt; constructor again: &lt;/P&gt;&lt;SPAN style="FONT-SIZE: 12px; FONT-FAMILY: Lucida Console"&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt; Point(id, x, y)&lt;BR&gt;{ &lt;BR&gt;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;._id = id; &lt;BR&gt;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;._x = x; &lt;BR&gt;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;._y = y; &lt;BR&gt;} &lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Last time we noted that we just stash the value if &lt;STRONG&gt;id&lt;/STRONG&gt; into the &lt;STRONG&gt;_id&lt;/STRONG&gt; member because that's the only thing that the &lt;STRONG&gt;Thing&lt;/STRONG&gt; constructor does with it. But what if &lt;STRONG&gt;Thing&lt;/STRONG&gt; did some more complex processing, or took a larger number of arguments? We could keep copy-and-pasting the code from &lt;STRONG&gt;Thing&lt;/STRONG&gt; into &lt;STRONG&gt;Point&lt;/STRONG&gt;, but that is a tiresome process known as the "double maintenance problem" and will very quickly lead to bugs. &lt;/P&gt;
&lt;P&gt;Much better is to simply let &lt;STRONG&gt;Thing&lt;/STRONG&gt; do its, err, thing, for us, by calling into it directly: &lt;/P&gt;&lt;SPAN style="FONT-SIZE: 12px; FONT-FAMILY: Lucida Console"&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;STRONG&gt;&lt;FONT face="Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt; Point(id, x, y)&lt;BR&gt;{ &lt;BR&gt;&amp;nbsp; Thing.call(&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;, id); &lt;BR&gt;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;._x = x; &lt;BR&gt;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;._y = y; &lt;BR&gt;} &lt;/FONT&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;The only potentially weird bit here is that rather than just calling the &lt;STRONG&gt;Thing&lt;/STRONG&gt; function directly, we call a function off the &lt;STRONG&gt;Thing&lt;/STRONG&gt; function to do some special house-keeping work for us. How so, you ask? Remember that in JScript, &lt;EM&gt;functions are first-class objects&lt;/EM&gt; and can have properties and methods of their own, just like any other object. They just happen to have some internal properties like &lt;STRONG&gt;[[Call]]&lt;/STRONG&gt; and &lt;STRONG&gt;[[Construct]]&lt;/STRONG&gt; that make them cleverer than the average object. &lt;/P&gt;
&lt;P&gt;So, the &lt;STRONG&gt;Thing&lt;/STRONG&gt; function has some functions of its own, one of which is called &lt;STRONG&gt;call&lt;/STRONG&gt;. What the &lt;STRONG&gt;call&lt;/STRONG&gt; method does is call the function that it belongs to and passes in a random object as the &lt;STRONG&gt;this&lt;/STRONG&gt; object. In ECMAScript you don't usually have to ask yourself "&lt;EM&gt;How does my function get a &lt;STRONG&gt;this&lt;/STRONG&gt; object anyway?&lt;/EM&gt;" because it just works. It's only when it doesn't work that you get confused. &lt;/P&gt;
&lt;P&gt;Well, when you call a function as a constructor (i.e., as part of a &lt;STRONG&gt;new&lt;/STRONG&gt; expression), JavaScript creates a new object for you and then passes it in as the &lt;STRONG&gt;this&lt;/STRONG&gt; object. So you can write stuff like &lt;STRONG&gt;this._id = id&lt;/STRONG&gt; and the &lt;STRONG&gt;this&lt;/STRONG&gt; object just happens to be there for you. And then typically you assign the result of the constructor to a variable -- something like &lt;STRONG&gt;var thing = new Thing(42)&lt;/STRONG&gt; -- and now the &lt;STRONG&gt;thing&lt;/STRONG&gt; variable holds onto that object. When you call a method off an object, JScript once again figures out the &lt;STRONG&gt;this&lt;/STRONG&gt; object for you (it's the thing holding the method), and passes it in for you. If you just call a function as if it were a normal method -- i.e., not as part of a &lt;STRONG&gt;new&lt;/STRONG&gt; expression, or not off an existing object -- then the script engine will just use the global object as the &lt;STRONG&gt;this&lt;/STRONG&gt; object. &lt;/P&gt;
&lt;P&gt;So what if you want to call a method on an object you already have? That's the case here -- we already have our &lt;STRONG&gt;this&lt;/STRONG&gt; object inside the &lt;STRONG&gt;Point&lt;/STRONG&gt; constructor, and we want to ask &lt;STRONG&gt;Thing&lt;/STRONG&gt; to do some work for us. But we don't want to create a new &lt;STRONG&gt;Thing&lt;/STRONG&gt; -- we're deriving from it, remember -- and we don't want it to operate on the global object either; we want it to operate on our currently existing &lt;STRONG&gt;this&lt;/STRONG&gt; object. And that's where the &lt;STRONG&gt;call&lt;/STRONG&gt; method (and it's cousin &lt;STRONG&gt;apply&lt;/STRONG&gt;) comes in -- it lets you call a method and supply an arbitrary object that will become the this object inside the method call. So we just call &lt;STRONG&gt;Thing.call&lt;/STRONG&gt; and supply our &lt;STRONG&gt;this&lt;/STRONG&gt; object as &lt;STRONG&gt;Thing&lt;/STRONG&gt;'s &lt;STRONG&gt;this&lt;/STRONG&gt; object, and everything is peachy. (The &lt;STRONG&gt;apply&lt;/STRONG&gt; method is basically the same as &lt;STRONG&gt;call&lt;/STRONG&gt;, but deals better with a variable number of arguments -- a programming practice you should try to avoid). &lt;/P&gt;
&lt;P&gt;OK, so now we have our &lt;STRONG&gt;Point&lt;/STRONG&gt; object calling into &lt;STRONG&gt;Thing&lt;/STRONG&gt; to do the work for it, and we have saved ourselves the cost and complexity if maintaining the same code in two places. Are we done? &lt;/P&gt;
&lt;P&gt;Nope! &lt;/P&gt;
&lt;P&gt;Two things are still pretty ugly about this: this method is still too expensive, and it's not conducive to copy-and-paste programming. &lt;/P&gt;
&lt;P&gt;
&lt;H2&gt;Reducing Duplicate Function Calls &lt;/H2&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;Let's look at the code for &lt;STRONG&gt;Point&lt;/STRONG&gt; again: &lt;/P&gt;&lt;SPAN style="FONT-SIZE: 12px; FONT-FAMILY: Lucida Console"&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&lt;STRONG&gt;&lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt; Point(id, x, y) &lt;BR&gt;{ &lt;BR&gt;&amp;nbsp; Thing.call(&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;, id); &lt;BR&gt;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;._x = x; &lt;BR&gt;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;._y = y; &lt;BR&gt;} &lt;/STRONG&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12px; FONT-FAMILY: Lucida Console"&gt;&lt;FONT face="Courier New" size=2&gt;&lt;STRONG&gt;Point.prototype = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; Thing(); &lt;BR&gt;Point.prototype._className = &lt;SPAN style="COLOR: maroon"&gt;"Point"&lt;/SPAN&gt;; &lt;BR&gt;Point.prototype.constructor = Point; &lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Notice something fishy going on here? If we create &lt;EM&gt;n&lt;/EM&gt; &lt;STRONG&gt;Point&lt;/STRONG&gt; objects, we actually call the &lt;STRONG&gt;Thing&lt;/STRONG&gt; constructor &lt;EM&gt;n&lt;/EM&gt; + 1 times -- that "+ 1" is caused by the initial call to set the &lt;STRONG&gt;Point.prototype&lt;/STRONG&gt; property. In this specific example, that's not too bad, because &lt;STRONG&gt;Thing&lt;/STRONG&gt; doesn't really do much. But in a more complicated scenario, it could cause problems. For a start, if the &lt;STRONG&gt;Thing&lt;/STRONG&gt; constructor is expensive, we will waste some CPU on that first initialisation (hopefully not a huge concern, but you never know). &lt;/P&gt;
&lt;P&gt;Secondly, if &lt;STRONG&gt;Thing&lt;/STRONG&gt; actually does anything "interesting" in the constructor (and by "interesting" I mean interacting with the world outside of &lt;STRONG&gt;this&lt;/STRONG&gt; -- incrementing a global counter, printing information on the screen, creating a row in a database, or whatever), then you will have an additional bogus interaction from that &lt;STRONG&gt;Point.prototype = new Thing()&lt;/STRONG&gt; call. Unlike the first point, this is more likely to be of concern, so it's something we should try to avoid. &lt;/P&gt;
&lt;P&gt;Thirdly, we construct &lt;STRONG&gt;Thing&lt;/STRONG&gt; without any arguments -- so if the constructor expects to receive meaningful parameters, it is likely to throw an exception or perform some other unpleasant acts because it got a bunch of &lt;STRONG&gt;undefined&lt;/STRONG&gt; values instead of real data. One way around this would be of course to supply &lt;STRONG&gt;Thing&lt;/STRONG&gt; with the parameters it needed, but since they are "throw away" parameters (they aren't really used for any specific &lt;STRONG&gt;Point&lt;/STRONG&gt; instance, because we're going to call the constructor with real values later on), it kind of defeats the purpose. And, again, it could put us into unchartered waters further down the road, depending on the complexity of the &lt;STRONG&gt;Thing&lt;/STRONG&gt; constructor. &lt;/P&gt;
&lt;P&gt;We can easily avoid all these pitfalls by using a different coding pattern that is tuned more to the way ECMAScript works and less to the way C++ works (unless you write COM objects for a living). Rather than doing any work inside the constructor, I make the constructor do the bare minimum initialisation steps (basically set everything to &lt;STRONG&gt;null&lt;/STRONG&gt; / zero / empty string) and then do the real work inside an &lt;STRONG&gt;Initialise&lt;/STRONG&gt; method. This avoids duplicating effort inside that initial call to setup the prototype, but still leaves the object in a bare-bones usable state should someone forget to call &lt;STRONG&gt;Initialise&lt;/STRONG&gt; before using it. (You could leave the constructor completely empty if you like, choosing to do all the initialisation during the &lt;STRONG&gt;Initialise&lt;/STRONG&gt; call, but personally I think that setting up all the properties in the constructor provides better documentation -- you only need to look at the constructor to find out what members the object has). &lt;/P&gt;
&lt;P&gt;So, using this technique, the code is modified thusly (only new things are re-printed here, not the whole script): &lt;/P&gt;&lt;SPAN style="FONT-SIZE: 12px; FONT-FAMILY: Lucida Console"&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&lt;STRONG&gt;&lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt; Thing() &lt;BR&gt;{ &lt;BR&gt;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;._id = &lt;SPAN style="COLOR: maroon"&gt;""&lt;/SPAN&gt;; &lt;BR&gt;} &lt;/STRONG&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12px; FONT-FAMILY: Lucida Console"&gt;&lt;FONT face="Courier New" size=2&gt;&lt;STRONG&gt;Thing.prototype.Initialise = &lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt; Thing_Initialise(id) &lt;BR&gt;{ &lt;BR&gt;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;._id = id; &lt;BR&gt;}; &lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12px; FONT-FAMILY: Lucida Console"&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&lt;STRONG&gt;&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; thing = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; Thing(); &lt;BR&gt;thing.Initialise(&lt;SPAN style="COLOR: maroon"&gt;'thing'&lt;/SPAN&gt;);&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12px; COLOR: green; FONT-FAMILY: Lucida Console"&gt;&lt;FONT face="Courier New" size=2&gt;&lt;STRONG&gt;////////////////////////////////////////////////// &lt;/STRONG&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12px; FONT-FAMILY: Lucida Console"&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&lt;STRONG&gt;&lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt; Point() &lt;BR&gt;{ &lt;BR&gt;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;._x = -1; &lt;BR&gt;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;._y = -1; &lt;BR&gt;} &lt;/STRONG&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12px; FONT-FAMILY: Lucida Console"&gt;&lt;FONT face="Courier New" size=2&gt;&lt;STRONG&gt;Point.prototype.Initialise = &lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt; Point_Initialise(id, x, y) &lt;BR&gt;{ &lt;BR&gt;&amp;nbsp; Thing.prototype.Initialise.call(&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;, id); &lt;BR&gt;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;._x = x; &lt;BR&gt;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;._y = y;&amp;nbsp;&lt;BR&gt;}; &lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12px; FONT-FAMILY: Lucida Console"&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&lt;STRONG&gt;&lt;SPAN style="COLOR: blue"&gt;var&lt;/SPAN&gt; point = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; Point(); &lt;BR&gt;point.Initialise(&lt;SPAN style="COLOR: maroon"&gt;'point'&lt;/SPAN&gt;, 0, 0); &lt;/STRONG&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Whilst this style might offend some of the more hard-core C# / Java / etc. enthusiasts, and it is a new coding convention that takes some getting used to, it definitely helps curtail the one-too-many-constructor-calls problem that will come up to bite you in the proverbial sooner or later. I recommend you consider it. &lt;/P&gt;
&lt;P&gt;
&lt;H2&gt;Making Code Copy-And-Paste-able &lt;/H2&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;Everyone knows that a lot of "programming" consists of copying your last project (or someone else's :-) ) and then tweaking it to do whatever you need to do next. In support of this, we should look for coding practices that make it easy to copy-and-paste code in such a way that the "programmer" doesn't have to go over every line with a fine-toothed comb to make sure there are no bugs. Because of JScript's loose typing (and very forgiving semantics), it is possible to copy and paste code that happens to "work" by mistake but isn't doing what you think it is. Days or weeks later you make a (seemingly) unrelated change elsewhere, and suddenly things stop working. &lt;/P&gt;
&lt;P&gt;Argh! &lt;/P&gt;
&lt;P&gt;So let's look at the code again: &lt;/P&gt;&lt;SPAN style="FONT-SIZE: 12px; FONT-FAMILY: Lucida Console"&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&lt;STRONG&gt;Point.prototype.Initialise = &lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt; Point_Initialise(id, x, y) &lt;BR&gt;{ &lt;BR&gt;&amp;nbsp; Thing.prototype.Initialise.call(&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;, id); &lt;BR&gt;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;._x = x; &lt;BR&gt;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;._y = y; &lt;BR&gt;}; &lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;If we're going to copy-and-paste this code a lot of times, we really want it to be as loosely-coupled to &lt;STRONG&gt;Thing&lt;/STRONG&gt; as possible... and yet here we have a direct call into a &lt;STRONG&gt;Thing.prototype&lt;/STRONG&gt; method right smack bang in the middle of our function (and imagine this is a large code-base where you have lots of methods that make calls to their base class' methods all over the place). The scary thing is that copied code will &lt;EM&gt;still work&lt;/EM&gt;, even if the object you copied it into doesn't derive from &lt;STRONG&gt;Thing&lt;/STRONG&gt;, because there exists a &lt;STRONG&gt;Thing&lt;/STRONG&gt; and it has an &lt;STRONG&gt;Initialise&lt;/STRONG&gt; method. &lt;STRONG&gt;Thing&lt;/STRONG&gt; will just happily dork around with the &lt;STRONG&gt;this&lt;/STRONG&gt; object, creating new expando properties if it needs to, or reading &lt;STRONG&gt;undefined&lt;/STRONG&gt; out of ones that don't exist, and it probably won't crash or do anything terribly noticeable. But the fact is that it won't be doing what you intended it to do, and you might never know that it's not really doing what you expected until it's too late. &lt;/P&gt;
&lt;P&gt;So how do we solve it? We remove any reference to &lt;STRONG&gt;Thing&lt;/STRONG&gt; from inside our functions. And how do we do that? I'm glad you asked: &lt;/P&gt;&lt;SPAN style="FONT-SIZE: 12px; FONT-FAMILY: Lucida Console"&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&lt;STRONG&gt;&lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt; Point() &lt;BR&gt;{ &lt;BR&gt;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;._x = -1; &lt;BR&gt;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;._y = -1; &lt;BR&gt;} &lt;/STRONG&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12px; FONT-FAMILY: Lucida Console"&gt;&lt;FONT face="Courier New" size=2&gt;&lt;STRONG&gt;Point.prototype = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; Thing(); &lt;BR&gt;Point.prototype._className = &lt;SPAN style="COLOR: maroon"&gt;"Point"&lt;/SPAN&gt;; &lt;BR&gt;Point.prototype.constructor = Point; &lt;BR&gt;Point._base = Thing.prototype; &lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;&lt;SPAN style="FONT-SIZE: 12px; FONT-FAMILY: Lucida Console"&gt;&lt;FONT face="Courier New" size=2&gt;&lt;STRONG&gt;Point.prototype.Initialise = &lt;SPAN style="COLOR: blue"&gt;function&lt;/SPAN&gt; Point_Initialise(id, x, y) &lt;BR&gt;{ &lt;BR&gt;&amp;nbsp; Point._base.Initialise.call(&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;, id); &lt;BR&gt;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;._x = x; &lt;BR&gt;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;._y = y; &lt;BR&gt;}; &lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Aha! We add a new &lt;STRONG&gt;_base&lt;/STRONG&gt; property to the &lt;STRONG&gt;Point&lt;/STRONG&gt; object itself (remember, &lt;STRONG&gt;Point&lt;/STRONG&gt; is an object too!) that points to the base object (in this case, &lt;STRONG&gt;Thing.prototype&lt;/STRONG&gt;) and then we call &lt;EM&gt;that&lt;/EM&gt; instead of &lt;STRONG&gt;Thing.prototype&lt;/STRONG&gt;. OK, OK, so you may be saying "But Peter you twit, this didn't solve anything -- when I copy-and-paste my code, I could still end up with &lt;STRONG&gt;Point._base.prototype&lt;/STRONG&gt; instead of &lt;STRONG&gt;Thing.prototype&lt;/STRONG&gt; and the same problems will still ensue!" &lt;/P&gt;
&lt;P&gt;How true! The difference, dear reader, is that I expect you are &lt;EM&gt;more&lt;/EM&gt; likely to do a search-and-replace for "Point" when you copy this code than you are to search-and-replace "Thing" (remember, you're copying code from &lt;STRONG&gt;Point&lt;/STRONG&gt; to &lt;STRONG&gt;YourNewObject&lt;/STRONG&gt;), and so the reference to &lt;STRONG&gt;Point._base&lt;/STRONG&gt; will be updated to &lt;STRONG&gt;YourNewObject._base&lt;/STRONG&gt; without any hassles. Of course if you don't do any kind of search-and-replace, you have the same problem you always had... life is tough. &lt;/P&gt;
&lt;P&gt;
&lt;H2&gt;Why Being Smarter Won't Work &lt;/H2&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;The "obvious" solution to the last problem is to put the &lt;STRONG&gt;_base&lt;/STRONG&gt; property onto the &lt;STRONG&gt;this&lt;/STRONG&gt; object -- rather than the constructor function itself -- then you can always refer to &lt;STRONG&gt;this._base.prototype&lt;/STRONG&gt; and never have to worry about referring to the wrong thing ever again, right? &lt;/P&gt;
&lt;P&gt;Wrong. &lt;/P&gt;
&lt;P&gt;Exactly &lt;EM&gt;why&lt;/EM&gt; it's wrong is a subject for another post (or perhaps a reader can comment...). Try it out for yourself, and see what happens (hint: you'll need more than two classes to see why it doesn't work). &lt;/P&gt;
&lt;P&gt;
&lt;H2&gt;Coming Up... &lt;/H2&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;In the next instalment: a feature that some people claim is impossible with JScript. Just you wait and see!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=638195" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ptorr/archive/tags/Script/default.aspx">Script</category><category domain="http://blogs.msdn.com/ptorr/archive/tags/iHD/default.aspx">iHD</category></item></channel></rss>