<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet href="/templates/default/atom.css" type="text/css" ?>

<feed 
   xmlns="http://www.w3.org/2005/Atom"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:admin="http://webns.net/mvcb/"
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
   xmlns:wfw="http://wellformedweb.org/CommentAPI/">
    <link href="http://blog.codekills.net/feeds/atom10.xml" rel="self" title="Code Kills" type="application/atom+xml" />
    <link href="http://blog.codekills.net/"                        rel="alternate"    title="Code Kills" type="text/html" />
    <link href="http://blog.codekills.net/rss.php?version=2.0"     rel="alternate"    title="Code Kills" type="application/rss+xml" />
    <title type="html">Code Kills</title>
    <subtitle type="html"></subtitle>
    <icon>http://blog.codekills.net/templates/default/img/s9y_banner_small.png</icon>
    <id>http://blog.codekills.net/</id>
    <updated>2010-02-19T20:35:09Z</updated>
    <generator uri="http://www.s9y.org/" version="1.1.3">Serendipity 1.1.3 - http://www.s9y.org/</generator>
    <dc:language>en</dc:language>
    <admin:errorReportsTo rdf:resource="mailto:david@wolever.net" />

    <entry>
        <link href="http://blog.codekills.net/archives/80-Absolute-paths-must-die.html" rel="alternate" title="Absolute paths must die" />
        <author>
            <name>David Wolever</name>
            <email>david@wolever.net</email>
        </author>
    
        <published>2010-02-13T22:23:22Z</published>
        <updated>2010-02-19T20:35:09Z</updated>
        <wfw:comment>http://blog.codekills.net/wfwcomment.php?cid=80</wfw:comment>
    
        <slash:comments>1</slash:comments>
        <wfw:commentRss>http://blog.codekills.net/rss.php?version=atom1.0&amp;type=comments&amp;cid=80</wfw:commentRss>
    
            <category scheme="http://blog.codekills.net/categories/6-Python" label="Python" term="Python" />
    
        <id>http://blog.codekills.net/archives/80-guid.html</id>
        <title type="html">Absolute paths must die</title>
        <content type="xhtml" xml:base="http://blog.codekills.net/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>Ok guys, it's pretty simple: if you're working in a Turing-complete environment and you've got paths which start with a '/', you're doing it wrong. <strong>Very wrong!</strong></p>

<p>Todays offender: <a href="http://www.wsgi.org/wsgi/">WSGI</a> scripts.</p>

<p>Here's the first line of a common WSGI script:</p>

<pre><code>app_path = '/path/to/application'</pre>

<p></code></p>

<p>See a problem there? That's right, the <strong>absolute path</strong>!</p>

<p>How could this be solved? Simple: put the WSGI script <em>in</em> <code>/path/to/application</code>, then get the <code>app_path</code> using: <code>app_path=os.path.abspath(os.path.dirname(__file__))</code>. Problem solved.</p>

<p>&lt;/rant></p>
 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://blog.codekills.net/archives/79-A-Parameterized-Testrunner-for-FlexUnit.html" rel="alternate" title="A Parameterized Testrunner for FlexUnit" />
        <author>
            <name>David Wolever</name>
            <email>david@wolever.net</email>
        </author>
    
        <published>2010-02-10T15:54:08Z</published>
        <updated>2010-02-10T16:57:48Z</updated>
        <wfw:comment>http://blog.codekills.net/wfwcomment.php?cid=79</wfw:comment>
    
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://blog.codekills.net/rss.php?version=atom1.0&amp;type=comments&amp;cid=79</wfw:commentRss>
    
            <category scheme="http://blog.codekills.net/categories/16-ActionScript" label="ActionScript" term="ActionScript" />
    
        <id>http://blog.codekills.net/archives/79-guid.html</id>
        <title type="html">A Parameterized Testrunner for FlexUnit</title>
        <content type="xhtml" xml:base="http://blog.codekills.net/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>A couple of days ago, I <a href="http://blog.codekills.net/archives/77-FlexUnits-Test-Theories-Dont-Bother.html">complained about FlexUnit's Theories</a>. Well, with a bit of encouragement from <a href="http://twitter.com/drewbourne">@drewbourne</a>, I broke down and wrote a proper parameterized testrunner:</p>

<pre style="margin-top: -1.5em"><code>
    [RunWith("utils.testrunners.ParameterizedRunner")]
    class AdditionTests {
        public static var numbersToTest:Array = [
            [1, 2, 3],
            [4, 5, 9],
            [-1, 1, 0]
        };

        [Parameterized("numbersToTest")]
        public function testAddition(a:int, b:int, expected:int):void {
            assertEqual(a+b, expected);
        }
    }
</pre>

<p></code></p>

<p>And that code will do exactly what you'd expect: run three test cases, one for each of the inputs. If one test fails, the others will still run. Helpful error messages will be provided when a test fails.</p>

<p>The <strong>source can be downloaded</strong> from: <a href="http://gist.github.com/299871">http://gist.github.com/299871</a> <small>(and it will be getting a new home when ever I get around to releasing all of my AS utilities)</small></p>

<p>Look useful? Give it a try and tell me what you think – I'd love to know.</p>
 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://blog.codekills.net/archives/78-How-WolframAlpha-makes-me-happy.html" rel="alternate" title="How Wolfram|Alpha makes me happy" />
        <author>
            <name>David Wolever</name>
            <email>david@wolever.net</email>
        </author>
    
        <published>2010-02-08T19:13:02Z</published>
        <updated>2010-02-11T21:57:52Z</updated>
        <wfw:comment>http://blog.codekills.net/wfwcomment.php?cid=78</wfw:comment>
    
        <slash:comments>1</slash:comments>
        <wfw:commentRss>http://blog.codekills.net/rss.php?version=atom1.0&amp;type=comments&amp;cid=78</wfw:commentRss>
    
    
        <id>http://blog.codekills.net/archives/78-guid.html</id>
        <title type="html">How Wolfram|Alpha makes me happy</title>
        <content type="xhtml" xml:base="http://blog.codekills.net/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <blockquote>
<strong>tl;dr</strong>: learn what <a href="http://www.wolframalpha.com">Alpha</a> can do, add <a href="http://support.mozilla.com/en-US/kb/Smart+keywords">a keyword search</a> for it.
</blockquote>

<p>Remember <a href="http://www.wolframalpha.com">Wolfram|Alpha</a>? Wolfram's attempt at a computer knowledge engine that got a little bit of hype, then drifted into obscurity?</p>

<p>Well, it has been making me pretty happy recently, and maybe it can make you happy too.  Here's my trick:</p>

<p>First, learn what it can and can't do: it won't help much with <a href="http://google.com/search?q=stupid+linux">a broken xorg.conf</a>… But if you need to <a href="http://www.wolframalpha.com/input/?i=π%20cm%20in%20inces">convert units</a> (especially <a href="http://www.wolframalpha.com/input/?i=7342192+bytes">units of storage</a>), <a href="http://www.wolframalpha.com/input/?i=08%2F16%2F1988">get information about a date</a>, <a href="http://www.wolframalpha.com/input/?i=GOOG%2C+APPL%2C+DELL">compare stock information</a> or <a href="http://www.wolframalpha.com/input/?i=x%5E-1">do anything with a mathematical equation</a>, Alpha is incredible.</p>

<p><small>(yes, there is nothing there that's unique to Alpha… But that's not the point. The point is that, once you know what it can do, you can, on the first try, get the information you need. There's no looking through Google search results (even Google's calculator <a href="http://google.com/search?q=4+CAD+in+USD">takes a couple of tries</a> (compare: <a href="http://www.wolframalpha.com/input/?i=4+CAD+in+USD">alpha: 4 CAD in USD</a>).)</small></p>

<p>Second, make it really, really easy to use: add <a href="http://support.mozilla.com/en-US/kb/Smart+keywords">a keyword search</a> (if you're in Safari, use <a href="http://hetima.com/safari/stand-e.html">Stand</a>) so searching Alpha is just as easy as searching the rest of the Internet:</p>

<p><img src="http://img.skitch.com/20100208-jnnfxssqbjy55peq84p2ak4c7a.png" /></p>

<p>Then just start using it <img src="http://blog.codekills.net/templates/default/img/emoticons/smile.png" alt=":-)" style="display: inline; vertical-align: bottom;" class="emoticon" /></p>
 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://blog.codekills.net/archives/77-FlexUnits-Test-Theories-Dont-Bother.html" rel="alternate" title="FlexUnit's Test Theories: Don't Bother" />
        <author>
            <name>David Wolever</name>
            <email>david@wolever.net</email>
        </author>
    
        <published>2010-02-05T23:47:58Z</published>
        <updated>2010-02-21T15:08:39Z</updated>
        <wfw:comment>http://blog.codekills.net/wfwcomment.php?cid=77</wfw:comment>
    
        <slash:comments>4</slash:comments>
        <wfw:commentRss>http://blog.codekills.net/rss.php?version=atom1.0&amp;type=comments&amp;cid=77</wfw:commentRss>
    
            <category scheme="http://blog.codekills.net/categories/16-ActionScript" label="ActionScript" term="ActionScript" />
    
        <id>http://blog.codekills.net/archives/77-guid.html</id>
        <title type="html">FlexUnit's Test Theories: Don't Bother</title>
        <content type="xhtml" xml:base="http://blog.codekills.net/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>I've just been playing around with FlexUnit 4's nifty new "Test Theories"… And I have come to the conclusion that, right now, they are basically worthless.</p>

<p>Here's why:</p>

<ul>
<li>They aren't documented. At all. There are approximately two examples on the internet, and the <a href="http://docs.flexunit.org/index.php?title=Theory">wiki page</a> is a joke. Nothing explains what algorithm is used to calculate which <a href="http://docs.flexunit.org/index.php?title=DataPoint">DataPoints</a> are applied to which theories.</li>
<li>They make test error messages <em>less</em> helpful. If a a theory fails, instead of getting a helpful error message like "<tt>Theory `checkUrl("this is a bad url")` failed with message: could not determine protocol</tt>", it gives a message like this: "<tt>checkUrl urls[1]</tt>". Yea, thanks guys.</li>
<li>They don't do anything "cool". At all. It would be cool if, given five data points, five distinct tests would be generated. It would be cool if one data point could fail while others succeed. Heck, anything which would make them better than a <tt>for</tt> loop would be cool. But, alas…</li>
</ul>

<p>So, don't waste your time on Theories just yet. For now, just use a <code>for</code> loop:</p>

<pre style="margin-left: 3em; margin-top: -1em; margin-bottom: 1em"><code>
[Test]
public function runTestsOnData():void {
    for each (datum in testData)
        doSomeTest(datum);
}
</code></pre>

<p>Or, if you want to test the <a href="http://en.wikipedia.org/wiki/Cartesian_product">cartesian product</a> of a set of data, use <a href="http://gist.github.com/296418">my handy cartesian product function</a>:</p>

<pre style="margin-left: 3em; margin-top: -1em; margin-bottom: 1em"><code>
[Test]
public function runTestsOnCartesianProduct():void {
    for each (data in cartesian_product(testData0, testData1))
        doSomeTest.apply(this, data);
}
</code></pre>

<p><strong>Followup</strong>: as Alan (see comments) said, what I really want is a parameterized testrunner. So I've gone ahead and written one. See <a href="http://blog.codekills.net/archives/79-A-Parameterized-Testrunner-for-FlexUnit.html">my post on a Parameterized Testrunner for FlexUnit</a>.</p>
 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://blog.codekills.net/archives/76-DVCSs-and-Changeset-Numbering.html" rel="alternate" title="DVCSs and Changeset Numbering" />
        <author>
            <name>David Wolever</name>
            <email>david@wolever.net</email>
        </author>
    
        <published>2010-01-29T22:30:21Z</published>
        <updated>2010-01-30T17:54:06Z</updated>
        <wfw:comment>http://blog.codekills.net/wfwcomment.php?cid=76</wfw:comment>
    
        <slash:comments>8</slash:comments>
        <wfw:commentRss>http://blog.codekills.net/rss.php?version=atom1.0&amp;type=comments&amp;cid=76</wfw:commentRss>
    
    
        <id>http://blog.codekills.net/archives/76-guid.html</id>
        <title type="html">DVCSs and Changeset Numbering</title>
        <content type="xhtml" xml:base="http://blog.codekills.net/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>One of my big beefs with DVCSs is their version numbers.</p>

<p>For example, take two changesets I committed today: 6899 and 02a9. Which one is more recent? How many changesets separate them? Without access to a repository, there's no way to tell… But that sort of information can be useful to have.</p>

<p>Two of the three DVCSs I have experience with, <code>bzr</code> and <code>hg</code>, both take steps towards solving this problem.</p>

<p><code>bzr</code> tries "really hard" to give everything a sequential ID, and uses those IDs in the UI (as far as I can tell) all the time (it does use unique hashes under the hood, but they aren't shown very much):</p>

<pre><code>$ bzr log
------------------------------------------------------------
revno: 3
message:
  A merge
    ------------------------------------------------------------
    revno: 1.1.1
    message:
      A conflicting change
</code></pre>

<p><code>hg</code> assigns local aliases for each changeset, and displays those aliases along with hashes:</p>

<pre><code>$ hg log -r 4:6
changeset:   4:658109dca65b
description:
A merge

changeset:   5:bd8053bf02f1
description:
A conflicting change
</code></pre>

<p>And, of course, <code>git</code> doesn't stand for this sort of frivolity and shows pure, unadulterated, hashes:</p>

<pre><code>$ git log
commit aa55884d693c92da6dc96eb7a45c9ecd774fefc2

    A merge

commit 8e47937468071ae29d385b76ff925d231c65b97b

    A conflicting change
</code></pre>

<p>I'd like to see this taken a step further, though: I'd like the changeset hashes themselves to encode some basic information about where they live in the repository.</p>

<p>For example, one way to do this could be using the first two bytes of the hash to store the distance from the root*, and the next two bytes to store a "repository id", which is generated once, when a repository is first cloned or initialized.</p>

<p>So, for example, one of these changeset hashes might look like this: <tt><strong>0afc</strong>53bf02f1</tt>, and committing again to the same repository would produce <tt><strong>0bfc</strong>109dca65</tt>.</p>

<p>Of course, this scheme doesn't guarantee anything - it's entirely possible to generate two completely different changesets with the exact same four-byte prefix… But in the general case, this sort of scheme could make it significantly easier to figure out how arbitrary changesets relate to one another.</p>

<p><small>*: <a href="http://twitter.com/dgou">Doug Philips</a> suggested this - thanks.</small></p>
 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://blog.codekills.net/archives/75-Self-documenting-code-is-a-lie.html" rel="alternate" title="Self documenting code is a lie" />
        <author>
            <name>David Wolever</name>
            <email>david@wolever.net</email>
        </author>
    
        <published>2010-01-22T22:51:44Z</published>
        <updated>2010-01-26T17:22:13Z</updated>
        <wfw:comment>http://blog.codekills.net/wfwcomment.php?cid=75</wfw:comment>
    
        <slash:comments>6</slash:comments>
        <wfw:commentRss>http://blog.codekills.net/rss.php?version=atom1.0&amp;type=comments&amp;cid=75</wfw:commentRss>
    
    
        <id>http://blog.codekills.net/archives/75-guid.html</id>
        <title type="html">Self documenting code is a lie</title>
        <content type="xhtml" xml:base="http://blog.codekills.net/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>Be very, very wary of anyone who suggests that "self documenting" code can replace comments.</p>

<p>Case in point: I consider myself a mediocre programmer, who is usually capable of producing mostly coherent code.</p>

<p>Below is a hunk of the code I wrote today - keywords are blue, variables are white, comments are green:</p>

<p><img src="http://img.skitch.com/20100122-kf68a32qf9arq6cdsqe8gxapyj.png" /></p>

<p>I don't think I could take much away from that without doing a serious disservice to the poor person (probably me) who will be tasked with fixing the inevitable bugs in the above code.</p>
 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://blog.codekills.net/archives/74-Django-settings.py-mini-tip-the-path-lambda.html" rel="alternate" title="Django settings.py mini-tip: the `path` lambda" />
        <author>
            <name>David Wolever</name>
            <email>david@wolever.net</email>
        </author>
    
        <published>2010-01-18T03:26:41Z</published>
        <updated>2010-01-18T03:37:25Z</updated>
        <wfw:comment>http://blog.codekills.net/wfwcomment.php?cid=74</wfw:comment>
    
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://blog.codekills.net/rss.php?version=atom1.0&amp;type=comments&amp;cid=74</wfw:commentRss>
    
            <category scheme="http://blog.codekills.net/categories/6-Python" label="Python" term="Python" />
    
        <id>http://blog.codekills.net/archives/74-guid.html</id>
        <title type="html">Django settings.py mini-tip: the `path` lambda</title>
        <content type="xhtml" xml:base="http://blog.codekills.net/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>There are a few things I do every time I start a new Django site, and one of those things is add my <code>path</code> lambda to the top of settings.py:</p>

<pre><code>    import os
    ROOT = os.path.abspath(os.path.dirname(__file__))
    path = lambda *args: os.path.join(ROOT, *args)
</code></pre>

<p>From then on, it's drop-dead simple to create absolute paths which are relative to the root of the project (or, at least, the directory which contains settings.py). For example:</p>

<pre><code>    >>> path('media/')
    '/Users/wolever/code/review_anywhere/media/
</code></pre>

<p>And some other places where it is useful:</p>

<pre><code>    DATABASE_ENGINE = 'sqlite3'
    DATABASE_NAME = path('db.sqlite3')
    ...
    TEMPLATE_DIRS = (
        path('templates/'),
    )
    ...
    DATA_DIR = path('data/')
    ...
</code></pre>
 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://blog.codekills.net/archives/72-dm-crypt-and-confusing-error-messages.html" rel="alternate" title="dm-crypt and confusing error messages" />
        <author>
            <name>David Wolever</name>
            <email>david@wolever.net</email>
        </author>
    
        <published>2010-01-12T15:13:13Z</published>
        <updated>2010-01-12T15:13:13Z</updated>
        <wfw:comment>http://blog.codekills.net/wfwcomment.php?cid=72</wfw:comment>
    
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://blog.codekills.net/rss.php?version=atom1.0&amp;type=comments&amp;cid=72</wfw:commentRss>
    
    
        <id>http://blog.codekills.net/archives/72-guid.html</id>
        <title type="html">dm-crypt and confusing error messages</title>
        <content type="xhtml" xml:base="http://blog.codekills.net/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>(this is a post intended for Google - sorry for bothering you, faithful RSS readers)</p>

<p>I've been setting up encrypted backups for my Linux machine, found that <code>cryptsetup</code> gives a really cryptic and unhelpful error message:</p>

<pre>
$ <em>cryptsetup luksFormat /dev/sda3 ~/.backupKey</em>
WARNING!
========
This will overwrite data on /dev/sda3 irrevocably.

Are you sure? (Type uppercase yes): YES
Failed to setup dm-crypt key mapping.
<strong>Check kernel for support for the aes-cbc-essiv:sha256 cipher spec and verify
that /dev/sda3 contains at least 133 sectors.</strong>
Failed to write to key storage.
Command failed.
$
</pre>

<p>Google will <a href="http://www.google.com/search?q=Check+kernel+for+support+for+the+aes-cbc-essiv:sha256+cipher+spec+and+verify+that+/dev/sda3+contains+at+least+133+sectors">suggest lots of things</a>… But none of them solved my problem.</p>

<p>What was I doing wrong? <strong>I needed to run <code>cryptsetup</code> as root</strong>.</p>

<p>D'oh.</p>
 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://blog.codekills.net/archives/71-Makefile-for-Arduino-0017.html" rel="alternate" title="Makefile for Arduino 0017" />
        <author>
            <name>David Wolever</name>
            <email>david@wolever.net</email>
        </author>
    
        <published>2010-01-10T22:05:51Z</published>
        <updated>2010-01-10T22:22:39Z</updated>
        <wfw:comment>http://blog.codekills.net/wfwcomment.php?cid=71</wfw:comment>
    
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://blog.codekills.net/rss.php?version=atom1.0&amp;type=comments&amp;cid=71</wfw:commentRss>
    
            <category scheme="http://blog.codekills.net/categories/13-Fixed-it" label="Fixed-it" term="Fixed-it" />
    
        <id>http://blog.codekills.net/archives/71-guid.html</id>
        <title type="html">Makefile for Arduino 0017</title>
        <content type="xhtml" xml:base="http://blog.codekills.net/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>I picked up an Arduino yesterday, and I was quite dismayed by how much work it took to build/flash from the command line.</p>

<p>After some hours of Googling, though, I finally found <a href="http://dorkbotpdx.org/blog/ax/arduino_0017_makefile">an up-to-date Makefile</a>, and it didn't take too much to make it "just work" with the default install of Arduino.app on the Mac.</p>

<p>To use this Makefile, simply drop it into the project sketch directory, then run <code>make</code> then <code>make upload</code>. You may need to tweak some variables (eg, it assumes Arduino.app is located at <code>/Applications/Arduino.app</code>), but that is fairly straight forward.</p>

<p>Get the Makefile from: <a href="http://gist.github.com/273821">http://gist.github.com/273821</a>.</p>

<p>Just a note: I haven't had much time to tinker with this system yet, so it may have some serious issues... If so, drop me a comment below.</p>

<p>Also, leave a comment if you want me to let you know if (when?) I update this.</p>
 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://blog.codekills.net/archives/70-Using-git-for-Backup-is-Asking-for-Pain.html" rel="alternate" title="Using git for Backup is Asking for Pain" />
        <author>
            <name>David Wolever</name>
            <email>david@wolever.net</email>
        </author>
    
        <published>2009-12-08T18:10:22Z</published>
        <updated>2009-12-08T21:09:22Z</updated>
        <wfw:comment>http://blog.codekills.net/wfwcomment.php?cid=70</wfw:comment>
    
        <slash:comments>9</slash:comments>
        <wfw:commentRss>http://blog.codekills.net/rss.php?version=atom1.0&amp;type=comments&amp;cid=70</wfw:commentRss>
    
    
        <id>http://blog.codekills.net/archives/70-guid.html</id>
        <title type="html">Using git for Backup is Asking for Pain</title>
        <content type="xhtml" xml:base="http://blog.codekills.net/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>git isn't a backup system.</p>

<p>Neither is Mercurial, Bazaar, Subversion or even (<em>even</em>) CVS <del>CSV</del>.</p>

<p>Version control systems, with the possible exception of SourceSafe, are great at keeping track of code. Why is that? Because they were <strong>designed to keep track of code</strong>.</p>

<p>Unfortunately, though, the features of a good VCS are <strong>entirely different</strong> – and often <strong>exactly the opposite</strong> – of the features which make a good backup system.</p>

<p>Take, for example, <strong>file ownership</strong>. A good VCS will, very rightly, <strong>ignore file ownership</strong>: when I check out someone else's code, I should be the owner of those file - not whatever <code>uid</code> originally created them. A good backup system, on the other hand, will do <strong>everything in its power to preserve file ownership</strong>: when I restore from my backups, I want <code>/etc/shaddow</code> to be owned by <code>root</code> and <code>/home/wolever/</code> to be owned by <code>wolever</code>.</p>

<p>And ownership is just one example - permissions†, creation and modification times, empty directories‡, hardlinks, xattrs, resource forks, … the list of details that a backup system must keep track of goes on and on.</p>

<p>In fact, there are so many things a backup system can get wrong, there is a project called <a href="http://www.n8gray.org/code/backup-bouncer/">Backup Bouncer</a>, designed specifically to verify that backup scripts correctly copy all the various bits of metadata tracked by the filesystem.</p>

<p>So, please: if you value your bytes, use a real backup system, not git.</p>

<p>†: Most VCSs only track the 'x' bit - for backup purposes, all bits, including suid bits, must be tracked.<br />
‡: fun fact - Mercurial and git don't track empty directories, but Bazaar does.</p>
 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://blog.codekills.net/archives/69-Best-Ever-Implementation-of-indexOf!.html" rel="alternate" title="Best Ever Implementation of &quot;indexOf&quot;!" />
        <author>
            <name>David Wolever</name>
            <email>david@wolever.net</email>
        </author>
    
        <published>2009-12-08T03:31:27Z</published>
        <updated>2009-12-08T05:09:10Z</updated>
        <wfw:comment>http://blog.codekills.net/wfwcomment.php?cid=69</wfw:comment>
    
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://blog.codekills.net/rss.php?version=atom1.0&amp;type=comments&amp;cid=69</wfw:commentRss>
    
            <category scheme="http://blog.codekills.net/categories/16-ActionScript" label="ActionScript" term="ActionScript" />
    
        <id>http://blog.codekills.net/archives/69-guid.html</id>
        <title type="html">Best Ever Implementation of &quot;indexOf&quot;!</title>
        <content type="xhtml" xml:base="http://blog.codekills.net/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>(alternate title: <em>The "Fail Early, Fail Often" Principle in Action</em>)</p>

<p>I would like to award Adobe the "best ever implementation of <code>indexOf</code>". Ready for it? Here it is:</p>

<pre><code>override flash_proxy function callProperty(name:*, ... rest):* {
    return null;
}
</code></pre>

<p>This beauty can be found in <code>mx.collections.ListCollectionView</code>.</p>

<p>And the kicker? The function's documentation:</p>

<pre><code>/**
 *  @private
 *  Any methods that can't be found on this class shouldn't be called,
 *  so return null
 */
</code></pre>

<p>The author clearly knew that unknown methods* shouldn't be called… But instead of doing something sensible – like throwing an exception – they do something wholly nonsensical and return <code>null</code>. Or, of course, they could also have left the function unimplemented, which would result in a strange and unhelpful exception… But, of course, I would expect nothing but the best from the Flex standard library.</p>

<p>Next up: why implicit conversions from <code>null</code> to <code>int</code> are always wrong.</p>

<p>&lt;/rant&gt;</p>

<p>*: the magic <code>callProperty</code> method is called on subclasses of <code>Proxy</code> when a method can't be found. For example if <code>bar</code> is not a method of <code>foo</code>, executing <code>foo.bar()</code>will call <code>foo.callProperty("bar")</code>.</p>

<p>PS: Instead of calling <code>indexOf</code>, I should have been calling <code>getItemIndex</code>.</p>
 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://blog.codekills.net/archives/68-You-and-Your-Editor-Vim-normal-mode-commands-g,-and-d-3-of-N.html" rel="alternate" title="You and Your Editor: Vim normal mode commands g, : and d (3 of N)" />
        <author>
            <name>David Wolever</name>
            <email>david@wolever.net</email>
        </author>
    
        <published>2009-12-06T01:22:14Z</published>
        <updated>2009-12-06T01:22:14Z</updated>
        <wfw:comment>http://blog.codekills.net/wfwcomment.php?cid=68</wfw:comment>
    
        <slash:comments>2</slash:comments>
        <wfw:commentRss>http://blog.codekills.net/rss.php?version=atom1.0&amp;type=comments&amp;cid=68</wfw:commentRss>
    
            <category scheme="http://blog.codekills.net/categories/10-Vim" label="Vim" term="Vim" />
    
        <id>http://blog.codekills.net/archives/68-guid.html</id>
        <title type="html">You and Your Editor: Vim normal mode commands g, : and d (3 of N)</title>
        <content type="xhtml" xml:base="http://blog.codekills.net/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>In my last post, I <a href="http://blog.codekills.net/archives/67-You-and-Your-Editor-Data-from-vim-logging-2-of-N.html">showed off some normal-mode data from vim-logging</a>. In this (and the next few) posts, I'll go though my most-used commands and describe how I use them.</p>

<p>(Don't use Vim? This post won't be too interesting… Although you may pick up something useful)</p>

<h3><a name="g">g</a></h3>

<p>My logs contain more than 60,000 references to the 'g' command (eight times more than ':', the next most frequently used command).  This may seem surprising at first, but stick with me and let me explain: the 'g' command is something of a 'gateway' command - a prefix for a number of common actions which don't have their own single-character command (for example, <tt>gd</tt>, goto definition and <tt>g?</tt>, rot13 encode).</p>

<p>Here is a breakdown of the 'g' suffixes I often use:</p>

<ul>
<li><p><strong>gj</strong> and <strong>gk</strong>: cursor to next row, cursor to previous row ("make <code>j</code> and <code>k</code> do the right thing"). The <code>j</code> and <code>k</code> commands are defined as "move to next line" and "move to previous line", not "move to next screen row" and "move to previous screen row". This is an important distinction to make when long lines are wrapped, and I find "move to next/previous screen row" is a more reasonable default. <em>Protip</em>: use <code>noremap j gj</code> and <code>noremap k gk</code> in your <code>vimrc</code>.</p></li>
<li><p><strong>gg</strong>: cursor to top of file. After using <code>gg</code> (for example, to edit some import statements or add a shebang line), I often use <code>''</code> (tick-tick) to jump back to the line I was editing at the time (for example, <code>ggofrom foo import bar&lt;esc&gt;''</code>). Also, I often use <code>ggVG</code> (go to top, enter line-visual-mode, go to bottom) to select the entire file. From there, I can pipe it to something (for example, <code>:!sort</code>), format it (<code>gw</code>) or copy it to the clipboard.</p></li>
<li><p><strong>gt</strong> and <strong>gT</strong>: go tab - move to next/previous tab.</p></li>
<li><p><strong>gf</strong>: goto file - edit the file under the cursor. For example, if the cursor is over the 'e' in <code>import "../eventDispatercherImpl.as"</code>, the equivalent of <code>:e ../eventDispatercherImpl.as</code> will be executed.</p></li>
<li><p><strong>gw</strong>: go wrap. Wrap the selected text (that is, text selected in visual mode). Try selecting a long line (pressing <code>V</code>), then using <code>gw</code> to wrap it.</p></li>
</ul>

<p>That's all the 'g' commands I can think of for now... The next version of vim-logging will log the sub-command used, so I will be able to provide better data in the future.</p>

<h3><a name="colon">:</a></h3>

<p>The colon command is fairly obvious: enter command-line mode to run commands like <code>:w</code> or <code>:help :</code>.</p>

<p>I'll write more about this later, when I analyze my most-used ex commands.</p>

<h3><a name="d">d</a></h3>

<p>Ah, <code>d</code> - delete - the programmers best friend.</p>

<p>As with <code>g</code>, I do not have detailed information about how I use <code>d</code>, but I'll list the first few combinations that come to mind when I move my left index finger over the <code>d</code> key:</p>

<ul>
<li><code>dd</code> to delete whole lines</li>
<li><code>di(</code> to delete everything inside a pair of parenthesise</li>
<li><code>dfx</code> to delete everything between the current position and the next occurrence of 'x'</li>
<li><code>dj</code> and <code>dk</code> to delete this and the next/previous line</li>
<li><code>d$</code> to delete from the current position to the end of the line</li>
<li><code>d</code> in visual mode to delete the selected text.</li>
</ul>
 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://blog.codekills.net/archives/67-You-and-Your-Editor-Data-from-vim-logging-2-of-N.html" rel="alternate" title="You and Your Editor: Data from vim-logging (2 of N)" />
        <author>
            <name>David Wolever</name>
            <email>david@wolever.net</email>
        </author>
    
        <published>2009-12-06T00:19:48Z</published>
        <updated>2009-12-12T04:46:41Z</updated>
        <wfw:comment>http://blog.codekills.net/wfwcomment.php?cid=67</wfw:comment>
    
        <slash:comments>11</slash:comments>
        <wfw:commentRss>http://blog.codekills.net/rss.php?version=atom1.0&amp;type=comments&amp;cid=67</wfw:commentRss>
    
            <category scheme="http://blog.codekills.net/categories/10-Vim" label="Vim" term="Vim" />
    
        <id>http://blog.codekills.net/archives/67-guid.html</id>
        <title type="html">You and Your Editor: Data from vim-logging (2 of N)</title>
        <content type="xhtml" xml:base="http://blog.codekills.net/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>Remember when I <a href="http://blog.codekills.net/archives/64-vim-logging-taking-the-superstition-out-of-most-used-command.html">blogged about <tt>vim-logging</tt></a>? Well, I've finally gotten around to interpreting the results.</p>

<p>First, I will cover what I believe to be the most important thing to know about vim: the normal mode commands.</p>

<p>Below is a chart of my 39 <small>(why 39? I can't remember - when I created the graph, that's the number I chose)</small> most-frequently-used normal-mode commands:</p>
 <br /><a href="http://blog.codekills.net/archives/67-You-and-Your-Editor-Data-from-vim-logging-2-of-N.html#extended">Continue reading "You and Your Editor: Data from vim-logging (2 of N)"</a>
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://blog.codekills.net/archives/66-codekills-and-wolever.net-downtime.html" rel="alternate" title="codekills (and wolever.net) downtime" />
        <author>
            <name>David Wolever</name>
            <email>david@wolever.net</email>
        </author>
    
        <published>2009-12-02T04:41:15Z</published>
        <updated>2009-12-02T18:23:37Z</updated>
        <wfw:comment>http://blog.codekills.net/wfwcomment.php?cid=66</wfw:comment>
    
        <slash:comments>3</slash:comments>
        <wfw:commentRss>http://blog.codekills.net/rss.php?version=atom1.0&amp;type=comments&amp;cid=66</wfw:commentRss>
    
    
        <id>http://blog.codekills.net/archives/66-guid.html</id>
        <title type="html">codekills (and wolever.net) downtime</title>
        <content type="xhtml" xml:base="http://blog.codekills.net/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>I'm sure you didn't notice, but I'll tell you about it anyway: the server that runs <a href="http://wolever.net/">wolever.net</a> and <a href="http://blog.codekills.net">codekills.net</a>, <tt>lazarus</tt>, died of unknown causes two weeks ago.</p>

<p>It took two weeks to get everything fixed because it lives in Toronto and I live in Waterloo… And the first weekend I went back to pick it up… I forgot to pick it up.</p>

<p>Right now the data has been migrated to another machine (the one you're talking to right now), and it is doubtful if <tt>lazarus</tt> will ever live again.</p>
 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://blog.codekills.net/archives/65-Splitting-Audio-on-the-Mac.html" rel="alternate" title="Splitting Audio on the Mac" />
        <author>
            <name>David Wolever</name>
            <email>david@wolever.net</email>
        </author>
    
        <published>2009-10-28T14:41:44Z</published>
        <updated>2009-10-28T14:41:44Z</updated>
        <wfw:comment>http://blog.codekills.net/wfwcomment.php?cid=65</wfw:comment>
    
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://blog.codekills.net/rss.php?version=atom1.0&amp;type=comments&amp;cid=65</wfw:commentRss>
    
    
        <id>http://blog.codekills.net/archives/65-guid.html</id>
        <title type="html">Splitting Audio on the Mac</title>
        <content type="xhtml" xml:base="http://blog.codekills.net/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>This is a quickie, but hopefully it'll help someone out there.</p>

<p>I had to setup my laptop so two people could use it to talk on Skype: one audio input (the call), two outputs.</p>

<p>First, I installed <a href="http://www.cycling74.com/products/soundflower">Soundflower</a>.</p>

<p>Second, I opened up "Audio MIDI Setup" (<tt>/Applications/Utilities/Audio MIDI Setup.app</tt>) and created an Aggregate Device (Audio -> Open Aggregate Device Editor). I checked all the output devices, and included the Soundflower device:</p>

<p><img src="http://img.skitch.com/20091028-tscw9xk3k5yfhbqns2kns6ch14.png" /></p>

<p>Third, I set the system's input and output to Soundflower:</p>

<p><img src="http://img.skitch.com/20091028-bnf67kgimpgwteiw35hc7d2fwe.png" /></p>

<p>Fourth, I opened up AU Lab (<tt>/Developer/Applications/Audio/AU Lab.app</tt>) and created a new… thing… with two outputs and one input. After hitting OK the right number of times and getting the main window up, I hit Window -> Show Studio, then selected the Aggregate device on the left. Finally, I checked both the "1" and the "2" on the left side of the "input" to send its output to both output 1 and 2. Some tinkering with the input and output streams (in the Studio) was also necessary.</p>

<p><img src="http://img.skitch.com/20091028-b5y7bbrqfgcjcttm14b49sx6qw.png" /></p>

<p>Finally, in Skype, I set the audio input to the built in microphone (which was fine for me), and everything was peachy!</p>
 
            </div>
        </content>
        
    </entry>

</feed>