<?xml version="1.0" encoding="UTF-8"?> <rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
><channel><title>stephenwoods.net</title> <atom:link href="http://stephenwoods.net/feed/" rel="self" type="application/rss+xml" /><link>http://stephenwoods.net</link> <description>!important</description> <lastBuildDate>Tue, 09 Mar 2010 08:05:06 +0000</lastBuildDate> <generator>http://wordpress.org/?v=2.9.2</generator> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <item><title>I&#8217;m just a simple hyperchicken from a backwood asteroid&#8230;</title><link>http://stephenwoods.net/2010/03/09/im-just-a-simple-hyperchicken-from-a-backwood-asteroid/</link> <comments>http://stephenwoods.net/2010/03/09/im-just-a-simple-hyperchicken-from-a-backwood-asteroid/#comments</comments> <pubDate>Tue, 09 Mar 2010 07:51:54 +0000</pubDate> <dc:creator>Stephen</dc:creator> <category><![CDATA[Uncategorized]]></category><guid
isPermaLink="false">http://stephenwoods.net/2010/03/09/im-just-a-simple-hyperchicken-from-a-backwood-asteroid/</guid> <description><![CDATA[&#8230;but I don&#8217;t think ORM is very useful. I would say that for hacking together a very simple crud interface in rails/django/whatever its really nice. But in the end, if your app has a database you ought to be writing your own queries.
UPDATE: This is a great answer to this post.
]]></description> <content:encoded><![CDATA[<p>&#8230;but I don&#8217;t think ORM is very useful. I would say that for hacking together a very simple crud interface in rails/django/whatever its really nice. But in the end, if your app has a database you ought to be writing your own queries.</p><p>UPDATE: <a
href="http://www.b-list.org/weblog/2006/jul/04/javascript-orm-and-hding-sql/">This</a> is a great answer to this post.</p> ]]></content:encoded> <wfw:commentRss>http://stephenwoods.net/2010/03/09/im-just-a-simple-hyperchicken-from-a-backwood-asteroid/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Run-time Code Generation</title><link>http://stephenwoods.net/2010/03/03/run-time-code-generation/</link> <comments>http://stephenwoods.net/2010/03/03/run-time-code-generation/#comments</comments> <pubDate>Wed, 03 Mar 2010 19:30:55 +0000</pubDate> <dc:creator>Stephen</dc:creator> <category><![CDATA[Uncategorized]]></category><guid
isPermaLink="false">http://stephenwoods.net/?p=159</guid> <description><![CDATA[I was speaking with my colleague Matt about refactoring Javascript. One of the most common &#8220;smells&#8221; in code, or at least in my code, is duplication. A really common one for me to see several event handlers or callback functions that all do the same thing, but in ever so slightly different cases. This came [...]]]></description> <content:encoded><![CDATA[<p>I was speaking with my colleague <a
href="http://twitter.com/rhyolight">Matt</a> about refactoring Javascript. One of the most common &#8220;smells&#8221; in code, or at least in my code, is duplication. A really common one for me to see several event handlers or callback functions that all do the same thing, but in ever so slightly different cases. This came up most recently when I was hacking together a routing module for a node.js project.<br
/> <span
id="more-159"></span><br
/> Because js is functional I had the idea of routes actually being an array of functions that took a request object and returned a route object. Pretty powerful, you could have routing based on anything, not just urls. Anyway, what actually ended up happening was this:</p><pre class="brush: js">
var routes = [

    /* / */
    function(request){
        if(/^\/$/.test(url.parse(request.url).pathname)){
            return {
                controller:'index',
                action:'index',
                data:{}
            };
        }else{
            return false;
        }
    },

    /* /about */
    function(request){
        if(/^\/about$/.test(url.parse(request.url).pathname)){
            return {
                controller:'index',
                action:'about',
                data:{}
            };
        }else{
            return false;
        }
    },

    /* /news/story/[0-9] */
    function(request){
        var test = /^\/news\/story\/([0-9]+)$/
                    .exec(url.parse(request.url).pathname);

        if(test){
            return {
                controller:'news',
                action:'showStory',
                data:{
                    storyId:test[1]
                }
            };
        }else{
            return false;
        }
    }
];
</pre><p>As you can see, I&#8217;ve written the same function twice at the top, more or less. Now there are a couple of ways to refactor this. The obvious one of course is to have the function which acts on this array check if the input is an object or a function and act accordingly, so that the route could just be an object with a regex and info about the action and controller. I decided not to go with this option because I like to avoid code with lots of switching and cases if possible, just running the function seems much cleaner to me.</p><p>So instead I created a function that would create the most common case functions. That way I could write my routes like this:</p><pre class="brush: js">
var routes = [

    /* / */
    r(/^\/$/, 'index', 'index'),

    /* /about */
    r(/^\/about$/, 'index', 'about', {foo:'bar'}),

    /* /news/story/[0-9] */
    function(request){
        var test = /^\/news\/story\/([0-9]+)$/
                    .exec(url.parse(request.url).pathname);

        if(test){
            return {
                controller:'news',
                action:'showStory',
                data:{
                    storyId:test[1]
                }
            };
        }else{
            return false;
        }
    }
];
</pre><p>Much cleaner, just as flexible, and to the caller it looks exactly the same, because the function &#8216;r&#8217; returns a function that looks like the one I created for the news story, like so (I also added the feature that query variables would be added to the data object):</p><pre class="brush: js">
function r(regex, controller, action, data){
    var exp = regex,
    d=data || false,
    ret = {
        controller:controller,
        action:action || 'index'
    };

    return function(request){
        var uri = url.parse(request.url, true);
        if(exp.test(uri.pathname)){

            //get the query string and add it to the data
            var retData = uri.query || {};
            if(d){
                for(var i in d){
                    retData[i] = d[i];
                }
            }

            ret.data = retData;

            return ret;

        }else{
            return false;
        }
    };
};
</pre>]]></content:encoded> <wfw:commentRss>http://stephenwoods.net/2010/03/03/run-time-code-generation/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Timepicker on the YUI blog</title><link>http://stephenwoods.net/2010/03/03/timepicker-on-the-yui-blog/</link> <comments>http://stephenwoods.net/2010/03/03/timepicker-on-the-yui-blog/#comments</comments> <pubDate>Wed, 03 Mar 2010 18:54:39 +0000</pubDate> <dc:creator>Stephen</dc:creator> <category><![CDATA[Uncategorized]]></category><guid
isPermaLink="false">http://stephenwoods.net/2010/03/03/timepicker-on-the-yui-blog/</guid> <description><![CDATA[I have a post up on the YUI blog. Check it out.
]]></description> <content:encoded><![CDATA[<p>I have a <a
href="http://www.yuiblog.com/blog/2010/03/03/gallery-timepicker/">post</a> up on the YUI blog. Check it out.</p> ]]></content:encoded> <wfw:commentRss>http://stephenwoods.net/2010/03/03/timepicker-on-the-yui-blog/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Automatically Erase Data from your iPhone</title><link>http://stephenwoods.net/2010/02/23/iphone-security-basics/</link> <comments>http://stephenwoods.net/2010/02/23/iphone-security-basics/#comments</comments> <pubDate>Tue, 23 Feb 2010 19:14:22 +0000</pubDate> <dc:creator>Stephen</dc:creator> <category><![CDATA[Uncategorized]]></category><guid
isPermaLink="false">http://stephenwoods.net/?p=151</guid> <description><![CDATA[(This is in response to the rash of iphone thefts)
People like to steal iphones. Its a fact of life. For the most part they just want to sell the phone without your sim card or your data. However, if you are like me you keep a lot of stuff on your phone&#8230;a contact list of [...]]]></description> <content:encoded><![CDATA[<p>(This is in response to the <a
href="http://sfist.com/2010/02/23/stay_safe_smartphone_users.php">rash of iphone thefts</a>)</p><p>People like to steal iphones. Its a fact of life. For the most part they just want to sell the phone without your sim card or your data. However, if you are like me you keep a lot of stuff on your phone&#8230;a contact list of course, but more importantly you keep your email on it. Also of course a thief could use it to call their best friend far away for free. To prevent this phones have always had the feature of a passcode, which you should be using already on your iphone. At some point in the recent past apple added an even more useful feature: you can set it so that the phone erases itself after 10 incorrect passcode entries.</p><p>To enable this setting follow these steps:<br
/> <span
id="more-151"></span></p><p>Go to general settings:<br
/> <img
src="http://img.skitch.com/20100223-xan8qd6gewp4sn19u6xjxn4x58.png" alt="step1"/></p><p>Click on &#8220;Passcode Lock&#8221;<br
/> <img
src="http://img.skitch.com/20100223-1y7r9kkbgegttmgqd5nu8a9ttj.png" alt="step2"/></p><p>Enter a passcode you won&#8217;t forget, then set &#8220;Erase Data&#8221; to on.<br
/> <img
src="http://img.skitch.com/20100223-ni7rk24kexyp8muf2gxua8hj4s.png" alt="Turn on Erase Data" /></p><p>Then you should be pretty much only out an iphone when it gets stolen. Still sucks, but not as bad.</p> ]]></content:encoded> <wfw:commentRss>http://stephenwoods.net/2010/02/23/iphone-security-basics/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Learning Python</title><link>http://stephenwoods.net/2010/02/21/learning-python/</link> <comments>http://stephenwoods.net/2010/02/21/learning-python/#comments</comments> <pubDate>Sun, 21 Feb 2010 07:05:07 +0000</pubDate> <dc:creator>Stephen</dc:creator> <category><![CDATA[Uncategorized]]></category><guid
isPermaLink="false">http://stephenwoods.net/?p=133</guid> <description><![CDATA[I&#8217;m taking the time to pick up python right now. So far I like it, very straightforward, has everything I want in a language. One of the things I do when I pick a new language is re-implement the very first program I wrote when learning how to program my calculator in High School. Its [...]]]></description> <content:encoded><![CDATA[<p>I&#8217;m taking the time to pick up python right now. So far I like it, very straightforward, has everything I want in a language. One of the things I do when I pick a new language is re-implement the very first program I wrote when learning how to program my calculator in High School. Its a very advanced piece of technology that &#8220;tosses coins&#8221;. Anyway, usually figuring out how to do it in a new language is a quick way to get the hang of the syntax and basics. Anyway, I did it today in php, python, c and JavaScript. Then for the heck of it I tested all three to see which was faster at flipping a coin a million times.<br
/> <span
id="more-133"></span></p><p>The results annoyed the crap out of me. I want to hate php. I want to break free of php. But it keeps pulling me back in. In a battle between php and python in the field of coin tossing, php mops the floor with python. The php script was six times faster (587ms vs 3075ms). But the python script was much more pleasant to write, for what its worth.</p><p>I wasn&#8217;t at all surprised by how well JavaScript (running in Node/V8) performed. The js script did the job in 123ms, better than 2x the php script. The C program took 40ms.</p><p>Obviously this is not a real test in any way, but the results were interesting:</p><pre>
> time ./toss.php
Heads: 501211
Tails: 498789

real	0m0.587s
user	0m0.555s
sys	0m0.015s

> time ./toss.py
{'tails': 500309, 'heads': 499691}

real	0m3.075s
user	0m2.989s
sys	0m0.052s

> time ./a.out
heads=  499798, tails= 500202

real	0m0.040s
user	0m0.027s
sys	0m0.002s

> time ./flip.js
{"heads":500140,"tails":499860}

real	0m0.123s
user	0m0.111s
sys	0m0.009s
</pre><p>Anyway, here is the code, my apologies if the C and python are ugly, I&#8217;m new to both:</p><p>PHP:</p><pre class="brush: php">
#!/usr/bin/php
&lt;?php
function getRandom(){
	return rand(0,1);
}
$num = 1000000;
$heads = 0;
$tails = 0;

for($i=0; $i &lt; $num; $i++){
	$t = getRandom();
	if($t){
		$heads++;
	}else{
		$tails++;
	}
}
echo(&quot;Heads: $heads\nTails: $tails\n&quot;);
</pre><p>And in Python:</p><pre class="brush: python">
#!/usr/bin/python
import random
rand = random.Random()
results = {&quot;heads&quot;:0, &quot;tails&quot;:0}
num = 1000000
def toss():
	return rand.randint(0,1)

for i in range(0, num):
	if toss():
		results[&apos;heads&apos;] += 1
	else:
		results[&apos;tails&apos;] += 1

print results
</pre><p>C:</p><pre class="brush: c">
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;time.h&gt;
int main (int argc, char *argv[])
{
  unsigned int iseed = (unsigned int)time(NULL);
  srand (iseed);

  int i, num, heads, tails;
  for (i=0; i&lt;1000000; i++)
  {

	num = rand() %10;
	if(num &gt; 4){
		tails++;
	}else{
		heads++;
	}

  }
	printf (&quot;heads=  %d, tails= %u&quot;, heads, tails);
  return 0;
}
</pre><p>Javascript:</p><pre class="brush: js">
#!/usr/local/bin/node
var sys = require(&quot;sys&quot;);

var i, len=1000000, floor=Math.floor, rand=Math.random;

function toss()
{
  return floor(rand() * 2) % 2;
}

var results = {heads:0,tails:0};

for(i =0; i &lt; len; i++ ){
	if(toss()){
		results.tails++;
	}else{
		results.heads++;
	}
}

sys.puts(JSON.stringify(results));
</pre><p>(<a
href="http://foohack.com/">Isaac</a> contributed a few performance suggestions for c and javascript. I had a bug with the c one, so I ignored it)</p> ]]></content:encoded> <wfw:commentRss>http://stephenwoods.net/2010/02/21/learning-python/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>A few quick updates.</title><link>http://stephenwoods.net/2009/11/02/a-few-quick-updates/</link> <comments>http://stephenwoods.net/2009/11/02/a-few-quick-updates/#comments</comments> <pubDate>Mon, 02 Nov 2009 19:12:13 +0000</pubDate> <dc:creator>Stephen</dc:creator> <category><![CDATA[Uncategorized]]></category><guid
isPermaLink="false">http://stephenwoods.net/?p=129</guid> <description><![CDATA[I had a busy week last week with YUIConf, the launch of the YUI Gallery and a trip back to Denver to see my parents.
Timepicker available on YUI Gallery
First things first, my YUI Timepicker widget is now part of the gallery. That means you can use it straight of the Yahoo CDN with a [...]]]></description> <content:encoded><![CDATA[<p>I had a busy week last week with <a
href="http://yuilibrary.com/yuiconf2009/">YUIConf</a>, the launch of the YUI Gallery and a trip back to Denver to see my parents.</p><h4>Timepicker available on YUI Gallery</h4><p>First things first, my YUI Timepicker widget is now <a
href="http://yuilibrary.com/gallery/show/timepicker">part of the gallery.</a> That means you can use it straight of the Yahoo CDN with a Y.use() statement. Please check it out and file bugs, feature requests, or go ahead and <a
href="http://github.com/saw/yui3-gallery">fork on github</a> and add the features yourself!</p><h4>YUI Doc Talk on Slideshare</h4><p>My talk on YUI Doc from YUI Conf is <a
href="http://www.slideshare.net/ysaw/beautiful-documentation-with-yui-doc">now on slideshare</a>. Please check it out, I have a video of the talk, but I am going to wait until its uploaded to the YUI Gallery before I post it.</p><h4>Still looking for a few good Javascripters</h4><p>We haven&#8217;t filled all our openings yet, but we have been getting great responses from the YUI Blog post. If you want to work at yahoo, please, <a
href="http://careers.yahoo.com/jdescription.php?oid=21972">send us those resumes!</a></p><h4><strong>UPDATE</strong></h4><p>Video is <a
href="http://developer.yahoo.com/yui/theater/video.php?v=woods-yuiconf2009-yuidoc">available here.</a></p> ]]></content:encoded> <wfw:commentRss>http://stephenwoods.net/2009/11/02/a-few-quick-updates/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>YUI Doc</title><link>http://stephenwoods.net/2009/10/28/yui-doc/</link> <comments>http://stephenwoods.net/2009/10/28/yui-doc/#comments</comments> <pubDate>Wed, 28 Oct 2009 20:48:46 +0000</pubDate> <dc:creator>Stephen</dc:creator> <category><![CDATA[Uncategorized]]></category><guid
isPermaLink="false">http://stephenwoods.net/?p=125</guid> <description><![CDATA[I am presenting on YUI Doc tomorrow at YUIConf. This is an excellent language neutral tool for generating documentation from comments, I highly recommend you check it out.
I cover the tool, some pest practices, etc. I&#8217;ll post the video as soon as its available, but in the meantime I have create a project on [...]]]></description> <content:encoded><![CDATA[<p>I am presenting on <a
href="http://developer.yahoo.com/yui/yuidoc/">YUI Doc</a> tomorrow at <a
href="http://yuilibrary.com/yuiconf2009/">YUIConf</a>. This is an excellent language neutral tool for generating documentation from comments, I highly recommend you check it out.</p><p>I cover the tool, some pest practices, etc. I&#8217;ll post the video as soon as its available, but in the meantime I have create a project on github that shows you a simple example of using YUI Doc as part of your build.</p><p><a
href="http://github.com/saw/YUI-Doc-Example">Get it here.</a></p> ]]></content:encoded> <wfw:commentRss>http://stephenwoods.net/2009/10/28/yui-doc/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Jobs at Yahoo!</title><link>http://stephenwoods.net/2009/10/16/jobs-at-yahoo/</link> <comments>http://stephenwoods.net/2009/10/16/jobs-at-yahoo/#comments</comments> <pubDate>Fri, 16 Oct 2009 17:46:42 +0000</pubDate> <dc:creator>Stephen</dc:creator> <category><![CDATA[Uncategorized]]></category><guid
isPermaLink="false">http://stephenwoods.net/2009/10/16/jobs-at-yahoo/</guid> <description><![CDATA[Yahoo! is looking for a few good frontend engineers&#8230;and I&#8217;m looking for one of them.
Check it out, send a resume, come work for us!
]]></description> <content:encoded><![CDATA[<p>Yahoo! is looking for a few good frontend engineers&#8230;and I&#8217;m looking for one of them.</p><p><a
href="http://www.yuiblog.com/blog/2009/10/16/f2e-jobs-091016/">Check it out</a>, send a resume, come work for us!</p> ]]></content:encoded> <wfw:commentRss>http://stephenwoods.net/2009/10/16/jobs-at-yahoo/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Awesome on OS X, Ratpoison on RHEL 5: Staying focused</title><link>http://stephenwoods.net/2009/10/14/awesome-on-os-x-ratpoison-on-rhel-5-staying-focused/</link> <comments>http://stephenwoods.net/2009/10/14/awesome-on-os-x-ratpoison-on-rhel-5-staying-focused/#comments</comments> <pubDate>Wed, 14 Oct 2009 22:30:18 +0000</pubDate> <dc:creator>Stephen</dc:creator> <category><![CDATA[Uncategorized]]></category><guid
isPermaLink="false">http://stephenwoods.net/?p=121</guid> <description><![CDATA[I spend a lot of time trying to stay focused on the task at hand. But with the joys of multitasking I generally have a lot of crap going on the desktop. Several documents open in text mate, an IM conversation and multiple tabs in the terminal:So I am always looking for ways to improve [...]]]></description> <content:encoded><![CDATA[<p>I spend a lot of time trying to stay focused on the task at hand. But with the joys of multitasking I generally have a lot of crap going on the desktop. Several documents open in text mate, an IM conversation and multiple tabs in the terminal:</p><p><img
title="Hugemess" src="http://img.skitch.com/20091014-tdbi2ihnnadb9itb3sm592bk4k.jpg" alt="a picture of all the things on my desktop" width="565" height="357" /></p><p>So I am always looking for ways to improve this situation. Lately two (or rather three) great tools have changed things quite a bit. First is <a
href="http://willmore.eu/software/isolator/">Isolator</a>, an incredibly useful little app that hides everything but the app you are using behind a little screen, which can be activated with a keyboard shortcut.</p><p>I have also been converted to the joys of a tiling window manager by a coworker. I installed awesomewm on my mac via macports, and Ratpoison on my RHEL 5 box (awesome is not available from yum for rhel 5). That way I can do all my terminal stuff with no distraction, and its great to have multiple terminals running together. Here is my workspace at work now:<br
/> <img
alt="A picture of my new workspace." src="http://img.skitch.com/20091014-jxmus8n6sikyddbci83nrwb8ne.jpg" title="My workspace" width="496" height="372" /></p> ]]></content:encoded> <wfw:commentRss>http://stephenwoods.net/2009/10/14/awesome-on-os-x-ratpoison-on-rhel-5-staying-focused/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>LZW Compression in Javascript: Why not?</title><link>http://stephenwoods.net/2009/10/03/lzw-compression-in-javascript-why-not/</link> <comments>http://stephenwoods.net/2009/10/03/lzw-compression-in-javascript-why-not/#comments</comments> <pubDate>Sun, 04 Oct 2009 01:45:44 +0000</pubDate> <dc:creator>Stephen</dc:creator> <category><![CDATA[Uncategorized]]></category><guid
isPermaLink="false">http://stephenwoods.net/?p=112</guid> <description><![CDATA[I enjoyed this very interesting post on ydn. The post is about the benefit of reducing the number of packets, not just the total file size. More interesting to me was this small note:
If your app sends largish amounts of data upstream (excluding images, which are already compressed), consider implementing client-side compression. It&#8217;s possible to [...]]]></description> <content:encoded><![CDATA[<p>I enjoyed <a
href="http://developer.yahoo.net/blog/archives/2009/10/a_engineers_gui.html">this very interesting post</a> on ydn. The post is about the benefit of reducing the number of packets, not just the total file size. More interesting to me was this small note:</p><blockquote><p>If your app sends largish amounts of data upstream (excluding images, which are already compressed), consider implementing client-side compression. It&#8217;s possible to get 1.5:1 compression with a simple LZW+Base64 function; if you&#8217;re willing to monkey with ActionScript you could probably do real gzip compression.</p></blockquote><p>So to try this out I implemented LZW compression in javascript, except instead of using Base64, which adds more complexity to encoding and inflates the file size quite a bit, I used a trick I&#8217;ve seen elsewhere: use the unicode character equivalent to the decimal code output by the LZW algorithm. For the example I used the first 256 first characters in the unicode set as the allowed characters. This breaks any non-latin script for this example, but this proves the concept. I was able to get decent compression. Using the 800 byte example string I got the output down to 705 bytes. In firefox encoding took around 2.38ms, and decoding took a little less. In safari encoding only took .83 milliseconds.</p><p>Not sure if this is really worth it or not, but its a cool thing to try out. I think in general just reducing the size of upstream data when possible is probably worth it, but like everything only testing will really say for sure.</p><p>Checkout my <a
href="/demos/lzw/lzw.html">example here.</a> And <a
href="http://github.com/saw/JS_LZW">get the code here.<br
/> </a></p> ]]></content:encoded> <wfw:commentRss>http://stephenwoods.net/2009/10/03/lzw-compression-in-javascript-why-not/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> </channel> </rss>
<!-- This site's performance optimized by W3 Total Cache. Dramatically improve the speed and reliability of your blog!

Learn more about our WordPress Plugins: http://www.w3-edge.com/wordpress-plugins/

Minified using apc
Page Caching using apc (user agent is rejected)
Database Caching 3/9 queries in 0.000 seconds using apc

Served from: 67-23-6-153.static.slicehost.net @ 2010-03-11 23:43:54 -->