<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>module?.exports = Blog &#187; programming</title>
	<atom:link href="http://benatkin.com/tag/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://benatkin.com</link>
	<description>Ben Atkin&#039;s blog</description>
	<lastBuildDate>Thu, 10 May 2012 04:36:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Links: Parsing in Ruby and JavaScript</title>
		<link>http://benatkin.com/2011/12/01/parsing-in-ruby-and-javascript/</link>
		<comments>http://benatkin.com/2011/12/01/parsing-in-ruby-and-javascript/#comments</comments>
		<pubDate>Fri, 02 Dec 2011 06:53:38 +0000</pubDate>
		<dc:creator>Ben Atkin</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[links]]></category>
		<category><![CDATA[parsing]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[templating]]></category>

		<guid isPermaLink="false">http://benatkin.com/?p=1067</guid>
		<description><![CDATA[I&#8217;ve been reading quite a bit about parsing and templating in ruby as I attempt to port a templating engine from JavaScript to Ruby. Here are some scattered links: Jison Jison is a parser generator for JavaScript that has separate &#8230; <a href="http://benatkin.com/2011/12/01/parsing-in-ruby-and-javascript/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been reading quite a bit about parsing and templating in ruby as I attempt to port a templating engine from JavaScript to Ruby. Here are some scattered links:</p>
<h3>Jison</h3>
<p>Jison is a parser generator for JavaScript that has separate lex and bnf definitions. It&#8217;s used by <a href="https://github.com/wycats/handlebars.js/">Handlebars.js</a>.</p>
<div class="resource-infobox"><div class="resource-infobox-field"><span class="resource-infobox-label">Repository</span><a class="resource-infobox-value" href="https://github.com/zaach/jison/">jison</a></div><div class="resource-infobox-field"><span class="resource-infobox-label">Owner</span><a class="resource-infobox-value" href="https://github.com/zaach/">zaach</a></div><div class="resource-infobox-field"><span class="resource-infobox-label">Last Commit</span><span class="resource-infobox-value">2012-05-16</span></div><div class="resource-infobox-field"><span class="resource-infobox-label">Watchers</span><span class="resource-infobox-value">560</span></div><div class="resource-infobox-clear"></div></div>
<h3>Treetop</h3>
<p>Treetop is a parser generator for Ruby. It&#8217;s installed with Ruby On Rails, through the <code>mail</code> gem which is installed by ActionMailer.</p>
<div class="resource-infobox"><div class="resource-infobox-field"><span class="resource-infobox-label">Repository</span><a class="resource-infobox-value" href="https://github.com/nathansobo/treetop/">treetop</a></div><div class="resource-infobox-field"><span class="resource-infobox-label">Owner</span><a class="resource-infobox-value" href="https://github.com/nathansobo/">nathansobo</a></div><div class="resource-infobox-field"><span class="resource-infobox-label">Last Commit</span><span class="resource-infobox-value">2012-03-29</span></div><div class="resource-infobox-field"><span class="resource-infobox-label">Watchers</span><span class="resource-infobox-value">447</span></div><div class="resource-infobox-clear"></div></div>
<h3>Citrus</h3>
<p>Citrus is another promising parsing gem for Ruby. It seems to be very easy to get started with, and I like many of the design decisions.</p>
<div class="resource-infobox"><div class="resource-infobox-field"><span class="resource-infobox-label">Repository</span><a class="resource-infobox-value" href="https://github.com/mjijackson/citrus/">citrus</a></div><div class="resource-infobox-field"><span class="resource-infobox-label">Owner</span><a class="resource-infobox-value" href="https://github.com/mjijackson/">mjijackson</a></div><div class="resource-infobox-field"><span class="resource-infobox-label">Last Commit</span><span class="resource-infobox-value">2012-02-24</span></div><div class="resource-infobox-field"><span class="resource-infobox-label">Watchers</span><span class="resource-infobox-value">177</span></div><div class="resource-infobox-clear"></div></div>
<h3>Temple</h3>
<p>Temple is a templating-specific library that helps with a lot of the AST transformation. It doesn&#8217;t seem to have a CFG syntax so it seems that using treetop or citrus would make sense for complex grammars. Otherwise, strscan could be used.</p>
<div class="resource-infobox"><div class="resource-infobox-field"><span class="resource-infobox-label">Repository</span><a class="resource-infobox-value" href="https://github.com/judofyr/temple/">temple</a></div><div class="resource-infobox-field"><span class="resource-infobox-label">Owner</span><a class="resource-infobox-value" href="https://github.com/judofyr/">judofyr</a></div><div class="resource-infobox-field"><span class="resource-infobox-label">Last Commit</span><span class="resource-infobox-value">2012-02-26</span></div><div class="resource-infobox-field"><span class="resource-infobox-label">Watchers</span><span class="resource-infobox-value">154</span></div><div class="resource-infobox-clear"></div></div>
<h3>temple-mustache</h3>
<p>This is an implementation of a mustache renderer in . It uses strscan to generate the initial parse tree, and Temple to generate the ruby code. It supports mustache sections.</p>
<div class="resource-infobox"><div class="resource-infobox-field"><span class="resource-infobox-label">Repository</span><a class="resource-infobox-value" href="https://github.com/minad/temple-mustache/">temple-mustache</a></div><div class="resource-infobox-field"><span class="resource-infobox-label">Owner</span><a class="resource-infobox-value" href="https://github.com/minad/">minad</a></div><div class="resource-infobox-field"><span class="resource-infobox-label">Last Commit</span><span class="resource-infobox-value">2011-05-04</span></div><div class="resource-infobox-field"><span class="resource-infobox-label">Watchers</span><span class="resource-infobox-value">1</span></div><div class="resource-infobox-clear"></div></div>
<h3>Slim</h3>
<p>Slim is a Haml-like templating library for Ruby that&#8217;s used in production by many. It uses Temple, with a line-based parser, which works well because it uses significant indentation for nesting.</p>
<div class="resource-infobox"><div class="resource-infobox-field"><span class="resource-infobox-label">Repository</span><a class="resource-infobox-value" href="https://github.com/stonean/slim/">slim</a></div><div class="resource-infobox-field"><span class="resource-infobox-label">Owner</span><a class="resource-infobox-value" href="https://github.com/stonean/">stonean</a></div><div class="resource-infobox-field"><span class="resource-infobox-label">Last Commit</span><span class="resource-infobox-value">2012-04-14</span></div><div class="resource-infobox-field"><span class="resource-infobox-label">Watchers</span><span class="resource-infobox-value">1119</span></div><div class="resource-infobox-clear"></div></div>
]]></content:encoded>
			<wfw:commentRss>http://benatkin.com/2011/12/01/parsing-in-ruby-and-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Front Range Pythoneers: Bowling Code Kata</title>
		<link>http://benatkin.com/2011/12/01/front-range-pythoneers-bowling-code-kata/</link>
		<comments>http://benatkin.com/2011/12/01/front-range-pythoneers-bowling-code-kata/#comments</comments>
		<pubDate>Thu, 01 Dec 2011 07:03:21 +0000</pubDate>
		<dc:creator>Ben Atkin</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[practice]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://benatkin.com/?p=1063</guid>
		<description><![CDATA[For the November meeting of Front Range Pythoneers we did a bowling code kata. We worked as a group on the projector, but I also worked on my own version on my laptop. Here&#8217;s my code, which was fun to &#8230; <a href="http://benatkin.com/2011/12/01/front-range-pythoneers-bowling-code-kata/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>For the November meeting of <a href="http://www.meetup.com/frpythoneers/">Front Range Pythoneers</a> we did a bowling code kata. We worked as a group on the projector, but I also worked on my own version on my laptop. Here&#8217;s my code, which was fun to write. It&#8217;s a single file which contains its test cases and can be run on the command line or imported:</p>
<pre class="brush: python; title: ; notranslate">
import unittest

class Frame(object):
    def __init__(self, tenth=False):
        self.rolls = []
        self.tenth = tenth

    def full(self):
        if len(self.rolls) &gt;= self.max_rolls():
            return True
        if self.tenth:
            has_special = all([roll in ('X', '/') for roll in self.rolls])
            return len(self.rolls) == 2 and not has_special
        else:
            return self.strike()

    def roll(self, score):
        if self.full():
            raise RuntimeError('attempted to record a roll on a full frame')
        self.rolls.append(score)

    def pins(self):
        if len(self.rolls) == 0:
            return 0
        if self.strike() or self.spare():
            return 10
        else:
            return sum([int(roll) for roll in self.rolls])

    def first_roll_pins(self):
        if len(self.rolls) == 0:
            return 0
        elif self.rolls[0] == 'X':
            return 10
        else:
            return int(self.rolls[0])

    def score(self, subsequent_frames):
        if self.tenth:
            return self.tenth_frame_score()

        score = self.pins()
        if self.strike():
            score += sum([frame.pins() for frame in subsequent_frames])
        elif self.spare():
            if len(subsequent_frames) &gt; 0:
                score += subsequent_frames[0].first_roll_pins()
        return score

    def tenth_frame_score(self):
        return min(Game(''.join(self.rolls)).score(), 40)

    def strike(self):
        return len(self.rolls) &gt; 0 and self.rolls[0] == 'X'

    def spare(self):
        return len(self.rolls) &gt; 0 and self.rolls[-1] == '/'

    def max_rolls(self):
        return 3 if self.tenth else 2

class Game(object):
    def __init__(self, roll_scores=''):
        self.frames = []
        for score in roll_scores:
            self.roll(score)

    def roll(self, score):
        if len(self.frames) == 0 or self.frames[-1].full():
            tenth = len(self.frames) == 9
            self.frames.append(Frame(tenth))
        self.frames[-1].roll(score)

    def score(self):
        return sum(self.frame_scores())

    def frame_scores(self):
        frame_scores = []
        for frame_index in xrange(len(self.frames)):
            frame = self.frames[frame_index]
            subsequent_frames = []
            if frame.strike() or frame.spare():
                subsequent_frames = self.frames[frame_index+1:]
                added_frames = 1
                if frame.strike() and len(subsequent_frames) &gt; 0:
                    added_frames = 2 if subsequent_frames[0].strike() else 1
                subsequent_frames = subsequent_frames[:added_frames]
            frame_scores.append(frame.score(subsequent_frames))
        return frame_scores

class GameTest(unittest.TestCase):
    def test_initial_strike(self):
        self.assertEqual(Game('X').score(), 10)

    def test_two_strikes(self):
        self.assertEqual(Game('XX').score(), 20+10)

    def test_three_strikes(self):
        self.assertEqual(Game('XXX').score(), 30+20+10)

    def test_strike_spare_strike(self):
        self.assertEqual(Game('X9/X').score(), 20+20+10)

    def test_strike_strike_spare(self):
        self.assertEqual(Game('XX9/').score(), 30+20+10)
        self.assertEqual(Game('XX9/71').score(), 30+20+17+8)

    def test_perfect_game(self):
        game = Game('X'*12)
        self.assertEqual(len(game.frames), 10)
        self.assertEqual(game.score(), 300)

    def test_made_up_game(self):
        game = Game('X907/818/X70070/72')
        self.assertEqual(len(game.frames), 10)
        self.assertEqual(game.score(), 132)

if __name__ == '__main__':
    unittest.main()
</pre>
<p>I think that the tenth frame calculation is incorrect. My limited understanding of bowling slowed me down a fair bit. I got an object system that I&#8217;m fairly happy with, though!</p>
]]></content:encoded>
			<wfw:commentRss>http://benatkin.com/2011/12/01/front-range-pythoneers-bowling-code-kata/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>how rails depends on treetop, and how I found that out</title>
		<link>http://benatkin.com/2011/11/28/how-rails-depends-on-treetop-and-how-i-found-that-out/</link>
		<comments>http://benatkin.com/2011/11/28/how-rails-depends-on-treetop-and-how-i-found-that-out/#comments</comments>
		<pubDate>Mon, 28 Nov 2011 07:55:22 +0000</pubDate>
		<dc:creator>Ben Atkin</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[dependencies]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[thought process]]></category>
		<category><![CDATA[treetop]]></category>

		<guid isPermaLink="false">http://benatkin.com/?p=1058</guid>
		<description><![CDATA[I&#8217;m working on a project where I think I&#8217;ll be using a parser library so I&#8217;ve been looking at the options. One thing I&#8217;ve noticed is that treetop is installed when Rails is installed. I didn&#8217;t know why, though, so &#8230; <a href="http://benatkin.com/2011/11/28/how-rails-depends-on-treetop-and-how-i-found-that-out/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m working on a project where I think I&#8217;ll be using a parser library so I&#8217;ve been looking at the options. One thing I&#8217;ve noticed is that treetop is installed when Rails is installed. I didn&#8217;t know why, though, so I looked around.</p>
<p>First I looked at the Gemfile.lock. Had I known the format I would have found out my answer more quickly. I didn&#8217;t, though, and so when I found my first result for treetop, I stopped. It showed treetop below specs in the hierarchy.</p>
<pre class="brush: plain; title: ; notranslate">
GEM
  remote: http://rubygems.org/
  specs:
    # ...snip...
    thor (0.14.6)
    tilt (1.3.3)
    treetop (1.4.10)
      polyglot
      polyglot (&gt;= 0.3.1)
    tzinfo (0.3.30)
    uglifier (1.0.3)
</pre>
<p>The next thing I did was run <code>find . -iname '*.treetop'</code> in <code>~/.rbenv</code>. It found the following results:</p>
<pre class="brush: plain; title: ; notranslate">
(mbp) ~/.rbenv/versions/1.9.2-p290 $ find . -iname '*.treetop'
./lib/ruby/gems/1.9.1/gems/erector-0.8.3/lib/erector/erect/rhtml.treetop
./lib/ruby/gems/1.9.1/gems/mail-2.3.0/lib/mail/parsers/address_lists.treetop
./lib/ruby/gems/1.9.1/gems/mail-2.3.0/lib/mail/parsers/content_disposition.treetop
./lib/ruby/gems/1.9.1/gems/mail-2.3.0/lib/mail/parsers/content_location.treetop
./lib/ruby/gems/1.9.1/gems/mail-2.3.0/lib/mail/parsers/content_transfer_encoding.treetop
./lib/ruby/gems/1.9.1/gems/mail-2.3.0/lib/mail/parsers/content_type.treetop
./lib/ruby/gems/1.9.1/gems/mail-2.3.0/lib/mail/parsers/date_time.treetop
./lib/ruby/gems/1.9.1/gems/mail-2.3.0/lib/mail/parsers/envelope_from.treetop
./lib/ruby/gems/1.9.1/gems/mail-2.3.0/lib/mail/parsers/message_ids.treetop
./lib/ruby/gems/1.9.1/gems/mail-2.3.0/lib/mail/parsers/mime_version.treetop
./lib/ruby/gems/1.9.1/gems/mail-2.3.0/lib/mail/parsers/phrase_lists.treetop
./lib/ruby/gems/1.9.1/gems/mail-2.3.0/lib/mail/parsers/received.treetop
./lib/ruby/gems/1.9.1/gems/mail-2.3.0/lib/mail/parsers/rfc2045.treetop
./lib/ruby/gems/1.9.1/gems/mail-2.3.0/lib/mail/parsers/rfc2822.treetop
./lib/ruby/gems/1.9.1/gems/mail-2.3.0/lib/mail/parsers/rfc2822_obsolete.treetop
./lib/ruby/gems/1.9.1/gems/treetop-1.4.10/examples/lambda_calculus/arithmetic.treetop
./lib/ruby/gems/1.9.1/gems/treetop-1.4.10/examples/lambda_calculus/lambda_calculus.treetop
./lib/ruby/gems/1.9.1/gems/treetop-1.4.10/lib/treetop/compiler/metagrammar.treetop
./lib/ruby/gems/1.9.1/gems/treetop-1.4.10/spec/compiler/test_grammar.treetop
./lib/ruby/gems/1.9.1/gems/treetop-1.4.10/spec/compiler/test_grammar_do.treetop
./lib/ruby/gems/1.9.1/gems/treetop-1.4.10/spec/composition/a.treetop
./lib/ruby/gems/1.9.1/gems/treetop-1.4.10/spec/composition/b.treetop
./lib/ruby/gems/1.9.1/gems/treetop-1.4.10/spec/composition/c.treetop
./lib/ruby/gems/1.9.1/gems/treetop-1.4.10/spec/composition/d.treetop
./lib/ruby/gems/1.9.1/gems/treetop-1.4.10/spec/composition/f.treetop
./lib/ruby/gems/1.9.1/gems/treetop-1.4.10/spec/composition/subfolder/e_includes_c.treetop
(mbp) ~/.rbenv/versions/1.9.2-p290 $
</pre>
<p>Aha, so there are numerous treetop files in actionmailer! I have my answer. Seems like a good use of a parser, plus those may be worth using as examples.</p>
<p>Then I took another look at a <a href="https://github.com/benatkin/dailygit/blob/master/Gemfile.lock">Gemfile.lock</a> from a rails project, and saw that it was plainly listed there. I just didn&#8217;t see it and didn&#8217;t keep looking after I found one.</p>
<pre class="brush: plain; title: ; notranslate">
GEM
  remote: http://rubygems.org/
  specs:
    XMLCanonicalizer (1.0.1)
      log4r (&gt;= 1.0.4)
    actionmailer (3.1.1)
      actionpack (= 3.1.1)
      mail (~&gt; 2.3.0)
  # ...snip...
</pre>
<p>I noticed something: Gemfile.lock doesn&#8217;t show an arbitrarily nested hierarchy; instead it shows a list of gems and their dependencies, where the list of gems includes all gems. Then, separately at the end of the file, it shows the top-level gems from the Gemfile.</p>
<p>To see a deeply nested, a graph could be constructed from the Gemfile.lock, using the two nesting levels under <code>specs</code> as an adjacency list.</p>
]]></content:encoded>
			<wfw:commentRss>http://benatkin.com/2011/11/28/how-rails-depends-on-treetop-and-how-i-found-that-out/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Five Megabyte Web Developer</title>
		<link>http://benatkin.com/2011/11/27/the-five-megabyte-web-developer/</link>
		<comments>http://benatkin.com/2011/11/27/the-five-megabyte-web-developer/#comments</comments>
		<pubDate>Sun, 27 Nov 2011 22:44:37 +0000</pubDate>
		<dc:creator>Ben Atkin</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[pontifications]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[servers]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[VPS]]></category>

		<guid isPermaLink="false">http://benatkin.com/?p=1048</guid>
		<description><![CDATA[In the last couple of years I&#8217;ve witnessed a disturbing trend: developers adopting free Heroku as their only means of hosting side projects. More disturbingly, I operated this way myself for a couple of years. (Yes, freemium can be a &#8230; <a href="http://benatkin.com/2011/11/27/the-five-megabyte-web-developer/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In the last couple of years I&#8217;ve witnessed a disturbing trend: developers adopting free Heroku as their only means of hosting side projects. More disturbingly, I operated this way myself for a couple of years. (Yes, freemium can be a trap for customers just like it can be a trap for businesses.)</p>
<p>Heroku has five megabytes for database space, which often sounds like it ought to be enough when it isn&#8217;t. Want auditing and comments? Nah, that&#8217;ll take up too much space. Its single dyno free plan serves one request at a time. The next steps up are twenty dollars a month and five cents an hour for databases and dynos, respectively. These aren&#8217;t that expensive for a major project, but for several side projects it quickly adds up.</p>
<p>I realized this and switched back to running a VPS, this time on <a href="http://zerigo.com/">Zerigo</a>, which I pay for annually. There is no limit to the number of apps I have. Concurrent requests are supported. They can use the same databases. Database backups are free and uncomplicated. I&#8217;m also happy to be outside of the cloud oligopoly that seems to be forming.</p>
<p>Besides that, it&#8217;s fun! I get to try niche language platforms. Node.js was building steam long before Heroku supported it, and it still doesn&#8217;t support websockets. It&#8217;s not hard to find, with a little thinking, other interesting platforms to try. How about <a href="http://racket-lang.org/">Racket</a> or <a href="http://factorcode.org/">Factor</a>? Or setting up your own <a href="http://lucene.apache.org/java/docs/index.html">Lucene</a> server, or a web server that uses the git command line tool? Those can&#8217;t (easily) be run with Heroku.</p>
<p>I find anecdotally that most developers don&#8217;t have their own websites or non-trivial side projects. I only have the first, but I can sense that my personal website is helping me prepare to launch non-trivial side projects. I&#8217;ve done very little work to set up this server, yet despite tweeting about it and having visitors and occasional commenters, it stays up. That gives me the confidence I need to launch something bigger.</p>
<p>My plea to other developers (and aspiring developers) out there is to draw parallels between programming and other creative works and find out how much you could responsibly be spending for hosting side projects, and then realize that there&#8217;s no reason you shouldn&#8217;t have at least a VPS.</p>
]]></content:encoded>
			<wfw:commentRss>http://benatkin.com/2011/11/27/the-five-megabyte-web-developer/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>converting a search to a replace in vim</title>
		<link>http://benatkin.com/2011/11/05/converting-a-search-to-a-replace-in-vim/</link>
		<comments>http://benatkin.com/2011/11/05/converting-a-search-to-a-replace-in-vim/#comments</comments>
		<pubDate>Sat, 05 Nov 2011 20:48:41 +0000</pubDate>
		<dc:creator>Ben Atkin</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[editing]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[regex]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://benatkin.com/?p=1028</guid>
		<description><![CDATA[I just googled something I&#8217;ve always wanted to know how to do in vim, and was surprised how quickly I found the answer. In vim, there are separate modes for searching and commands. This generally works well as they have &#8230; <a href="http://benatkin.com/2011/11/05/converting-a-search-to-a-replace-in-vim/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I just googled something I&#8217;ve always wanted to know how to do in vim, and was surprised how quickly I found the answer.</p>
<p>In vim, there are separate modes for searching and commands. This generally works well as they have separate completion buffers and since I do them a lot, it keeps my command history from cluttering up my search history and vice versa. The area where I&#8217;ve wished that they were unified is when I want to convert from a search to a substitution expression. Normally in vim you do search expressions in search mode and command expressions in command mode. For example, if I wanted to search for trailing whitespace I might type:</p>
<pre class="brush: plain; title: ; notranslate">
/\s\s*
</pre>
<p>If I want to replace it with an empty string through the whole file I might type:</p>
<pre class="brush: plain; title: ; notranslate">
:%s/\s\s*//g
</pre>
<p>I can&#8217;t remove the / at the front of the command line with a backspace and replace it with a colon, so until I learned the tip I&#8217;m about to reveal I had to retype it. No longer.</p>
<p>The StackOverflow answer I found for the query, <a href="http://stackoverflow.com/questions/4655484/convert-vim-search-to-search-and-replace-without-retyping-regular-expression/4655518#4655518">Convert vim / search to search and replace without retyping regular expression</a>, suggests this remarkably simple technique:</p>
<blockquote><p>
You can type</p>
<pre class="brush: plain; title: ; notranslate">
/search_term
</pre>
<p>and then</p>
<pre class="brush: plain; title: ; notranslate">
:%s/&lt;ctrl-r&gt;// etc
</pre>
<p>where you actually press <code>ctrl+r</code> and then <code>/</code> to insert the search term.
</p></blockquote>
<p>It works! No longer do I desire for search and command modes to be unified.</p>
]]></content:encoded>
			<wfw:commentRss>http://benatkin.com/2011/11/05/converting-a-search-to-a-replace-in-vim/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>vim&#8217;s lcd command</title>
		<link>http://benatkin.com/2011/11/04/vims-lcd-command/</link>
		<comments>http://benatkin.com/2011/11/04/vims-lcd-command/#comments</comments>
		<pubDate>Fri, 04 Nov 2011 20:16:30 +0000</pubDate>
		<dc:creator>Ben Atkin</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[directories]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://benatkin.com/?p=1019</guid>
		<description><![CDATA[I find vim&#8217;s :lcd command to be quite useful. For a long time I didn&#8217;t use it, mainly because I didn&#8217;t understand how it works. First, using it is simple. It works just like :cd. You type :lcd path/to/directory in &#8230; <a href="http://benatkin.com/2011/11/04/vims-lcd-command/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I find vim&#8217;s <code>:lcd</code> command to be quite useful. For a long time I didn&#8217;t use it, mainly because I didn&#8217;t understand how it works.</p>
<p>First, using it is simple. It works just like <code>:cd</code>. You type <code>:lcd path/to/directory</code> in command mode. The path is relative to the current directory, so <code>:lcd ..</code>, <code>:lcd ~/Desktop</code>, and <code>:lcd /etc/apache2</code> all work.</p>
<p>The <code>:lcd</code> command changes the path of the current window. The current window is the current frame within the current tab. Now, what&#8217;s really neat, is that a new window (created from commands such as <code>:sp</code> and <code>:tabedit</code>) gets the local directory of the window it&#8217;s created from.</p>
<p>Most plugins respect it. Both <a href="https://wincent.com/products/command-t">Command-T</a> and <a href="https://github.com/mileszs/ack.vim">ack.vim</a> search within the local current directory. Another plugin, <a href="https://github.com/tpope/vim-fugitive">fugitive</a>, bases its commands on the git repository of the current file so it works smoothly with different local directories as well.</p>
<p>Bang commands (like <code>:!cp README.md ~/Desktop</code>) also use the local current directory.</p>
<p>Finally, after using it for a while it gets easy to tell which directory I&#8217;m in. The status line displays the path of the current file based on the local current directory, so if I know where the current file is I can quickly figure out where the local current directory is.</p>
<p>I used it the other day with <code><a href="http://gembundler.com/">bundle show</a></code> to dig through the source of two dependencies of my Rails project to better understand them.</p>
<p>If you use vim and haven&#8217;t got in the habit of using <code>:lcd</code> I highly recommend it. If you use another editor and wish it handled working in multiple directories gracefully, consider giving vim a shot!</p>
]]></content:encoded>
			<wfw:commentRss>http://benatkin.com/2011/11/04/vims-lcd-command/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>jQuery 1.7.0 is out!</title>
		<link>http://benatkin.com/2011/11/04/jquery-1-7-0-is-out/</link>
		<comments>http://benatkin.com/2011/11/04/jquery-1-7-0-is-out/#comments</comments>
		<pubDate>Fri, 04 Nov 2011 10:20:20 +0000</pubDate>
		<dc:creator>Ben Atkin</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://benatkin.com/?p=1015</guid>
		<description><![CDATA[&#8230;and I like the new .on() and .off() API for setting up events. I wrote some code that uses it, just for practice. Nothing too fancy.]]></description>
			<content:encoded><![CDATA[<p>&#8230;and I like <a href="http://blog.jquery.com/2011/11/03/jquery-1-7-released/">the new <em>.on()</em> and <em>.off()</em> API for setting up events.</a></p>
<p>I wrote some code that uses it, just for practice.</p>
<pre class="brush: jscript; title: ; notranslate">
$.fn.tree = function(data) {
  var $el = $(this),
      html = [];

  function renderNode(node) {
    if (typeof node === "object") {
      html.push("&lt;ul&gt;");
      for (var key in node) {
        if (node.hasOwnProperty(key)) {
          html.push("&lt;li&gt;&lt;strong&gt;" + key + ": &lt;/strong&gt;");
          html.push(typeof node[key] == "object" ? renderNode(node[key]) : node[key]);
          html.push("&lt;/li&gt;");
        }
      }
      html.push("&lt;/ul&gt;");
    }
  }

  renderNode(data);
  $el.html(html.join(""));

  $el.on('click', 'strong', function() {
    $(this).closest('li').find('ul').toggle(200);
  });
};

$("&lt;div&gt;").appendTo("body").tree({
  name: {
    first: "Benjamin",
    last: "Atkin"
  },
  location: {
    city: "Boulder",
    state: "CO"
  },
  accounts: {
    social: {
      twitter: "http://twitter.com/benatkin",
      facebook: "http://facebook.com/atkin",
      gplus: "http://gplus.to/benatkin",
      identica: "http://identi.ca/benatkin",
      rstatus: "http://rstat.us/bat"
    },
    creative: {
      github: "http://github.com/benatkin",
      blog: "http://benatkin.com/"
    }
  }
});
</pre>
<p><a href="http://jsbin.com/opicit">Nothing too fancy.</a></p>
<div class="resource-infobox"><div class="resource-infobox-field"><span class="resource-infobox-label">Repository</span><a class="resource-infobox-value" href="https://github.com/jquery/jquery/">jquery</a></div><div class="resource-infobox-field"><span class="resource-infobox-label">Owner</span><a class="resource-infobox-value" href="https://github.com/jquery/">jquery</a></div><div class="resource-infobox-field"><span class="resource-infobox-label">Last Commit</span><span class="resource-infobox-value">2012-05-17</span></div><div class="resource-infobox-field"><span class="resource-infobox-label">Watchers</span><span class="resource-infobox-value">14063</span></div><div class="resource-infobox-clear"></div></div>
]]></content:encoded>
			<wfw:commentRss>http://benatkin.com/2011/11/04/jquery-1-7-0-is-out/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using environment variables to avoid .gitignore bloat</title>
		<link>http://benatkin.com/2011/09/28/using-environment-variables-to-avoid-gitignore-bloat/</link>
		<comments>http://benatkin.com/2011/09/28/using-environment-variables-to-avoid-gitignore-bloat/#comments</comments>
		<pubDate>Wed, 28 Sep 2011 23:13:17 +0000</pubDate>
		<dc:creator>Ben Atkin</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://benatkin.com/?p=961</guid>
		<description><![CDATA[After setting up some Heroku addons I got used to using environment variables to specify add-on settings. I then started using them for non-addon settings, and now I&#8217;ve started using them outside of Heroku a bit too. One area where &#8230; <a href="http://benatkin.com/2011/09/28/using-environment-variables-to-avoid-gitignore-bloat/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>After setting up some <a href="http://addons.heroku.com/">Heroku addons</a> I got used to using environment variables to specify add-on settings. I then started using them for non-addon settings, and now I&#8217;ve started using them outside of Heroku a bit too.</p>
<p>One area where they work well is for a Heroku-deployable open source app with <a href="https://github.com/intridea/omniauth">OmniAuth</a> <a href="http://develop.github.com/p/oauth.html">GitHub OAuth</a> integration. Here is an <a href="http://railscasts.com/episodes/241-simple-omniauth">example initializer</a> (<code>config/initializers/omniauth.rb</code>) from a RailsCast:</p>
<pre class="brush: ruby; title: ; notranslate">
Rails.application.config.middleware.use OmniAuth::Builder do
  provider :github, 'CLIENT_KEY', 'CLIENT_SECRET'
end
</pre>
<p>I would replace CLIENT_KEY and CLIENT_SECRET with my own keys, but I can&#8217;t commit them to a public repository, or else another person could use them and I could be held responsible. Rather than leave out my client key and secret using a .gitignore and a sample config, I can use an environment variable:</p>
<pre class="brush: ruby; title: ; notranslate">
Rails.application.config.middleware.use OmniAuth::Builder do
  provider :github, ENV['GITHUB_CLIENT_KEY'], ENV['GITHUB_CLIENT_SECRET']
end
</pre>
<p>With a note in the README about the environment variables used, this should be easy for developers to set this up on their own private apps.</p>
<p>So far I&#8217;ve been typing environment variables into the command line when running apps locally and on my VPS, but that&#8217;s about to change. I may specify them in my nginx config, which is backed up to a private git repo. I&#8217;m not sure yet. Also I&#8217;m going to dump out my Heroku environment variables and back them up too.</p>
<div class="resource-infobox"><div class="resource-infobox-field"><span class="resource-infobox-label">Repository</span><a class="resource-infobox-value" href="https://github.com/intridea/omniauth/">omniauth</a></div><div class="resource-infobox-field"><span class="resource-infobox-label">Owner</span><a class="resource-infobox-value" href="https://github.com/intridea/">intridea</a></div><div class="resource-infobox-field"><span class="resource-infobox-label">Last Commit</span><span class="resource-infobox-value">2012-05-03</span></div><div class="resource-infobox-field"><span class="resource-infobox-label">Watchers</span><span class="resource-infobox-value">3085</span></div><div class="resource-infobox-clear"></div></div>
]]></content:encoded>
			<wfw:commentRss>http://benatkin.com/2011/09/28/using-environment-variables-to-avoid-gitignore-bloat/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Resources for Learning Rails</title>
		<link>http://benatkin.com/2011/09/26/resources-for-learning-rails/</link>
		<comments>http://benatkin.com/2011/09/26/resources-for-learning-rails/#comments</comments>
		<pubDate>Tue, 27 Sep 2011 03:21:04 +0000</pubDate>
		<dc:creator>Ben Atkin</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[learning]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[review]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://benatkin.com/?p=947</guid>
		<description><![CDATA[Here is a list of a few awesome sites offering tools for learning Rails: PeepCode Pricing: Starts at $12 for one screencast; Twitter: @peepcode and @topfunky I bought my first PeepCode screencast back in 2008, before Rails and Merb merged. &#8230; <a href="http://benatkin.com/2011/09/26/resources-for-learning-rails/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Here is a list of a few awesome sites offering tools for learning Rails:</p>
<h1><a href="http://peepcode.com/">PeepCode</a></h1>
<p><a href="http://peepcode.com/"><img src="http://benatkin.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-26-at-6.12.41-PM.png" alt="" title="Screen Shot 2011-09-26 at 6.12.41 PM" width="241" height="101" class="alignnone size-full wp-image-948"></a></p>
<p><em>Pricing:</em> Starts at $12 for one screencast; <em>Twitter</em>: <a href="http://twitter.com/peepcode">@peepcode</a> and <a href="http://twitter.com/topfunky">@topfunky</a></p>
<p>I bought my first PeepCode screencast back in 2008, before Rails and Merb merged. It&#8217;s been around for a while, but <a href="https://twitter.com/topfunky">Geoffrey Grosenbach</a> does a great job of keeping it up-to-date. There are now a number of screencasts about current topics of interest to the Ruby on Rails community, including <a href="http://rubyonrails.org/">Rails 3</a>, <a href="http://documentcloud.github.com/backbone/">Backbone.js</a>, <a href="http://www.postgresql.org/">PostgreSQL</a>, <a href="http://coffeescript.com/">CoffeeScript</a>, and <a href="http://www.jbarnette.com/">John Barnette</a>.</p>
<h1><a href="http://railscasts.com/">Railscasts</a></h1>
<p><a href="http://railscasts.com/"><img src="http://benatkin.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-26-at-6.31.31-PM.png" alt="" title="RailsCasts" width="432" height="69" class="alignnone size-full wp-image-949"></a></p>
<p><em>Pricing:</em> Free weekly episodes, additional weekly episodes and revised episodes for $9/mo (RailsCasts Pro); <em>Twitter: <a href="http://twitter.com/railscasts">@railscasts</a></em> </p>
<p><a href="http://railscasts.com/">Railscasts</a> is great for keeping up on Ruby On Rails, and because it&#8217;s free, it&#8217;s also great for recommending to people who are curious about Rails but not ready to spend money to help them learn it. <a href="https://twitter.com/#!/rbates">Ryan Bates</a> is great at explaining things. He covers a wide variety of topics in his screencasts and presents them in a nice format with code snippets.</p>
<p>Update: since I posted this Ryan Bates released <a href="http://railscasts.com/pro">Railscasts Pro</a>, which is fantastic!</p>
<h1><a href="http://ruby.railstutorial.org/">Ruby on Rails Tutorial</a></h1>
<p><a href="http://ruby.railstutorial.org/"><img src="http://benatkin.com/wp-content/uploads/2011/09/railstutorial.png" alt="" title="railstutorial" width="133" height="123" class="alignnone size-full wp-image-950"></a></p>
<p><em>Pricing:</em> $26 (book), $85 (screencasts), $95 (both); <em>Twitter: <a href="http://twitter.com/railstutorial">@railstutorial</a></em> </p>
<p><a href="http://www.michaelhartl.com/about">Michael Hartl</a> is a physicist who does a number of other things (see his about page) including Web Development with Ruby On Rails. I&#8217;ve watched all of his screencasts; they&#8217;re fantastic. He builds a web application TDD-style and teaches many different concepts including MVC and how TDD can help with authorization (which is trickier than authentication IMO).</p>
<h1><a href="http://railsapps.github.com/">Rails Apps</a></h1>
<p><a href="http://railsapps.github.com/"><img src="http://benatkin.com/wp-content/uploads/2011/09/rails_apps.png" alt="" title="rails_apps" width="127" height="133" class="alignnone size-full wp-image-951"></a></p>
<p><em>Pricing:</em> Free; <em>Twitter: <a href="http://twitter.com/rails_apps">@rails_apps</a></em> </p>
<p>I always thought that the <a href="https://github.com/thoughtbot/suspenders">Rails</a> <a href="https://github.com/quickleft/prologue">Starter</a> <a href="https://github.com/relevance/new-world-order">App</a> templates were cool, but they were missing something: <a href="https://github.com/railsapps/rails3-devise-rspec-cucumber/wiki/Tutorial">in-depth tutorials</a> and a <a href="http://railsapps.github.com/rails-examples-tutorials.html">comparison between the many different templates and quick-start tools</a>. <a href="http://danielkehoe.com/">Daniel Kehoe</a> has provided both and many more useful resources in his <a href="http://railsapps.github.com/">Rails Apps</a> GitHub account.</p>
<h1><a href="http://codeschool.com/">Code School</a></h1>
<p><a href="http://codeschool.com/"><img src="http://benatkin.com/wp-content/uploads/2011/09/code_school.png" alt="" title="code_school" width="325" height="81" class="alignnone size-full wp-image-952"></a></p>
<p><em>Pricing:</em> Free (one substantial free product), $45-55 (single paid products); <em>Twitter: <a href="http://twitter.com/codeschool">@codeschool</a></em> </p>
<p><a href="http://www.codeschool.com/">Code School</a> is a set of tutorials designed to help developers to quickly get up to speed building web applications. <a href="http://blog.envylabs.com/">Gregg Pollack</a> and <a href="http://envylabs.com/">Envy Labs</a> have been doing podcasts and screencasts for quite some time, and it&#8217;s not surprising that they still do it, because they&#8217;re very enthusiastic in front of a camera and a microphone.</p>
]]></content:encoded>
			<wfw:commentRss>http://benatkin.com/2011/09/26/resources-for-learning-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SyntaxHighlighter Brush Pack: Now on WordPress.org</title>
		<link>http://benatkin.com/2011/09/23/syntaxhighlighter-brush-pack-now-on-wordpress-org/</link>
		<comments>http://benatkin.com/2011/09/23/syntaxhighlighter-brush-pack-now-on-wordpress-org/#comments</comments>
		<pubDate>Fri, 23 Sep 2011 07:28:43 +0000</pubDate>
		<dc:creator>Ben Atkin</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[SyntaxHighlighter]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://benatkin.com/?p=941</guid>
		<description><![CDATA[I put my SyntaxHighlighter Brush Pack on WordPress.org, using the excellent git to WordPress.org Subversion instructions to preserve history. In order to check that it works, I moved my plugin (installed as a git submodule) outside the wp-content/plugins directory, went &#8230; <a href="http://benatkin.com/2011/09/23/syntaxhighlighter-brush-pack-now-on-wordpress-org/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I put my <a href="http://wordpress.org/extend/plugins/syntaxhighlighter-brush-pack/">SyntaxHighlighter Brush Pack</a> on WordPress.org, using the excellent <a href="http://www.farbeyondprogramming.com/2011/09/81-how-to-deploy-a-wordpress-plugin-with-git-svn">git to WordPress.org Subversion instructions</a> to <a href="http://plugins.trac.wordpress.org/log/syntaxhighlighter-brush-pack/">preserve history</a>.</p>
<p>In order to check that it works, I moved my plugin (installed as a git submodule) outside the <code>wp-content/plugins</code> directory, went to Add Plugin, searched for it, and <a href="http://codex.wordpress.org/Plugins_Add_New_Screen">instructed WordPress to automatically install it</a>. It works! The following CoffeeScript code was highlighted using it:</p>
<pre class="brush: coffeescript; title: ; notranslate">
launch() if ignition is on
</pre>
<p>If you use WordPress and either CoffeeScript or Clojure, I&#8217;d love for you to give it a shot!</p>
<div class="resource-infobox"><div class="resource-infobox-field"><span class="resource-infobox-label">Repository</span><a class="resource-infobox-value" href="https://github.com/benatkin/wordpress-syntaxhighlighter-brush-pack/">wordpress-syntaxhighlighter-brush-pack</a></div><div class="resource-infobox-field"><span class="resource-infobox-label">Owner</span><a class="resource-infobox-value" href="https://github.com/benatkin/">benatkin</a></div><div class="resource-infobox-field"><span class="resource-infobox-label">Last Commit</span><span class="resource-infobox-value">2011-09-23</span></div><div class="resource-infobox-field"><span class="resource-infobox-label">Watchers</span><span class="resource-infobox-value">1</span></div><div class="resource-infobox-clear"></div></div>
]]></content:encoded>
			<wfw:commentRss>http://benatkin.com/2011/09/23/syntaxhighlighter-brush-pack-now-on-wordpress-org/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

