<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="en-US">
  <title>the { buckblogs :here } - Home</title>
  <id>tag:weblog.jamisbuck.org,2010:mephisto/</id>
  <generator uri="http://mephistoblog.com" version="0.8.0">Mephisto Drax</generator>
  
  <link href="http://weblog.jamisbuck.org/" rel="alternate" type="text/html" />
  <updated>2010-03-02T03:53:05Z</updated>
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/buckblog" /><feedburner:info uri="buckblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-nc-sa/2.0/" /><feedburner:browserFriendly>This is an XML content feed. It is intended to be viewed in a newsreader or syndicated to another site, subject to copyright and fair use.</feedburner:browserFriendly><entry xml:base="http://weblog.jamisbuck.org/">
    <author>
      <name>Jamis</name>
    </author>
    <id>tag:weblog.jamisbuck.org,2010-03-02:7942</id>
    <published>2010-03-02T00:15:00Z</published>
    <updated>2010-03-02T03:53:05Z</updated>
    <category term="Projects" />
    <category term="Tips &amp; Tricks" />
    <category term="javascript" />
    <category term="rails" />
    <category term="ujs" />
    <link href="http://weblog.jamisbuck.org/2010/3/2/unobtrusive-yet-explicit" rel="alternate" type="text/html" />
    <title>Unobtrusive, yet explicit</title>
<summary type="html">&lt;p&gt;A few weeks ago I started a new side project (a string-figure catalog, not yet ready for an audience, sadly), and I figured it would be a good opportunity to dabble in the new goodies in Rails 3. It’s been a fun experience, for the most part, but I’ll save my “wins and fails” for a separate post.&lt;/p&gt;


	&lt;p&gt;For now, I want to focus on one particular frustration: &lt;a href="http://en.wikipedia.org/wiki/Unobtrusive_JavaScript"&gt;Unobtrusive Javascript&lt;/a&gt; (UJS). In any project of even moderate complexity, I’ve found that Javascript plays a role, and in Rails 2 the primary way to play that game was by inlining your Javascript. (This is where you put Javascript directly into your tags, for instance in “onchange” or “onclick” handlers.)&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;A few weeks ago I started a new side project (a string-figure catalog, not yet ready for an audience, sadly), and I figured it would be a good opportunity to dabble in the new goodies in Rails 3. It’s been a fun experience, for the most part, but I’ll save my “wins and fails” for a separate post.&lt;/p&gt;


	&lt;p&gt;For now, I want to focus on one particular frustration: &lt;a href="http://en.wikipedia.org/wiki/Unobtrusive_JavaScript"&gt;Unobtrusive Javascript&lt;/a&gt; (UJS). In any project of even moderate complexity, I’ve found that Javascript plays a role, and in Rails 2 the primary way to play that game was by inlining your Javascript. (This is where you put Javascript directly into your tags, for instance in “onchange” or “onclick” handlers.)&lt;/p&gt;
&lt;p&gt;Apparently this is a Bad Thing, although the only arguments I’ve found against inline Javascript sound suspiciously like “purity for purity’s sake”. At any rate, Rails 3 is embracing &lt;span class="caps"&gt;UJS&lt;/span&gt;, and you’ll find that helper methods like “link_to_function” don’t even exist in Rails 3.&lt;/p&gt;


	&lt;p&gt;This raises the question: what do you do instead? Well, you have to use &lt;span class="caps"&gt;UJS&lt;/span&gt;. Only, &lt;span class="caps"&gt;UJS&lt;/span&gt; in Rails isn’t super mature yet; there’s a lot of manual labor involved simply trying to work around the absence of “link_to_function”.&lt;/p&gt;


	&lt;p&gt;So, I set to work. Initially, I tried to copy what &lt;a href="http://github.com/rails/prototype-ujs"&gt;rails.js&lt;/a&gt; was doing (for Ajax operations, etc.): I installed a handler, and examined the triggering element to see what operations match:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="pt"&gt;document&lt;/span&gt;.observe(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;dom:loaded&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="r"&gt;function&lt;/span&gt;() {&lt;tt&gt;
&lt;/tt&gt;  $(&lt;span class="pt"&gt;document&lt;/span&gt;.body).observe(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="r"&gt;function&lt;/span&gt;(&lt;span class="pt"&gt;event&lt;/span&gt;) {&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;var&lt;/span&gt; element = &lt;span class="pt"&gt;event&lt;/span&gt;.findElement(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;a[data-toggle]&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;if&lt;/span&gt;(element) {&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;var&lt;/span&gt; action = element.readAttribute(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;data-toggle&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;      element.hide();&lt;tt&gt;
&lt;/tt&gt;      element.next().show();&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="pt"&gt;event&lt;/span&gt;.&lt;span class="fu"&gt;stop&lt;/span&gt;();&lt;tt&gt;
&lt;/tt&gt;    } &lt;span class="r"&gt;else&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;var&lt;/span&gt; element = &lt;span class="pt"&gt;event&lt;/span&gt;.element();&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;if&lt;/span&gt;(!element.readAttribute(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;data-tab&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)) element = element.up(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;a[data-tab]&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;if&lt;/span&gt;(element) {&lt;tt&gt;
&lt;/tt&gt;        selectTab(element.readAttribute(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;data-tab&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;));&lt;tt&gt;
&lt;/tt&gt;      }&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;  });&lt;tt&gt;
&lt;/tt&gt;});&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;I quickly realized that this does not scale, for two reasons. The first is that you quickly wind up with a massive branch statement inside each of your observer functions, with finicky conditions that (hopefully) map to actual elements in your views. The second is that the relationship between your markup and your Javascript is tenuous at best; even coming back to my code just a few days later, I found it was challenging to discover what code was executed when a link was clicked.&lt;/p&gt;


	&lt;p&gt;This is, I believe, one of the greatest strengths of inline Javascript: the relationship between markup and code is immediately obvious, and it requires very little hunting to follow the path of execution from the inception of an event.&lt;/p&gt;


	&lt;p&gt;So I went looking at what other options exist. &lt;a href="http://github.com/danwrong/low-pro"&gt;Low Pro&lt;/a&gt;, an extension to Prototype for aiding with &lt;span class="caps"&gt;UJS&lt;/span&gt;, looked promising; I liked how each behavior was registered separately, which seemed like it would give a stronger relationship between markup and execution. However, Low Pro uses &lt;span class="caps"&gt;CSS&lt;/span&gt; selectors to identify which markup gets associated with which callbacks, and while this &lt;em&gt;sounds&lt;/em&gt; like it ought to be a great idea, it falls down for one really big reason: &lt;span class="caps"&gt;CSS&lt;/span&gt; selectors depend on styling attributes (classes and ids), and trying to tie functionality to those means you are still left staring at markup and wondering where all the events go. Sometimes a class is stylistic, and sometimes it is logical, and there is not generally any clear way to determine which is which.&lt;/p&gt;


	&lt;p&gt;Now, you could resort to naming conventions: if a class name is prefixed with “behavior-” (or similar), then it refers to a behavior that is defined in Javascript. That’s closer to what I was looking for, so I played with that.&lt;/p&gt;


	&lt;p&gt;But what I soon discovered was that you wind up with a bunch of &lt;span class="caps"&gt;CSS&lt;/span&gt; classes that are not used for styling at all, because they specifically refer to dynamic behaviors. What I &lt;em&gt;really&lt;/em&gt; wanted was an altogether different attribute for specifying behaviors, like what “onchange” and “onclick” gave me before. Only I had to beware upsetting the Manifold Avatars of &lt;span class="caps"&gt;UJS&lt;/span&gt; Purity by embedding actual Javascript.&lt;/p&gt;


	&lt;p&gt;What I finally ended up doing (I’ll say I “stumbled on it”, rather than “invented it”, since I’m positive it’s been done before) was defining a “data-behaviors” attribute on every element that needed one:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="c"&gt;&amp;lt;%= link_to &amp;quot;Add an alias&amp;quot;, &amp;quot;#&amp;quot;, &amp;quot;data-behaviors&amp;quot; =&amp;gt; &amp;quot;add-alias&amp;quot; %&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Then, in my Javascript driver, I registered callbacks for those named behaviors:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;Behaviors.add(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;add-alias&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="r"&gt;function&lt;/span&gt;(element) {&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="c"&gt;// ...&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;});&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;The result is &lt;span class="caps"&gt;UJS&lt;/span&gt; that clearly reveals the relationship between the markup and the code; you can easily search for all elements in the views that behave like “add-alias”, for instance, and given a behavior name (like “add-alias”), you can quickly find the code that gets executed for it. Elements can have multiple behaviors, too: just give a space-delimited list of behavior names in the “data-behaviors” attribute.&lt;/p&gt;


	&lt;p&gt;It’s not perfect, though: the current implementation doesn’t deal well with elements that want to behave like X on “click”, but Y on “change”. That’s not a scenario I’ve needed to deal with yet, though, so I’m sure when (if?) it comes up, a solution can be found. In the meantime, I’m quite pleased with this. It “clicks”, whereas other &lt;span class="caps"&gt;UJS&lt;/span&gt; solutions just felt obscure and heavy-weight.&lt;/p&gt;


	&lt;p&gt;Below is the code for behaviors.js. Please feel free to fork the gist on Github and hack away; I’m sure it can be improved upon in lots of ways.&lt;/p&gt;


&lt;p&gt;Enjoy!&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Josh Peek suggested some tips that resulted in a drastic simplification of behaviors.js. It’s simple enough now that there’s almost no point in providing it as a separate library!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.jamisbuck.org/">
    <author>
      <name>Jamis</name>
    </author>
    <id>tag:weblog.jamisbuck.org,2010-01-26:7923</id>
    <published>2010-01-26T04:51:00Z</published>
    <updated>2010-01-31T23:42:02Z</updated>
    <category term="Essays and Rants" />
    <link href="http://weblog.jamisbuck.org/2010/1/26/there-is-no-magic-there-is-only-awesome-part-4" rel="alternate" type="text/html" />
    <title>There is no magic, there is only awesome (Part 4)</title>
<summary type="html">&lt;p&gt;&lt;em&gt;This is the fourth (and final) article in a series titled “There is no magic, there is only awesome.” The first article introduced the &lt;a href="http://weblog.jamisbuck.org/2009/9/17/there-is-no-magic-there-is-only-awesome-part-1"&gt;four cardinal rules of awesomeness&lt;/a&gt;, the second was about &lt;a href="http://weblog.jamisbuck.org/2009/9/25/there-is-no-magic-there-is-only-awesome-part-2"&gt;knowing thy tools&lt;/a&gt;, and the third encouraged you to &lt;a href="http://weblog.jamisbuck.org/2009/10/9/there-is-no-magic-there-is-only-awesome-part-3"&gt;know thy languages&lt;/a&gt; .&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;First off, I apologize for dragging this out. It’s really become a weight on my shoulders. I’ve been fretting and fretting about writing the last two or three posts in this series, and I just couldn’t find the inspiration to make them come out like I wanted…and they’ve been holding up other posts I’ve been wanting to write.&lt;/p&gt;


	&lt;p&gt;So I’m going to cheat. You’re going to get a braindump, more or less, of the last two rules of awesomeness. Yes, I am entirely cognizant of the irony here. Nonetheless, here goes.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;&lt;em&gt;This is the fourth (and final) article in a series titled “There is no magic, there is only awesome.” The first article introduced the &lt;a href="http://weblog.jamisbuck.org/2009/9/17/there-is-no-magic-there-is-only-awesome-part-1"&gt;four cardinal rules of awesomeness&lt;/a&gt;, the second was about &lt;a href="http://weblog.jamisbuck.org/2009/9/25/there-is-no-magic-there-is-only-awesome-part-2"&gt;knowing thy tools&lt;/a&gt;, and the third encouraged you to &lt;a href="http://weblog.jamisbuck.org/2009/10/9/there-is-no-magic-there-is-only-awesome-part-3"&gt;know thy languages&lt;/a&gt; .&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;First off, I apologize for dragging this out. It’s really become a weight on my shoulders. I’ve been fretting and fretting about writing the last two or three posts in this series, and I just couldn’t find the inspiration to make them come out like I wanted…and they’ve been holding up other posts I’ve been wanting to write.&lt;/p&gt;


	&lt;p&gt;So I’m going to cheat. You’re going to get a braindump, more or less, of the last two rules of awesomeness. Yes, I am entirely cognizant of the irony here. Nonetheless, here goes.&lt;/p&gt;
&lt;h2&gt;Rule #3: Know thy libraries!&lt;/h2&gt;


	&lt;p&gt;If you want to be awesome, know your dependencies. At the very least, understand what each plugin, library, and technique you use, does. If called on to explain why you are using a particular design pattern, could you justify it? If someone asked you to compare plugin X and plugin Y, could you explain what their different strengths and weaknesses are? If you discover a particular library behaving erratically, would you be able to dig into the library’s guts to tell the author roughly where the problem is? Or would you be one of those who has to tug on the author’s sleeve and say, metaphorically, “it hurts when I do this”?&lt;/p&gt;


	&lt;p&gt;By libraries, I mean (essentially) any bit of code that you depend on, that has a life of its own outside your application. I’m including design patterns in this, although they aren’t really code, but they do represent a “library” of possibly ways to architect code. Basically, if you’re using someone else’s code, algorithms, or techniques, know why you’re using them. Make sure you can answer the four questions:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;What does this do best?&lt;/li&gt;
		&lt;li&gt;What does this do worst?&lt;/li&gt;
		&lt;li&gt;Why should I use this in particular?&lt;/li&gt;
		&lt;li&gt;When was the last time I learned something new about this?&lt;/li&gt;
	&lt;/ol&gt;


	&lt;h2&gt;Rule #4: Know thy communities!&lt;/h2&gt;


	&lt;p&gt;The last rule says that if you want to be awesome, you can’t do it in a vacuum. By writing code, you automatically join an ecosystem, whether it be a network of coworkers who will help you write, debug, deploy, and maintain that code, or a community of hobbyists who might wish to use your code in applications of their own (or who are writing code that &lt;em&gt;you&lt;/em&gt; want to use). Even if all you do is pop up out of your cave long enough to toss some code into the public domain, you’re still contributing to a community, and if you’re using other people’s code, then you’re a consumer as well.&lt;/p&gt;


	&lt;p&gt;Don’t be blind to those communities. Stop for a minute and think about the communities you belong to, whether explicitly (where you’re a card-carrying, due-paying member) or implicitly (where you’re passively consuming someone else’s code), or somewhere in-between.&lt;/p&gt;


	&lt;p&gt;Why is this important? Mostly because communities are resources. Each community will be good for different kinds of help, collaboration, or criticism, and if you want to make the most of those resources (which, if you’re really awesome, you will), you need to know where each shines. Again, apply the four questions. What does this community do best? What is it worst at? Why should I participate in this particular community, over all the possible alternatives? And when was the last time I learned from this community?&lt;/p&gt;


	&lt;p&gt;That last is important, and surprisingly deep. If you are no longer learning from a community, what are you still doing there? Some of you are no doubt saying “but, but, but” and eagerly pointing out that maybe someone is part of a community so that they can lift others up, but note: if you’re doing that right, you’re still learning from those you teach. You learn new ways that your craft can be confusing to people. You learn new ways of looking at things that you’ve been taking from granted. You learn new ways to rephrase concepts that have grown stale in your own mind. It keeps you fresh. If you’re doing it wrong, though, then the only reason you remain in a community that teaches you nothing is complacency. And complacency is on the opposite end of the excellence spectrum from awesomeness.&lt;/p&gt;


	&lt;h2&gt;Words of caution&lt;/h2&gt;


	&lt;p&gt;So, those are the four rules. There is one overriding caveat to all of this, though, and that is: use moderation. You’re not going to master all of this in a day. Or even a week, or month, or year. I don’t know anyone that is perfect at all four things (though I know many who are much, much better than I am). To sound all zen and mysterious: awesomeness is a journey, not a destination. Enjoy the trip, appreciate the view, but don’t overdo it.&lt;/p&gt;


	&lt;p&gt;When you overdo it, you risk burning out. I’ve been riding that line for a couple years now, which was frightening. When writing code is your bread and butter, paying the bills and putting food on the table for you and your family, it is scary to contemplate “what do I do when I suddenly don’t want to do what I’ve been doing”. This is a big reason why I had to let go of &lt;a href="http://capify.org"&gt;Capistrano&lt;/a&gt; and other projects, and why I’ve discovered other hobbies (like woodcarving, string figuring, and cooking) that do not involve computers. I’m trying to find the middle ground, so that I can recapture the joy of writing code.&lt;/p&gt;


	&lt;p&gt;So: be awesome. But only in moderation.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.jamisbuck.org/">
    <author>
      <name>Jamis</name>
    </author>
    <id>tag:weblog.jamisbuck.org,2009-10-09:7794</id>
    <published>2009-10-09T16:48:00Z</published>
    <updated>2009-10-09T16:50:10Z</updated>
    <category term="Essays and Rants" />
    <category term="awesome" />
    <category term="keynote" />
    <category term="programming" />
    <category term="talk" />
    <link href="http://weblog.jamisbuck.org/2009/10/9/there-is-no-magic-there-is-only-awesome-part-3" rel="alternate" type="text/html" />
    <title>There is no magic, there is only awesome (Part 3)</title>
<summary type="html">&lt;p&gt;&lt;em&gt;This is the third article in a series titled “There is no magic, there is only awesome.” The &lt;a href="http://weblog.jamisbuck.org/2009/9/17/there-is-no-magic-there-is-only-awesome-part-1"&gt;first article&lt;/a&gt; introduced the “four cardinal rules of awesomeness”. The &lt;a href="http://weblog.jamisbuck.org/2009/9/25/there-is-no-magic-there-is-only-awesome-part-2"&gt;second article&lt;/a&gt; discussed knowing your tools.&lt;/em&gt;&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;Opening A.—Pass index finger of right hand distal to the little-finger loop, and passing round the ulnar side of that loop, bring it up from the proximal side into the thumb loop, and with the index finger pointing downard, take up with the back of the index finger the radial thumb string and return.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Even to string figure adepts, it can be challenging to parse those instructions. That paragraph is an extract from the instructions for an Eskimo Caribou string figure, written in 1903 by Dr. &lt;a href="http://en.wikipedia.org/wiki/Alfred_Cort_Haddon"&gt;A. C. Haddon&lt;/a&gt; and published in &lt;em&gt;American Anthropologist&lt;/em&gt; (you can read the whole thing on &lt;a href="http://books.google.com/books?id=vlkWAAAAMAAJ&amp;amp;#38;pg=PA216"&gt;Google Books&lt;/a&gt; if you’re really feeling sleepless).&lt;/p&gt;


	&lt;p&gt;The &lt;a href="http://books.google.com/books?id=yRP0I0s8QdEC&amp;amp;#38;pg=PA146"&gt;original string figure notation&lt;/a&gt; described by Drs. &lt;a href="http://en.wikipedia.org/wiki/W._H._R._Rivers"&gt;Rivers&lt;/a&gt; and Haddon in 1902 used very technical anatomical terms to identify each finger, and the location of the string on each finger. As in that paragraph, you’ll see terms such as &lt;em&gt;proximal&lt;/em&gt; (closer to the base of the finger), &lt;em&gt;distal&lt;/em&gt; (closer to the finger tip), &lt;em&gt;radial&lt;/em&gt; (closer to the thumb), and &lt;em&gt;ulnar&lt;/em&gt; (closer to the little finger). These and other terms are used to describe locations relative to the fingers, as well as to name specific strings (“radial thumb string”) on the hand.&lt;/p&gt;


	&lt;p&gt;The strength of this notation is that it is very precise, and can be used with little need of external illustration. However, it is also fairly verbose, making it hard to parse without very focused attention and (potentially) multiple read-throughs. Also, the use of the technical anatomical terms makes the descriptions hard for novices to pick up.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;&lt;em&gt;This is the third article in a series titled “There is no magic, there is only awesome.” The &lt;a href="http://weblog.jamisbuck.org/2009/9/17/there-is-no-magic-there-is-only-awesome-part-1"&gt;first article&lt;/a&gt; introduced the “four cardinal rules of awesomeness”. The &lt;a href="http://weblog.jamisbuck.org/2009/9/25/there-is-no-magic-there-is-only-awesome-part-2"&gt;second article&lt;/a&gt; discussed knowing your tools.&lt;/em&gt;&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;Opening A.—Pass index finger of right hand distal to the little-finger loop, and passing round the ulnar side of that loop, bring it up from the proximal side into the thumb loop, and with the index finger pointing downard, take up with the back of the index finger the radial thumb string and return.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Even to string figure adepts, it can be challenging to parse those instructions. That paragraph is an extract from the instructions for an Eskimo Caribou string figure, written in 1903 by Dr. &lt;a href="http://en.wikipedia.org/wiki/Alfred_Cort_Haddon"&gt;A. C. Haddon&lt;/a&gt; and published in &lt;em&gt;American Anthropologist&lt;/em&gt; (you can read the whole thing on &lt;a href="http://books.google.com/books?id=vlkWAAAAMAAJ&amp;amp;#38;pg=PA216"&gt;Google Books&lt;/a&gt; if you’re really feeling sleepless).&lt;/p&gt;


	&lt;p&gt;The &lt;a href="http://books.google.com/books?id=yRP0I0s8QdEC&amp;amp;#38;pg=PA146"&gt;original string figure notation&lt;/a&gt; described by Drs. &lt;a href="http://en.wikipedia.org/wiki/W._H._R._Rivers"&gt;Rivers&lt;/a&gt; and Haddon in 1902 used very technical anatomical terms to identify each finger, and the location of the string on each finger. As in that paragraph, you’ll see terms such as &lt;em&gt;proximal&lt;/em&gt; (closer to the base of the finger), &lt;em&gt;distal&lt;/em&gt; (closer to the finger tip), &lt;em&gt;radial&lt;/em&gt; (closer to the thumb), and &lt;em&gt;ulnar&lt;/em&gt; (closer to the little finger). These and other terms are used to describe locations relative to the fingers, as well as to name specific strings (“radial thumb string”) on the hand.&lt;/p&gt;


	&lt;p&gt;The strength of this notation is that it is very precise, and can be used with little need of external illustration. However, it is also fairly verbose, making it hard to parse without very focused attention and (potentially) multiple read-throughs. Also, the use of the technical anatomical terms makes the descriptions hard for novices to pick up.&lt;/p&gt;
&lt;p&gt;To make &lt;a href="http://www.stringfigures.info/cfj/"&gt;her book&lt;/a&gt; more accessible to a larger audience, &lt;a href="http://en.wikipedia.org/wiki/Caroline_Furness_Jayne"&gt;Caroline Furness Jayne&lt;/a&gt; (or “CFJ”) modified this notation so that “proximal” and “distal” were replaced with “lower” and “upper”, and “radial” and “ulnar” were replaced with “near” and “far”. (She left dorsal/palmar alone, for the most part, although in some figures she referred to the “front” or “back” of a hand or finger.) Her modifications introduced ambiguity, though, and required even more verbosity and copious illustrations to counter.&lt;/p&gt;


	&lt;p&gt;For example, she described the same movements (from the Eskimo Caribou figure) as follows:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;First: Opening A. (The left palmar string &lt;em&gt;must&lt;/em&gt; be taken up first). Second: Bend the right index away from you over the right far index string and over both strings of the right little finger loop and down on the far side of the right far little finger string; then draw toward you on the near side of the right index both right little finger strings and the right far index string, allowing the right near index string to slip over the knuckle of the index and to the far side of the finger. Now put the right index (still bent and holding the strings on its near side) from below into the thumb loop, by pressing the near side of the bent index toward you against the right far thumb string, and putting the tip down toward you over and on the near side of the right near thumb string. Pick up, on the far side of the bent right index, this right near thumb string, and lift it and the former near index string up by turning the index away from you and up to its usual position.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;(I ommitted the illustrations for brevity’s sake, but if you want to see them, you can view the complete instructions &lt;a href="http://www.stringfigures.info/cfj/cariboo.html"&gt;here&lt;/a&gt;.)&lt;/p&gt;


	&lt;p&gt;The lack of technical terms is definitely an improvement, but the (significantly!) greater quantity of text means that the instructions require even &lt;em&gt;more&lt;/em&gt; effort to parse. To combat this, the &lt;a href="http://www.isfa.org"&gt;&lt;span class="caps"&gt;ISFA&lt;/span&gt;&lt;/a&gt; (International String Figure Association), in its &lt;a href="http://www.isfa.org/isfa3.htm"&gt;publications&lt;/a&gt;, uses an abbreviated notation, numbering the fingers 1 (thumb) through 5 (little finger), and using other one-letter abbreviations for right (R), left (L), near (n), and far (f). They retain the use of proximal/distal in some cases, but also use “below”/”above” and “lower”/”upper” where it isn’t too ambiguous. The &lt;span class="caps"&gt;ISFA&lt;/span&gt; notation reduces the above text to this:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;Opening A. R2 rotates away from you, over all strings, around 5f, then back under the strings, and proximally enters R1 loop.  R2 hooks up R1n and retraces its path. (from &lt;a href="http://www.isfa.org/arctic/30.htm"&gt;http://www.isfa.org/arctic/30.htm&lt;/a&gt;)&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;This is much more concise, and is easier to scan. It settles on &lt;a href="http://www.isfa.org/arctic/n.htm"&gt;standard meanings&lt;/a&gt; of terms like “rotate away”, “hook up”, and “release”, which reduces verbosity, but also requires the reader to know how those words are defined in this context. Also, it is concise at the cost of specificity; there is often ambiguity that must either be resolved at “runtime”, or be countered with more verbose descriptions.&lt;/p&gt;


	&lt;p&gt;Two other notable attempts at describing string figures are &lt;a href="http://www.alysion.org/figures/notation.htm"&gt;&lt;span class="caps"&gt;SFN&lt;/span&gt;&lt;/a&gt; (String Figure Notation) by Eric Lee, and &lt;a href="http://home.p07.itscom.net/nenemei/v2/index.html"&gt;Mizz Code&lt;/a&gt; by Kyoichi Miyazaki (“Mizz”). The former is a variation on &lt;span class="caps"&gt;ISFA&lt;/span&gt; notation, employing various abbreviations to reduce verbosity, while the latter is an entirely new take on describing string figures that simply denotes how the string needs to move, without specifying finger movements at all. Both of these are much more concise than any of the others described above, but are also quite specialized and require some study before you can really make heads or tails of them.&lt;/p&gt;


	&lt;p&gt;So, that gives &lt;em&gt;five&lt;/em&gt; different ways of describing string figure construction! How do you choose which one to use? Ultimately, the &lt;span class="caps"&gt;ISFA&lt;/span&gt; notation is the most widly used, as well as the verbose prose of &lt;span class="caps"&gt;CFJ&lt;/span&gt; (thanks to the popularity of her book). But a string figurist will benefit from knowing as many ways to describe a figure as possible, because each notation’s strategies reveal different insights into the techniques, and has different strengths in different situations. &lt;span class="caps"&gt;CFJ&lt;/span&gt;’s prose (if accompanied by a modicum of illustration) is good for beginners, because it does not require any specialized knowledge. The &lt;span class="caps"&gt;ISFA&lt;/span&gt; notation is a good general tool that allows people to quickly learn figures, with only a little training. And notations like &lt;span class="caps"&gt;SFN&lt;/span&gt; are great for quickly jotting down a figure as you learn it from someone else, or as you invent it yourself.&lt;/p&gt;


	&lt;p&gt;Really, as a string figurist, the more string figure languages you know, the more power you have.&lt;/p&gt;


	&lt;h2&gt;Computer Languages&lt;/h2&gt;


	&lt;p&gt;Thus, the second rule of awesomeness: &lt;em&gt;know thy languages&lt;/em&gt;.&lt;/p&gt;


	&lt;p&gt;As a computer programmer, you’re faced with an &lt;a href="http://en.wikipedia.org/wiki/List_of_programming_languages"&gt;even greater flood of languages&lt;/a&gt; than string figurists are. Even if you use primarily a single language, you might be surprised at how many incidental languages you use on a regular basis. Are you a web developer? Odds are that you dabble in both &lt;span class="caps"&gt;HTML&lt;/span&gt; and &lt;span class="caps"&gt;CSS&lt;/span&gt;, and probably Javascript, too. &lt;span class="caps"&gt;SQL&lt;/span&gt; is almost mandatory for most interactive systems. Furthermore, if you do anything at all in a text console, you probably know a little bit of shell script. Building your application and deploying it to production probably require a specialized &lt;span class="caps"&gt;DSL&lt;/span&gt; or two as well. And regular expressions are practically everywhere these days.&lt;/p&gt;


	&lt;p&gt;Despite there being more computer languages than string figure languages, the advice is the same: &lt;em&gt;the more you know, the more power you have&lt;/em&gt;. And “knowing” is not merely “knowing about”. Look back at the four “knowledge gauge” questions from &lt;a href="http://weblog.jamisbuck.org/2009/9/25/there-is-no-magic-there-is-only-awesome-part-2#article_body"&gt;Part 2&lt;/a&gt;:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;What does this do best?&lt;/li&gt;
		&lt;li&gt;What does this do worst?&lt;/li&gt;
		&lt;li&gt;Why should I use this in particular?&lt;/li&gt;
		&lt;li&gt;When was the last time I learned something new about this?&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Take a minute and try to list all the languages you use on a regular basis. This includes even languages you use only tangentially, like &lt;span class="caps"&gt;SQL&lt;/span&gt;, regular expressions, Javascript, &lt;span class="caps"&gt;HTML&lt;/span&gt;, XML, &lt;span class="caps"&gt;CSS&lt;/span&gt;, and so forth. Try to answer each of the four gauge questions for every language in your list. If you struggle to answer any of them, consider that a jumping off point for further investigation.&lt;/p&gt;


	&lt;p&gt;If you aren’t really sure what a particular language is best or worst at, it may be because you aren’t familiar with enough programming languages to compare it with. You’ve probably heard the old saying, “to a man with a hammer, everything looks like a nail,” and that surely applies here. You may be at the pinnacle of guruship in your chosen programming language, but if that’s all you know, then you can’t give worthwhile advice on when that language should be used. You’re living in a house with no windows, and no matter how well you know that house, and no matter how big it is, you can never tell callers what’s just outside.&lt;/p&gt;


	&lt;p&gt;It’s been suggested by &lt;a href="http://pragprog.com/titles/tpp/the-pragmatic-programmer"&gt;people much smarter than me&lt;/a&gt; that you should learn a new programming language every year. I can’t recommend this enough. I won’t deny that there have been years where I haven’t followed this advice, but every time I’ve spent a few months tinkering with a new programming language I’ve come away with my eyes open that much wider. It’s like having a lever, and finally discovering a fulcrum to use it with.&lt;/p&gt;


	&lt;h2&gt;Learning a new language&lt;/h2&gt;


	&lt;p&gt;Now, it’s all well and good to say “learn a new programming language”. It’s also remarkably easy to download the development kit for &lt;a href="http://www.ruby-lang.org/en/downloads/"&gt;Ruby&lt;/a&gt;, &lt;a href="http://python.org/download/"&gt;Python&lt;/a&gt;, &lt;a href="http://java.com/en/download/"&gt;Java&lt;/a&gt;, &lt;a href="http://ftp.sunet.se/pub//lang/erlang/download.html"&gt;Erlang&lt;/a&gt;, &lt;a href="http://hackage.haskell.org/platform/"&gt;Haskell&lt;/a&gt;, or just about any other language you want to learn. And once you’ve started learning a language, the learning effect tends to snowball, so that’s not really a challenge either.&lt;/p&gt;


	&lt;p&gt;What’s hardest (for me, at least) is discovering a good “entry vector” into the language.&lt;/p&gt;


	&lt;p&gt;Here’s what works for me:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Find the documentation for the language. Look for a page or two that give you a glimpse into the syntax. Not every language provides an introduction like this, but when you can find one, it’s a great way to get a “feel” for how the language expresses things.&lt;/li&gt;
		&lt;li&gt;Next, look for a “hello world” example, or tutorial. Generally, these things are useless, but as an introduction to the language, it’s a good way to see what’s involved in a fully functional program. How much boilerplate does a program need? How is a program compiled or interpreted, and run? The “hello world” example is also a good place to start experimenting. As trivial as it sounds, try changing the string that gets printed. Try displaying an additional string. Hold on to this file; you can use it to play with as you progress through the next steps.&lt;/li&gt;
		&lt;li&gt;Now, look deeper. Try and find a more advanced tutorial. Look for examples that demonstrate writing procedures, objects, conditional branching, and so forth. They will almost certainly include concepts unique to the language, which will be new to you, but that’s the point! Work through those tutorials. Find additional documentation to clarify concepts that are unfamiliar to you. Go beyond the tutorials and experiment with these concepts, to solidify their meaning in your mind.&lt;/li&gt;
		&lt;li&gt;Once you’ve finished some tutorials, look for actual production code written in that language. &lt;a href="http://www.github.com"&gt;GitHub&lt;/a&gt; is a fantastic resource for this kind of exploration, as are similar sites like &lt;a href="http://sourceforge.net/"&gt;SourceForge&lt;/a&gt;. Individual languages may have their own project “forges”, like &lt;a href="http://rubyforge.org"&gt;RubyForge&lt;/a&gt;. Just find a project that looks interesting and &lt;em&gt;read the code&lt;/em&gt;. This kind of “code spelunking” in a new language will give you valuable experience with the practical, day-to-day idioms used by experienced programmers, and will also give you solid examples of the concepts you read about and played with in the tutorials. (I intend to talk a lot more about “code spelunking” in the fourth article in this series.)&lt;/li&gt;
		&lt;li&gt;Lastly, think of a program or library you’d like to write, and &lt;em&gt;write it&lt;/em&gt; in this new language. Nothing else you do will teach you the language as well as this step. You’re going to run into road blocks, but don’t get discouraged. If you need to do something that wasn’t covered in any of the tutorials, consider it an opportunity to read more documentation! Look at other projects and see how they accomplished similar tasks. Your first couple of programs in the new language will be very “unidiomatic”, but that’s how you start. Find someone experienced in the language and ask them to review your program, and point out better ways to do it.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;By the end of the process, you won’t necessarily be an expert in the language, but you’ll know enough to compare it to other languages you know. You’ll also know whether you enjoyed the language enough to keep playing with it. Who knows? Maybe you’ll discover your new favorite language this way! I certainly wasn’t expecting to fall in love with &lt;a href="http://ruby-lang.org"&gt;Ruby&lt;/a&gt; when I started tinkering with it, but here I am, eight years later, and still tinkering.&lt;/p&gt;


	&lt;h2&gt;Learning more&lt;/h2&gt;


	&lt;p&gt;If you are already familiar with a language, the steps described above are not going to be as effective for increasing your knowledge. You’re probably in a rut, comfortable with what you know and able to accomplish almost everything you need to with it. That’s no excuse to stop learning, though; if you push yourself and learn even just a little more, you’ll almost certainly be surprised how useful that extra knowledge can be, even on a daily basis.&lt;/p&gt;


	&lt;p&gt;But how do you push yourself out of your comfort zone? This is probably harder than learning a new language, in many ways, because when you’re in the rut, it’s hard to see what the benefit of more knowledge would be.&lt;/p&gt;


	&lt;p&gt;One way is to find a good reference for the language, electronic or otherwise. Spend a little time each day (even just 15 minutes!) skimming that reference, looking for something you didn’t know before, or weren’t as familiar with as you would like to be. Once you find something, spend a little time playing with it. Find a way to add it to a project you’re working on. Blog about it. Tweet it. Just &lt;em&gt;do something&lt;/em&gt; with it! Then, try to do something with it on a regular basis, so it stays in your memory.&lt;/p&gt;


	&lt;p&gt;Another technique is to find a library or program that uses concepts that are new to you. Unfamiliar with socket programming? Look for a networking library to read through. Want to be more familiar with threading techniques? Look for something that does a lot of parallel processing. Even if you have no specific learning goal, a good starting point is to select a programmer you admire, and find projects that they’ve worked on. You’re sure to find idioms, tips, tricks, and language features you’ve not seen before.&lt;/p&gt;


	&lt;p&gt;Ultimately, though, the game is not about “who can learn the most programming languages”. No one is keeping score. There is no tally scratched into the bedpost of your career, here. The goal is to educate your opinions. &lt;em&gt;Awesome people have opinions born by experience.&lt;/em&gt; You want to be awesome? Then you need to be willing to keep pushing the envelope of your knowledge. Never settle for what you already have, even if you’re otherwise content. Keep looking. Lift the curtain on the unknown. If you want to be awesome, you need to explore.&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;Know thy languages.&lt;/em&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.jamisbuck.org/">
    <author>
      <name>Jamis</name>
    </author>
    <id>tag:weblog.jamisbuck.org,2009-09-25:7775</id>
    <published>2009-09-25T14:15:00Z</published>
    <updated>2009-09-27T23:10:56Z</updated>
    <category term="Essays and Rants" />
    <category term="awesome" />
    <category term="keynote" />
    <category term="programming" />
    <category term="talk" />
    <link href="http://weblog.jamisbuck.org/2009/9/25/there-is-no-magic-there-is-only-awesome-part-2" rel="alternate" type="text/html" />
    <title>There is no magic, there is only awesome (Part 2)</title>
<summary type="html">&lt;p&gt;&lt;em&gt;This is the second article in a series titled “There is no magic, there is only awesome.” The &lt;a href="http://weblog.jamisbuck.org/2009/9/17/there-is-no-magic-there-is-only-awesome-part-1"&gt;first article&lt;/a&gt; introduced the “four cardinal rules of awesomeness”.&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;If you’ve ever &lt;a href="http://www.youtube.com/watch?v=PEwOLndlSWM"&gt;watched&lt;/a&gt; &lt;a href="http://www.youtube.com/watch?v=ZLh3ZrFRhm0"&gt;someone&lt;/a&gt; &lt;a href="http://www.youtube.com/watch?v=5qdcG7Ztn3c"&gt;make&lt;/a&gt; &lt;a href="http://www.youtube.com/watch?v=rQkJpTVIyeA"&gt;string&lt;/a&gt; &lt;a href="http://www.youtube.com/results?search_type=videos&amp;amp;#38;search_query=string+figures"&gt;figures&lt;/a&gt;, it’s pretty obvious that the tool set includes a loop of string, and your fingers. But if you haven’t played with string figures much, you might be surprised to learn that you’ve got a lot more than string and fingers at your disposal.&lt;/p&gt;


	&lt;p&gt;There are figures that require the use of your &lt;a href="http://www.stringfigures.info/cfj/apache-door.html"&gt;wrists&lt;/a&gt; to hold the string. Some require you to use your lips, &lt;a href="http://www.stringfigures.info/cfj/ten-men.html"&gt;teeth&lt;/a&gt;, tongue, or &lt;a href="http://www.stringfigures.info/cfj/fly-on-nose.html"&gt;nose&lt;/a&gt;. I know a few that use the &lt;a href="http://www.stringfigures.info/cfj/hanging.html"&gt;neck&lt;/a&gt;. There are some that use the elbow, knee, &lt;a href="http://www.alysion.org/figures/introduc.htm##climbing"&gt;foot&lt;/a&gt;, or &lt;a href="http://www.alysion.org/figures/fairlyeasy.htm#palmtree"&gt;toes&lt;/a&gt;. A few require you to &lt;a href="http://www.stringfigures.info/cfj/carrying-money.html"&gt;set the figure down on a flat surface&lt;/a&gt; to manipulate it.&lt;/p&gt;


	&lt;p&gt;There are many figures that require the use of &lt;a href="http://www.stringfigures.info/cfj/real-cats-cradle.html"&gt;another person&lt;/a&gt;, or several people. Some figures actually require &lt;a href="http://www.stringfigures.info/cfj/house.html"&gt;multiple strings&lt;/a&gt;. Some require &lt;a href="http://www.stringfigures.info/cfj/two-boys-fighting-for-arrow.html"&gt;additional props&lt;/a&gt;, such as sticks.&lt;/p&gt;


	&lt;p&gt;Different figures might require different &lt;em&gt;types&lt;/em&gt; of string. Some, like &lt;a href="http://www.isfa.org/arctic/jenness.htm"&gt;Eskimo figures&lt;/a&gt;, work best with a thicker, shorter, stiffer string, while those of the Pacific islands tend to prefer longer, more supple and slippery strings.&lt;/p&gt;


	&lt;p&gt;With so many variables, and so many ways of combining them, how then does one ever excel at string figures? Is it hopeless?&lt;/p&gt;


	&lt;p&gt;Of course it isn’t. As with any other activity, there are simply a set of tools to be employed, and the expert will be well acquainted with them. It’s rule #1 of being awesome: &lt;em&gt;know thy tools&lt;/em&gt;.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;&lt;em&gt;This is the second article in a series titled “There is no magic, there is only awesome.” The &lt;a href="http://weblog.jamisbuck.org/2009/9/17/there-is-no-magic-there-is-only-awesome-part-1"&gt;first article&lt;/a&gt; introduced the “four cardinal rules of awesomeness”.&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;If you’ve ever &lt;a href="http://www.youtube.com/watch?v=PEwOLndlSWM"&gt;watched&lt;/a&gt; &lt;a href="http://www.youtube.com/watch?v=ZLh3ZrFRhm0"&gt;someone&lt;/a&gt; &lt;a href="http://www.youtube.com/watch?v=5qdcG7Ztn3c"&gt;make&lt;/a&gt; &lt;a href="http://www.youtube.com/watch?v=rQkJpTVIyeA"&gt;string&lt;/a&gt; &lt;a href="http://www.youtube.com/results?search_type=videos&amp;amp;#38;search_query=string+figures"&gt;figures&lt;/a&gt;, it’s pretty obvious that the tool set includes a loop of string, and your fingers. But if you haven’t played with string figures much, you might be surprised to learn that you’ve got a lot more than string and fingers at your disposal.&lt;/p&gt;


	&lt;p&gt;There are figures that require the use of your &lt;a href="http://www.stringfigures.info/cfj/apache-door.html"&gt;wrists&lt;/a&gt; to hold the string. Some require you to use your lips, &lt;a href="http://www.stringfigures.info/cfj/ten-men.html"&gt;teeth&lt;/a&gt;, tongue, or &lt;a href="http://www.stringfigures.info/cfj/fly-on-nose.html"&gt;nose&lt;/a&gt;. I know a few that use the &lt;a href="http://www.stringfigures.info/cfj/hanging.html"&gt;neck&lt;/a&gt;. There are some that use the elbow, knee, &lt;a href="http://www.alysion.org/figures/introduc.htm##climbing"&gt;foot&lt;/a&gt;, or &lt;a href="http://www.alysion.org/figures/fairlyeasy.htm#palmtree"&gt;toes&lt;/a&gt;. A few require you to &lt;a href="http://www.stringfigures.info/cfj/carrying-money.html"&gt;set the figure down on a flat surface&lt;/a&gt; to manipulate it.&lt;/p&gt;


	&lt;p&gt;There are many figures that require the use of &lt;a href="http://www.stringfigures.info/cfj/real-cats-cradle.html"&gt;another person&lt;/a&gt;, or several people. Some figures actually require &lt;a href="http://www.stringfigures.info/cfj/house.html"&gt;multiple strings&lt;/a&gt;. Some require &lt;a href="http://www.stringfigures.info/cfj/two-boys-fighting-for-arrow.html"&gt;additional props&lt;/a&gt;, such as sticks.&lt;/p&gt;


	&lt;p&gt;Different figures might require different &lt;em&gt;types&lt;/em&gt; of string. Some, like &lt;a href="http://www.isfa.org/arctic/jenness.htm"&gt;Eskimo figures&lt;/a&gt;, work best with a thicker, shorter, stiffer string, while those of the Pacific islands tend to prefer longer, more supple and slippery strings.&lt;/p&gt;


	&lt;p&gt;With so many variables, and so many ways of combining them, how then does one ever excel at string figures? Is it hopeless?&lt;/p&gt;


	&lt;p&gt;Of course it isn’t. As with any other activity, there are simply a set of tools to be employed, and the expert will be well acquainted with them. It’s rule #1 of being awesome: &lt;em&gt;know thy tools&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;Knowing vs. &lt;em&gt;Knowing&lt;/em&gt;&lt;/h2&gt;


	&lt;p&gt;But what does that mean? It certainly doesn’t mean just “knowing what your tools are”, otherwise you’d all be on your way to string figure mastery, just by reading the above paragraphs. Knowing your tools necessarily means knowing, deeply, how to use a tool. It means knowing the strengths and weaknesses of each tool, knowing why a particular tool is best in any given situation, and knowing how to learn more about them.&lt;/p&gt;


	&lt;p&gt;In fact, those statements can be generalized into four questions that can be used to gauge the depth of your knowledge about most anything:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;What does this do best?&lt;/li&gt;
		&lt;li&gt;What does this do worst?&lt;/li&gt;
		&lt;li&gt;Why should I use this in particular?&lt;/li&gt;
		&lt;li&gt;When was the last time I learned something new about this?&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;We’ll hit those four questions in each of the articles that follow, but for now, I’m going to apply them specifically the tools of my own professional domain: writing software.&lt;/p&gt;


	&lt;h2&gt;The tools of computing&lt;/h2&gt;


	&lt;p&gt;If you write software, step back for a minute and think about the tools you use every day. This includes your operating system, your text editor, your command shell, your &lt;span class="caps"&gt;SCM&lt;/span&gt;. It’s your web browser, your terminal client, your email and IM clients. It includes command-line utilities you probably use without thinking, every day: grep, sed, awk, find, ls and cd, to name a few. It’s even your hardware: the keyboard you use, your mouse, your monitor, your computer. It probably includes many other things that I’ve completely overlooked! (Note, though, that programming languages will be covered separately; they are certainly tools of the trade, but they’re such spectacularly important tools that they deserve their own rule of awesomeness. More on that when we hit rule #2.)&lt;/p&gt;


	&lt;p&gt;So, now it’s your turn. Go ahead and grab a scrap of paper. Make a list, right now, of the tools you use every day. I’ll wait.&lt;/p&gt;


	&lt;p&gt;Done? Okay, awesome. Now, go through each item on your list and ask yourself each of the four “knowledge gauge” questions:&lt;/p&gt;


	&lt;h2&gt;1. What does this do best?&lt;/h2&gt;


	&lt;p&gt;&lt;strong&gt;Compared with similar tools, what does this tool do best?&lt;/strong&gt; Don’t use a pre-recorded, generic answer. Think about it. Consider it carefully. Be specific. For particularly powerful or flexible tools, there may be multiple answers, and that’s okay. Your answer may quite possibly be debatable, and that’s okay, too. The point here is that &lt;em&gt;you need to have an opinion&lt;/em&gt;. If someone asks you why in the world you choose to use Vim instead of Emacs, don’t let the silence stretch awkwardly. Know your mind!&lt;/p&gt;


	&lt;h2&gt;2. What does this do worst?&lt;/h2&gt;


	&lt;p&gt;Related to the previous question: &lt;strong&gt;At what is this tool particularly bad?&lt;/strong&gt; Again, this is in comparison with similar tools. And there is no such thing as a perfect tool, so there’s no point trying to skip this question. That’s a cop out. If you don’t have a few pet peeves for each tool in your toolbox, then chances are you aren’t familiar enough with your tools. Have an opinion.&lt;/p&gt;


	&lt;h2&gt;3. Why should I use this in particular?&lt;/h2&gt;


	&lt;p&gt;&lt;strong&gt;Given all possible alternatives, why am I using this tool in particular?&lt;/strong&gt; Was it recommended to you? Are you using it “by mandate”? Perhaps it was it a gift, or a hand-me-down? Have you personally tried any of the alternatives? The real test of this question is having someone ask you for a recommendation. If you were to recommend this tool, and they were to ask “why” in return, what would you tell them? Similarly, if someone were to ask you about one of the alternatives, would you be able to give them an educated opinion? (You do have one, right?)&lt;/p&gt;


	&lt;h2&gt;4. When was the last time I learned something new about this?&lt;/h2&gt;


	&lt;p&gt;In many ways, this is the most important of the four questions. It’s purpose is to make you aware of potential stagnation. Certainly there is a point at which you say can that you know a tool “well enough”. It gets your job done. It suffices. Perhaps you’re even something of an expert, with deep knowledge about the tool. But no matter how well you know a tool, if you stop learning and instead put your expertise on “cruise control”, you’ll stagnate. Expire. Rot. Guaranteed. To be exceptional, you must be &lt;em&gt;active&lt;/em&gt;.&lt;/p&gt;


	&lt;p&gt;Don’t stagnate. Seriously, just don’t. If it’s been a while since you learned something new about one of your tools, take a good look at that tool. Look at its documentation. Find tutorials or blog articles. Books, videos, podcasts, whatever. Try to find something new about it, something that you didn’t know before. Perhaps it’s a feature you weren’t aware of. Maybe it’s just a new application of the tool. Perhaps-&lt;del&gt;now, don’t freak out here&lt;/del&gt;-it’s another tool altogether! Never be afraid of replacing your tools when something better comes along. (It’s actually really, really valuable to continually experiment with similar tools, even if you’re satisifed with what you already have. It’s like learning a foreign language: it gives you a new perspective, and can introduce you to things, to which you might otherwise have never been exposed.)&lt;/p&gt;


	&lt;p&gt;Keep in mind, too, that “something new” does not have to mean “something mind-blowing”. In fact, such discoveries will be the exception. The point here is to simply be proactive, regularly flexing your knowledge muscles. &lt;em&gt;And then, you must apply that new bit of knowledge in your workflow.&lt;/em&gt; Otherwise, it’s not really learned, is it? It’ll atrophy if you don’t exercise it.&lt;/p&gt;


	&lt;p&gt;Try to find at least one new thing per day. It may be cliche, but it’s also true: “practice makes awesome.” Or something like that.&lt;/p&gt;


	&lt;h2&gt;Have an opinion.&lt;/h2&gt;


	&lt;p&gt;These questions are intended to make you think about your tool set. It can be hard, at first, to step back and “meta-analyze” yourself and your habits, but you really can’t have a meaningful opinion if you don’t think about things. And trust me, you want to have opinions. People without opinions are, frankly, boring. They’re pretty much the opposite of awesome. Blindly accepting recommendations, mindlessly reciting others’ claims, and cargo-culting others’ solutions might be an okay place to start, if you must, but it’s always a lousy place to finish.&lt;/p&gt;


	&lt;p&gt;Get first-hand experience. Learn. Expose your hidden assumptions. Ask “why”. Have an opinion.&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;Know thy tools.&lt;/em&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.jamisbuck.org/">
    <author>
      <name>Jamis</name>
    </author>
    <id>tag:weblog.jamisbuck.org,2009-09-17:7759</id>
    <published>2009-09-17T02:45:00Z</published>
    <updated>2009-09-17T02:53:21Z</updated>
    <category term="Essays and Rants" />
    <category term="awesome" />
    <category term="keynote" />
    <category term="programming" />
    <category term="talk" />
    <link href="http://weblog.jamisbuck.org/2009/9/17/there-is-no-magic-there-is-only-awesome-part-1" rel="alternate" type="text/html" />
    <title>There is no magic, there is only awesome (Part 1)</title>
<summary type="html">&lt;p&gt;&lt;em&gt;The following is the first of a series of articles that I will be posting in the coming weeks, based on the keynote address I gave at the 2009 Ruby Hoedown in Nashville, entitled “There is no magic, there is only awesome.” I originally intended to publish the entire series of articles as a single article, but it got too long. At any rate, I think it’ll be more easily digestible as multiple posts.&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;I’m always surprised to discover that there are people who have never heard of &lt;a href="http://en.wikipedia.org/wiki/String_figure"&gt;string figures&lt;/a&gt;. These are the games that are played (in western culture, at least) primarily by children, using a loop of string. They place the string on their hands and, either by themselves or with a friend, manipulate the string into various patterns. As a kid, I learned how to do a few such patterns, including &lt;a href="http://www.stringfigures.info/cfj/real-cats-cradle.html"&gt;Cat’s Cradle&lt;/a&gt; and the &lt;a href="http://www.alysion.org/figures/introduc.htm##cup"&gt;cup and saucer&lt;/a&gt;, but it was just a novelty, and I was interested in other things. I promptly forgot nearly everything about these games, except that they existed.&lt;/p&gt;


	&lt;p&gt;Fast-forward almost thirty years. My wife bought one of those &lt;a href="http://www.amazon.com/Jo-Ann-Stores-579-Cats-Cradle/dp/B001E01RY8"&gt;Klutz books&lt;/a&gt; for our kids, this one about string games. It only described a handful of figures, but it was enough to pique my curiosity. I hopped online to see if there was any other information available about the subject.&lt;/p&gt;


	&lt;p&gt;Thus did the floodgates open! I discovered that string figures are a nearly universal pastime, being found in almost every culture around the world. In fact, many widely separated cultures share string figure repertoires—a discovery that fascinated and intrigued ethnologists over a century ago.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;&lt;em&gt;The following is the first of a series of articles that I will be posting in the coming weeks, based on the keynote address I gave at the 2009 Ruby Hoedown in Nashville, entitled “There is no magic, there is only awesome.” I originally intended to publish the entire series of articles as a single article, but it got too long. At any rate, I think it’ll be more easily digestible as multiple posts.&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;I’m always surprised to discover that there are people who have never heard of &lt;a href="http://en.wikipedia.org/wiki/String_figure"&gt;string figures&lt;/a&gt;. These are the games that are played (in western culture, at least) primarily by children, using a loop of string. They place the string on their hands and, either by themselves or with a friend, manipulate the string into various patterns. As a kid, I learned how to do a few such patterns, including &lt;a href="http://www.stringfigures.info/cfj/real-cats-cradle.html"&gt;Cat’s Cradle&lt;/a&gt; and the &lt;a href="http://www.alysion.org/figures/introduc.htm##cup"&gt;cup and saucer&lt;/a&gt;, but it was just a novelty, and I was interested in other things. I promptly forgot nearly everything about these games, except that they existed.&lt;/p&gt;


	&lt;p&gt;Fast-forward almost thirty years. My wife bought one of those &lt;a href="http://www.amazon.com/Jo-Ann-Stores-579-Cats-Cradle/dp/B001E01RY8"&gt;Klutz books&lt;/a&gt; for our kids, this one about string games. It only described a handful of figures, but it was enough to pique my curiosity. I hopped online to see if there was any other information available about the subject.&lt;/p&gt;


	&lt;p&gt;Thus did the floodgates open! I discovered that string figures are a nearly universal pastime, being found in almost every culture around the world. In fact, many widely separated cultures share string figure repertoires—a discovery that fascinated and intrigued ethnologists over a century ago.&lt;/p&gt;
&lt;h2&gt;A Bit of History…&lt;/h2&gt;


	&lt;p&gt;When &lt;a href="http://en.wikipedia.org/wiki/Franz_Boas"&gt;Franz Boas&lt;/a&gt; first described an Eskimo string figure in 1888, there was a sudden flood of academic interest in string figures. Ethnologists began theorizing that the shared string figure repertoires could imply a common origin of mankind, or might indicate migration paths or intercultural interactions of “primitive” societies. Some of these figures were so elaborate that it seemed almost impossible to believe that they could come from independent invention. Efforts were made to “collect” these string figures by sketching them, photographing them, or even mounting the finished patterns on cardboard.&lt;/p&gt;


	&lt;p&gt;In 1902 there was another breakthrough: Drs. &lt;a href="http://en.wikipedia.org/wiki/W._H._R._Rivers"&gt;Rivers&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Alfred_Cort_Haddon"&gt;Haddon&lt;/a&gt;, two ethnolgists, devised a way to describe the process by which string figures were constructed, allowing researchers to collect not only the finished products, but also the steps leading up to them. This helped reveal an interesting fact: many of these different cultures’ figures that looked the same superficially were actually produced by very different methods. The argument for independent invention was strengthened, but it also became possible to see where one culture may have learned a figure from another, by comparing the similarities between the two methods of construction.&lt;/p&gt;


	&lt;p&gt;A few years later, in 1906, a remarkable woman named &lt;a href="http://en.wikipedia.org/wiki/Caroline_Furness_Jayne"&gt;Caroline Furness Jayne&lt;/a&gt; published one of the first books about string figures, called &lt;a href="http://www.stringfigures.info/cfj/"&gt;String Figures and How to Make Them&lt;/a&gt;. Amazingly, this book &lt;a href="http://www.amazon.com/String-Figures-How-Make-Them/dp/048620152X"&gt;remains in print&lt;/a&gt;, and is still one of the definitive works on string figures. In this book, Jayne took the nomenclature devised by Rivers and Haddon, and with a few simple modifications, made it more accessible to the layman. Using this modified nomenclature, Jayne then proceeded to describe (and, with the help of a friend, illustrate) 97 string figures from around the world, many of which she had collected herself and which had never been published before.&lt;/p&gt;


	&lt;p&gt;It really is a spectacular book.&lt;/p&gt;


	&lt;p&gt;However, because the system for describing string figure construction was so new at the time, there was a large body of string figures that had been collected, but for which there was no known construction method. Among these figures were several from the Pacific island of &lt;a href="http://en.wikipedia.org/wiki/Nauru"&gt;Nauru&lt;/a&gt;. These Nauruan (which is a palindrome, making this a &lt;em&gt;de facto&lt;/em&gt; awesome word) string figures were so elaborate and complex that Jayne was skeptical they could be created entirely “on the hand”, and she speculated that perhaps they were (at least partially) created “artificially” (e.g., by laying the string down and moving loops around).&lt;/p&gt;


	&lt;p&gt;Still, she included illustrations of 15 of these figures in her book (see the section entitled “Nauru Figures” in &lt;a href="http://www.stringfigures.info/cfj/chapter-09.html"&gt;Chapter 9&lt;/a&gt;), and said:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;“I have brought together such of these [drawings] as I could obtain, in the hope that other observers will find out the method by which they are made; with our &lt;em&gt;present knowledge&lt;/em&gt; it is &lt;em&gt;practically impossible&lt;/em&gt; to work back from the finished pattern to the opening movements.”—Caroline Furness Jayne, “String Figures and How to Make Them”, 1906 (emphasis added).&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Although Jayne died just a few years after her book was published, her work remained influential. Years later it was read by a woman named Honor Maude, who was intrigued by the Nauruan patterns. When, in the 1930’s, she had the opportunity to visit Nauru for a few weeks, she immediately dove in and began interrogating the natives about their string figures. She was able to learn many (though not all) of the Nauruan figures from Jayne’s book, and many others besides.&lt;/p&gt;


	&lt;p&gt;It turns out that the figures &lt;em&gt;were&lt;/em&gt; (for the most part) created entirely on the hand. For many of the figures, including fairly complex ones, the process of construction was even surprisingly straightforward. And armed with the results of Maude’s research, other researchers have since been able to reverse engineer the rest of the Nauruan patterns from Jayne’s book.&lt;/p&gt;


	&lt;p&gt;The mystery was dispelled. There was no magic. There were only awesome patterns that could now be documented, described, and duplicated.&lt;/p&gt;


	&lt;p&gt;This could never have happened if it were not for the willingness of a few to explore. Late 19th and early 20th century ethnologists explored the world, travelling to places most people had never even heard of. Caroline Jayne explored both the body of existing research, as well as travelled the US herself, collecting figures. And Honor Maude explored much of the south Pacific, including Nauru, collecting string figures.&lt;/p&gt;


	&lt;p&gt;More recently, string figurists have explored in other ways. By “playing with string”, attempting variations on existing patterns and testing combinations of maneuvers, and by working backward from known patterns, they were able to unravel figures that Caroline Jayne called “practically impossible” to reverse engineer. These people explored their domain, understood it at a new level, and did the impossible.&lt;/p&gt;


	&lt;p&gt;These people understood that string figures were not magic. &lt;em&gt;String figures were only awesome&lt;/em&gt;.&lt;/p&gt;


	&lt;h2&gt;Being Awesome&lt;/h2&gt;


	&lt;p&gt;It is human nature to look at something exceptional and feel distanced from it. But calling that feeling of distance “magic” does the exceptional a disservice. It’s a barrier we build to give us an excuse for not being exceptional ourselves. It’s not magic that separates the exceptional from the mundane: it’s awesomeness.&lt;/p&gt;


	&lt;p&gt;“Awesome” is excellence. “Awesome” is the willingness to dig into one’s domain, to explore what has been discovered, and to look beyond. “Awesome” is understanding what you do, and how and why you do it. You cannot be awesome until you look inside that black box and dispel the magic around it.&lt;/p&gt;


	&lt;p&gt;As a string figurist and a computer programmer (and someone generally aspiring to awesomeness!), I suggest that there are four cardinal rules to being awesome.&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;&lt;em&gt;Know thy tools.&lt;/em&gt;&lt;/li&gt;
		&lt;li&gt;&lt;em&gt;Know thy languages.&lt;/em&gt;&lt;/li&gt;
		&lt;li&gt;&lt;em&gt;Know thy libraries.&lt;/em&gt;&lt;/li&gt;
		&lt;li&gt;&lt;em&gt;Know thy communities.&lt;/em&gt;&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Now, when I say “know” here, I mean more than just “know about”. I mean the deeper, intuitive knowledge that comes from prolonged first-hand experience. It’s one thing to say that you know what is inside a cave. It’s another to actually go spelunking.&lt;/p&gt;


	&lt;p&gt;And it’s another entirely to meticulously explore a cave, acting as cartographer and biologist, geologist and poet, cowboy and scientist, all in one.&lt;/p&gt;


	&lt;p&gt;Part of meticulously exploring your domain, then, is asking questions. Make no assumptions. Have your own opinions. Look under every rock, and behind every corner. &lt;a href="http://en.wikipedia.org/wiki/5_Whys"&gt;Ask why five times for every question&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;When I worked at &lt;a href="http://www.byu.edu"&gt;&lt;span class="caps"&gt;BYU&lt;/span&gt;&lt;/a&gt;, my boss at the time, Doug Walker, liked to hold what he called “obnoxious question sessions”. In them, he would ask “obnoxious” questions that challenged the assumptions we had made about our systems. These could be painful and awkward if we didn’t have good answers for them. It became obvious, quickly, that we needed to have opinions about everything we did, and that we shouldn’t take anything for granted. And neither should you.&lt;/p&gt;


	&lt;p&gt;The articles that follow in this series will each be a kind of obnoxious question session. They might be painful. They might be painfully obvious! Regardless, I’ll be taking each of those four cardinal “rules of awesomeness” one at a time.&lt;/p&gt;


	&lt;p&gt;And I hope you’ll bear with me as I drag string figuring into each one!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.jamisbuck.org/">
    <author>
      <name>Jamis</name>
    </author>
    <id>tag:weblog.jamisbuck.org,2009-09-11:7754</id>
    <published>2009-09-11T15:14:00Z</published>
    <updated>2009-09-11T15:20:44Z</updated>
    <category term="Redirect" />
    <category term="interview" />
    <link href="http://weblog.jamisbuck.org/2009/9/11/new-interview-online" rel="alternate" type="text/html" />
    <title>New Interview Online</title>
<content type="html">
            &lt;p&gt;Dmitry Belitsky sent an email to prominent Rubyists with several different questions around the theme of “How to become a successful Rubyist”. He then posted their answers in interview form on &lt;a href="http://belitsky.info/"&gt;his blog&lt;/a&gt;. I was a bit late to get my answers submitted, but they’re there now. Essentially, my advice is to participate in open source, use moderation, and have non-virtual hobbies, but you can &lt;a href="http://belitsky.info/freelance/jamis-buck/"&gt;read the entire interview&lt;/a&gt; if you like.&lt;/p&gt;


	&lt;p&gt;Thanks, Dmitry!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.jamisbuck.org/">
    <author>
      <name>Jamis</name>
    </author>
    <id>tag:weblog.jamisbuck.org,2009-05-15:7586</id>
    <published>2009-05-15T03:55:00Z</published>
    <updated>2009-05-15T03:56:19Z</updated>
    <category term="Announcements" />
    <category term="Projects" />
    <category term="bucketwise" />
    <link href="http://weblog.jamisbuck.org/2009/5/15/bucketwise-v1-1-0" rel="alternate" type="text/html" />
    <title>BucketWise v1.1.0</title>
<content type="html">
            &lt;p&gt;So, I’ve now been using BucketWise for almost two months, and it’s been fantastic. Admittedly, as the author of the application, I’m willing to overlook a lot of the warts and inconsistencies, but I can honestly say I’ve felt more control over my finances these last two months than I’ve felt in the last 10 years. It’s an awesome feeling!&lt;/p&gt;


	&lt;p&gt;Tonight, I tagged &lt;a href="http://github.com/jamis/bucketwise/tree/v1.1.0"&gt;version 1.1.0 of BucketWise&lt;/a&gt;, which (if you haven’t been &lt;a href="http://github.com/jamis/bucketwise/commits/master"&gt;following along&lt;/a&gt;) fixes a few bugs and adds several new features (account reconciliation, memorized transactions, actor name autocompletion, simple budget reporting, and more; I’ll just refer you to the &lt;a href="http://github.com/jamis/bucketwise/blob/f241f0e771b2014c7d06c1fc3183671767f25d19/CHANGELOG.rdoc"&gt;changelog&lt;/a&gt; for the full list). It’s really been a fun project to tinker on. The last feature I myself really want is scheduled transactions; I may be hacking on that one in the near future.&lt;/p&gt;


	&lt;p&gt;I figured this might be a good time to talk a little about how I, personally, am using BucketWise. I’ve been surprised by a few things, both good and bad: some features I’ve found to be less useful than I anticipated, and others have been surprisingly handy!&lt;/p&gt;


	&lt;p&gt;Firstly, when you log into BucketWise, you see a short list at the top, called “Recent transactions”. This list was intended to let you see, at a glace, what you most recently had &lt;em&gt;entered&lt;/em&gt;. (It also provided a handy landing place for newly entered transactions.) It hasn’t been very useful, though; I find that what I really want is to see the register of transactions for my checking account. I may be reworking that dashboard view soon.&lt;/p&gt;


	&lt;p&gt;Also, bucket reallocations haven’t been quite as useful as I expected. I do use them, and they are definitely handy, but I find that if you shuffle money around too much, it muddies your register. The reallocations are basically noise, especially when viewing transactions at the account level. I’m going to be pondering ways to reduce their visibility.&lt;/p&gt;


	&lt;p&gt;Buckets, though, I’ve found to be spectacularly useful. I’ve got my savings account partitioned into three buckets (short term, medium term, and long term), and that’s been a great way to keep track of how those savings funds are earmarked. Also, I’m &lt;em&gt;trying&lt;/em&gt; to save 10% of each paycheck (trying, but not very successfully yet!), so I’ve got a “savings” bucket in my checking account, too. When the funds get to a certain threshold, I transfer the money to my savings account. (Yeah, I could just do a transfer with each paycheck…but I find I’m more likely to do it if I do it infrequently. Not sure why that is.)&lt;/p&gt;


	&lt;p&gt;Buckets are also great for indicating money that was given as a gift. My wife and I share the same checking account, so when it was her birthday, I transfered money from my Paypal account and put it in a “Tarasine” bucket. She was then welcome to record whatever purchases she wanted against that bucket. Similarly, when I receive money as a gift (birthday, Christmas, whatever) I just deposit it into a “Jamis” bucket.&lt;/p&gt;


	&lt;p&gt;Lastly, having credit card debt repayment built into the application has been awesome. I’ve loved being able to immediately indicate which checking account bucket a credit card purchase will be repaid from, and seeing that those funds are set aside, inviolate, ready for when the credit card bill comes.&lt;/p&gt;


	&lt;p&gt;My checking account currently has 35 buckets, and I can see my wife and I adding more. Most are purely for budgeting purposes (“groceries”, “auto fuel”, etc.), but they are so handy as ways to arbitrarily earmark money. Tithes, charitable offerings, savings, and credit card repayment are just some of the ways I’ve used them. (In fact, I’ve found myself wishing I could mark additional buckets as being “aside” buckets; I’m still pondering ways to make that happen, if it needs to.)&lt;/p&gt;


	&lt;p&gt;I’ll probably blog more about BucketWise down the road, and talk about specific use cases and how it’s helped me with them. However, I’d love to hear from others, too. Are you using BucketWise? If so, what do you like and dislike about it? I’m definitely only writing this application for me, but I’m curious to hear what the experience is like for others.&lt;/p&gt;


	&lt;p&gt;Lastly, if you’re interested in giving BucketWise a test drive, I’ve set up a demo account that you are welcome to log into and play with. I’ll reset the data there periodically, so feel free to try out all the features! Just go to &lt;a href="http://www.bucketwise.com"&gt;http://www.bucketwise.com&lt;/a&gt;, and log in with the “bw.demo” user (password “demo”). Note that this is hosted on a modest Linode host, and will almost certainly be swamped into unusability with any significant traffic, but you’re welcome to try it out.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.jamisbuck.org/">
    <author>
      <name>Jamis</name>
    </author>
    <id>tag:weblog.jamisbuck.org,2009-04-20:7494</id>
    <published>2009-04-20T13:36:00Z</published>
    <updated>2009-04-20T13:39:53Z</updated>
    <category term="Announcements" />
    <category term="bucketwise" />
    <link href="http://weblog.jamisbuck.org/2009/4/20/bucketwise-v1-0-0" rel="alternate" type="text/html" />
    <title>BucketWise v1.0.0</title>
<content type="html">
            &lt;p&gt;&lt;a href="http://github.com/jamis/bucketwise"&gt;BucketWise&lt;/a&gt; is now available! It’s far from “done”, but I’m labelling it “1.0.0” because giving code pre-1.0 version numbers is a coward’s game. (ha!)&lt;/p&gt;


	&lt;p&gt;At any rate, fork it on &lt;a href="http://github.com/jamis/bucketwise"&gt;GitHub&lt;/a&gt;, see what you think, and contribute back if you feel so inclined. The &lt;a href="https://github.com/jamis/bucketwise/blob/59a056f1dd49527ff510e506e0cbf3e807b7148d/TODO"&gt;&lt;span class="caps"&gt;TODO&lt;/span&gt;&lt;/a&gt; includes a list of unresolved issues and features I’d like to see land someday: knock yourselves out. :)&lt;/p&gt;


	&lt;p&gt;Note that I’ve tried to document the &lt;span class="caps"&gt;REST API&lt;/span&gt; for BucketWise, too; the first draft is in &lt;a href="https://github.com/jamis/bucketwise/blob/ef1d837287629fba7b034553472c89d76de632f9/doc/API.rdoc;"&gt;doc/API.rdoc&lt;/a&gt; let me know if any of that is too confusing or not informative enough (I’m sure that will be the case). I’m really looking forward to seeing what people use the &lt;span class="caps"&gt;API&lt;/span&gt; for.&lt;/p&gt;


	&lt;p&gt;Note that while the source code is now available, I’m only actually hosting the application itself for myself and a few close friends. But please feel free to deploy it to your own servers, or even just run it locally. And let me know what you think! BucketWise is super opinionated, so I’m sure I’ll get some hate mail, but that’s the name of the game when you’re playing things like this on the Internet. For me, personally, BucketWise has already proved more than worth the time I’ve invested in it so far; hopefully it’ll prove useful to others as well.&lt;/p&gt;


	&lt;p&gt;Enjoy!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.jamisbuck.org/">
    <author>
      <name>Jamis</name>
    </author>
    <id>tag:weblog.jamisbuck.org,2009-04-09:7440</id>
    <published>2009-04-09T00:46:00Z</published>
    <updated>2009-04-09T00:47:50Z</updated>
    <category term="Projects" />
    <link href="http://weblog.jamisbuck.org/2009/4/9/bucketwise-preview-2" rel="alternate" type="text/html" />
    <title>BucketWise: Preview #2</title>
<content type="html">
            &lt;p&gt;“Buckets” is now “BucketWise”. The name was more unique, easier to identify as an application, and just felt better than “Buckets”.&lt;/p&gt;


	&lt;p&gt;To celebrate the new name, I’ve also made another screencast, this one demonstrating BucketWise’s anti-debt features. It’s a bit more long-winded than the first one: five and a half minutes of me talk-talk-talking:&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://buckblog.s3.amazonaws.com/videos/bucketwise-02.mov"&gt;BucketWise Preview #2&lt;/a&gt; (QuickTime, 5:30, 10MB)&lt;/p&gt;


	&lt;p&gt;I’m slowly working my way through the list of things that I want done before I release the code. For the curious, here’s what I’m wanting done before I open it up:&lt;/p&gt;


	&lt;p&gt;Existing bugs:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;after saving a reallocation event, the line items don’t reset&lt;/li&gt;
		&lt;li&gt;green “your transaction has been recorded” notice doesn’t disappear when starting a new event&lt;/li&gt;
		&lt;li&gt;date column for event row is squashed in safari&lt;/li&gt;
		&lt;li&gt;“Add a new bucket” should set focus on new bucket line&lt;/li&gt;
		&lt;li&gt;check number and “select repayment options” links are out of whack when editing an event&lt;/li&gt;
		&lt;li&gt;deleting event from account perma results in ajax error (maybe only when there is only a single event in the account?)&lt;/li&gt;
		&lt;li&gt;Reallocating a bucket doesn’t change the updated_at field for the bucket?&lt;/li&gt;
		&lt;li&gt;“move in” and “move out” links on dashboard don’t use existing form—they go to events/new&lt;/li&gt;
		&lt;li&gt;make all autocompleting fields refresh their source array after event creation&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Remaining features:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;tag delete (optionally move transactions to different tag, e.g. “tag merge”)&lt;/li&gt;
		&lt;li&gt;tag rename&lt;/li&gt;
		&lt;li&gt;&lt;span class="caps"&gt;API&lt;/span&gt;&lt;/li&gt;
		&lt;li&gt;validations&lt;/li&gt;
		&lt;li&gt;rake tasks for user and subscription creation&lt;/li&gt;
		&lt;li&gt;change style for event detail view: “window shade” style isn’t really working&lt;/li&gt;
		&lt;li&gt;attr_protected everywhere (perhaps implement an update_override method or something for places where it would be useful to do mass updates despite protected attrs?)&lt;/li&gt;
		&lt;li&gt;spinner for ajax actions&lt;/li&gt;
		&lt;li&gt;user info page (for password change)&lt;/li&gt;
		&lt;li&gt;password reset from login page&lt;/li&gt;
		&lt;li&gt;cache balances on events (?)&lt;/li&gt;
		&lt;li&gt;&lt;span class="caps"&gt;README&lt;/span&gt; with installation instructions&lt;/li&gt;
		&lt;li&gt;&lt;span class="caps"&gt;CHANGELOG&lt;/span&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Those lists are straight from my &lt;span class="caps"&gt;TODO&lt;/span&gt; file. But for those who think I’m waiting for too much to be finished, never fear. I’ve got plenty that I want to implement, but which I’m willing to wait until post-release to work on:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;signup process&lt;/li&gt;
		&lt;li&gt;exception notifier (?)&lt;/li&gt;
		&lt;li&gt;/subscriptions index&lt;/li&gt;
		&lt;li&gt;autocomplete actor field in event form&lt;/li&gt;
		&lt;li&gt;better 404 and 500 error pages&lt;/li&gt;
		&lt;li&gt;searching &amp; reporting&lt;/li&gt;
		&lt;li&gt;account reconciliation&lt;/li&gt;
		&lt;li&gt;transaction templates (“saved” or “memorized” transactions)&lt;/li&gt;
		&lt;li&gt;scheduled transactions (occur automatically at specified intervals)&lt;/li&gt;
		&lt;li&gt;show check numbers in event detail view&lt;/li&gt;
		&lt;li&gt;add a memo field for events&lt;/li&gt;
		&lt;li&gt;print stylesheet&lt;/li&gt;
		&lt;li&gt;oauth authentication for &lt;span class="caps"&gt;API&lt;/span&gt;&lt;/li&gt;
		&lt;li&gt;filter event views to show only events with a non-zero balance for the account in question&lt;/li&gt;
		&lt;li&gt;filter event views to show only deposits, or only expenses&lt;/li&gt;
		&lt;li&gt;normalize ‘actor’ so we can do actor-centric queries more efficiently&lt;/li&gt;
		&lt;li&gt;full-text searching on the memo field&lt;/li&gt;
		&lt;li&gt;show bucket and account balances next to names in drop-downs&lt;/li&gt;
		&lt;li&gt;make bucket reallocation work from bucket perma&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Depending on how soon my bank sends the next statement for my checking account, I may or may not need to have “account reconciliation” done before launch, too.&lt;/p&gt;


	&lt;p&gt;As before, let me state: I’m writing this application for myself, and really only for myself. If other people like it, that’s cool. I’m more than happy to share and let other people hack on it. I may even release it into the public domain (I haven’t yet decided what license I’ll use). But BucketWise will &lt;em&gt;always&lt;/em&gt; be very opinionated. If you prefer having your finance app download your transactions from your bank, you’ll be disappointed by BucketWise. If you need currencies other than the US dollar, you’ll be disappointed by BucketWise. If you need pretty charts and graphs to analyze your cash flow, or if you want to track investments, or any number of other things, you’ll be disappointed by BucketWise.&lt;/p&gt;


	&lt;p&gt;Just &lt;span class="caps"&gt;FYI&lt;/span&gt;. :)&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.jamisbuck.org/">
    <author>
      <name>Jamis</name>
    </author>
    <id>tag:weblog.jamisbuck.org,2009-03-24:6683</id>
    <published>2009-03-24T14:07:00Z</published>
    <updated>2009-03-24T14:30:02Z</updated>
    <category term="Projects" />
    <category term="buckets" />
    <link href="http://weblog.jamisbuck.org/2009/3/24/buckets-preview" rel="alternate" type="text/html" />
    <title>Buckets: Preview</title>
<content type="html">
            &lt;p&gt;So, yeah. With &lt;a href="http://weblog.jamisbuck.org/2009/2/25/net-ssh-capistrano-and-saying-goodbye"&gt;Capistrano and friends off my plate&lt;/a&gt;, I’ve actually found time to work on a project that has been in the works for &lt;em&gt;years&lt;/em&gt; (and that’s no exaggeration, I first mentioned it in a blog post in &lt;a href="http://weblog.jamisbuck.org/2004/10/31/too-many-distractions"&gt;October 2004&lt;/a&gt;). I’ve named it and renamed it (“Penny Pincher”, “Chump Change”, “Make Me Rich”, and “BudgetWise”) but its current incarnation is “Buckets”.&lt;/p&gt;


	&lt;p&gt;Buckets is a simple web-based personal finance application that I’ve been working on, written specifically for my wife and me. Its focus is on simple budgeting, and reducing debt, and It is intentionally “feature-poor”. It is loosely based on an &lt;a href="http://www.daveramsey.com/etc/cms/index.cfm?intContentID=3461"&gt;envelope budgeting strategy&lt;/a&gt;, and while it definitely isn’t the only web-based finance app using such a strategy, it just may be the simplest.&lt;/p&gt;


	&lt;p&gt;I recorded a screencast demonstrating the budgeting aspect of Buckets; it’s a 5M QuickTime movie, 2:42 in length. &lt;a href="http://buckblog.s3.amazonaws.com/videos/buckets-01.mov"&gt;Click here to view it, if you care to.&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Buckets is still private: it has been deployed and my wife and I are using it, but that’s it. The source code is in a private repository on &lt;a href="http://www.github.com"&gt;GitHub&lt;/a&gt;, and the production instance of the app is currently only accessible to me. That will change eventually (maybe a couple of weeks, depending on how initial testing goes), but I want to make sure it’s actually going to be useful before I open it up.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.jamisbuck.org/">
    <author>
      <name>Jamis</name>
    </author>
    <id>tag:weblog.jamisbuck.org,2009-02-25:6054</id>
    <published>2009-02-25T04:38:00Z</published>
    <updated>2009-04-09T13:43:03Z</updated>
    <category term="Projects" />
    <category term="capistrano" />
    <category term="net-scp" />
    <category term="net-sftp" />
    <category term="net-ssh" />
    <link href="http://weblog.jamisbuck.org/2009/2/25/net-ssh-capistrano-and-saying-goodbye" rel="alternate" type="text/html" />
    <title>Net::SSH, Capistrano, and Saying Goodbye</title>
<content type="html">
            &lt;p&gt;It is with mixed emotions that I announce two things this evening.&lt;/p&gt;


	&lt;p&gt;First, I’m announcing the final release of both Net::SSH (2.0.11) and Capistrano (2.5.5). Both are minor changes: Net::SSH 2.0.11 adds support for a :key_data option, so you can supply raw &lt;span class="caps"&gt;PEM&lt;/span&gt;-formatted key data. Capistrano 2.5.5 enhances the role() method so you can now declare empty roles. Either way, not much to get excited about, but the changes were pending and deserved releasing.&lt;/p&gt;


	&lt;p&gt;Secondly: I’m ceasing development on &lt;a href="http://github.com/jamis/sqlite-ruby/tree/master"&gt;SQLite/Ruby&lt;/a&gt;, &lt;a href="http://github.com/jamis/sqlite3-ruby/tree/master"&gt;SQLite3/Ruby&lt;/a&gt;, &lt;a href="http://github.com/jamis/net-ssh/tree"&gt;Net::SSH&lt;/a&gt; (and related libs, &lt;a href="http://github.com/jamis/net-sftp/tree"&gt;Net::SFTP&lt;/a&gt;, &lt;a href="http://github.com/jamis/net-scp/tree"&gt;Net::SCP&lt;/a&gt;, etc.) and &lt;a href="http://github.com/jamis/capistrano/tree"&gt;Capistrano&lt;/a&gt;. I will no longer be accepting patches, bug reports, support requests, feature requests, or general emails related to any of these projects. For Capistrano, I will continue to follow the mailing list, and might appear in the #capistrano irc channel from time to time, but I am no longer the maintainer of these projects. I will continue to host the capify.org site and wiki for as long as they are of use to people.&lt;/p&gt;


	&lt;p&gt;This was a very hard decision, and one that has taken me months to come to grips with. I cannot express how much I appreciate the huge support from everyone that has found value in Capistrano, in particular. Your kind words and encouragement have meant a lot to me. But I’m burning out, and I have to drop these before things get worse. Maybe after some period of time I’ll come back to them—I don’t know. But I’m not planning on it.&lt;/p&gt;


	&lt;p&gt;So where do these projects go from here? That’s entirely up to the community. If you have a neat idea for any of these, please feel free to fork the project on GitHub (see my &lt;a href="http://github.com/jamis"&gt;profile page&lt;/a&gt; for the links to the individual projects) and release updates on your own schedule. If no one steps forward, that’s fine—I’m not asking for volunteers. But if someone feels passionately that any of these are not “finished”, and has ideas for how they could be further improved, I will not stand in the way.&lt;/p&gt;


	&lt;p&gt;However, please know that I am &lt;em&gt;not available&lt;/em&gt; for questions about the code, or for advice on how to implement changes. I’m trying to cut as cleanly as I can. Any emails I get asking about the code will likely be ignored. I’m not trying to be rude; I’m just setting expectations.&lt;/p&gt;


	&lt;p&gt;I won’t disappear, though. These libraries were just becoming millstones around my neck; without their weight dragging me down, I look forward to being able to experiment and play with new projects and new ideas. We’ll see what the future holds!&lt;/p&gt;


	&lt;p&gt;So, thanks all for a fantastic couple of years.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.jamisbuck.org/">
    <author>
      <name>Jamis</name>
    </author>
    <id>tag:weblog.jamisbuck.org,2009-02-02:5883</id>
    <published>2009-02-02T03:58:00Z</published>
    <updated>2009-02-02T04:10:10Z</updated>
    <category term="Announcements" />
    <category term="sftp" />
    <category term="ssh" />
    <link href="http://weblog.jamisbuck.org/2009/2/2/net-ssh-and-friends-update" rel="alternate" type="text/html" />
    <title>Net::SSH and friends, update</title>
<content type="html">
            &lt;p&gt;This is a multi-project release announcement, so brace yourselves.&lt;/p&gt;


	&lt;p&gt;In short, Net::SSH 2.0.9, Net::SFTP 2.0.2, Net::SSH::Gateway 1.0.1, and Net::SSH::Multi 1.0.1 have been released. Get ‘em while they’re hot!&lt;/p&gt;


	&lt;p&gt;It’s all just bug fixes, for the most part, but if you want more nitty gritty, read on.&lt;/p&gt;


	&lt;h2&gt;Net::SSH 2.0.9&lt;/h2&gt;


	&lt;p&gt;The following issues have been addressed in Net::SSH 2.0.9:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;If you specify a non-nil &lt;code&gt;user&lt;/code&gt; argument to Net::SSH#start, it will override whatever setting exists for &lt;code&gt;User&lt;/code&gt; in your .ssh/config file. (Prior to this, the .ssh/config’s &lt;code&gt;User&lt;/code&gt; setting would always be used, regardless of what user you specified to Net::SSH::start.)&lt;/li&gt;
		&lt;li&gt;Some naughty ssh servers send channel requests even after the channel has been closed. Net::SSH handles these spurious requests better now.&lt;/li&gt;
		&lt;li&gt;Net::SSH::Connection::Session#shutdown! has been added for hard shutdown scenarios (where an error leaves the connection in an ambiguous state and you just want to terminate the connection without all that touchy-feely “graceful shutdown” nonsense).&lt;/li&gt;
		&lt;li&gt;The key loading behavior has been further tweaked so that Net::SSH will try to load public keys first (by appending ”.pub” to the given key file name), and if no public key with that name exists, the corresponding private key will be attempted. This way, operations that only need the public key will not require the (possibly encrypted) private key to be loaded in order to succeed.&lt;/li&gt;
		&lt;li&gt;The :passphrase option was being dropped on its way to the key manager. It is now passed all the way through, so that specifying the :passphrase option actually works now.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h2&gt;Net::SFTP 2.0.2&lt;/h2&gt;


	&lt;p&gt;Only one bug fix: if an exception was raised from within the Net::SFTP::start block, it could leave the Net::SSH session trying to gracefully close channels on a borked connection. Net::SFTP will now, instead, do a hard shutdown of the ssh session connection, rather than trying to gracefully close, if an exception every bubbles up outside the block. (A side effect of this is that Net::SFTP 2.0.2 depends on Net::SSH 2.0.9, so you can’t get one without the other.)&lt;/p&gt;


	&lt;h2&gt;Net::SSH::Gateway 1.0.1&lt;/h2&gt;


	&lt;p&gt;Just one minor new feature was added: you can now specify the exact port number on the local host that you want the gateway to be created on. Just pass an optional third parameter to Gateway#open. This will default to the original behavior (selecting the next available port number), but now allows you greater flexibility in how you use Net::SSH::Gateway.&lt;/p&gt;


	&lt;h2&gt;Net::SSH::Multi 1.0.1&lt;/h2&gt;


	&lt;p&gt;Just one minor new feature: an Channel#on_open_failed callback hook was added, to mirror the on_open_failed callback hook in Net::SSH.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.jamisbuck.org/">
    <author>
      <name>Jamis</name>
    </author>
    <id>tag:weblog.jamisbuck.org,2009-01-28:5847</id>
    <published>2009-01-28T17:47:00Z</published>
    <updated>2009-04-09T04:27:17Z</updated>
    <category term="Projects" />
    <category term="fuzzyfinder" />
    <category term="textmate" />
    <category term="vim" />
    <link href="http://weblog.jamisbuck.org/2009/1/28/the-future-of-fuzzyfinder-textmate" rel="alternate" type="text/html" />
    <title>The future of FuzzyFinder-TextMate</title>
<content type="html">
            &lt;p&gt;Back in October I released a Vim extension for &lt;a href="http://weblog.jamisbuck.org/2008/10/10/coming-home-to-vim"&gt;mimicking TextMate’s cmd-T file lookup feature&lt;/a&gt;. I use it heavily now, and it works great for me.&lt;/p&gt;


	&lt;p&gt;Sadly, the author of the &lt;a href="http://www.vim.org/scripts/script.php?script_id=1984"&gt;FuzzyFinder&lt;/a&gt; Vim script, upon which my extension depends, keeps changing internal implementation details that I had to hook into to make my extension work. The result? Every few weeks my extension breaks with the latest FuzzyFinder.&lt;/p&gt;


	&lt;p&gt;Needless to say, this is work I don’t need. The fuzzyfinder-textmate stuff works fine for me. It works fine for people on older versions of FuzzyFinder. And I really don’t care to support this anymore.&lt;/p&gt;


	&lt;p&gt;If you’re passionate about this, please feel free to &lt;a href="http://github.com/jamis/fuzzyfinder_textmate/tree/master"&gt;fork the project on GitHub&lt;/a&gt; and release your changes independently. Feel free to post your changes on the vim script page, even! I hereby release that code into the public domain. Do with it as you please!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.jamisbuck.org/">
    <author>
      <name>Jamis</name>
    </author>
    <id>tag:weblog.jamisbuck.org,2008-12-07:5632</id>
    <published>2008-12-07T05:16:00Z</published>
    <updated>2008-12-07T05:22:40Z</updated>
    <category term="Projects" />
    <category term="sqlite3-ruby" />
    <link href="http://weblog.jamisbuck.org/2008/12/7/sqlite3-ruby-windows-builds" rel="alternate" type="text/html" />
    <title>SQlite3-Ruby Windows Builds</title>
<content type="html">
            &lt;p&gt;So, I’ve got a new sqlite3-ruby release pending (just a minor bug fix, is all), but I’ve learned my lesson about releasing a new version without a windows version pre-built.&lt;/p&gt;


	&lt;p&gt;The problem is, I’m not a Windows guy. My build environment for Windows is cobbled together and painful to use, when it works at all. I’ve decided that I won’t put myself through that pain anymore.&lt;/p&gt;


	&lt;p&gt;If you are a developer on Windows, and you have a sqlite3 build environment, and would be willing to compile the sqlite3-ruby extension for me, please do the following:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Add a comment to this post, indicating your name, and what platform you would be willing to build for (cygwin, native windows, whatever. I don’t even know the right names.)&lt;/li&gt;
		&lt;li&gt;Reload the page, and make sure no one commented before you, claiming those platforms.&lt;/li&gt;
		&lt;li&gt;Grab the latest version of sqlite3-ruby here: &lt;a href="http://github.com/jamis/sqlite3-ruby/tree/master"&gt;http://github.com/jamis/sqlite3-ruby/tree/master&lt;/a&gt;.&lt;/li&gt;
		&lt;li&gt;Build the extension, and email it to me at jamis at 37signals dot com.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Once I have a build of sqlite3-ruby for windows, I’ll release the new gem. (It amazes me how painful Windows makes this process. Mac &lt;span class="caps"&gt;OS X&lt;/span&gt;, Linux, &lt;span class="caps"&gt;BSD&lt;/span&gt;, etc. —you just gem install and build the source. No such luck in the Windows realm, apparently.)&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://weblog.jamisbuck.org/">
    <author>
      <name>Jamis</name>
    </author>
    <id>tag:weblog.jamisbuck.org,2008-11-29:5601</id>
    <published>2008-11-29T14:40:00Z</published>
    <updated>2008-11-29T14:44:27Z</updated>
    <category term="Redirect" />
    <category term="copland" />
    <category term="dependency-injection" />
    <category term="java" />
    <category term="needle" />
    <category term="net-ssh" />
    <category term="rubyconf" />
    <link href="http://weblog.jamisbuck.org/2008/11/29/recovering-from-enterprise-video-available" rel="alternate" type="text/html" />
    <title>"Recovering from Enterprise" video available</title>
<content type="html">
            &lt;p&gt;It appears that &lt;a href="http://www.confreaks.com"&gt;Confreaks&lt;/a&gt; has posted the video of my &lt;a href="http://rubyconf2008.confreaks.com/recovering-from-enterprise.html"&gt;‘Recovering from Enterprise’ talk from RubyConf 2008&lt;/a&gt;. As usual, Confreaks did a great job recording the talks at RubyConf.&lt;/p&gt;


	&lt;p&gt;For those who missed it, I also posted an article version of my presentation, titled &lt;a href="http://weblog.jamisbuck.org/2008/11/9/legos-play-doh-and-programming"&gt;Legos, Play-doh, and Programming&lt;/a&gt;.&lt;/p&gt;
          </content>  </entry>
</feed>
