<?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">
  <title type="text">Free PeepCode Blog</title>
  <generator uri="http://effectif.com/nesta">Nesta</generator>
  <id>tag:blog.peepcode.com,2009:/</id>
  
  <link rel="alternate" href="http://blog.peepcode.com" />
  <subtitle type="text">Short, Free Screencasts for Web Developers and Alpha Geeks</subtitle>
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/nubyonrails" /><feedburner:info uri="nubyonrails" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><logo>http://topfunky.com/clients/peepcode/peepcode-feedburner.png</logo><feedburner:emailServiceId>nubyonrails</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><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>
    <title>Elixir is for programmers</title>
    <link type="text/html" rel="alternate" href="http://blog.peepcode.com/blog/2013/elixir-is-for-programmers" />
    <id>tag:blog.peepcode.com,2013-06-19:/blog/2013/elixir-is-for-programmers</id>
    <content type="html">&lt;p&gt;&lt;strong&gt;This article is heavily styled and is best viewed at &lt;a href="http://blog.peepcode.com/blog/2013/elixir-is-for-programmers"&gt;PeepCode&lt;/a&gt;!&lt;/strong&gt;&lt;/p&gt;&lt;div id='attribution'&gt;
  &lt;div class='row'&gt;
    &lt;div class='column'&gt;
      &lt;p&gt;words and design Geoffrey Grosenbach&lt;br /&gt;
      photography Paula Lavalle&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;div id='intro'&gt;
  &lt;div class='row'&gt;
    &lt;div class='column'&gt;
      &lt;p&gt;The early 2000&amp;#8217;s were an exciting time for dynamic programming languages.&lt;/p&gt;
      &lt;p&gt;Excitement was high for the upcoming Perl 6. It ran on a brand new VM built specifically for dynamic languages and included dozens of experimental syntax sugars such as the &lt;a href="http://perl6.wikia.com/wiki/Hyper_operator"&gt;hyper operator&lt;/a&gt;, which could run a calculation on every element of an array (somewhat like &lt;code&gt;map&lt;/code&gt;). I attended the Seattle Perl User Group every month where you couldn&amp;#8217;t ignore the anticipation!&lt;/p&gt;
      &lt;p&gt;It was during these years that I first heard about a weird language that used indentation to define scope (now known as Python). And on January 1, 2001, Dr. Dobb&amp;#8217;s journal published an &lt;a href="http://www.drdobbs.com/web-development/programming-in-ruby/184404436"&gt;article&lt;/a&gt; by Dave Thomas introducing Ruby to the West.&lt;/p&gt;
      &lt;p&gt;That&amp;#8217;s not even counting the other languages I tried out for a few weeks each such as &lt;a href="http://www.rebol.com/"&gt;&lt;span class="caps"&gt;REBOL&lt;/span&gt;&lt;/a&gt;, RealBasic, and AppleScript.&lt;/p&gt;
      &lt;p&gt;There must be something special about the start of a decade, because I&amp;#8217;m feeling that same kind of excitement and seeing that same kind of experimentation again. At the beginning of May we filmed a &lt;a href="https://peepcode.com/products/elixir"&gt;2 hour video&lt;/a&gt; with Elixir creator Jos&amp;eacute; Valim. Elixir is a language that runs on the Erlang VM but is inspired by the syntax and concepts of many other languages including Ruby, Python, and even Lisp.&lt;/p&gt;
      &lt;p&gt;It&amp;#8217;s not just a transpiler like CoffeeScript; it makes real Erlang &lt;code&gt;.beam&lt;/code&gt; bytecode. According to &lt;a href="http://devintorr.es/blog/2013/06/11/elixir-its-not-about-syntax/"&gt;some&lt;/a&gt;, parts of Elixir are even more optimized than Erlang itself. It benefits from all the concurrency and deployment options available to Erlang programs. Elixir can call Erlang functions and vice versa.&lt;/p&gt;
      &lt;p&gt;I don&amp;#8217;t pretend to be an Elixir expert (that&amp;#8217;s why we worked with Jos&amp;eacute;, who is), but I left the session with a lot of enthusiasm for Elixir&amp;#8217;s design and features. Here are a few of them.&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;div class='implement'&gt;
  &lt;div class='row'&gt;
    &lt;div class='column'&gt;
      &lt;h2&gt;Smart &lt;code&gt;assert&lt;/code&gt;&lt;/h2&gt;
      &lt;p&gt;A programming language like Ruby loses a lot of data when you run it. It quickly loses access to the original source code. If you write a test with Ruby&amp;#8217;s basic &lt;code&gt;assert&lt;/code&gt;, it can only tell you that the test passed or that it didn&amp;#8217;t; it can&amp;#8217;t tell you why. Projects like &lt;a href="https://github.com/seattlerb/ruby2ruby"&gt;ruby2ruby&lt;/a&gt; have tried to bridge this gap but haven&amp;#8217;t had support from the core team.&lt;/p&gt;
      &lt;p&gt;Elixir works directly with your source code to do smart things. Tests rarely need more than the built-in &lt;code&gt;assert&lt;/code&gt;, yet meaningful errors can be displayed. Take this Elixir code:&lt;/p&gt;
      &lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;makes bacon&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&amp;#x000A;&lt;span class="k"&gt;  &lt;/span&gt;&lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="no"&gt;Bacon&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;make_bacon&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;avocado&amp;quot;&lt;/span&gt;&amp;#x000A;&lt;span class="k"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
      &lt;p&gt;By reading it, we can see that it&amp;#8217;s erroneously making &lt;code&gt;bacon&lt;/code&gt; but looking for &lt;code&gt;"avocado"&lt;/code&gt;. We expect that it will fail. If this were a test in Ruby (or any other language), we would see an error such as &lt;code&gt;expected true, got false&lt;/code&gt;. Not too helpful.&lt;/p&gt;
      &lt;p&gt;In Elixir, we see this:&lt;/p&gt;
      &lt;div class="highlight"&gt;&lt;pre&gt;** (ExUnit.ExpectationError)&amp;#x000A;             expected: &amp;quot;bacon&amp;quot;&amp;#x000A;  to be equal to (==): &amp;quot;avocado&amp;quot;&amp;#x000A;at test/bacon_test.exs:14&lt;/pre&gt;&lt;/div&gt;
      &lt;p&gt;Elixir knows that &lt;code&gt;==&lt;/code&gt; is being used in the assertion, and shows you the values on either side of &lt;code&gt;==&lt;/code&gt; when the test fails. Now that&amp;#8217;s a useful error!&lt;/p&gt;
      &lt;h2&gt;Multi-block control flow&lt;/h2&gt;
      &lt;p&gt;For years I&amp;#8217;ve wanted to be able to write my own control flow structures, such as an &lt;code&gt;each...else&lt;/code&gt; that runs an &lt;code&gt;else&lt;/code&gt; block if the &lt;code&gt;each&lt;/code&gt; is empty (&lt;a href="http://handlebarsjs.com/#iteration"&gt;Handlebars&lt;/a&gt; templates have this).&lt;/p&gt;
      &lt;p&gt;The only way to do that in Ruby would be to pass several lambdas to a method, which would be ugly.&lt;/p&gt;
      &lt;p&gt;In Elixir, the relationship between single line functions and multi-line blocks is well thought out.&lt;/p&gt;
      &lt;p&gt;These two are equivalent:&lt;/p&gt;
      &lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c1"&gt;# Single line&lt;/span&gt;&amp;#x000A;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&amp;#x000A;&amp;#x000A;&lt;span class="c1"&gt;# Multiple lines&lt;/span&gt;&amp;#x000A;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;condition&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&amp;#x000A;&lt;span class="k"&gt;  &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&amp;#x000A;&lt;span class="k"&gt;else&lt;/span&gt;&amp;#x000A;  &lt;span class="n"&gt;b&lt;/span&gt;&amp;#x000A;&lt;span class="k"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
      &lt;p&gt;In the single line version, &lt;code&gt;if&lt;/code&gt; is a function that takes two arguments: the &lt;code&gt;condition&lt;/code&gt; and the &lt;code&gt;clauses&lt;/code&gt;. The &lt;code&gt;clauses&lt;/code&gt; are &lt;code&gt;do&lt;/code&gt; and &lt;code&gt;else&lt;/code&gt;.&lt;/p&gt;
      &lt;p&gt;The multi-line version needs no explanation.&lt;/p&gt;
      &lt;p&gt;But the fact that these two are equivalent means you can write a macro that works just like a built-in. Because that&amp;#8217;s how the built-ins are written, too! (&lt;a href="https://github.com/elixir-lang/elixir/blob/c572cb80fced4111ea98ed4a0e27550e09816f66/lib/elixir/lib/kernel.ex#L2526"&gt;source&lt;/a&gt;)&lt;/p&gt;
      &lt;h2&gt;Consistent use of &lt;code&gt;do&lt;/code&gt;&lt;/h2&gt;
      &lt;p&gt;Developers who love Ruby like the fact that they can override built-in operators and write DSLs that look like built-in Ruby syntax.&lt;/p&gt;
      &lt;p&gt;But many of Ruby&amp;#8217;s syntactical elements are off limits. You can&amp;#8217;t write Ruby code that works like a &lt;code&gt;class&lt;/code&gt; definition, or an &lt;code&gt;if&lt;/code&gt;, or a &lt;code&gt;case...when&lt;/code&gt;. Why? &lt;code&gt;class&lt;/code&gt; has an &lt;code&gt;end&lt;/code&gt;, but no &lt;code&gt;do&lt;/code&gt;. There&amp;#8217;s no way to write a custom method that takes a block without &lt;code&gt;do&lt;/code&gt;.&lt;/p&gt;
      &lt;p&gt;Elixir is consistent.&lt;/p&gt;
      &lt;p&gt;Need a module? It&amp;#8217;s &lt;code&gt;defmodule...do&lt;/code&gt;. Need an &lt;code&gt;if&lt;/code&gt;? It also uses &lt;code&gt;do&lt;/code&gt;. Same with &lt;code&gt;def&lt;/code&gt;.&lt;/p&gt;
      &lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;MyModule&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&amp;#x000A;&lt;span class="k"&gt;  def&lt;/span&gt; &lt;span class="n"&gt;my_function&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&amp;#x000A;&lt;span class="k"&gt;  &lt;/span&gt;&amp;#x000A;&lt;span class="k"&gt;  end&lt;/span&gt;&amp;#x000A;&lt;span class="k"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
      &lt;p&gt;If you want to write a macro that works like the language does, you can. Because Elixir is implemented with the same tools available for you to use.&lt;/p&gt;
      &lt;h2&gt;Built-in &lt;span class="caps"&gt;TDD&lt;/span&gt;&lt;/h2&gt;
      &lt;p&gt;I find it extremely difficult to learn a new language if I can&amp;#8217;t write unit tests. My confidence in writing JavaScript and many other languages went way up once I started using a decent test runner.&lt;/p&gt;
      &lt;p&gt;With Elixir, it&amp;#8217;s built in. Use the &lt;code&gt;mix&lt;/code&gt; command to generate a &lt;code&gt;new&lt;/code&gt; app and you&amp;#8217;re ready to go with a unit test. Run &lt;code&gt;mix test&lt;/code&gt; to run the test suite. Done.&lt;/p&gt;
      &lt;p&gt;It even has conveniences like a &lt;code&gt;test&lt;/code&gt; function that takes a quoted descriptive message as the name of the test.&lt;/p&gt;
      &lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;extracts m3u8 from index file&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&amp;#x000A;&lt;span class="k"&gt;  &lt;/span&gt;&lt;span class="n"&gt;m3u8s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Streamers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;extract_m3u8&lt;/span&gt; &lt;span class="n"&gt;index_file&lt;/span&gt;&amp;#x000A;  &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m3u8s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;Streamers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;M3U8&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;program_id:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;bandwidth:&lt;/span&gt; &lt;span class="m"&gt;110000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;path:&lt;/span&gt; &lt;span class="n"&gt;m3u8_sample&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&amp;#x000A;  &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m3u8s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&amp;#x000A;&lt;span class="k"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
      &lt;p&gt;And it can run your tests concurrently with a single &lt;code&gt;async&lt;/code&gt; option (&lt;a href="http://elixir-lang.org/getting_started/ex_unit/1.html"&gt;docs&lt;/a&gt;).&lt;/p&gt;
      &lt;h2&gt;Mind-blowing metaprogramming: &lt;code&gt;upcase&lt;/code&gt;&lt;/h2&gt;
      &lt;p&gt;One of the most ingenious techniques that Jos&amp;eacute; mentioned didn&amp;#8217;t make it into the final cut of our video.&lt;/p&gt;
      &lt;p&gt;To capitalize a word, Elixir could implement a single &lt;code&gt;upcase&lt;/code&gt; function that keeps a list of Unicode letters in memory and figures out how to translate between them.&lt;/p&gt;
      &lt;p&gt;Instead, it generates a function definition for each letter. They look roughly like this (&lt;a href="https://github.com/elixir-lang/elixir/blob/b535f0746e9a0d198033509c19457a5182af2102/lib/elixir/priv/unicode.ex#L78"&gt;source&lt;/a&gt;):&lt;/p&gt;
      &lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;upcase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;é&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&amp;#x000A;&lt;span class="k"&gt;  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;É&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="n"&gt;upcase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&amp;#x000A;&lt;span class="k"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
      &lt;p&gt;A few things are going on here. Elixir can match functions on the number, type, and &lt;em&gt;content&lt;/em&gt; of its arguments. So it looks for a letter such as &lt;code&gt;é&lt;/code&gt;. It knows the upper case version of the letter, then sends the rest of the string to the next letter&amp;#8217;s &lt;code&gt;upcase&lt;/code&gt; function.&lt;/p&gt;
      &lt;p&gt;Pretty cool!&lt;/p&gt;
      &lt;h2&gt;Conclusion&lt;/h2&gt;
      &lt;p&gt;Elixir has many of the features that I look for in a programming language. Its authors have stolen useful features from other languages, it focuses on making it easier to write complex applications, and it has a healthy balance between performance and syntax.&lt;/p&gt;
      &lt;p&gt;Elixir isn&amp;#8217;t the only way to write concurrent applications, but it&amp;#8217;s definitely one I&amp;#8217;ll be experimenting with for a few months. If you want to learn what it&amp;#8217;s about, check out our fast-paced two hour video at PeepCode:
      &lt;a href="https://peepcode.com/products/elixir"&gt;&lt;img src="https://peepcode.com/system/uploads/2013/peepcode-elixir-cover-sale.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</content>
    <published>Wed Jun 19 21:00:00 +0000 2013</published>
  </entry>
  <entry>
    <title>PeepCode iOS App Update: Fast Playback Option</title>
    <link type="text/html" rel="alternate" href="http://blog.peepcode.com/blog/2013/the-peepcode-ios-app-fast-play" />
    <id>tag:blog.peepcode.com,2013-06-05:/blog/2013/the-peepcode-ios-app-fast-play</id>
    <content type="html">&lt;p&gt;&lt;strong&gt;This article is heavily styled and is best viewed at &lt;a href="http://blog.peepcode.com/blog/2013/the-peepcode-ios-app-fast-play"&gt;PeepCode&lt;/a&gt;!&lt;/strong&gt;&lt;/p&gt;&lt;div id='essay'&gt;
  &lt;div class='row'&gt;
    &lt;div class='column author'&gt;
      &lt;p&gt;
        by
        &lt;span&gt;
          Geoffrey Grosenbach
        &lt;/span&gt;
        and
        &lt;span&gt;
          Paula Lavalle
        &lt;/span&gt;
      &lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column article'&gt;
      &lt;p class="appbadgecentered"&gt;&lt;a href="http://appstore.com/peepcode"&gt;&lt;img src="https://peepcode.com/images/promo-appbadge.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
      &lt;p&gt;A new version of the PeepCode iOS app is free on the App Store! It fixes some bugs and adds a new useful feature.&lt;/p&gt;
      &lt;h2&gt;Fast Playback&lt;/h2&gt;
      &lt;div class="playback"&gt;&lt;img src="/blog/2013/the-peepcode-ios-app-fast-play/img/playback-1-5-x.png" alt="The 1.5x button plays downloaded videos much faster." title="The 1.5x button plays downloaded videos much faster." /&gt;&lt;p class="caption"&gt;The 1.5x button plays downloaded videos much faster.&lt;/p&gt;&lt;/div&gt;&lt;p&gt;We&amp;#8217;ve designed PeepCode videos to be consumed however you want to. Watch straight through to become familiar with a framework such as &lt;a href="https://peepcode.com/products/emberjs"&gt;Ember.js&lt;/a&gt; (whether or not you choose to build anything with it). Or go step by step to interactively type along with the code in your text editor. Or relax after work watching &lt;a href="https://peepcode.com/products/play-by-play-benorenstein"&gt;Refactoring with Ben Orenstein&lt;/a&gt; on your TV.&lt;/p&gt;
      &lt;p&gt;And now there&amp;#8217;s a new way: at 1.5x speed. Download a video in the app and you&amp;#8217;ll see an extra button in the playback controls when you play a video you&amp;#8217;ve downloaded.&lt;/p&gt;
      &lt;p&gt;We&amp;#8217;ve already benefited from this on a recent plane flights to La Conf in Paris. We watched the 40 minute long &lt;a href="https://peepcode.com/products/gallery-css"&gt;Gallery &lt;span class="caps"&gt;CSS&lt;/span&gt;&lt;/a&gt; in about 25 minutes. Even less for &lt;a href="https://peepcode.com/products/troubleshooting"&gt;Troubleshooting&lt;/a&gt;. Two hour Play by Play videos can be viewed in under an hour and a half.&lt;/p&gt;
      &lt;h2&gt;Design &amp;amp; Implementation&lt;/h2&gt;
      &lt;img src="/blog/2013/the-peepcode-ios-app-fast-play/img/design-1-5-x.png" alt="Custom 1.5x button." title="Custom 1.5x button." /&gt;&lt;p class="caption"&gt;Custom 1.5x button.&lt;/p&gt;&lt;p&gt;Fast playback isn&amp;#8217;t built into the iOS movie player, so we had to build most of this from scratch. Our iOS developer built a new playback control with a spot for the 1.5x button. Our designer created a custom button that fits the color and style of the native buttons.&lt;/p&gt;
      &lt;p&gt;Should Apple implement fast playback in the future, we can revert to the native playback controls by changing a single line of code.&lt;/p&gt;
      &lt;p&gt;Someone already pointed out that this doesn&amp;#8217;t work for streaming locally or to AppleTV. Would that even be possible? Our minds raced. We could re-encode all videos on the server at a faster speed and stream the faster version to AppleTV. Possible? Yes. &lt;a href="mailto:peepcode@peepcode.com"&gt;Tell us&lt;/a&gt; if you would find this useful in a future update of the app.&lt;/p&gt;
      &lt;p&gt;Get the app on the &lt;a href="http://appstore.com/peepcode"&gt;App Store&lt;/a&gt;. Upgrade to &lt;a href="https://peepcode.com/plans"&gt;PeepCode Unlimited&lt;/a&gt; for full-length download and streaming!&lt;/p&gt;
      &lt;p class="small"&gt;Did you know&amp;#8230;if you&amp;#8217;ve ever had a PeepCode Unlimited subscription, you can &lt;a href="https://peepcode.com/plans"&gt;renew&lt;/a&gt; now for only $109! Or tell your employer to &lt;a href="mailto:sales@peepcode.com"&gt;contact us&lt;/a&gt; for a business subscription.&lt;/p&gt;&lt;p class="appbadgecentered"&gt;&lt;a href="http://appstore.com/peepcode"&gt;&lt;img src="https://peepcode.com/images/promo-appbadge.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</content>
    <published>Wed Jun 05 17:15:00 +0000 2013</published>
  </entry>
  <entry>
    <title>Teaching Developers</title>
    <link type="text/html" rel="alternate" href="http://blog.peepcode.com/blog/2013/teaching-developers" />
    <id>tag:blog.peepcode.com,2013-05-21:/blog/2013/teaching-developers</id>
    <content type="html">&lt;p&gt;&lt;strong&gt;This article is heavily styled and is best viewed at &lt;a href="http://blog.peepcode.com/blog/2013/teaching-developers"&gt;PeepCode&lt;/a&gt;!&lt;/strong&gt;&lt;/p&gt;&lt;div id='essay'&gt;
  &lt;div class='row'&gt;
    &lt;div class='column author'&gt;
      &lt;small&gt;
        &lt;p&gt;Written by &lt;a href="http://twitter.com/topfunky"&gt;Geoffrey Grosenbach&lt;/a&gt; &amp;middot; Design by &lt;a href="http://twitter.com/lalavalse"&gt;Paula Lavalle&lt;/a&gt;&lt;/p&gt;
      &lt;/small&gt;
    &lt;/div&gt;
    &lt;div class='column article'&gt;
      &lt;p&gt;The only thing more difficult than learning something new is teaching it.&lt;/p&gt;
      &lt;p&gt;At PeepCode, we put a lot of &lt;strong&gt;time&lt;/strong&gt; into creating &lt;strong&gt;great explanations&lt;/strong&gt; of &lt;strong&gt;difficult concepts&lt;/strong&gt;. We won’t publish a video until we’re confident that it explains the topic better than anything else out there. And feedback from people who have viewed our videos on &lt;a href="https://peepcode.com/products/emberjs"&gt;Ember.js&lt;/a&gt;, &lt;a href="https://peepcode.com/screencasts/ruby-on-rails"&gt;Ruby on Rails&lt;/a&gt;, &lt;a href="https://peepcode.com/screencasts/javascript"&gt;JavaScript&lt;/a&gt; and other topics show that we’re doing just that.&lt;/p&gt;
      &lt;div class="magnifyright"&gt;&lt;img src="/blog/2013/teaching-developers/img/notebook.png" alt="&amp;nbsp;" title="&amp;nbsp;" /&gt;&lt;p class="caption"&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt;&lt;h2&gt;Summary&lt;/h2&gt;
      &lt;p&gt;Here’s some of what we’ve learned about explaining technical topics to developers.&lt;/p&gt;
      &lt;ul&gt;
      	&lt;li&gt;Teach &lt;strong&gt;one thing&lt;/strong&gt; at a time&lt;/li&gt;
      	&lt;li&gt;Tell a &lt;strong&gt;story&lt;/strong&gt;&lt;/li&gt;
      	&lt;li&gt;Use appropriate &lt;strong&gt;terminology&lt;/strong&gt;&lt;/li&gt;
      	&lt;li&gt;Know your &lt;strong&gt;audience&lt;/strong&gt;&lt;/li&gt;
      &lt;/ul&gt;
      &lt;h2&gt;The Goal&lt;/h2&gt;
      &lt;p&gt;The goal of any tutorial is to get back into the mind of someone who doesn’t understand the topic. If an explanation only makes sense to people who already know what you know, then it’s not a very good explanation.&lt;/p&gt;
      &lt;p&gt;But that insight alone doesn’t tell you how to explain well. Instead, it might help to think about how &lt;strong&gt;developers go wrong&lt;/strong&gt; when trying to explain a concept.&lt;/p&gt;
      &lt;ul&gt;
      	&lt;li&gt;They try to teach &lt;strong&gt;too many things&lt;/strong&gt; at once. This overwhelms the student.&lt;/li&gt;
      	&lt;li&gt;They are &lt;strong&gt;disorganized&lt;/strong&gt;. Teaching things out of order makes the student do too much work to sort it out in their mind.&lt;/li&gt;
      	&lt;li&gt;They use the &lt;strong&gt;wrong words&lt;/strong&gt;. Throwing an unknown term into an explanation can intimidate a student or even cause fear.&lt;/li&gt;
      	&lt;li&gt;They don’t know who they are &lt;strong&gt;speaking to&lt;/strong&gt;. I don’t know of any single explanation that works for all people at all levels of learning. When developers are unclear about their audience, they risk delivering ideas that will confuse everyone listening.&lt;/li&gt;
      &lt;/ul&gt;
      &lt;p&gt;Here are four solutions to these problems.&lt;/p&gt;
      &lt;h2&gt;Teach one thing at a time&lt;/h2&gt;
      &lt;p&gt;This is the biggest problem I see, and it’s the first strategy you should use to improve your explanations.&lt;/p&gt;
      &lt;div class="magnifyleft"&gt;&lt;img src="/blog/2013/teaching-developers/img/map.png" alt="&amp;nbsp;" title="&amp;nbsp;" /&gt;&lt;p class="caption"&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt;&lt;p class="extendright"&gt;Decide what you’re trying to teach, and only talk about that. You’ll have to intentionally block out the 10 other things you want to communicate. If a concept is important enough, dedicate a separate chapter, slide, or day to it. Then focus on the &lt;em&gt;one thing&lt;/em&gt; you’re trying to teach right now.&lt;/p&gt;
      &lt;p class="extendright"&gt;This is extremely difficult for developers. We love details. We love to debate some tiny nuance of a program before it even runs. We like discovering edge cases that no one else has thought about.&lt;/p&gt;
      &lt;p class="extendright"&gt;And we’re afraid. We’re afraid that when we conclude a presentation, one person in the audience will be able to say “Hah! You forgot to mention X!” Or &amp;#8220;You were wrong on this one point!&amp;#8221;&lt;/p&gt;
      &lt;p class="extendright"&gt;To teach well, you need to get over these fears. You need to allow yourself to say something that’s 99% true, even if you know someone will correct you for the 1%. Because mentioning that 1% in your explanation will probably hinder you from sticking to teaching just one thing at a time.&lt;/p&gt;
      &lt;p&gt;To teach well, you need to abandon your insurance policy of saying “We’ll cover &lt;em&gt;this other thing&lt;/em&gt; later.” That disclaimer is only there to comfort you, not to help the student. Teach the one thing you’re trying to teach now, then teach one other thing later when you’ve finished teaching the one thing you’re teaching now.&lt;/p&gt;
      &lt;p&gt;In fact, leaving out an important concept or saying something that’s only 99% true can be used to your advantage. It can help you tell a story.&lt;/p&gt;
      &lt;h2&gt;Tell a story with problems and solutions&lt;/h2&gt;
      &lt;p&gt;Stories are great because they hold our attention. The story could go anywhere, but we also have a hunch about what will happen next. That anticipation keeps our interest: “Will it turn out like I think it will, or will something unexpected happen?”&lt;/p&gt;
      &lt;p&gt;&lt;a href="http://www.ted.com/talks/malcolm_gladwell_on_spaghetti_sauce.html"&gt;Malcolm Gladwell&lt;/a&gt; is a great storyteller. Many of his stories use problems as a way to hold attention and lead to a solution (or continue the cycle with another problem and another solution).&lt;/p&gt;
      &lt;div class="magnifyleft"&gt;&lt;img src="/blog/2013/teaching-developers/img/problemsolution.png" alt="&amp;nbsp;" title="&amp;nbsp;" /&gt;&lt;p class="caption"&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt;&lt;blockquote class="extendright"&gt;
      &lt;p class="extendright"&gt;A person figured this thing out. But then they discovered they were partly wrong. And it gave them a new insight into how it really worked. So they applied that knowledge to something else. And then&amp;#8230;&lt;/p&gt;
      &lt;/blockquote&gt;
      &lt;p class="extendright"&gt;When explaining a technical concept, start with a &lt;em&gt;partial explanation&lt;/em&gt; that’s easy to understand. In order to make it understandable, you might have to leave out some details. But filling in those details now becomes the next part of your story.&lt;/p&gt;
      &lt;p class="extendright"&gt;For example:&lt;/p&gt;
      &lt;p class="extendright"&gt;&lt;strong&gt;Solution&lt;/strong&gt;: &lt;em&gt;Fixtures&lt;/em&gt; are Rails’ built-in way for feeding data to your tests. They are a concise way to describe all the data your application needs.&lt;/p&gt;
      &lt;p class="extendright"&gt;&lt;strong&gt;Problem&lt;/strong&gt;: But fixtures become difficult to maintain when you have many different pieces of data.&lt;/p&gt;
      &lt;p class="extendright"&gt;&lt;strong&gt;Solution&lt;/strong&gt;: It turns out they aren’t the only way. There are also factories. Here’s how factories work…&lt;/p&gt;
      &lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: But there’s a problem with factories&amp;#8230;&lt;/p&gt;
      &lt;p&gt;So teach one concept at a time. If you have to leave out a glaring edge case or alternate option, use it to organize your thoughts into problems and solutions that lead from one to the other.&lt;/p&gt;
      &lt;p&gt;When you’re telling a story, you need to use words. But be careful what words you use&amp;#8230;&lt;/p&gt;
      &lt;h2&gt;Beware of Terminology&lt;/h2&gt;
      &lt;p&gt;In every hobby, field of study, or domain, a set of words emerges.&lt;/p&gt;
      &lt;p&gt;Mountain bikers want to grin while flowing through chunder. Skateboarders are stoked about gnar. Philosophers try not to equivocate about their ideology. Agile developers want to be clean while they keep their objects dry.&lt;/p&gt;
      &lt;p&gt;These words&amp;#8212;big and small&amp;#8212;are shortcuts. They make it easy for experts to discuss advanced topics after they already understand the basics.&lt;/p&gt;
      &lt;div class="magnifyright"&gt;&lt;img src="/blog/2013/teaching-developers/img/symbols.png" alt="&amp;nbsp;" title="&amp;nbsp;" /&gt;&lt;p class="caption"&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;If you are teaching experts about advanced topics, then you should use these shortcut words.But if you are teaching people who are not experts, then using domain-specific language will confuse them.&lt;/p&gt;
      &lt;p&gt;For any term, one’s relationship to the word falls under one of these categories:&lt;/p&gt;
      &lt;ul&gt;
      	&lt;li&gt;I have never heard it before, and have no idea what it means.&lt;/li&gt;
      	&lt;li&gt;I have heard it a few times but don’t understand it.&lt;/li&gt;
      	&lt;li&gt;I have a basic understanding of the word.&lt;/li&gt;
      	&lt;li&gt;I have thorough understanding. It’s part of my vocabulary. I can use it to explain other concepts.&lt;/li&gt;
      &lt;/ul&gt;
      &lt;p&gt;Part of your job as a teacher is to help students add new words to their vocabulary. Finding their place in the list above will help you know which words to teach, and which ones to use.&lt;/p&gt;
      &lt;h2&gt;Know your audience&lt;/h2&gt;
      &lt;div class="magnifyleft"&gt;&lt;img src="/blog/2013/teaching-developers/img/audience.png" alt="&amp;nbsp;" title="&amp;nbsp;" /&gt;&lt;p class="caption"&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt;&lt;p class="extendright"&gt;Finally, understand your audience. I’m mentioning it last, but it should happen first in your preparations.&lt;/p&gt;
      &lt;p class="extendright"&gt;Are you teaching beginners or experts? Backend programmers or front-end? People with a computer science degree or the self-taught?&lt;/p&gt;
      &lt;p class="extendright"&gt;This determines what terms you can use. Your professional audience will be frustrated if you spend large amounts of time explaining things they already know. Your beginner audience will be confused if you assume they are fluent in concepts they have never heard about.&lt;/p&gt;
      &lt;p class="extendright"&gt;This is the first part of your preparations for teaching, but is also the most uncertain. The people who show up for your presentation or consume your material online might not be the audience you prepared it for.&lt;/p&gt;
      &lt;h2&gt;Conclusion&lt;/h2&gt;
      &lt;p&gt;There is a massive need for great explanations on all kinds of topics. Without good explanations, many open source projects will fail. It’s pretty simple: if people don’t know to use your software, they won’t.&lt;/p&gt;
      &lt;p&gt;So teach &lt;strong&gt;one thing&lt;/strong&gt; at a time that &lt;strong&gt;flows&lt;/strong&gt; from one idea to another with the &lt;strong&gt;appropriate words&lt;/strong&gt; for the &lt;strong&gt;intended audience&lt;/strong&gt;.&lt;/p&gt;
      &lt;p&gt;And if you think you want to take a crack at explaining a technical topic, &lt;a href="mailto:peepcode@peepcode.com"&gt;contact us&lt;/a&gt;. We&amp;#8217;re always looking to pay skilled teachers to make videos for us!&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</content>
    <published>Tue May 21 23:45:00 +0000 2013</published>
  </entry>
  <entry>
    <title>Troubleshooting Strategies Poster</title>
    <link type="text/html" rel="alternate" href="http://blog.peepcode.com/blog/2013/seven-troubleshooting-strategies-poster" />
    <id>tag:blog.peepcode.com,2013-05-09:/blog/2013/seven-troubleshooting-strategies-poster</id>
    <content type="html">&lt;p&gt;&lt;strong&gt;This article is heavily styled and is best viewed at &lt;a href="http://blog.peepcode.com/blog/2013/seven-troubleshooting-strategies-poster"&gt;PeepCode&lt;/a&gt;!&lt;/strong&gt;&lt;/p&gt;&lt;div id='essay'&gt;
  &lt;div class='row'&gt;
    &lt;div class='column author'&gt;
      &lt;p&gt;
        by
        &lt;span&gt;
          Geoffrey Grosenbach
        &lt;/span&gt;
      &lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column article'&gt;
      &lt;div class="screencast"&gt;&lt;a href="https://peepcode.com/products/troubleshooting"&gt;&lt;img src="https://peepcode.com/system/ios-thumbnails/troubleshooting-large.png" alt="7 Strategies Video" title="7 Strategies Video" /&gt;&lt;/a&gt;&lt;p class="caption"&gt;7 Strategies Video&lt;/p&gt;&lt;/div&gt;&lt;p&gt;Troubleshooting is a skill that transcends programming languages, frameworks, and even time.&lt;/p&gt;
      &lt;p&gt;My first few years of professional programming were full of frustration. I would frequently run into problems and have no clue about how to solve them. I treated them as unexpected and unwanted interruptions.&lt;/p&gt;
      &lt;p&gt;Now I know that encountering and fixing problems is part of the developer&amp;#8217;s job description. It&amp;#8217;s a rare day that ends without unexpected behavior from code, a deployment, or another library.&lt;/p&gt;
      &lt;p&gt;But with the right plan, these unexpected events can be resolved quickly. Here&amp;#8217;s the order of events we use regularly at PeepCode:&lt;/p&gt;
      &lt;ul&gt;
      	&lt;li&gt;Gather data&lt;/li&gt;
      	&lt;li&gt;Isolate the fault&lt;/li&gt;
      	&lt;li&gt;Form a hypothesis&lt;/li&gt;
      	&lt;li&gt;Read the documentation&lt;/li&gt;
      	&lt;li&gt;Describe the problem&lt;/li&gt;
      	&lt;li&gt;Read the code&lt;/li&gt;
      	&lt;li&gt;Try another angle&lt;/li&gt;
      &lt;/ul&gt;
      &lt;h2&gt;Free poster!&lt;/h2&gt;
      &lt;p&gt;Download this &lt;a href="/blog/2013/seven-troubleshooting-strategies-poster/img/7strategiesposter.pdf"&gt;free poster&lt;/a&gt;, print it out, and hang it on your office wall for easy reference. Works on US Letter or A4. Also available in &lt;a href="/blog/2013/seven-troubleshooting-strategies-poster/img/7strategiesposter-color.pdf"&gt;color&lt;/a&gt;.&lt;/p&gt;
      &lt;div class="poster"&gt;&lt;a href="/blog/2013/seven-troubleshooting-strategies-poster/img/7strategiesposter.pdf"&gt;&lt;img src="/blog/2013/seven-troubleshooting-strategies-poster/img/7strategiesposter.png" alt="7 Strategies Poster" title="7 Strategies Poster" /&gt;&lt;/a&gt;&lt;p class="caption"&gt;7 Strategies Poster&lt;/p&gt;&lt;/div&gt;&lt;p&gt;Or watch our &lt;a href="https://peepcode.com/products/troubleshooting"&gt;video&lt;/a&gt; for explanations and stories behind these troubleshooting strategies.&lt;/p&gt;
      &lt;p class="small"&gt;Start a PeepCode subscription for &lt;a href="https://peepcode.com/plans"&gt;$200&lt;/a&gt; or renew for &lt;a href="https://peepcode.com/plans"&gt;$109&lt;/a&gt;! Full access to all videos and our iOS app. Or tell your employer to &lt;a href="mailto:sales@peepcode.com"&gt;contact us&lt;/a&gt; for a business subscription quote.&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</content>
    <published>Thu May 09 12:10:00 +0000 2013</published>
  </entry>
  <entry>
    <title>New Memes</title>
    <link type="text/html" rel="alternate" href="http://blog.peepcode.com/blog/2013/charismatic-duo" />
    <id>tag:blog.peepcode.com,2013-04-06:/blog/2013/charismatic-duo</id>
    <content type="html">&lt;p&gt;&lt;strong&gt;This article is heavily styled and is best viewed at &lt;a href="http://blog.peepcode.com/blog/2013/charismatic-duo"&gt;PeepCode&lt;/a&gt;!&lt;/strong&gt;&lt;/p&gt;&lt;div id='essay'&gt;
  &lt;div class='row'&gt;
    &lt;div class='column author'&gt;
      &lt;p&gt;
        by
        &lt;span&gt;
          Geoffrey Grosenbach
        &lt;/span&gt;
        and
        &lt;span&gt;
          Paula Lavalle
        &lt;/span&gt;
      &lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column article'&gt;
      &lt;div class='tweet'&gt;
        &lt;blockquote class="twitter-tweet"&gt;&lt;p&gt;Oh man, I want a looping gif of @&lt;a href="https://twitter.com/coreyhaines"&gt;coreyhaines&lt;/a&gt; and @&lt;a href="https://twitter.com/tenderlove"&gt;tenderlove&lt;/a&gt; doing the COMPUTERING motion at the same time.&lt;/p&gt;&amp;mdash; ashe dryden (@ashedryden) &lt;a href="https://twitter.com/ashedryden/status/309892296806121472"&gt;March 8, 2013&lt;/a&gt;&lt;/blockquote&gt;&lt;script async src="//platform.twitter.com/widgets.js" charset="utf-8"&gt;&lt;/script&gt;
      &lt;/div&gt;
      &lt;p&gt;Wish granted! Use the following in your presentations, status updates, meme generators, or just for laughs!&lt;/p&gt;
      &lt;p&gt;Buy the &lt;a href="https://peepcode.com/products/play-by-play-aaroncorey"&gt;full-length Play by Play&lt;/a&gt; or tell your boss to buy you a &lt;a href="https://peepcode.com/plans#bidnez"&gt;PeepCode Unlimited subscription&lt;/a&gt; for full access to all our videos and our &lt;a href="https://peepcode.com/blog/2013/the-peepcode-ios-app"&gt;iOS app&lt;/a&gt;.&lt;/p&gt;
      &lt;h3&gt;&lt;span class="caps"&gt;COMPUTERING&lt;/span&gt;&lt;/h3&gt;
      &lt;ul&gt;
      	&lt;li class="ss-usersframe"&gt;&lt;a href="/blog/2013/charismatic-duo/img/dinosaur-hands.jpg"&gt;Full size image&lt;/a&gt;&lt;/li&gt;
      	&lt;li class="ss-playfilm"&gt;&lt;a href="/blog/2013/charismatic-duo/img/dinosaur-hands.gif"&gt;Animated &lt;span class="caps"&gt;GIF&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
      &lt;div class="animated-gif"&gt;&lt;img src="/blog/2013/charismatic-duo/img/dinosaur-hands.gif" alt="Every day we&amp;#8217;re computering." title="Every day we&amp;#8217;re computering." /&gt;&lt;p class="caption"&gt;Every day we&amp;#8217;re computering.&lt;/p&gt;&lt;/div&gt;    &lt;p class="tweet-link"&gt;
            &lt;a href="https://twitter.com/share" class="twitter-share-button" data-url="https://peepcode.com/blog/2013/charismatic-duo/img/dinosaur-hands.gif" data-text="How to program:" data-count="none" data-size="large" data-dnt="true"&gt;Tweet&lt;/a&gt;
            &lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");&lt;/script&gt;
          &lt;/p&gt;
      &lt;h3&gt;Solo Computering&lt;/h3&gt;
      &lt;ul&gt;
      	&lt;li class="ss-usersframe"&gt;&lt;a href="/blog/2013/charismatic-duo/img/howiprogram.jpg"&gt;Full size image&lt;/a&gt;&lt;/li&gt;
      	&lt;li class="ss-playfilm"&gt;&lt;a href="/blog/2013/charismatic-duo/img/howiprogram.gif"&gt;Animated &lt;span class="caps"&gt;GIF&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
      &lt;div class="animated-gif"&gt;&lt;img src="/blog/2013/charismatic-duo/img/howiprogram.gif" alt="&amp;#8220;This is how I program.&amp;#8221;" title="&amp;#8220;This is how I program.&amp;#8221;" /&gt;&lt;p class="caption"&gt;&amp;#8220;This is how I program.&amp;#8221;&lt;/p&gt;&lt;/div&gt;    &lt;p class="tweet-link"&gt;
            &lt;a href="https://twitter.com/share" class="twitter-share-button" data-url="https://peepcode.com/blog/2013/charismatic-duo/img/howiprogram.gif" data-text="Current status:" data-count="none" data-size="large" data-dnt="true"&gt;Tweet&lt;/a&gt;
            &lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");&lt;/script&gt;
          &lt;/p&gt;
      &lt;h3&gt;High Five!&lt;/h3&gt;
      &lt;ul&gt;
      	&lt;li class="ss-usersframe"&gt;&lt;a href="/blog/2013/charismatic-duo/img/high-five.jpg"&gt;Full size image&lt;/a&gt;&lt;/li&gt;
      	&lt;li class="ss-playfilm"&gt;&lt;a href="/blog/2013/charismatic-duo/img/high-five.gif"&gt;Animated &lt;span class="caps"&gt;GIF&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
      &lt;div class="animated-gif"&gt;&lt;img src="/blog/2013/charismatic-duo/img/high-five.gif" alt="High five." title="High five." /&gt;&lt;p class="caption"&gt;High five.&lt;/p&gt;&lt;/div&gt;    &lt;p class="tweet-link"&gt;
            &lt;a href="https://twitter.com/share" class="twitter-share-button" data-url="https://peepcode.com/blog/2013/charismatic-duo/img/high-five.gif" data-text="High five!" data-count="none" data-size="large" data-dnt="true"&gt;Tweet&lt;/a&gt;
            &lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");&lt;/script&gt;
          &lt;/p&gt;
      &lt;h3&gt;Bingo!&lt;/h3&gt;
      &lt;ul&gt;
      	&lt;li class="ss-usersframe"&gt;&lt;a href="/blog/2013/charismatic-duo/img/awyep.jpg"&gt;Full size image&lt;/a&gt;&lt;/li&gt;
      	&lt;li class="ss-playfilm"&gt;&lt;a href="/blog/2013/charismatic-duo/img/awyep.gif"&gt;Animated &lt;span class="caps"&gt;GIF&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
      &lt;img src="/blog/2013/charismatic-duo/img/awyep.gif" alt="Aww yeah!" title="Aww yeah!" /&gt;&lt;p class="caption"&gt;Aww yeah!&lt;/p&gt;    &lt;p class="tweet-link"&gt;
            &lt;a href="https://twitter.com/share" class="twitter-share-button" data-url="https://peepcode.com/blog/2013/charismatic-duo/img/awyep.gif" data-text="Aww yeah!" data-count="none" data-size="large" data-dnt="true"&gt;Tweet&lt;/a&gt;
            &lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");&lt;/script&gt;
          &lt;/p&gt;
      &lt;h3&gt;That&amp;#8217;s the word!&lt;/h3&gt;
      &lt;ul&gt;
      	&lt;li class="ss-usersframe"&gt;&lt;a href="/blog/2013/charismatic-duo/img/the-word.jpg"&gt;Full size image&lt;/a&gt;&lt;/li&gt;
      	&lt;li class="ss-playfilm"&gt;&lt;a href="/blog/2013/charismatic-duo/img/the-word.gif"&gt;Animated &lt;span class="caps"&gt;GIF&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
      &lt;img src="/blog/2013/charismatic-duo/img/the-word.gif" alt="“That’s the word!”" title="“That’s the word!”" /&gt;&lt;p class="caption"&gt;“That’s the word!”&lt;/p&gt;    &lt;p class="tweet-link"&gt;
            &lt;a href="https://twitter.com/share" class="twitter-share-button" data-url="https://peepcode.com/blog/2013/charismatic-duo/img/the-word.gif" data-text="That&amp;#8217;s the word!" data-count="none" data-size="large" data-dnt="true"&gt;Tweet&lt;/a&gt;
            &lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");&lt;/script&gt;
          &lt;/p&gt;
      &lt;h3&gt;Cold Stare&lt;/h3&gt;
      &lt;ul&gt;
      	&lt;li class="ss-usersframe"&gt;&lt;a href="/blog/2013/charismatic-duo/img/refute.jpg"&gt;Full size image&lt;/a&gt;&lt;/li&gt;
      	&lt;li class="ss-playfilm"&gt;&lt;a href="/blog/2013/charismatic-duo/img/refute.gif"&gt;Animated &lt;span class="caps"&gt;GIF&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
      &lt;img src="/blog/2013/charismatic-duo/img/refute.gif" alt="Cold stare." title="Cold stare." /&gt;&lt;p class="caption"&gt;Cold stare.&lt;/p&gt;    &lt;p class="tweet-link"&gt;
            &lt;a href="https://twitter.com/share" class="twitter-share-button" data-url="https://peepcode.com/blog/2013/charismatic-duo/img/refute.gif" data-text="Cold stare." data-count="none" data-size="large" data-dnt="true"&gt;Tweet&lt;/a&gt;
            &lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");&lt;/script&gt;
          &lt;/p&gt;
      &lt;h3&gt;Stand back!&lt;/h3&gt;
      &lt;ul&gt;
      	&lt;li class="ss-usersframe"&gt;&lt;a href="/blog/2013/charismatic-duo/img/whoawhoa.jpg"&gt;Full size image&lt;/a&gt;&lt;/li&gt;
      	&lt;li class="ss-playfilm"&gt;&lt;a href="/blog/2013/charismatic-duo/img/whoawhoa.gif"&gt;Animated &lt;span class="caps"&gt;GIF&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
      &lt;img src="/blog/2013/charismatic-duo/img/whoawhoa.gif" alt="Whoa!" title="Whoa!" /&gt;&lt;p class="caption"&gt;Whoa!&lt;/p&gt;    &lt;p class="tweet-link"&gt;
            &lt;a href="https://twitter.com/share" class="twitter-share-button" data-url="https://peepcode.com/blog/2013/charismatic-duo/img/whoawhoa.gif" data-text="Whoa!" data-count="none" data-size="large" data-dnt="true"&gt;Tweet&lt;/a&gt;
            &lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");&lt;/script&gt;
          &lt;/p&gt;
      &lt;h3&gt;Facepalm&lt;/h3&gt;
      &lt;ul&gt;
      	&lt;li class="ss-usersframe"&gt;&lt;a href="/blog/2013/charismatic-duo/img/firstiwas.jpg"&gt;Full size image&lt;/a&gt;&lt;/li&gt;
      	&lt;li class="ss-playfilm"&gt;&lt;a href="/blog/2013/charismatic-duo/img/firstiwas.gif"&gt;Animated &lt;span class="caps"&gt;GIF&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
      &lt;img src="/blog/2013/charismatic-duo/img/firstiwas.gif" alt="So the reason is&amp;#8230;" title="So the reason is&amp;#8230;" /&gt;&lt;p class="caption"&gt;So the reason is&amp;#8230;&lt;/p&gt;    &lt;p class="tweet-link"&gt;
            &lt;a href="https://twitter.com/share" class="twitter-share-button" data-url="https://peepcode.com/blog/2013/charismatic-duo/img/firstiwas.gif" data-text="Facepalm." data-count="none" data-size="large" data-dnt="true"&gt;Tweet&lt;/a&gt;
            &lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");&lt;/script&gt;
          &lt;/p&gt;
      &lt;h3&gt;What?&lt;/h3&gt;
      &lt;ul&gt;
      	&lt;li class="ss-usersframe"&gt;&lt;a href="/blog/2013/charismatic-duo/img/look.jpg"&gt;Full size image&lt;/a&gt;&lt;/li&gt;
      	&lt;li class="ss-playfilm"&gt;&lt;a href="/blog/2013/charismatic-duo/img/look.gif"&gt;Animated &lt;span class="caps"&gt;GIF&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
      &lt;img src="/blog/2013/charismatic-duo/img/look.gif" alt="What? No. No." title="What? No. No." /&gt;&lt;p class="caption"&gt;What? No. No.&lt;/p&gt;    &lt;p class="tweet-link"&gt;
            &lt;a href="https://twitter.com/share" class="twitter-share-button" data-url="https://peepcode.com/blog/2013/charismatic-duo/img/look.gif" data-text="What?" data-count="none" data-size="large" data-dnt="true"&gt;Tweet&lt;/a&gt;
            &lt;script&gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");&lt;/script&gt;
          &lt;/p&gt;
      &lt;p&gt;Watch the full-length &lt;a href="https://peepcode.com/products/play-by-play-aaroncorey"&gt;Play by Play with Aaron Patterson and Corey Haines&lt;/a&gt;&lt;/p&gt;
      &lt;p class="small"&gt;Did you know&amp;#8230;if you&amp;#8217;ve ever had a PeepCode Unlimited subscription, you can &lt;a href="https://peepcode.com/plans"&gt;renew&lt;/a&gt; now for only $109! Or tell your employer to &lt;a href="mailto:sales@peepcode.com"&gt;contact us&lt;/a&gt; for a business subscription.&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</content>
    <published>Sat Apr 06 00:20:00 +0000 2013</published>
  </entry>
  <entry>
    <title>The PeepCode iOS App</title>
    <link type="text/html" rel="alternate" href="http://blog.peepcode.com/blog/2013/the-peepcode-ios-app" />
    <id>tag:blog.peepcode.com,2013-03-22:/blog/2013/the-peepcode-ios-app</id>
    <content type="html">&lt;p&gt;&lt;strong&gt;This article is heavily styled and is best viewed at &lt;a href="http://blog.peepcode.com/blog/2013/the-peepcode-ios-app"&gt;PeepCode&lt;/a&gt;!&lt;/strong&gt;&lt;/p&gt;&lt;div id='essay'&gt;
  &lt;div class='row'&gt;
    &lt;div class='column author'&gt;
      &lt;p&gt;
        by
        &lt;span&gt;
          Geoffrey Grosenbach
        &lt;/span&gt;
        and
        &lt;span&gt;
          Paula Lavalle
        &lt;/span&gt;
      &lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column article'&gt;
      &lt;p&gt;&lt;a href="http://appstore.com/peepcode"&gt;&lt;img src="https://peepcode.com/images/promo-appbadge.png" class="appbadge" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
      &lt;p class="department"&gt;From the It Just Makes Sense department&lt;/p&gt;
      &lt;div class="left"&gt;&lt;img src="/blog/2013/the-peepcode-ios-app/img/onatv.jpg" alt="Stream to your Apple TV! We&amp;#8217;re watching Play by Play with Corey Haines and Aaron Patterson." title="Stream to your Apple TV! We&amp;#8217;re watching Play by Play with Corey Haines and Aaron Patterson." /&gt;&lt;p class="caption"&gt;Stream to your Apple TV! We&amp;#8217;re watching Play by Play with Corey Haines and Aaron Patterson.&lt;/p&gt;&lt;/div&gt;&lt;p&gt;As a bootstrapped company, it&amp;#8217;s not always clear what the next step is, but an iOS app for viewing PeepCode videos has been one of the longest standing requests we&amp;#8217;ve received. Which makes sense! It&amp;#8217;s almost as if these devices were perfectly designed for watching PeepCode videos. The new iPhone 5 is the right dimensions for displaying HD video, which is what all our new videos have been filmed in since the end of last year (and some before that).&lt;/p&gt;
      &lt;p&gt;So we (finally) took the plunge and built an iOS app. We worked with expert iOS developer (and PeepCode &lt;a href="https://peepcode.com/screencasts/iphone"&gt;author&lt;/a&gt;) Alex Vollmer of &lt;a href="http://www.radiantcapsule.com/"&gt;Radiant Capsule&lt;/a&gt;, and while he did most of the heavy lifting we certainly put in a lot of work and learned a lot along the way.&lt;/p&gt;
      &lt;h2&gt;Solving the Progress Bar Problem&lt;/h2&gt;
      &lt;img src="/blog/2013/the-peepcode-ios-app/img/design-download.png" alt="Download progress shows both percentage and remaining MB." title="Download progress shows both percentage and remaining MB." /&gt;&lt;p class="caption"&gt;Download progress shows both percentage and remaining MB.&lt;/p&gt;&lt;p&gt;Desiging a good progress bar is &lt;a href="http://xkcd.com/612/"&gt;famously difficult&lt;/a&gt;. Given that our audience is technical and speaks MB and GB, we settled on a great solution that works specifically for the content we&amp;#8217;re delivering.&lt;/p&gt;
      &lt;p&gt;We decided to combine a standard progress bar with a numerical percentage. This works well for any videos under 100MB. But large videos might appear to be stalled if we can only show 100 points of progress. If a video is 500MB, it might take a minute or more to download 1/100th of it (5MB) and show progress.&lt;/p&gt;
      &lt;p&gt;So we also show you the number of MB remaining. This gives visual feedback that&amp;#8217;s useful for videos larger than 100MB. The end result is that for any video you&amp;#8217;ll download, progress is frequent and keeps you updated.&lt;/p&gt;
      &lt;h2&gt;Delivering Instant Gratification&lt;/h2&gt;
      &lt;img src="/blog/2013/the-peepcode-ios-app/img/design-streaming.png" alt="The UI shows progress in two steps." title="The UI shows progress in two steps." /&gt;&lt;p class="caption"&gt;The UI shows progress in two steps.&lt;/p&gt;&lt;p&gt;One of the things we find frustrating about video streaming applications is all the waiting.&lt;/p&gt;
      &lt;p&gt;Starting an &lt;span class="caps"&gt;HTTP&lt;/span&gt; video stream can involve an &lt;span class="caps"&gt;API&lt;/span&gt; call, requests for 2 metadata files, and another request for a media file&amp;#8230;all before you see a single frame of video.&lt;/p&gt;
      &lt;p&gt;We wanted to improve on that by showing you some progress along the way. So you&amp;#8217;ll see an initial spinner when you click the &amp;#8220;Play&amp;#8221; button on the cover. When the first &lt;span class="caps"&gt;API&lt;/span&gt; call has completed, you&amp;#8217;ll be taken to the video player where the video will start to stream.&lt;/p&gt;
      &lt;p&gt;Splitting progress into two visual steps makes the application feel more responsive than it would if we just sent you directly to the video player where you would have to wait for 5 or 10 seconds. It&amp;#8217;s part of the attention we&amp;#8217;ve put into the UI of this application to make it enjoyable to use.&lt;/p&gt;
      &lt;p class="small"&gt;Note: Video streams start at low quality while the device figures out what bandwidth is available. If you have a good Internet connection, you&amp;#8217;ll see better quality video after a few seconds. We&amp;#8217;re working on adding full HD streams to videos, too.&lt;/p&gt;&lt;h2&gt;The Value of a Flaky Development Server&lt;/h2&gt;
      &lt;p&gt;It&amp;#8217;s not easy to bootstrap a multimedia application that requires client, server, and media.&lt;/p&gt;
      &lt;p&gt;Due to misbehaving third-party libraries, our first implementation of a video streaming server would sometimes monopolize 100% of the server&amp;#8217;s &lt;span class="caps"&gt;CPU&lt;/span&gt; and hang, or never return a response at all. This was bad news for the iOS client application since it couldn&amp;#8217;t get the data it needed to start streaming a video.&lt;/p&gt;
      &lt;p&gt;Or was it? The early flakiness forced Alex to add more error checking code to the iOS client, and better error messages for the user. And it forced us to write the server code to look for timeouts or blank &lt;span class="caps"&gt;API&lt;/span&gt; responses. Overall, it made our code more robust.&lt;/p&gt;
      &lt;div class="floatleft"&gt;&lt;img src="/blog/2013/the-peepcode-ios-app/img/inacoffeeshop.jpg" alt="Brother Baba Budan, Melbourne" title="Brother Baba Budan, Melbourne" /&gt;&lt;p class="caption"&gt;Brother Baba Budan, Melbourne&lt;/p&gt;&lt;/div&gt;&lt;p&gt;And yes, we rewrote the server so it doesn&amp;#8217;t use 100% &lt;span class="caps"&gt;CPU&lt;/span&gt; anymore. In fact, it&amp;#8217;s been smooth sailing since the launch.&lt;/p&gt;
      &lt;h2&gt;Keeping it Simple&lt;/h2&gt;
      &lt;p&gt;We&amp;#8217;ve launched version 1.0 with a simple but straightforward feature set: &lt;a href="https://peepcode.com/plans"&gt;PeepCode Unlimited&lt;/a&gt; subscribers can download or stream any video we&amp;#8217;ve published in the last two years. We&amp;#8217;re starting with only PeepCode Unlimited subscribers so we can fine-tune our streaming infrastructure and determine what mirrors we need around the world for a top notch download and streaming experience. So far everything has been running very well.&lt;/p&gt;
      &lt;p&gt;Anyone with a PeepCode account of any kind can use the app to stream previews of current videos.&lt;/p&gt;
      &lt;h2&gt;Interesting Features&lt;/h2&gt;
      &lt;ul&gt;
      	&lt;li&gt;The app will remember the playback time of each video you&amp;#8217;ve watched. If you have iCloud, it will sync that across all your devices. So you can watch part of &lt;a href="https://peepcode.com/products/play-by-play-aaroncorey"&gt;Play by Play with Aaron Patterson and Corey Haines&lt;/a&gt; on your iPhone, then resume watching on your iPad at the same time in the video.&lt;/li&gt;
      	&lt;li&gt;We&amp;#8217;ve done extensive testing, literally all around the world (Seattle, Melbourne, Kauai, San Francisco). We hope to add video streaming mirrors for an even better experience.&lt;/li&gt;
      	&lt;li&gt;Stream to your AppleTV with AirPlay. &lt;a href="https://peepcode.com/screencasts/play-by-play"&gt;Play by Play&lt;/a&gt; looks fantastic on an &lt;span class="caps"&gt;HDTV&lt;/span&gt;.&lt;/li&gt;
      	&lt;li&gt;Smart download doesn&amp;#8217;t drain your battery if you leave the app. It resumes when you&amp;#8217;ve re-launched the app and are back in Wi-Fi range. (Our developer tested this by walking down the street until he was out of range).&lt;/li&gt;
      	&lt;li&gt;Download full quality videos or stream up to half resolution. Our new HD videos look amazing on the iPhone 5!&lt;/li&gt;
      	&lt;li&gt;We built a custom, self-contained Sinatra server for streaming video. This will make it easier for us to deploy extra streaming or download servers around the world or whenever needed.&lt;/li&gt;
      	&lt;li&gt;A series of command line scripts together with &lt;a href="http://www.pandastream.com/"&gt;remote APIs&lt;/a&gt; makes it a breeze to encode video for all the necessary formats and copy it to our servers.&lt;/li&gt;
      &lt;/ul&gt;
      &lt;h2&gt;Try it!&lt;/h2&gt;
      &lt;p&gt;We&amp;#8217;re proud of this application, our first shipping iOS application. For a 1.0, it covers most of what&amp;#8217;s needed for a great mobile experience.&lt;/p&gt;
      &lt;p&gt;Possibly the best evidence of how useful this application is was how much we started using it in-house! On the bus, at home streamed to an Apple TV, or on a plane. The last three months of rigorous testing and refinement have been a lot of fun.&lt;/p&gt;
      &lt;p&gt;&lt;a href="http://appstore.com/peepcode"&gt;Try it out&lt;/a&gt; with any PeepCode account. Or upgrade to &lt;a href="https://peepcode.com/plans"&gt;PeepCode Unlimited&lt;/a&gt; for full-length streaming!&lt;/p&gt;
      &lt;p class="small"&gt;Did you know&amp;#8230;if you&amp;#8217;ve ever had a PeepCode Unlimited subscription, you can &lt;a href="https://peepcode.com/plans"&gt;renew&lt;/a&gt; now for only $109! Or tell your employer to &lt;a href="mailto:sales@peepcode.com"&gt;contact us&lt;/a&gt; for a business subscription.&lt;/p&gt;&lt;p class="appbadgecentered"&gt;&lt;a href="http://appstore.com/peepcode"&gt;&lt;img src="https://peepcode.com/images/promo-appbadge.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
      &lt;img src="/blog/2013/the-peepcode-ios-app/img/ipad-landscape-700.png" alt="Watch on the iPad, too!" title="Watch on the iPad, too!" /&gt;&lt;p class="caption"&gt;Watch on the iPad, too!&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</content>
    <published>Fri Mar 22 02:03:00 +0000 2013</published>
  </entry>
  <entry>
    <title>Jake Mitchell is One of the Topfunky Ones</title>
    <link type="text/html" rel="alternate" href="http://blog.peepcode.com/blog/2012/jake-mitchell" />
    <id>tag:blog.peepcode.com,2012-11-30:/blog/2012/jake-mitchell</id>
    <content type="html">&lt;p&gt;&lt;strong&gt;This article is heavily styled and is best viewed at &lt;a href="http://blog.peepcode.com/blog/2012/jake-mitchell"&gt;PeepCode&lt;/a&gt;!&lt;/strong&gt;&lt;/p&gt;&lt;div id='essay'&gt;
  &lt;div class='row'&gt;
    &lt;div class='column author'&gt;
      &lt;p&gt;
        by
        &lt;span&gt;
          Geoffrey Grosenbach
        &lt;/span&gt;
      &lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column article'&gt;
      &lt;p&gt;Software developers are hard to find. Good ones are even harder.&lt;/p&gt;
      &lt;p&gt;We&amp;#8217;re fortunate to have found one.&lt;/p&gt;
      &lt;p&gt;Jake Mitchell has degrees in Computer Science and Mathematics. He&amp;#8217;s a polyglot programmer with experience in many languages and frameworks. Jake&amp;#8217;s the kind of person who you&amp;#8217;ll find implementing a &lt;span class="caps"&gt;TIFF&lt;/span&gt; image parser in CoffeeScript that renders to the &lt;span class="caps"&gt;HTML&lt;/span&gt; canvas. For fun.&lt;/p&gt;
      &lt;p&gt;Jake started working full time at PeepCode about a month ago and has already implemented some useful backend code and started on a new video series for us. If you&amp;#8217;ve ever wanted to understand how cryptography works, you&amp;#8217;ll want to keep an eye out for it.&lt;/p&gt;
      &lt;p&gt;You can follow Jake on Twitter &lt;a href="http://twitter.com/mekajfire"&gt;here&lt;/a&gt;. Subscribe to PeepCode &lt;a href="https://peepcode.com/plans"&gt;here&lt;/a&gt;.&lt;/p&gt;
      &lt;img src="/blog/2012/jake-mitchell/img/JakeMitchellRD-940px.jpg" alt="Jamming at the Pioneer Valley Roller Derby in Massachusetts. Photo by Susan Farber" title="Jamming at the Pioneer Valley Roller Derby in Massachusetts. Photo by Susan Farber" /&gt;&lt;p class="caption"&gt;Jamming at the Pioneer Valley Roller Derby in Massachusetts. Photo by Susan Farber&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</content>
    <published>Fri Nov 30 21:15:00 +0000 2012</published>
  </entry>
  <entry>
    <title>Awesome Business Card</title>
    <link type="text/html" rel="alternate" href="http://blog.peepcode.com/blog/2012/awesome-business-card" />
    <id>tag:blog.peepcode.com,2012-10-30:/blog/2012/awesome-business-card</id>
    <content type="html">&lt;p&gt;&lt;strong&gt;This article is heavily styled and is best viewed at &lt;a href="http://blog.peepcode.com/blog/2012/awesome-business-card"&gt;PeepCode&lt;/a&gt;!&lt;/strong&gt;&lt;/p&gt;&lt;div id='essay'&gt;
  &lt;div class='row'&gt;
    &lt;div class='column author'&gt;
      &lt;p&gt;
        words
        &lt;span&gt;
          Geoffrey Grosenbach
        &lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        card design
        &lt;span&gt;
          Paula Lavalle
        &lt;/span&gt;
      &lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column article'&gt;
      &lt;p&gt;&lt;img src="awesome-business-card/img/peepcode-awesome-business-card-front.jpg" title="Card front" alt="Card front" /&gt;&lt;/p&gt;
      &lt;p&gt;While waiting in line to buy the original iPad, I gave someone my &lt;a href="https://peepcode.com/blog/2009/business-card"&gt;business card&lt;/a&gt;. He said it was an amazing card. In fact, it was the second best business card he had ever seen.&lt;/p&gt;
      &lt;p&gt;&amp;#8220;Only the &lt;em&gt;second&lt;/em&gt; best?&amp;#8221; I asked. &amp;#8220;What did the best one look like?&amp;#8221;&lt;/p&gt;
      &lt;p&gt;&amp;#8220;It was a plain looking card,&amp;#8221; he said, &amp;#8220;but if you sprinkled water on it for a week, it would grow grass in the shape of the company logo.&amp;#8221;&lt;/p&gt;
      &lt;p&gt;I knew it was time to improve our game.&lt;/p&gt;
      &lt;h2&gt;Refresh&lt;/h2&gt;
      &lt;p&gt;Earlier this year we ran out of our old business cards. And PeepCode has grown since three years ago! We now have at least five people who need an awesome card to hand out at tech conferences, at nerd parties, and to random strangers.&lt;/p&gt;
      &lt;p&gt;We put our best designer on the job. We contracted &lt;a href="http://evolutionpress.net"&gt;Evolution Press&lt;/a&gt; for advice on paper, ink, foil, paint, and lead type.&lt;/p&gt;
      &lt;p&gt;Glossy black ink together with silver foil and white lettering make for a combination that can&amp;#8217;t really be represented on screen.&lt;/p&gt;
      &lt;p&gt;Although it doesn&amp;#8217;t contain any grass seeds (can you even take those through international customs?), we&amp;#8217;re extremely happy with it.&lt;/p&gt;
      &lt;p&gt;We&amp;#8217;ll be at &lt;a href="http://cascadiajs.com/"&gt;Cascadia JS&lt;/a&gt; and other conferences in the next few months. Find us and ask for one!&lt;/p&gt;
      &lt;p&gt;&lt;img src="awesome-business-card/img/peepcode-awesome-business-card-edge.jpg" title="Card edge" alt="Card edge" /&gt;&lt;/p&gt;
      &lt;p&gt;&lt;img src="awesome-business-card/img/peepcode-awesome-business-card-foil.jpg" title="Card foil detail" alt="Card foil detail" /&gt;&lt;/p&gt;
      &lt;p&gt;&lt;img src="awesome-business-card/img/peepcode-awesome-business-card-varnish.jpg" title="Card glossy black ink detail" alt="Card glossy black ink detail" /&gt;&lt;/p&gt;
      &lt;div class='footer'&gt;
        &lt;p&gt;Can you find the pattern in this article&amp;#8217;s title and subtitle?&lt;/p&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</content>
    <published>Tue Oct 30 16:45:00 +0000 2012</published>
  </entry>
  <entry>
    <title>Commanding Your Text Editor</title>
    <link type="text/html" rel="alternate" href="http://blog.peepcode.com/blog/2012/commanding-your-text-editor" />
    <id>tag:blog.peepcode.com,2012-10-18:/blog/2012/commanding-your-text-editor</id>
    <content type="html">&lt;p&gt;&lt;strong&gt;This article is heavily styled and is best viewed at &lt;a href="http://blog.peepcode.com/blog/2012/commanding-your-text-editor"&gt;PeepCode&lt;/a&gt;!&lt;/strong&gt;&lt;/p&gt;&lt;div id='essay'&gt;
  &lt;div class='row'&gt;
    &lt;div class='column author'&gt;
      &lt;p&gt;
        words
        &lt;span&gt;
          &lt;a href='http://twitter.com/topfunky'&gt;Geoffrey Grosenbach&lt;/a&gt;
        &lt;/span&gt;
      &lt;/p&gt;
      &lt;p&gt;
        design
        &lt;span&gt;
          &lt;a href='http://twitter.com/lalavalse'&gt;Paula Lavalle&lt;/a&gt;
        &lt;/span&gt;
      &lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column article toc'&gt;
      &lt;div class='column commands'&gt;
        &lt;a href='#manipulate-words'&gt;
          &lt;div class='toc words'&gt;&lt;/div&gt;
          &lt;br /&gt;
          Words
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class='column commands'&gt;
        &lt;a href='#add-lines'&gt;
          &lt;div class='toc lines'&gt;&lt;/div&gt;
          &lt;br /&gt;
          Lines
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class='column commands'&gt;
        &lt;a href='#infile-search'&gt;
          &lt;div class='toc search'&gt;&lt;/div&gt;
          &lt;br /&gt;
          Search
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class='column commands'&gt;
        &lt;a href='#fuzzy-search'&gt;
          &lt;div class='toc switch'&gt;&lt;/div&gt;
          &lt;br /&gt;
          Switch
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class='column commands'&gt;
        &lt;a href='#auto-indent'&gt;
          &lt;div class='toc format'&gt;&lt;/div&gt;
          &lt;br /&gt;
          Format
        &lt;/a&gt;
      &lt;/div&gt;
      &lt;div class='column commands'&gt;
        &lt;a href='#auto-complete'&gt;
          &lt;div class='toc complete'&gt;&lt;/div&gt;
          &lt;br /&gt;
          Complete
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class='column article'&gt;
      &lt;p&gt;The process of writing code is much different from the process of editing code. It&amp;#8217;s easy to confuse the two since they both involve mashing buttons on a keyboard while staring at a computer screen.&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://peepcode.com/products/smash-into-vim-i"&gt;Vim&lt;/a&gt; users know this already. Their editor works in two completely different ways depending on whether they are adding new words to a document or changing existing words.&lt;/p&gt;
      &lt;p&gt;They also know that there&amp;#8217;s more to text editing than moving around with the arrow keys and selecting one letter at a time. But you don&amp;#8217;t have to memorize hundreds of commands. I think only these six will handle most of the editing that you&amp;#8217;ll do every day.&lt;/p&gt;
      &lt;ul&gt;
      	&lt;li&gt;&lt;strong&gt;Delete&lt;/strong&gt; whole &lt;strong&gt;words&lt;/strong&gt; (before and after the cursor)&lt;/li&gt;
      	&lt;li&gt;&lt;strong&gt;Create&lt;/strong&gt; a &lt;strong&gt;newline&lt;/strong&gt; and put the cursor there (above or below)&lt;/li&gt;
      	&lt;li&gt;&lt;strong&gt;Search&lt;/strong&gt; in a file&lt;/li&gt;
      	&lt;li&gt;&lt;strong&gt;Switch&lt;/strong&gt; files&lt;/li&gt;
      	&lt;li&gt;&lt;strong&gt;Indent&lt;/strong&gt; code automatically&lt;/li&gt;
      	&lt;li&gt;Use &lt;strong&gt;completion&lt;/strong&gt;&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/div&gt;
    &lt;div class='column grid_12'&gt;
      &lt;h3 id="manipulate-words"&gt;1. Delete Whole Words&lt;/h3&gt;
    &lt;/div&gt;
    &lt;div class='column article'&gt;
      &lt;p&gt;Steve Yegge writes that it&amp;#8217;s much faster to delete an entire word and retype it than it is to navigate to and correct a single letter (see his post on &lt;a href="https://sites.google.com/site/steveyegge2/effective-emacs"&gt;Effective Emacs&lt;/a&gt;).&lt;/p&gt;
      &lt;p&gt;There&amp;#8217;s not much else to say here: learn to delete the word before the cursor and the word after the cursor. You&amp;#8217;ll immediately find yourself using it constantly throughout the day.&lt;/p&gt;
      &lt;p&gt;This one is even built in to Mac OS X, so it works in any text editing application (Sublime Text, Pages, TextMate).&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column editor short'&gt;
      &lt;h4&gt;Mac OS X&lt;/h4&gt;
      &lt;p&gt;Delete next word:&lt;/p&gt;
      &lt;p&gt;&lt;img src="commanding-your-text-editor/control-keys/fn.png" class="shortcut-tall" alt="" /&gt;
      &lt;img src="commanding-your-text-editor/control-keys/option.png" class="shortcut-tall" alt="" /&gt;
      &lt;img src="commanding-your-text-editor/control-keys/delete.png" class="shortcut" alt="" /&gt;&lt;/p&gt;
      &lt;p&gt;Delete previous word:&lt;/p&gt;
      &lt;p&gt;&lt;img src="commanding-your-text-editor/control-keys/option.png" class="shortcut-tall" alt="" /&gt;
      &lt;img src="commanding-your-text-editor/control-keys/delete.png" class="shortcut" alt="" /&gt;&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column editor'&gt;
      &lt;h4&gt;Vim&lt;/h4&gt;
      &lt;p&gt;Delete next word:&lt;/p&gt;
      &lt;p&gt;&lt;img src="commanding-your-text-editor/control-keys/d.png" class="shortcut" alt="" /&gt;
      &lt;img src="commanding-your-text-editor/control-keys/w.png" class="shortcut" alt="" /&gt;&lt;/p&gt;
      &lt;p&gt;Delete previous word:&lt;/p&gt;
      &lt;p&gt;&lt;img src="commanding-your-text-editor/control-keys/d.png" class="shortcut" alt="" /&gt;
      &lt;img src="commanding-your-text-editor/control-keys/b.png" class="shortcut" alt="" /&gt;&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column editor'&gt;
      &lt;h4&gt;Emacs (and Terminal)&lt;/h4&gt;
      &lt;p&gt;Delete next word:&lt;/p&gt;
      &lt;p&gt;&lt;img src="commanding-your-text-editor/control-keys/esc.png" class="shortcut" alt="" /&gt;
      &lt;img src="commanding-your-text-editor/control-keys/d.png" class="shortcut" alt="" /&gt;&lt;/p&gt;
      &lt;p&gt;Delete previous word:&lt;/p&gt;
      &lt;p&gt;&lt;img src="commanding-your-text-editor/control-keys/esc.png" class="shortcut" alt="" /&gt;
      &lt;img src="commanding-your-text-editor/control-keys/delete.png" class="shortcut" alt="" /&gt;&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column grid_12'&gt;
      &lt;h3 id="add-lines"&gt;2. Add Lines&lt;/h3&gt;
    &lt;/div&gt;
    &lt;div class='column article'&gt;
      &lt;p&gt;The novice learns to make a newline by moving the cursor to the end of the line and hitting the &lt;span class="caps"&gt;ENTER&lt;/span&gt; key. Or a newline above by moving the cursor up one line, to the end of that line, hitting &lt;span class="caps"&gt;ENTER&lt;/span&gt;, then indent&amp;#8230;shouldn&amp;#8217;t this be easier?&lt;/p&gt;
      &lt;p&gt;The Pro can add a newline above or below from any point in the line. You don&amp;#8217;t have to move your cursor at all.&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column editor'&gt;
      &lt;h4&gt;Textmate&lt;/h4&gt;
      &lt;p&gt;Newline below&lt;/p&gt;
      &lt;p&gt;&lt;img src="commanding-your-text-editor/control-keys/command.png" class="shortcut-tall" alt="" /&gt;
      &lt;img src="commanding-your-text-editor/control-keys/enter.png" class="shortcut" alt="" /&gt;&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column editor'&gt;
      &lt;h4&gt;Vim&lt;/h4&gt;
      &lt;p&gt;Newline below&lt;/p&gt;
      &lt;p&gt;&lt;img src="commanding-your-text-editor/control-keys/o.png" class="shortcut" alt="" /&gt;&lt;/p&gt;
      &lt;p&gt;Newline above&lt;/p&gt;
      &lt;p&gt;&lt;img src="commanding-your-text-editor/control-keys/shift.png" class="shortcut" alt="" /&gt;
      &lt;img src="commanding-your-text-editor/control-keys/o.png" class="shortcut" alt="" /&gt;&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column editor'&gt;
      &lt;h4&gt;Emacs&lt;/h4&gt;
      &lt;p&gt;&lt;a href="commanding-your-text-editor/emacs-newline.el"&gt;Newline up/down snippet&lt;/a&gt;&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column editor'&gt;
      &lt;h4&gt;Sublime Text&lt;/h4&gt;
      &lt;p&gt;Newline below&lt;/p&gt;
      &lt;p&gt;&lt;img src="commanding-your-text-editor/control-keys/command.png" class="shortcut" alt="" /&gt;
      &lt;img src="commanding-your-text-editor/control-keys/enter.png" class="shortcut" alt="" /&gt;&lt;/p&gt;
      &lt;p&gt;Newline above&lt;/p&gt;
      &lt;p&gt;&lt;img src="commanding-your-text-editor/control-keys/command.png" class="shortcut" alt="" /&gt;
      &lt;img src="commanding-your-text-editor/control-keys/shift-short.png" class="shortcut" alt="" /&gt;
      &lt;img src="commanding-your-text-editor/control-keys/enter.png" class="shortcut" alt="" /&gt;&lt;/p&gt;
      &lt;p&gt;&lt;a href="https://twitter.com/joaquinvicente/status/259050831045857280"&gt;Thanks to Joaquin Vicente&lt;/a&gt;&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column grid_12'&gt;
      &lt;h3 id="infile-search"&gt;3. In-file Search&lt;/h3&gt;
    &lt;/div&gt;
    &lt;div class='column article'&gt;
      &lt;p&gt;Search isn&amp;#8217;t just for finding words. It&amp;#8217;s an efficient way to navigate.&lt;/p&gt;
      &lt;p&gt;And live search is much faster than using a search dialog. Hit the hotkey and start typing the word. &lt;span class="caps"&gt;BAM&lt;/span&gt;! You&amp;#8217;re there. It&amp;#8217;s great for navigation instead of using the arrow keys to navigate within a file.&lt;/p&gt;
      &lt;p&gt;Emacs-style &lt;code&gt;Ctrl-s&lt;/code&gt; is also available in TextMate.&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column editor'&gt;
      &lt;h4&gt;Textmate&lt;/h4&gt;
      &lt;p&gt;Live search&lt;/p&gt;
      &lt;p&gt;&lt;img src="commanding-your-text-editor/control-keys/control.png" class="shortcut-tall" alt="" /&gt;
      &lt;img src="commanding-your-text-editor/control-keys/s.png" class="shortcut" alt="" /&gt;&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column editor'&gt;
      &lt;h4&gt;Vim&lt;/h4&gt;
      &lt;p&gt;Live search&lt;/p&gt;
      &lt;p&gt;&lt;img src="commanding-your-text-editor/control-keys/questionmark.png" class="shortcut" alt="" /&gt;&lt;/p&gt;
      &lt;p&gt;Hit &lt;code&gt;n&lt;/code&gt; to repeat search.&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column editor'&gt;
      &lt;h4&gt;Emacs&lt;/h4&gt;
      &lt;p&gt;Search foward:&lt;/p&gt;
      &lt;p&gt;&lt;img src="commanding-your-text-editor/control-keys/control.png" class="shortcut-tall" alt="" /&gt;
      &lt;img src="commanding-your-text-editor/control-keys/s.png" class="shortcut" alt="" /&gt;&lt;/p&gt;
      &lt;p&gt;Search backward:&lt;/p&gt;
      &lt;p&gt;&lt;img src="commanding-your-text-editor/control-keys/control.png" class="shortcut-tall" alt="" /&gt;
      &lt;img src="commanding-your-text-editor/control-keys/r.png" class="shortcut" alt="" /&gt;&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column editor'&gt;
      &lt;h4&gt;Sublime Text&lt;/h4&gt;
      &lt;p&gt;Search forward:&lt;/p&gt;
      &lt;p&gt;&lt;img src="commanding-your-text-editor/control-keys/command.png" class="shortcut-tall" alt="" /&gt;
      &lt;img src="commanding-your-text-editor/control-keys/i.png" class="shortcut" alt="" /&gt;&lt;/p&gt;
      &lt;p&gt;Hit Cmd-i again to repeat search.&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column grid_12'&gt;
      &lt;h3 id="fuzzy-search"&gt;4. Fuzzy File Search&lt;/h3&gt;
    &lt;/div&gt;
    &lt;div class='column article'&gt;
      &lt;p&gt;Programming happens in files, usually several. TextMate&amp;#8217;s fuzzy file search revolutionized my use of my text editor. But it only searches filenames, not directory paths.&lt;/p&gt;
      &lt;p&gt;This is why I wrote &lt;a href="https://peepcode.com/products/peepopen"&gt;PeepOpen&lt;/a&gt;, and I still use it every day.&lt;/p&gt;
      &lt;p&gt;&lt;img src="commanding-your-text-editor/img/peepopen.png" alt="" /&gt;&lt;/p&gt;
      &lt;p&gt;I think Sublime Text has the best built-in fuzzy file finder of any current text editor. It&amp;#8217;s not initially clear that it does this, but it searches on paths as well as filenames. The search score on the left is completely useless to me, but the file and path are a huge improvement over TextMate.&lt;/p&gt;
      &lt;p&gt;&lt;img src="commanding-your-text-editor/img/sublime.png" alt="" /&gt;&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column editor'&gt;
      &lt;h4&gt;TextMate&lt;/h4&gt;
      &lt;p&gt;Search by filename&lt;/p&gt;
      &lt;p&gt;&lt;img src="commanding-your-text-editor/control-keys/command.png" class="shortcut-tall" alt="" /&gt;
      &lt;img src="commanding-your-text-editor/control-keys/t.png" class="shortcut" alt="" /&gt;&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column editor'&gt;
      &lt;h4&gt;Vim&lt;/h4&gt;
      &lt;p&gt;Search open buffers by filename&lt;/p&gt;
      &lt;p&gt;&lt;code&gt;:b filename&lt;/code&gt;&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column editor'&gt;
      &lt;h4&gt;Emacs&lt;/h4&gt;
      &lt;p&gt;Search filenames (using &lt;a href="https://peepcode.com/products/peepopen"&gt;PeepOpen&lt;/a&gt; or &lt;a href="https://github.com/defunkt/textmate.el"&gt;textmate.el&lt;/a&gt;)&lt;/p&gt;
      &lt;p&gt;&lt;img src="commanding-your-text-editor/control-keys/command.png" class="shortcut-tall" alt="" /&gt;
      &lt;img src="commanding-your-text-editor/control-keys/t.png" class="shortcut" alt="" /&gt;&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column editor'&gt;
      &lt;h4&gt;Sublime Text&lt;/h4&gt;
      &lt;p&gt;Built-in fuzzy file search&lt;/p&gt;
      &lt;p&gt;&lt;img src="commanding-your-text-editor/control-keys/command.png" class="shortcut-tall" alt="" /&gt;
      &lt;img src="commanding-your-text-editor/control-keys/t.png" class="shortcut" alt="" /&gt;&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column grid_12'&gt;
      &lt;h3 id="auto-indent"&gt;5. Automatic Indentation&lt;/h3&gt;
    &lt;/div&gt;
    &lt;div class='column article'&gt;
      &lt;p&gt;Now we&amp;#8217;re getting into more advanced features, but still ones that I use constantly.&lt;/p&gt;
      &lt;p&gt;When using languages without syntactically significant whitespace (e.g. CoffeeScript), I let the editor do the formatting for me. It works 90% of the time, and for the other 10% I&amp;#8217;d rather modify my code to work with the built-in formatting than do it manually.&lt;/p&gt;
      &lt;p&gt;Most developers would refuse to use a text editor without syntax highlighting. To me, auto-indentation is a show stopping feature.&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column editor'&gt;
      &lt;h4&gt;Textmate&lt;/h4&gt;
      &lt;p&gt;For some languages only&lt;/p&gt;
      &lt;p&gt;&lt;img src="commanding-your-text-editor/control-keys/command.png" class="shortcut-tall" alt="" /&gt;
      &lt;img src="commanding-your-text-editor/control-keys/shift-short.png" class="shortcut" alt="" /&gt;
      &lt;img src="commanding-your-text-editor/control-keys/h.png" class="shortcut" alt="" /&gt;&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column editor'&gt;
      &lt;h4&gt;Vim&lt;/h4&gt;
      &lt;p&gt;Select a range with &lt;code&gt;V&lt;/code&gt;&lt;/p&gt;
      &lt;p&gt;&lt;img src="commanding-your-text-editor/control-keys/equal.png" class="shortcut" alt="" /&gt;&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column editor'&gt;
      &lt;h4&gt;Emacs&lt;/h4&gt;
      &lt;p&gt;&lt;code&gt;cleanup-buffer&lt;/code&gt;&lt;/p&gt;
      &lt;p&gt;Bound to &lt;code&gt;C-c n&lt;/code&gt;&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column editor'&gt;
      &lt;h4&gt;Sublime Text&lt;/h4&gt;
      &lt;p&gt;Only available with language-specific plugins&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column grid_12'&gt;
      &lt;h3 id="auto-complete"&gt;6. Completion&lt;/h3&gt;
    &lt;/div&gt;
    &lt;div class='column article'&gt;
      &lt;p&gt;Let&amp;#8217;s admit it: the simple text-based auto-completion in open source text editors doesn&amp;#8217;t come close to matching Microsoft Visual Studio from a decade ago.&lt;/p&gt;
      &lt;p&gt;I hope that a decade from now, I can use a text editor that understands not only the words I&amp;#8217;m typing, but their meaning within the application. Without bogging down the rest of the editor or toasting my battery, of course!&lt;/p&gt;
      &lt;p&gt;In the meantime, I like the way Emacs completes words from all open buffers. TextMate and Sublime Text are limited to only words in the current file, which rarely includes the keywords or methods I&amp;#8217;m looking for.&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column editor'&gt;
      &lt;h4&gt;Textmate&lt;/h4&gt;
      &lt;p&gt;For current file only&lt;/p&gt;
      &lt;p&gt;&lt;img src="commanding-your-text-editor/control-keys/esc.png" class="shortcut" alt="" /&gt;&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column editor'&gt;
      &lt;h4&gt;Vim&lt;/h4&gt;
      &lt;p&gt;Next completion&lt;/p&gt;
      &lt;p&gt;&lt;img src="commanding-your-text-editor/control-keys/control.png" class="shortcut" alt="" /&gt;
      &lt;img src="commanding-your-text-editor/control-keys/n.png" class="shortcut" alt="" /&gt;&lt;/p&gt;
      &lt;p&gt;Previous completion&lt;/p&gt;
      &lt;p&gt;&lt;img src="commanding-your-text-editor/control-keys/control.png" class="shortcut" alt="" /&gt;
      &lt;img src="commanding-your-text-editor/control-keys/p.png" class="shortcut" alt="" /&gt;&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column editor'&gt;
      &lt;h4&gt;Emacs&lt;/h4&gt;
      &lt;p&gt;Using &lt;code&gt;dabbrev-expand&lt;/code&gt;&lt;/p&gt;
      &lt;p&gt;&lt;img src="commanding-your-text-editor/control-keys/esc.png" class="shortcut" alt="" /&gt;
      &lt;img src="commanding-your-text-editor/control-keys/questionmark.png" class="shortcut" alt="" /&gt;&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column editor'&gt;
      &lt;h4&gt;Sublime Text&lt;/h4&gt;
      &lt;p&gt;Current file only&lt;/p&gt;
      &lt;p&gt;&lt;img src="commanding-your-text-editor/control-keys/control.png" class="shortcut" alt="" /&gt;
      &lt;code&gt;SPACE&lt;/code&gt;&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column article'&gt;
      &lt;h2&gt;Conclusion&lt;/h2&gt;
      &lt;p&gt;Learning these basic text manipulations has improved my editing speed. More importantly, I spend less time thinking about my text editor and more time thinking about the content of the text itself.&lt;/p&gt;
      &lt;p&gt;Try it! I bet you&amp;#8217;ll use each of these multiple times in the first day you learn to do them.&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column footer'&gt;
      &lt;p&gt;Learn your editors at PeepCode! Videos on &lt;a href="https://peepcode.com/products/smash-into-vim-i"&gt;Vim&lt;/a&gt;, &lt;a href="https://peepcode.com/products/smash-into-vim-ii"&gt;Advanced Vim&lt;/a&gt;, &lt;a href="https://peepcode.com/products/meet-emacs"&gt;Emacs&lt;/a&gt;, and &lt;a href="https://peepcode.com/products/textmate-for-rails-2"&gt;TextMate&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt;See also: &lt;a href="http://ionrails.com/2009/09/23/textmate-shortcuts-cheatsheet/"&gt;TextMate Shortcuts Cheatsheet&lt;/a&gt;&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</content>
    <published>Thu Oct 18 20:00:00 +0000 2012</published>
  </entry>
  <entry>
    <title>PeepCode's Birthday!</title>
    <link type="text/html" rel="alternate" href="http://blog.peepcode.com/blog/2012/birthday" />
    <id>tag:blog.peepcode.com,2012-09-22:/blog/2012/birthday</id>
    <content type="html">&lt;p&gt;&lt;strong&gt;This article is heavily styled and is best viewed at &lt;a href="http://blog.peepcode.com/blog/2012/birthday"&gt;PeepCode&lt;/a&gt;!&lt;/strong&gt;&lt;/p&gt;&lt;div id='essay'&gt;
  &lt;div class='row'&gt;
    &lt;div class='column author'&gt;
      &lt;p&gt;
        by
        &lt;span&gt;
          Geoffrey Grosenbach
        &lt;/span&gt;
      &lt;/p&gt;
    &lt;/div&gt;
    &lt;div class='column article'&gt;
      &lt;p&gt;PeepCode is now 6 years old!&lt;/p&gt;
      &lt;p&gt;The last month has been a good sample of the excitement that has been happening for us this past year. In September we:&lt;/p&gt;
      &lt;ul&gt;
      	&lt;li&gt;Published a live Play by Play &lt;a href="https://peepcode.com/products/play-by-play-mrgan"&gt;design video&lt;/a&gt; and finished a draft of a new tutorial.&lt;/li&gt;
      	&lt;li&gt;Moved into a small office suite in an artistic building a block from Seattle&amp;#8217;s Pike Place Market. It&amp;#8217;s an inspiring place shared by fashion designers, web developers, and &lt;span class="caps"&gt;CAD&lt;/span&gt; drafters.&lt;/li&gt;
      	&lt;li&gt;Hired a full time &lt;em&gt;Developer Educator&lt;/em&gt; to help us produce more tutorials and launch new kinds of videos. &lt;a href="http://twitter.com/mekajfire"&gt;Jake Mitchell&lt;/a&gt; starts at PeepCode next month!&lt;/li&gt;
      	&lt;li&gt;Gave a presentation at the new &lt;a href="http://www.meetup.com/SASSlang/events/76611802/"&gt;Seattle Sass Meetup&lt;/a&gt;.&lt;/li&gt;
      	&lt;li&gt;Started a redesign of our website.&lt;/li&gt;
      &lt;/ul&gt;
      &lt;p&gt;&lt;img src="/blog/2012/birthday/img/makers-office.jpg" alt="" /&gt;&lt;/p&gt;
      &lt;h2&gt;Vision&lt;/h2&gt;
      &lt;p&gt;My title is &lt;em&gt;Senior Visionary&lt;/em&gt;, which I take as a daily challenge.&lt;/p&gt;
      &lt;p&gt;It&amp;#8217;s fulfilling to look back and see some of the people we&amp;#8217;ve worked with over the last six years who have gone on to do even greater things.&lt;/p&gt;
      &lt;ul&gt;
      	&lt;li&gt;In 2008 we published Scott Chacon&amp;#8217;s book on &lt;a href="https://peepcode.com/products/git-internals-pdf"&gt;Git Internals&lt;/a&gt;. He later went on to become a co-founder of GitHub.&lt;/li&gt;
      	&lt;li&gt;In 2010 we launched the &lt;a href="https://peepcode.com/products/play-by-play-bernhardt"&gt;Play by Play series&lt;/a&gt; starting with Gary Bernhardt. I had watched him write code and knew that his unique skills were something that had to be experienced in real time. It was an immediate success and he went on to start his own business, &lt;a href="http://destroyallsoftware.com/"&gt;Destroy All Software&lt;/a&gt;.&lt;/li&gt;
      	&lt;li&gt;Earlier this year, Ben Schwarz published &lt;a href="https://peepcode.com/products/html5-browser-caching"&gt;HTML5 Browser Caching&lt;/a&gt; with us and is now a member of the &lt;span class="caps"&gt;CSS&lt;/span&gt; Working Group on the W3C.&lt;/li&gt;
      &lt;/ul&gt;
      &lt;h2&gt;People&lt;/h2&gt;
      &lt;p&gt;Two years ago, I was confident that I could run this business best if I operated on my own. Fortunately I discovered there&amp;#8217;s a better way!&lt;/p&gt;
      &lt;p&gt;Right now, 8 employees and contractors work on PeepCode every week and I can&amp;#8217;t imagine working without any one of them. We have skilled people who work on marketing, sales, development, finance, design, customer service, and production.&lt;/p&gt;
      &lt;p&gt;Adding their fresh ideas and hard work to my own has made a huge difference in the profitability of the business and the kinds of projects we can accomplish. Now that we&amp;#8217;re adding our first full-time developer, we&amp;#8217;ll be digging into our notebooks of ideas and launching some new ideas we&amp;#8217;ve been waiting to work on!&lt;/p&gt;
      &lt;h2&gt;Place&lt;/h2&gt;
      &lt;p&gt;I like variety. In addition to traveling to and &lt;a href="https://vimeo.com/43590848"&gt;speaking at conferences&lt;/a&gt;, I enjoyed working without a fixed office for several years. It seemed like the way to go when running an online business with remote contractors.&lt;/p&gt;
      &lt;p&gt;But now that we have a consistent space to work from, I realize its value. Planning is much easier (every day starts at the office). And even though much of our work happens on screen, it still helps to have a fixed place to record drafts of new tutorials before they go out for transcription.&lt;/p&gt;
      &lt;p&gt;If you&amp;#8217;re freelancing, working remotely, or starting a business, I highly recommend finding an office space to work from, even if only occasionally.&lt;/p&gt;
      &lt;h2&gt;Our Supporters!&lt;/h2&gt;
      &lt;p&gt;Thank you for subscribing to PeepCode and supporting our original productions over these years. We&amp;#8217;re proud of the people we&amp;#8217;ve promoted, the ideas we&amp;#8217;ve brought to light, and the explanations we&amp;#8217;ve delivered. Your support has made it happen!&lt;/p&gt;
      &lt;p&gt;&lt;img src="/blog/2012/birthday/img/six-cake.jpg" class="cake" alt="" /&gt;&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
</content>
    <published>Sat Sep 22 01:00:00 +0000 2012</published>
  </entry>
</feed>
