unethical blogger - JavaScript http://unethicalblogger.com/taxonomy/term/15/0 Posts pertaining to all that is JavaScript, for better or worse. en V8 and FastCGI, Exploring an Idea http://unethicalblogger.com/posts/2009/03/v8_and_fastcgi_exploring_idea <p>Over the past couple years I've talked a lot of trash about JavaScript (really, a <strong>lot</strong>) but I've slowly started to come around to a more neutral stance, I actually hate <em>browsers</em>, I like JavaScript just fine by itself! While the prototype-based object system is a little weird at first coming from a more classical object-oriented background, the concept grows on you the more you use it.</p> <p>Since I hate browsers so much (I really do), I was pleased as punch to hear that <a href="http://code.google.com/p/v8/" target="_blank">Google's V8 JavaScript Engine</a> was embeddable. While WebKit's <a href="http://webkit.org/projects/javascript/" target="_blank">JavaScriptCore</a> is quite a nice JavaScript engine, it doesn't lend itself to being embedded the same way that V8 does. The only immediate downside to V8 is that it's written entirely in C++, which does provide some hurdles to embedding (for example, I'm likely never going to be able to embed it into a <a href="http://www.mono-project.com" target="_blank">Mono</a> application), but for the majority of cases embedding the engine into a project shouldn't be all that difficult. </p> <p>A few weekends ago I started exploring the possibility of running server-side JavaScript courtesy of V8, after reading about <a href="http://journal.paul.querna.org/articles/2008/12/23/mod_v8/" target="_blank">mod_v8</a> I felt more confident to try my project: <a href="http://github.com/rtyler/fastjs/tree/master" target="_blank"><strong>FastJS</strong></a>. </p> <p>In a nutshell, FastJS is a <a href="http://www.fastcgi.com/" target="_blank">FastCGI</a> server to process server-side JavaScript, this means FastJS can hook up to <a href="http://www.lighttpd.net/" target="_blank">Lighttpd</a>, <a href="http://nginx.net/" target="_blank">Nginx</a>, or even Apache via <a href="http://fastcgi.coremail.cn/" target="_blank">mod_fcgi</a>. Currently FastJS is in a state of "extremely unstable and downright difficult", there's not a lot there as I'm exploring what should be provided by the FastJS server-side software, and what should be provided by JavaScript libraries. As it stands now, FastJS preloads the environment with <a href="http://jquery.com/" target="_blank">jQuery</a> 1.3.2 and a "fastjs" object which contains some important callbacks like: </p> <pre>fastjs.write() // write to the output stream fastjs.log() // write to the FastCGI error.lgo fastjs.source() // Include and execute other JavaScript files</pre><p> On the server side, a typical request looks something like this (for now):</p> <pre>2009-03-09 05:04:06: (response.c.114) Response-Header: HTTP/1.1 200 OK Transfer-Encoding: chunked Content-type: text/html X-FastJS-Request: 1 X-FastJS-Process: 11515 X-FastJS-Engine: V8 Date: Mon, 09 Mar 2009 09:04:06 GMT Server: lighttpd/1.4.18</pre><p><!--break--><br /> Below is an example of the current test page "<a href="http://github.com/rtyler/fastjs/blob/fe29a4feca79a861968449be1dbd520247d6d3f3/pages/index.fjs" target="_blank">index.fjs</a>":</p> <div style="overflow: scroll; height: 210px;"> <div class="geshifilter"><pre class="geshifilter-javascript"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #003366; font-weight: bold;">var</span> index = <span style="color: #003366; font-weight: bold;">new</span> Object<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">index.<span style="color: #006600;">header</span> = <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> fastjs.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;&lt;html&gt;&lt;head&gt;&lt;title&gt;FastJS&lt;/title&gt;&lt;/head&gt;&quot;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> fastjs.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;&lt;body&gt;&quot;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> fastjs.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;&lt;center&gt;&lt;h2&gt;FastJS Test Page&lt;/h2&gt;&lt;/center&gt;&lt;br/&gt;&quot;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #66cc66;">&#125;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">index.<span style="color: #006600;">footer</span> = <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span> </div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> fastjs.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;&lt;/body&gt;&lt;/html&gt;&quot;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #66cc66;">&#125;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">index.<span style="color: #006600;">dump_attributes</span> = <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>title, obj<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> fastjs.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;&lt;br/&gt;&lt;strong&gt;&quot;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> fastjs.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #66cc66;">&#40;</span>title<span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> fastjs.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;&lt;/strong&gt;&lt;br/&gt;&lt;hr/&gt;&quot;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> k <span style="color: #000066; font-weight: bold;">in</span> obj<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> fastjs.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #66cc66;">&#40;</span>k + <span style="color: #3366CC;">&quot; = &quot;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span><span style="color: #66cc66;">&#40;</span>obj<span style="color: #66cc66;">&#91;</span>k<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">!</span>= <span style="color: #3366CC;">&quot;string&quot;</span><span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> fastjs.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span><span style="color: #66cc66;">&#40;</span>obj<span style="color: #66cc66;">&#91;</span>k<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #000066; font-weight: bold;">else</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> fastjs.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #66cc66;">&#40;</span>obj<span style="color: #66cc66;">&#91;</span>k<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> fastjs.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;&lt;br/&gt;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #66cc66;">&#125;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> index.<span style="color: #006600;">header</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> fastjs.<span style="color: #006600;">source</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;pages/test.fjs&quot;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> index.<span style="color: #006600;">dump_attributes</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;window&quot;</span>, window<span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> index.<span style="color: #006600;">dump_attributes</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'location'</span>, location<span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> index.<span style="color: #006600;">dump_attributes</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;fastjs.env&quot;</span>, fastjs.<span style="color: #006600;">env</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> index.<span style="color: #006600;">dump_attributes</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;fastjs.fcgi_env&quot;</span>, fastjs.<span style="color: #006600;">fcgi_env</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> index.<span style="color: #006600;">footer</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> fastjs.<span style="color: #006600;">log</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">&quot;This should go into the error.log&quot;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div></li></ol></pre></div></div> <p>The code above generates a page that looks pretty basic, but informative nonetheless (<small>click to enlarge</small>):<center><a href="http://agentdero.cachefly.net/unethicalblogger.com/images/fastjs_testpage.jpeg" rel="lightbox"><img src="http://agentdero.cachefly.net/unethicalblogger.com/images/fastjs_testpage.jpeg" width="450"/></a></center></p> <p>Pretty fun in general to play with, I think I'm near on the point where I can stop writing more of my terrible C/C++ code and get back into the wonderful land of JavaScript. As it stands now, here's what still needs to be done: <ul> <li>Proper handling of erroring scripts via an informative 500 page that reports on the error</li> <li>Templating? Lots of fastjs.write() calls are likely to drive you mad</li> <li>Performance concerns? As of now, the whole stack (jQuery + .fjs) are evaluated every page request.</li> <li>Tests! I should really get around to writing some level of integration tests to make sure that FastJS is returning expected results for particular chunks of .fjs scripts</li> </ul> <p>The project is hosted on GitHub right now, <a href="http://github.com/rtyler/fastjs/tree/master" target="_blank">here</a> and is under a 2-clause BSD license.</p> http://unethicalblogger.com/posts/2009/03/v8_and_fastcgi_exploring_idea#comments JavaScript Miscellaneous Software Development Mon, 09 Mar 2009 09:49:58 +0000 R. Tyler Croy 213 at http://unethicalblogger.com Lazily loading attributes. http://unethicalblogger.com/posts/2008/09/lazily_loading_attributes <p>I found myself talking to <a href="http://jasonrubenstein.blogspot.com/" target="_blank">Jason</a> today about the virtues of <span class="geshifilter"><code class="python geshifilter-python"><span style="color: #008000;">getattr</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></code></span>, <span class="geshifilter"><code class="python geshifilter-python"><span style="color: #008000;">setattr</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></code></span>, and <span class="geshifilter"><code class="python geshifilter-python"><span style="color: #008000;">hasattr</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></code></span> in Python and "abusing" the dynamic nature of the language which reminded me of some lazy-loading code I wrote a while back. In February I found the need to have portions of the logic behind one of our web applications fetch data once per-request. The nature of the web applications we're building on top of the <a href="http://developer.myspace.com/community/" target="_blank">MySpace</a>, <A href="http://developer.hi5.com/" target="_blank">Hi5</a> and <a href="http://developers.facebook.com/" target="_blank">Facebook</a> platforms require some level of network data-access (traditionally via REST-like APIs). This breaks our data access model into the following tiers:<center><img src="http://agentdero.cachefly.net/unethicalblogger.com/images/data_model.png" alt=" Dia FTW "/></center><br /> Working with network-centric data resources is difficult in any scenario (desktop, mobile, web) but the particularly difficult thing about network data access in the mod_python-driven request model is that it will be synchronous (mod_python doesn't support "<a href="http://msdn.microsoft.com/en-us/magazine/cc163725.aspx" target="_blank">asynchronous pages</a>" like ASP.NET does). This means <strong>every</strong> REST call to Facebook, for example, is going to block execution of the request handler until the REST request to Facebook's API tier completes. <div class="geshifilter"><pre class="geshifilter-python"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #ff7700;font-weight:bold;">def</span> request_handler<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>:</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> fb_uid = kwargs.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'fb_sig_user'</span><span style="color: black;">&#41;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Fetching the name for %s&quot;</span> <span style="color: #66cc66;">%</span> fb_uid</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> name = facebook.<span style="color: black;">users</span>.<span style="color: black;">getInfo</span><span style="color: black;">&#40;</span>uid=fb_uid<span style="color: black;">&#41;</span> </div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #808080; font-style: italic;">### WAIT-WAIT-WAIT-WAIT-WAIT</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> </div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #808080; font-style: italic;">### Continue generating the page...</span></div></li></ol></pre></div>There is also a network hit (albeit minor) for accessing cached data or data stored in databases. The general idea is that we'll need to have some level of data resident in memory through-out a request that can differ widely from request-to-request.</p> <h3>Lazy loading in Python</h3> <p> To help avoid unnecessary database access or network access I wrote a bit of class-sugar to make this a bit easier and more fail-proof:<div class="geshifilter"><pre class="geshifilter-python"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #ff7700;font-weight:bold;">class</span> LazyProgrammer<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #483d8b;">''</span><span style="color: #483d8b;">' </span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #483d8b;"> LazyProgrammer allows for lazily-loaded attributes on the subclasses </span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #483d8b;"> of this object. In order to enable lazily-loaded attributes define</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #483d8b;"> &quot;_X_attr_init()&quot; for the attribute &quot;obj.X&quot;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #483d8b;"> '</span><span style="color: #483d8b;">''</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__getattr__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, name<span style="color: black;">&#41;</span>:</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> rc = <span style="color: #008000;">object</span>.<span style="color: #0000cd;">__getattribute__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #483d8b;">'_%s_attr_init'</span><span style="color: black;">&#41;</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #008000;">setattr</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, name, rc<span style="color: black;">&#41;</span> </div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #ff7700;font-weight:bold;">return</span> rc</div></li></ol></pre></div>This makes developing with network-centric web applications a bit easier, for example, if I have a "friends" lazily-loading attribute off the base "FacebookRequest" class, all developers writing code subclassing FacebookRequest can simply refer to <span class="geshifilter"><code class="python geshifilter-python"><span style="color: #008000;">self</span>.<span style="color: black;">friends</span></code></span> and feel confident they aren't incurring unnecessary bandwidth hits, and the friends-list fetching code is located in once spot. If one-per-request starts to become too resource intensive as well, it'd be trivial to override the <span class="geshifilter"><code class="python geshifilter-python">_friends_attr_init<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></code></span> method to hit a caching server instead of the REST servers first, without needing to change any code "downstream."<br /> <br/></p> <h3>Lazy loading in C#</h3> <p> Since C# is not a dynamically-typed language like Python or JavaScript, you can't implement lazily-loaded attributes in the same fashion (calling something like <span class="geshifilter"><code class="python geshifilter-python"><span style="color: #008000;">setattr</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></code></span>) but you can "abuse" properties in a manner similar to the C# singleton pattern, to get the desired effect:<div class="geshifilter"><pre class="geshifilter-python"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">using System<span style="color: #66cc66;">;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">using System.<span style="color: black;">Collections</span>.<span style="color: black;">Generic</span><span style="color: #66cc66;">;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">public <span style="color: #ff7700;font-weight:bold;">class</span> LazySharp</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: black;">&#123;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #808080; font-style: italic;">#region &quot;Lazy Members&quot;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> private Dictionary<span style="color: #66cc66;">&lt;</span>int, string<span style="color: #66cc66;">&gt;</span> _names = null<span style="color: #66cc66;">;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #808080; font-style: italic;">#endregion</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #808080; font-style: italic;">#region &quot;Lazy Properties&quot;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> public Dictionary<span style="color: #66cc66;">&lt;</span>int, string<span style="color: #66cc66;">&gt;</span> Names</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: black;">&#123;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> get <span style="color: black;">&#123;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#40;</span>this._names == null<span style="color: black;">&#41;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> this._names = this.<span style="color: black;">SomeExpensiveCall</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #ff7700;font-weight:bold;">return</span> this._names<span style="color: #66cc66;">;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: black;">&#125;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: black;">&#125;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #808080; font-style: italic;">#endregion</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: black;">&#125;</span></div></li></ol></pre></div>Admittedly I don't find myself writing Facebook/MySpace/Hi5 applications these days on top of ASP.NET so I cannot say I actually <em>use</em> the class above in production, but conceptually it makes sense.</p> <p>Lazy loading attributes I find useful in the more hodge-podge situations, where code and feature-sets have both grown organically over time, they're not for everybody but I figured I'd share anyways.</p> http://unethicalblogger.com/posts/2008/09/lazily_loading_attributes#comments JavaScript Miscellaneous Mono Mon, 15 Sep 2008 07:27:41 +0000 R. Tyler Croy 187 at http://unethicalblogger.com Resurgange of the shell. http://unethicalblogger.com/posts/2008/09/resurgange_shell <p>Two things happened in such short proximity time-wise that I can't help but thing they're somehow related to the larger shift to <em>interpreters</em>. Earlier this week Miguel introduced <a href="http://tirania.org/blog/archive/2008/Sep-08.html" target="_blank">csharp shell</a> which forced me to dust off my shoddy Mono 1.9 build and rebuild Mono from Subversion just because this is too interesting to pass up on.</p> <p>One of my favorite aspects of using IronPyhton, or Python for that matter is the interpreter which allows for prototyping that doesn't involve creating little test apps that I have to build to prove a point. For example, I can work through fetching a web page in the csharp shell really easily, instead of creating a silly little application, compiling, fixing errors, and recompiling:<br /> <div class="geshifilter"><pre class="geshifilter-bash"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">tyler<span style="color: #000000; font-weight: bold;">@</span>pineapple:~<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">source</span><span style="color: #000000; font-weight: bold;">/</span>mono-project<span style="color: #000000; font-weight: bold;">/</span>mono<span style="color: #000000; font-weight: bold;">&gt;</span> csharp</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">Mono C<span style="color: #808080; font-style: italic;"># Shell, type &quot;help;&quot; for help</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">Enter statements below.</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> using System;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> Console.WriteLine<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">&quot;This changes everything.&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">This changes everything.</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> String url = <span style="color: #ff0000;">&quot;http://tycho.usno.navy.mil/cgi-bin/timer.pl&quot;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> using System.Web;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> using System.Net;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> using System.IO;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> using System.Text;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> HttpWebRequest req = HttpWebRequest.Create<span style="color: #7a0874; font-weight: bold;">&#40;</span>url<span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;</span>interactive<span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">1</span>,<span style="color: #000000;">17</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>: error CS0266: Cannot implicitly convert <span style="color: #7a0874; font-weight: bold;">type</span> `System.Net.WebRequest<span style="color: #ff0000;">' to `System.Net.HttpWebRequest'</span>. An explicit conversion exists <span style="color: #7a0874; font-weight: bold;">&#40;</span>are you missing a cast?<span style="color: #7a0874; font-weight: bold;">&#41;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> HttpWebRequest req = HttpWebRequest.Create<span style="color: #7a0874; font-weight: bold;">&#40;</span>url<span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #c20cb9; font-weight: bold;">as</span> HttpWebRequest;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> HttpWebResponse response = req.GetResponse<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #c20cb9; font-weight: bold;">as</span> HttpWebResponse;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> StreamReader reader = new StreamReader<span style="color: #7a0874; font-weight: bold;">&#40;</span>req.GetResponseStream<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #c20cb9; font-weight: bold;">as</span> Stream, Encoding.UTF8<span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;</span>interactive<span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">1</span>,<span style="color: #000000;">45</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>: error CS1061: Type `System.Net.HttpWebRequest<span style="color: #ff0000;">' does not contain a definition for `GetResponseStream'</span> and no extension method `GetResponseStream<span style="color: #ff0000;">' of type `System.Net.HttpWebRequest'</span> could be found <span style="color: #7a0874; font-weight: bold;">&#40;</span>are you missing a using directive or an assembly reference?<span style="color: #7a0874; font-weight: bold;">&#41;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> StreamReader reader = new StreamReader<span style="color: #7a0874; font-weight: bold;">&#40;</span>response.GetResponseStream<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #c20cb9; font-weight: bold;">as</span> Stream, Encoding.UTF8<span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> String result = reader.ReadToEnd<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> Console.WriteLine<span style="color: #7a0874; font-weight: bold;">&#40;</span>result<span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;!</span>DOCTYPE HTML PUBLIC <span style="color: #ff0000;">&quot;-//W3C//DTD HTML 3.2 Final&quot;</span><span style="color: #000000; font-weight: bold;">//</span>EN<span style="color: #000000; font-weight: bold;">&gt;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;</span>html<span style="color: #000000; font-weight: bold;">&gt;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;</span>body<span style="color: #000000; font-weight: bold;">&gt;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;</span>TITLE<span style="color: #000000; font-weight: bold;">&gt;</span>What <span style="color: #000000; font-weight: bold;">time</span> is it?<span style="color: #000000; font-weight: bold;">&lt;/</span>TITLE<span style="color: #000000; font-weight: bold;">&gt;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;</span>H2<span style="color: #000000; font-weight: bold;">&gt;</span> US Naval Observatory Master Clock Time<span style="color: #000000; font-weight: bold;">&lt;/</span>H2<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">&lt;</span>H3<span style="color: #000000; font-weight: bold;">&gt;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;</span>BR<span style="color: #000000; font-weight: bold;">&gt;</span>Sep. <span style="color: #000000;">11</span>, <span style="color: #000000;">07</span>:<span style="color: #000000;">29</span>:<span style="color: #000000;">02</span> UTC</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;</span>BR<span style="color: #000000; font-weight: bold;">&gt;</span>Sep. <span style="color: #000000;">11</span>, <span style="color: #000000;">03</span>:<span style="color: #000000;">29</span>:<span style="color: #000000;">02</span> AM EDT</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;</span>BR<span style="color: #000000; font-weight: bold;">&gt;</span>Sep. <span style="color: #000000;">11</span>, <span style="color: #000000;">02</span>:<span style="color: #000000;">29</span>:<span style="color: #000000;">02</span> AM CDT</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;</span>BR<span style="color: #000000; font-weight: bold;">&gt;</span>Sep. <span style="color: #000000;">11</span>, <span style="color: #000000;">01</span>:<span style="color: #000000;">29</span>:<span style="color: #000000;">02</span> AM MDT</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;</span>BR<span style="color: #000000; font-weight: bold;">&gt;</span>Sep. <span style="color: #000000;">11</span>, <span style="color: #000000;">12</span>:<span style="color: #000000;">29</span>:<span style="color: #000000;">02</span> AM PDT</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;</span>BR<span style="color: #000000; font-weight: bold;">&gt;</span>Sep. <span style="color: #000000;">10</span>, <span style="color: #000000;">11</span>:<span style="color: #000000;">29</span>:<span style="color: #000000;">02</span> PM AKDT</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;</span>BR<span style="color: #000000; font-weight: bold;">&gt;</span>Sep. <span style="color: #000000;">10</span>, <span style="color: #000000;">09</span>:<span style="color: #000000;">29</span>:<span style="color: #000000;">02</span> PM HAST</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;/</span>H3<span style="color: #000000; font-weight: bold;">&gt;&lt;</span>P<span style="color: #000000; font-weight: bold;">&gt;&lt;</span>A <span style="color: #007800;">HREF=</span><span style="color: #ff0000;">&quot;http://tycho.usno.navy.mil&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span>Time Service Department, US Naval Observatory<span style="color: #000000; font-weight: bold;">&lt;/</span>A<span style="color: #000000; font-weight: bold;">&gt;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;/</span>body<span style="color: #000000; font-weight: bold;">&gt;&lt;/</span>html<span style="color: #000000; font-weight: bold;">&gt;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> reader.Close<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> response.Close<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> </div></li></ol></pre></div><br /> <!--break--><br /> I really think Miguel and Co. have adding something infinitely more useful in this Hackweek project than anything I've seen come out of recent hackweeks at Novell. The only feature request that I'd add along to the csharp shell would be "recording", i.e.:<br /> <div class="geshifilter"><pre class="geshifilter-bash"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">tyler<span style="color: #000000; font-weight: bold;">@</span>pineapple:~<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">source</span><span style="color: #000000; font-weight: bold;">/</span>mono-project<span style="color: #000000; font-weight: bold;">/</span>mono<span style="color: #000000; font-weight: bold;">&gt;</span> csharp</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">Mono C<span style="color: #808080; font-style: italic;"># Shell, type &quot;help;&quot; for help</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">Enter statements below.</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> Shell.record<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">&quot;public void Main(string[] args)&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">recording...</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> using System;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> Console.WriteLien<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">&quot;I prototyped this in csharp shell!&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;</span>interactive<span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">1</span>,<span style="color: #000000;">10</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>: error CS0117: `System.Console<span style="color: #ff0000;">' does not contain a definition for `WriteLien'</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>tyler<span style="color: #000000; font-weight: bold;">/</span>basket<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>mono<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2.0</span><span style="color: #000000; font-weight: bold;">/</span>mscorlib.dll <span style="color: #7a0874; font-weight: bold;">&#40;</span>Location of the symbol related to previous error<span style="color: #7a0874; font-weight: bold;">&#41;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> Console.WriteLine<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">&quot;I prototyped this in csharp shell!&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> Shell.save_record<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">&quot;Hello.cs&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">recording saved to <span style="color: #ff0000;">&quot;Hello.cs&quot;</span></div></li></ol></pre></div>Which could conceptually generate the following file:<div class="geshifilter"><pre class="geshifilter-python"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">using System<span style="color: #66cc66;">;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">public <span style="color: #ff7700;font-weight:bold;">class</span> Hello</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: black;">&#123;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> public void Main<span style="color: black;">&#40;</span><span style="color: #dc143c;">string</span><span style="color: black;">&#91;</span><span style="color: black;">&#93;</span> args<span style="color: black;">&#41;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: black;">&#123;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> Console.<span style="color: black;">WriteLine</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;I prototyped this in csharp shell!&quot;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: black;">&#125;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: black;">&#125;</span></div></li></ol></pre></div></p> <h3>JavaScript Shell</h3> <p>In addition to the C# shell, I've been playing with <a href="http://code.google.com/p/v8/" target="_blank">v8</a>, the JavaScript engine that powers Google Chrome. The V8 engine is capable of being embedded easily, or running standalone, one of the examples they ship with is a JavaScript shell. I've created a little wrapper script to give me the ability to load jQuery into the V8 shell to prototype jQuery code without requiring a browser to be up and running:<br /> <div class="geshifilter"><pre class="geshifilter-bash"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">tyler<span style="color: #000000; font-weight: bold;">@</span>pineapple:~<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">source</span><span style="color: #000000; font-weight: bold;">/</span>v8<span style="color: #000000; font-weight: bold;">&gt;</span> .<span style="color: #000000; font-weight: bold;">/</span>shell</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">V8 version <span style="color: #000000;">0.3</span><span style="color: #000000;">.0</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&gt;</span> load<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">&quot;window-compat.js&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&gt;</span> load<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">&quot;jquery.js&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&gt;</span> $ = window.$</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">function</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>selector,context<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #7a0874; font-weight: bold;">return</span> new jQuery.fn.init<span style="color: #7a0874; font-weight: bold;">&#40;</span>selector,context<span style="color: #7a0874; font-weight: bold;">&#41;</span>;<span style="color: #7a0874; font-weight: bold;">&#125;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&gt;</span> x = <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">1</span>, <span style="color: #000000;">5</span>, <span style="color: #000000;">6</span>, <span style="color: #000000;">12</span>, <span style="color: #000000;">42</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000;">1</span>,<span style="color: #000000;">5</span>,<span style="color: #000000;">6</span>,<span style="color: #000000;">12</span>,<span style="color: #000000;">42</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&gt;</span> $.each<span style="color: #7a0874; font-weight: bold;">&#40;</span>x, <span style="color: #000000; font-weight: bold;">function</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>index<span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span> print<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">&quot;x[&quot;</span> + index + <span style="color: #ff0000;">&quot;] = &quot;</span> + this<span style="color: #7a0874; font-weight: bold;">&#41;</span>; <span style="color: #7a0874; font-weight: bold;">&#125;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">x<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">0</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> = <span style="color: #000000;">1</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">x<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> = <span style="color: #000000;">5</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">x<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">2</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> = <span style="color: #000000;">6</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">x<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">3</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> = <span style="color: #000000;">12</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">x<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">4</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> = <span style="color: #000000;">42</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000;">1</span>,<span style="color: #000000;">5</span>,<span style="color: #000000;">6</span>,<span style="color: #000000;">12</span>,<span style="color: #000000;">42</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&gt;</span> </div></li></ol></pre></div>The contents of "window-compat.js" being:<br /> <div class="geshifilter"><pre class="geshifilter-javascript"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #009900; font-style: italic;">/*</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #009900; font-style: italic;">&nbsp;* Providing stub &quot;window&quot; objects for jQuery</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #009900; font-style: italic;">&nbsp;*/</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span><span style="color: #66cc66;">&#40;</span>window<span style="color: #66cc66;">&#41;</span> == <span style="color: #3366CC;">'undefined'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> window = <span style="color: #003366; font-weight: bold;">new</span> Object<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> document = window;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> self = window;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> navigator = <span style="color: #003366; font-weight: bold;">new</span> Object<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> navigator.<span style="color: #006600;">userAgent</span> = navigator.<span style="color: #006600;">userAgent</span> <span style="color: #66cc66;">||</span> <span style="color: #3366CC;">'Chrome v8 Shell'</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> location = <span style="color: #003366; font-weight: bold;">new</span> Object<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> location.<span style="color: #006600;">href</span> = <span style="color: #3366CC;">'file:///dev/null'</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> location.<span style="color: #006600;">protocol</span> = <span style="color: #3366CC;">'file:'</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> location.<span style="color: #006600;">host</span> = <span style="color: #3366CC;">''</span>; </div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #66cc66;">&#125;</span>;</div></li></ol></pre></div></p> <p>In general I don't really have anything insightful or especially interesting to add, but I wanted to put out my "+1" in support of both of these projects. Making any language or API more easily accessible through these shells/interpreters can really help developers double-check syntax, expected API behavior etc. Thanks Novell/Google, interpreters rock!</p> http://unethicalblogger.com/posts/2008/09/resurgange_shell#comments JavaScript Mono Thu, 11 Sep 2008 07:57:36 +0000 R. Tyler Croy 186 at http://unethicalblogger.com Data Binding with jQuery http://unethicalblogger.com/posts/2008/04/data_binding_with_jquery <p>Since I've come from the land of desktop application development, there are a few concepts that I don't think quite "made the voyage" from desktop/thick-client development to web/thin-client development. The concept of "data binding" is completely lost in my opinion in the land of Javascript and HTML (not to mention the concept of "controls" to begin with).A few weeks ago while exploring a couple other concepts for how to improve our overall frontend development at <a href="http://slide.com" target="_blank">Slide</a> I prototyped a means of "databinding" controls, or at the very least DOM elements to data-providing Javascript functions.</p> <p>I've posted <a href="http://tyler.geekisp.com/binding.html" target="_blank">an example here</a> of some of the data binding code I've written for experimentation purposes. In the example page linked, there is a &lt;ul&gt; tag that is "bound" to a Javascript function, the Javascript function creates an array of associative arrays inline (it could very well be powered by some AJAX-oriented Javascript with minor adjustments). Using the results of the "databind" function specified on the bindable element, it creates a set of child nodes to attach to the parent list. In effect, the following code:<div class="geshifilter"><pre class="geshifilter-python"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #66cc66;">&lt;</span>script <span style="color: #008000;">type</span>=<span style="color: #483d8b;">&quot;text/javascript&quot;</span><span style="color: #66cc66;">&gt;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> var bindSimpleList = function<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> var simple_list = <span style="color: #dc143c;">new</span> Array<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> simple_list.<span style="color: black;">push</span><span style="color: black;">&#40;</span><span style="color: black;">&#123;</span><span style="color: #483d8b;">'contents'</span> : <span style="color: #483d8b;">'List Item #1 OMG'</span>, <span style="color: #483d8b;">'onclick'</span> : function<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span> alert<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;You clicked the first list item! lulz&quot;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span> <span style="color: black;">&#125;</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> simple_list.<span style="color: black;">push</span><span style="color: black;">&#40;</span><span style="color: black;">&#123;</span><span style="color: #483d8b;">'contents'</span> : <span style="color: #483d8b;">'List Item #2'</span>, <span style="color: #483d8b;">'style'</span> : <span style="color: #483d8b;">'border-bottom: 1px dashed red; width: 100px;'</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> simple_list.<span style="color: black;">push</span><span style="color: black;">&#40;</span><span style="color: black;">&#123;</span><span style="color: #483d8b;">'contents'</span> : <span style="color: #483d8b;">'&lt;strong&gt;List Item #3&lt;/strong&gt;'</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #ff7700;font-weight:bold;">return</span> simple_list<span style="color: #66cc66;">;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: black;">&#125;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #66cc66;">&lt;</span>/script<span style="color: #66cc66;">&gt;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #66cc66;">&lt;</span>ul <span style="color: #ff7700;font-weight:bold;">class</span>=<span style="color: #483d8b;">&quot;bindable&quot;</span> databind=<span style="color: #483d8b;">&quot;bindSimpleList&quot;</span> databindto=<span style="color: #483d8b;">&quot;li&quot;</span><span style="color: #66cc66;">&lt;</span>/ul<span style="color: #66cc66;">&gt;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #66cc66;">&lt;</span>/ul<span style="color: #66cc66;">&gt;</span></div></li></ol></pre></div>Will generate the following DOM tree, after the "<strong>bind()</strong>" function has been run on page load:<div class="geshifilter"><pre class="geshifilter-python"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #66cc66;">&lt;</span>ul <span style="color: #ff7700;font-weight:bold;">class</span>=<span style="color: #483d8b;">&quot;bindable&quot;</span> databind=<span style="color: #483d8b;">&quot;bindSimpleList&quot;</span> databindto=<span style="color: #483d8b;">&quot;li&quot;</span><span style="color: #66cc66;">&gt;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #66cc66;">&lt;</span>li onclick=<span style="color: #483d8b;">&quot;alert('You clicked the first list item! lulz');&quot;</span><span style="color: #66cc66;">&gt;</span>List Item <span style="color: #808080; font-style: italic;">#1 OMG&lt;/li&gt;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #66cc66;">&lt;</span>li style=<span style="color: #483d8b;">&quot;border-bottom: 1px dashed red; width: 100px;&quot;</span><span style="color: #66cc66;">&gt;</span>List Item <span style="color: #808080; font-style: italic;">#2&lt;/li&gt;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #66cc66;">&lt;</span>li<span style="color: #66cc66;">&gt;&lt;</span>strong<span style="color: #66cc66;">&gt;</span>List Item <span style="color: #808080; font-style: italic;">#3&lt;/strong&gt;&lt;/li&gt;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #66cc66;">&lt;</span>/ul<span style="color: #66cc66;">&gt;</span></div></li></ol></pre></div></p> <p>Since the code is relatively simple (in my opinion) I figured I would throw it out there in all it's minimalistic glory and get some general feedback on the concept before I go "all out" and create a full-on jQuery extension based off of the linked prototype above. I'm trying to think of ways to make it more powerful as well, built-in support for binding to the results of an asynchrounous call to a URL that returns JSON that would then create the elements is at the top of my TODO list at this point. Feedback, flames and actual useful critiques are all welcome; I'll be sure to post again once I have the time to create the jQuery extension for binding, this however is more experimental quality (i.e. don't use it, i'm not).</p> <p>What do you think?<br/></p> <hr/> <em>Did you know!</em> <a href="http://www.slide.com/static/jobs">Slide is hiring</a>! Looking for talented engineers to write some good Python and/or JavaScript, feel free to contact me at tyler[at]<a href="http://slide.com">slide</a><br /> <!--break--></p> http://unethicalblogger.com/posts/2008/04/data_binding_with_jquery#comments JavaScript Miscellaneous Slide Wed, 02 Apr 2008 14:52:38 +0000 R. Tyler Croy 175 at http://unethicalblogger.com Srsly ur doin it wrong. http://unethicalblogger.com/posts/2008/03/srsly_ur_doin_it_wrong <p>Via <a href="http://twitter.com" target="_blank">twitter</a> I have been <a href="http://twitter.com/agentdero/statuses/774638272" target="_blank">griping</a> <a href="http://twitter.com/agentdero/statuses/774813774" target="_blank">a bit</a> <a href="http://twitter.com/agentdero/statuses/775163974" target="_blank">about</a> <a href="http://twitter.com/agentdero/statuses/776116331" target="_blank">Javascript</a> recently. It's quite possible that I've been complaining about it far more than I complain about other things via twitter, which is a tall order to match.</p> <p>When addressing something as big and scary as say, <a href="http://code.google.com/apis/opensocial/" target="_blank">a platform built on Javascript</a>, it forces you into looking at Javascript in a way different than how I think most developers (myself included) have looked at Javascript. Most Javascript that I've seen has been hideous. Gobs and gobs of functions and procedural garbage thrown into a series of files that <em>kinda</em> makes sense, but really doesn't. It would seem that most developers charged with writing Javascript don't understand how to write object-oriented Javascript. In fact about two or three months ago when considering topics to discuss in a front-end developers meeting here at <a href="http://slide.com">Slide</a>, I bit the bullet, raised my hand and said "Can you explain how to do object-oriented Javascript? Because I honestly don't have a fucking clue."</p> <p>In the past Javascript that I've written has been to compliment existing backend web-application code and front-end code, i.e. I wasn't looking at Javascript as one of the building blocks of my application, I was looking at it as a bit of mortar spread between the cracks to smooth out the surface of the application. The difference in how you start to use Javascript in a web application makes an enormous difference 6 months to a year down the road. How <em>terrible</em> your code (this isn't actually segregated to Javascript) is becomes far more apparent when other developers start to work with your code as well, it's tremendously embarrassing to have to answer questions like "where's the code that generates that one DOM element?" As a general rule, coding all by your lonesome, especially with a tight schedule, will produce less than clean results (unfortunately Javascript is one of the languages I've found where this is more of the norm than the exception).</p> <p>A lot of what's driven the change from my Javascript being the mortar to being the bricks in my work has been the adoption of <a href="http://jquery.com/" target="_blank">jQuery</a> which I highly recommend along with the <a href="http://ui.jquery.com/" target="_blank">jQuery.ui</a> library. jQuery makes developing Javascript feel like <strong>actual programming</strong>, instead of hackish-scripting, which means you'll start to view your Javascript code differently too. Dealing with scoping issues, and prototype-based programming in Javascript isn't all rainbows and butterflies but "doing it right" will help you sleep at night and help reduce the amount of embarrassing questions you'll have to answer to the next poor unfortunate soul that inherits your code.</p> <p>Some of the resources I've found useful in getting over the barrier to object-oriented Javascript have been: <ul> <li>This <a href="http://developer.mozilla.org/en/docs/Introduction_to_Object-Oriented_JavaScript">Introduction to Object-Oriented Javascript</a> on the Mozilla Developer Center</li> <li>Almost anything <a href="http://ejohn.org/">John Resig</a> writes, especially gems like his recent post on <a href="http://ejohn.org/blog/simple-javascript-inheritance/">Simple Javascript Inheritance</a></li> <li>The code included in some <a href="http://prototypejs.org/download">mainstream</a> <a href="http://docs.jquery.com/Downloading_jQuery">javascript</a> <a href="http://developer.yahoo.com/yui/">libraries</a></li> </ul> <p>I'm still not a huge fan of Javascript, but I'm hating it less these days :)<br /> <!--break--></p> http://unethicalblogger.com/posts/2008/03/srsly_ur_doin_it_wrong#comments JavaScript Opinion Software Development Mon, 24 Mar 2008 11:18:53 +0000 R. Tyler Croy 173 at http://unethicalblogger.com Javascript Wonks: "missing : after property id" http://unethicalblogger.com/posts/2008/03/javascript_wonks_missing_after_property_id <p>I've been doing work with <a href="http://code.google.com/apis/opensocial/" target="_blank">OpenSocial</a> recently and have used the opportunity to bring my <strike>tolerance</strike> talent in Javascript up a notch or two. In doing so, I've been slowly but surely running into a myriad of browser-specific quirks along with a few cross-browser gems that have left me thinking about putting some browser developers on my "To Anonymously Beat Up In Alleyway" list (so far, <a href="http://en.wikipedia.org/wiki/James_Gosling" target="_blank">James Gosling</a>, and <a href="http://twitter.com/whurley" target="_blank">this man</a> top the list).</p> <p>After working on a few "classes" tonight (the notion that Javascript is object-oriented still makes me chuckle) I ran into an interesting problem with some of my global-level "constants" defined in the same file that I was working in, that my "class" just so happened to make use of. As I tend to do when I fall into situations like this to where I can't tell if I'm hallucinating or if something with Javascript has gone awry, I called over <a href="http://sergio.slide.com/" target="_blank">Sergio</a> (in-house CSS master and Javascript Lvl. 60 Mage).</p> <p><big><strong>Some background to how Javascript works</strong></big><br /> Javascript engines essentially have two "modes" that it runs over your code that you can spot errors in. The first mode, "<strong>parsing</strong>", is where you'll find syntax errors spewing into the Javascript console. If you've used any interpreted language before (Python, Java, C#, Ruby), this is really just "compilation". Using Python as an example, when you import a module (i.e. <span class="geshifilter"><code class="python geshifilter-python"><span style="color: #ff7700;font-weight:bold;">import</span> some_module</code></span>) the Python interpreter actually compiles your code into Python byte-code to be executed at a later date. The second mode, "<strong>execution</strong>", is where you'll run into your run-time errors, using an accessing an undefined object property, overrunning an array index, etc. In Python/Java terms, this is where your compiled byte-code is actually being run in the Python/Java virtual machine.</p> <p><big><strong>The gripe</strong></big><br /> The crux of the problem comes down to two different ways to declare an associative array in Javascript, the following two notations are both correct and both "work":<br /> <strong>Notation #1</strong><div class="geshifilter"><pre class="geshifilter-python"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">var mapped_values = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span><span style="color: #66cc66;">;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">mapped_values<span style="color: black;">&#91;</span><span style="color: #483d8b;">'key'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">'value'</span><span style="color: #66cc66;">;</span></div></li></ol></pre></div><br /> <strong>Notation #2</strong><div class="geshifilter"><pre class="geshifilter-python"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">var mapped_values = <span style="color: black;">&#123;</span><span style="color: #483d8b;">'key'</span> : <span style="color: #483d8b;">'value'</span><span style="color: black;">&#125;</span><span style="color: #66cc66;">;</span></div></li></ol></pre></div><br /> Everything looks correct yes? (hint: <strong><em>say yes</em></strong>)<br /> <br/><br /> <!--break--><br /> Incorrect, because of the point at which the two are evaluated. The first example will be notated at run-time, whereas the second example will be evaluated at parse/compile-time. Who cares right? <img src="http://tyler.geekisp.com/images/noooo_birds.jpg" height="150" align="right"/>The distinction becomes much more apparent when you start to use references to <em>other</em> code for your keys. Keep in mind, with both notations it is actually valid to have a key "undefined" when you declare your associative array. For example:<br clear="all"/><br /> <strong>Notation #1</strong><div class="geshifilter"><pre class="geshifilter-python"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">/<span style="color: #66cc66;">*</span> the variable <span style="color: #483d8b;">&quot;foo&quot;</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> defined <span style="color: #66cc66;">*</span>/</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">var mapped_values = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span><span style="color: #66cc66;">;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">mapped_values<span style="color: black;">&#91;</span>foo<span style="color: black;">&#93;</span> = <span style="color: #483d8b;">'value'</span><span style="color: #66cc66;">;</span></div></li></ol></pre></div><br /> <strong>Notation #2</strong><div class="geshifilter"><pre class="geshifilter-python"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">/<span style="color: #66cc66;">*</span> the variable <span style="color: #483d8b;">&quot;foo&quot;</span> <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> defined <span style="color: #66cc66;">*</span>/</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">var mapped_values = <span style="color: black;">&#123;</span> foo : <span style="color: #483d8b;">'value'</span> <span style="color: black;">&#125;</span><span style="color: #66cc66;">;</span></div></li></ol></pre></div></p> <p>This still works perfectly fine, both at parse/compile-time and at run-time. Since I mentioned I'm working on OpenSocial, chances are I'm going to need to reference some of the OpenSocial code. So for the next example let's say I need to create an associative array with one of the keys defined by the OpenSocial container, using the two different notations I would write something like:<br /> <strong>Notation #1</strong><div class="geshifilter"><pre class="geshifilter-python"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">var mapped_values = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span><span style="color: #66cc66;">;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">mapped_values<span style="color: black;">&#91;</span>opensocial.<span style="color: black;">DataRequest</span>.<span style="color: black;">PeopleRequestFields</span>.<span style="color: black;">FILTER</span><span style="color: black;">&#93;</span> = opensocial.<span style="color: black;">DataRequest</span>.<span style="color: black;">FilterType</span>.<span style="color: black;">ALL</span><span style="color: #66cc66;">;</span></div></li></ol></pre></div><br /> <strong>Notation #2</strong><div class="geshifilter"><pre class="geshifilter-python"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">var mapped_values = <span style="color: black;">&#123;</span>opensocial.<span style="color: black;">DataRequest</span>.<span style="color: black;">PeopleRequestFields</span>.<span style="color: black;">FILTER</span> : opensocial.<span style="color: black;">DataRequest</span>.<span style="color: black;">FilterType</span>.<span style="color: black;">ALL</span><span style="color: black;">&#125;</span><span style="color: #66cc66;">;</span></div></li></ol></pre></div></p> <p>Because of the different points in time at which the two notations above will be evaluated, #1 will properly "compile" and then execute correctly when called (regardless of the scope-level at which it is defined). The second one however, will fail to "compile" when the browser's rendering engine is loading the Javascript (also regardless of the scope-level at which it is defined), and will result in the following error at load-time:<br /> <center><strong>"<big>missing : after property id</big>"</strong><br/><small>(verified in both IE6 and Firefox)</small></center></p> <p>The issue here is that the variable "opensocial" is not defined at "compile-time" as far as the Javascript engine is concerned (which is fine) but the code attempts to access a property of that object, which causes the error at "compile-time". This will error at at *any* level (as far as I've tried) so it's not a scoping issue, just an unfortunate fact of life with how Javascript is loaded and eventually executed in the browser.</p> <p>Sergio and I tried a few more examples (the scope of which was in side a function, not at the global level):<br /> <div class="geshifilter"><pre class="geshifilter-python"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">// Works <span style="color: #ff7700;font-weight:bold;">in</span> IE/FF</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">var <span style="color: #dc143c;">test</span> = <span style="color: black;">&#123;</span> magic : <span style="color: #483d8b;">'thing'</span> <span style="color: black;">&#125;</span><span style="color: #66cc66;">;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">var test2 = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span><span style="color: #66cc66;">;</span> </div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">test2<span style="color: black;">&#91;</span>rick.<span style="color: black;">roll</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">'thing'</span><span style="color: #66cc66;">;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">test2<span style="color: black;">&#91;</span>alert<span style="color: black;">&#93;</span> = <span style="color: #483d8b;">'somethingelse'</span><span style="color: #66cc66;">;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">var test3 = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span><span style="color: #66cc66;">;</span> </div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">test3<span style="color: black;">&#91;</span>function<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span> alert<span style="color: black;">&#40;</span><span style="color: #483d8b;">'sux'</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span> <span style="color: black;">&#125;</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">'test'</span><span style="color: #66cc66;">;</span></div></li></ol></pre></div></p> <p><div class="geshifilter"><pre class="geshifilter-python"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">// Fail <span style="color: #ff7700;font-weight:bold;">in</span> IE/FF</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">var test4 =<span style="color: black;">&#123;</span> opensocial<span style="color: black;">&#91;</span><span style="color: #483d8b;">'DataRequest'</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'PeopleRequestFields'</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'FILTER'</span><span style="color: black;">&#93;</span> : opensocial<span style="color: black;">&#91;</span><span style="color: #483d8b;">'DataRequest'</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'FilterType'</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'ALL'</span><span style="color: black;">&#93;</span><span style="color: black;">&#125;</span> <span style="color: #66cc66;">;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">var test5 = <span style="color: black;">&#123;</span> rick<span style="color: black;">&#91;</span><span style="color: #483d8b;">'roll'</span><span style="color: black;">&#93;</span> : <span style="color: #483d8b;">'thing'</span><span style="color: black;">&#125;</span><span style="color: #66cc66;">;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">var test6 = <span style="color: black;">&#123;</span> rick.<span style="color: black;">roll</span> : <span style="color: #483d8b;">'thing'</span><span style="color: black;">&#125;</span><span style="color: #66cc66;">;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">var test7 = <span style="color: black;">&#123;</span> function<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span> alert<span style="color: black;">&#40;</span><span style="color: #483d8b;">'sux'</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span> <span style="color: black;">&#125;</span> : <span style="color: #483d8b;">'test'</span><span style="color: black;">&#125;</span><span style="color: #66cc66;">;</span></div></li></ol></pre></div></p> <p>Object accessor calls work in "test2" for example because that's going to be evaluated at run-time instead of at compile-time, as is happening in "test5" and "test6". I would love to be proven wrong on our analysis of the issue here (our tests were less than scientific, and there may have been Corona involved) but switching from inline-declarations for associative arrays (<span class="geshifilter"><code class="python geshifilter-python">var t = <span style="color: black;">&#123;</span><span style="color: #483d8b;">'k'</span> : <span style="color: #483d8b;">'v'</span><span style="color: black;">&#125;</span><span style="color: #66cc66;">;</span></code></span>) to the more sequential alternative (<span class="geshifilter"><code class="python geshifilter-python">var t = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span><span style="color: #66cc66;">;</span> t<span style="color: black;">&#91;</span><span style="color: #483d8b;">'k'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">'v'</span><span style="color: #66cc66;">;</span></code></span>) solved the issue of the Javascript engine's parser spewing errors on the loading of the Javascript.</p> <p>Food for thought I suppose.</p> http://unethicalblogger.com/posts/2008/03/javascript_wonks_missing_after_property_id#comments JavaScript Miscellaneous Slide Software Development Fri, 21 Mar 2008 09:33:06 +0000 R. Tyler Croy 170 at http://unethicalblogger.com