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

<channel>
	<title>Dodgeball Cannon</title>
	<atom:link href="http://www.johntantalo.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.johntantalo.com/blog</link>
	<description>It's not so much a time machine as it is my blog.</description>
	<lastBuildDate>Fri, 20 Apr 2012 19:50:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Go-flavored JavaScript</title>
		<link>http://www.johntantalo.com/blog/go-flavored-javascript/</link>
		<comments>http://www.johntantalo.com/blog/go-flavored-javascript/#comments</comments>
		<pubDate>Mon, 10 Oct 2011 08:20:09 +0000</pubDate>
		<dc:creator>John Tantalo</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.johntantalo.com/blog/?p=203</guid>
		<description><![CDATA[This week I learned a little bit of Go. I was fascinated by the power and simplicity of goroutines and channels. With these ideas fresh in my mind, I decided to reproduce Mark C. Chu-Carroll&#8217;s Go prime sieve in JavaScript with goroutines and channels as my toolset instead of conventional JavaScript idioms. Find my translation [...]]]></description>
			<content:encoded><![CDATA[<p>This week I learned a little bit of <a href="http://en.wikipedia.org/wiki/Go_(programming_language)">Go</a>. I was fascinated by the power and simplicity of goroutines and channels.</p>
<p>With these ideas fresh in my mind, I decided to reproduce Mark C. Chu-Carroll&#8217;s <a href="http://scienceblogs.com/goodmath/2009/11/the_go_i_forgot_concurrency_an.php">Go prime sieve</a> in JavaScript with goroutines and channels as my toolset instead of conventional JavaScript idioms. <strong><a href="https://github.com/tantalor/gojs">Find my translation on GitHub.</a></strong></p>
<p>I chose JavaScript because it shares many traits with Go, such as multiple threads of control, but doesn&#8217;t have a notion of channels.</p>
<h2>Background: goroutines and channels</h2>
<p>A <em>goroutine</em> is an independent concurrent thread of control.</p>
<p>A <em>channel</em> is a mechanism for two concurrently executing functions to communicate by passing a value. A channel has two methods, <em>read</em> and <em>write</em>, which are synchronous by default. That is, a <em>write</em> blocks until there is a <em>read</em> to consume it, and a <em>read</em> blocks until there is a <em>write</em> to consume.</p>
<h2>JavaScript implementation</h2>
<p>Goroutines are rather trivial to implement, a simple <em>setTimeout</em> will schedule an independent thread of control.</p>
<blockquote><pre><code>function go (fn) {
  setTimeout(fn, 0);
};</code></pre>
</blockquote>
<p>Synchronous channels will require a queue of <em>reader</em> and <em>writer</em> callbacks. I decided to call the reader callbacks before the writers, but I don&#8217;t think it matters.</p>
<blockquote><pre><code>var chan = function () {
  this.readers = []; // [cb, ...]
  this.writers = []; // [[value, cb], ...]
};

chan.prototype.read = function (cb) {
  if (this.writers.length) {
    // consume a writer
    var writer = this.writers.shift();
    cb(writer[0]);
    writer[1](writer[0]);
  } else {
    // queue the reader
    this.readers.push(cb);
  }
};

chan.prototype.write = function (value, cb) {
  if (this.readers.length) {
    // consumer a reader
    var reader = this.readers.shift();
    reader(value);
    cb(value);
  } else {
    // queue the writer
    this.writers.push([value, cb]);
  }
};</code></pre>
</blockquote>
<p>I also pass the writer&#8217;s value to its callback because it could be useful.</p>
<h2>The prime sieve</h2>
<p>Mark&#8217;s Go sieve begins with an integer generator.</p>
<blockquote><pre><code>func generate_integers() chan int {
    ch := make(chan int);
    go func(){
        for i := 2; ; i++ {
            ch <- i;
        }
     }();
    return ch;
}</code></pre>
</blockquote>
<p>The problem here is that the channel write (<code>ch <- i</code>) blocks inside of a loop. In JavaScript, we "block" by passing a callback that is called once the procedure can continue. Here, the <em>producer</em> function passes itself as the callback to <em>write</em>.</p>
<blockquote><pre><code>function integers () {
  var ch = new chan();
  go(function () {
    var producer = function (i) {
      ch.write(i + 1, producer);
    };
    ch.write(2, producer);
  });
  return ch;
};</code></pre>
</blockquote>
<p>This Go function excludes multiples of a given prime from the given channel.</p>
<blockquote><pre><code>func filter_multiples(in chan int, prime int) chan int {
   out := make(chan int);
   go func() {
      for {
         if i := <- in; i % prime != 0 {
             out <- i;
         }
      }
    }();
   return out;
}
</code></pre>
</blockquote>
<p>We can rewrite this with another recursive callback, but this time we only have to block when we do a write.</p>
<blockquote><pre><code>function filter_multiples (ch, prime) {
  var out = new chan();
  go(function () {
      var consumer = function (i) {
        if (i % prime != 0) {
          out.write(i, function () {
            ch.read(consumer);
          });
        } else {
          ch.read(consumer);
        }
      }
      ch.read(consumer);
  });
  return out;
};
</code></pre>
</blockquote>
<p>The sieve in Go will chain a series of channels to exclude multiples of all the primes we have seen.</p>
<blockquote><pre><code>func sieve() chan int {
   out := make(chan int);
   go func() {
      ch := generate_integers();
      for {
	     prime := <- ch;
	     out <- prime;
	     ch = filter_multiples(ch, prime);
      }
   }();
   return out;
}</code></pre>
</blockquote>
<p>We achieve the same in JavaScript with another recursive callback.</p>
<blockquote><pre><code>function sieve () {
   var out = new chan();
   go(function () {
      var ch = integers();
      function iteration () {
        ch.read(function (prime) {
          out.write(prime, function () {
            ch = filter_multiples(ch, prime);
            iteration();
          });
        });
      };
      iteration();
   });
   return out;
};</code></pre>
</blockquote>
<p>Mark's program simply reads from the sieve channel and prints out each prime number.</p>
<blockquote><pre><code>func main() {
  primes := sieve();
  for {
    fmt.Println(<-primes);
  }
}</code></pre>
</blockquote>
<p>Mine uses another recursive callback to do the same.</p>
<blockquote><pre><code>function main () {
  var primes = sieve();
  function iteration() {
    primes.read(function (i) {
      sys.puts(i);
      iteration();
    });
  };
  iteration();
}

main();</code></pre>
</blockquote>
<h2>Demo</h2>
<p><a href="http://github.johntantalo.com/gojs/">Go-flavored JavaScript: Prime Sieve</a></p>
<h2>Discussion</h2>
<p>Note that the call to <em>main()</em> returns (practically) immediately, since the goroutine in <em>sieve()</em>, which hasn't executed, has not yet written anything to the channel, so the <em>read</em> inside <em>iteration</em> just pushes the callback onto a read queue and returns. Once the main thread of control stops, the event loop begins running the goroutines, which drive the rest of the program. (Please correct me if I'm wrong.)</p>
<p>That functions return quickly is generally desirable, in JavaScript or Go, because a caller should not have to wait for a function to do some "hard work" before it returns. Instead, the hard work should occur in a separate thread of control and passed back to the caller by some layer of indirection.</p>
<p>JavaScript programmers typically solve this problem with callbacks which receive result of the hard work. The Go language offers synchronous channels between independent threads of control as a more sophisticated solution. These tools are easily ported to idiomatic JavaScript based on callbacks. Although unconventional, these tools are simple and may be very powerful when composed.</p>
<p>I hope this toy example borrowed from Go inspires JavaScript programmers to consider the unconventional.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johntantalo.com/blog/go-flavored-javascript/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>URI-Escaping JavaScript Bookmarklets in Chrome</title>
		<link>http://www.johntantalo.com/blog/uri-escaping-javascript-bookmarklets-in-chrome/</link>
		<comments>http://www.johntantalo.com/blog/uri-escaping-javascript-bookmarklets-in-chrome/#comments</comments>
		<pubDate>Mon, 03 Oct 2011 21:00:24 +0000</pubDate>
		<dc:creator>John Tantalo</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Chrome]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.johntantalo.com/blog/?p=173</guid>
		<description><![CDATA[John Gruber published a helpful JavaScript Bookmarklet Builder which I used to generate my IPA TTS bookmarklet. A few users reported that Chrome choked on the bookmarklet. I found that the bookmarklet builder does not produce the output that Chrome expects. I was using Chrome 15.0.874.54 beta. For example, take this simple script. (function () [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://daringfireball.net/">John Gruber</a> published a helpful <a href="http://daringfireball.net/2007/03/javascript_bookmarklet_builder">JavaScript Bookmarklet Builder</a> which I used to generate my <a href="http://www.johntantalo.com/blog/ipa-tts-bookmarklet">IPA TTS bookmarklet</a>.</p>
<p>A few users reported that <a href="http://www.google.com/chrome">Chrome</a> choked on the bookmarklet. I found that the bookmarklet builder does not produce the output that Chrome expects. I was using Chrome 15.0.874.54 beta.</p>
<p>For example, take this simple script.</p>
<blockquote><pre><code>(function () {
  // what is 1+1?
  alert(["1+1=",(1+1)].join(''));
})()
</code></pre>
</blockquote>
<p>Gruber&#8217;s script produces this bookmarklet: <a href="javascript:(function%20()%20{alert([%221+1=%22,(1+1)].join(%27%27));})()">Example 1</a></p>
<blockquote><p><code>javascript:(function%20()%20{alert([%221+1=%22,(1+1)].join(%27%27));})()</code></p></blockquote>
<p>If you drag this example to your bookmark bar in Chrome, it will produce this error when invoked.<br />
<blockquote><p><code>Uncaught SyntaxError: Unexpected token %</code></p></blockquote>
<p>What happened? If you edit the bookmark, you will see that Chrome double-escaped the string,</p>
<blockquote><p><code>javascript:(function%2520()%2520%7Balert(%5B%25221+1=%2522,(1+1)%5D.join(%2527%2527));%7D)()</code></p></blockquote>
<p>I believe this happened because the string contained some non-escaped characters such as parentheses.</p>
<p>Gruber points out in a footnote that his script intentionally leaves some characters unescaped for the purpose of readability.</p>
<blockquote>
<p>It’s unclear to me what characters must be escaped in a bookmarklet URL. Some sources suggest that other punctuation characters, such as brackets and semicolons, ought to be escaped, too, but I can see no practical reason to do so. If you want to be really conservative and escape just about everything, change this line:</p>
<p><code>uri_escape_utf8($bookmarklet, qq('" \x00-\x1f\x7f-\xff));</code></p>
<p>to:</p>
<p><code>uri_escape_utf8($bookmarklet);</code></p>
<p>Personally, I prefer to keep the bookmarklet URL itself as readable as possible.
</p></blockquote>
<p>With this change, we get this bookmarklet: <a href="javascript:%28function%20%28%29%20%7Balert%28%5B%221%2B1%3D%22%2C%281%2B1%29%5D.join%28%27%27%29%29%3B%7D%29%28%29">Example 2</a></p>
<blockquote style="overflow-x: scroll;"><p><code>javascript:%28function%20%28%29%20%7Balert%28%5B%221%2B1%3D%22%2C%281%2B1%29%5D.join%28%27%27%29%29%3B%7D%29%28%29</code></p></blockquote>
<p>It may not be as readable as &#8220;Example 1&#8243;, but it works.</p>
<p><strong><a href="https://gist.github.com/1259477/3920d0ad6b8393094acaf9b909c70bdd80a9cfe2">Find my modifications to Gruber&#8217;s JavaScript Bookmarklet Builder on GitHub</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.johntantalo.com/blog/uri-escaping-javascript-bookmarklets-in-chrome/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Paginating with Bookmarks in App Engine</title>
		<link>http://www.johntantalo.com/blog/paginating-with-bookmarks-in-app-engine/</link>
		<comments>http://www.johntantalo.com/blog/paginating-with-bookmarks-in-app-engine/#comments</comments>
		<pubDate>Wed, 28 Sep 2011 22:57:57 +0000</pubDate>
		<dc:creator>John Tantalo</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Ideas]]></category>
		<category><![CDATA[Google App Engine]]></category>

		<guid isPermaLink="false">http://www.johntantalo.com/blog/?p=159</guid>
		<description><![CDATA[Let&#8217;s say we have a Google App Engine model with two fields, &#8220;x&#8221; and &#8220;y&#8221;, and all objects are distinct. We&#8217;d like to paginate with the sort order criteria &#8220;x ascending, y ascending&#8221;. For example, that index might look like this. While paginating, we need to know whether there is a &#8220;next page&#8221;, because we [...]]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s say we have a Google App Engine model with two fields, &#8220;x&#8221; and &#8220;y&#8221;, and all objects are distinct.</p>
<p>We&#8217;d like to paginate with the sort order criteria &#8220;x ascending, y ascending&#8221;. For example, that index might look like this.</p>
<p><a href="http://www.johntantalo.com/blog/wp-content/uploads/2011/09/example-data.png"><img src="http://www.johntantalo.com/blog/wp-content/uploads/2011/09/example-data.png" alt="" title="example-data" width="387" height="363" class="aligncenter size-full wp-image-160" /></a></p>
<p>While paginating, we need to know whether there is a &#8220;next page&#8221;, because we don&#8217;t want to return an empty page unless we have no objects.</p>
<p>To do this, we&#8217;ll look-ahead for the next item in our search. So, if the page size is 2, we&#8217;ll just fetch 3 items. That extra object will give us the necessary (x, y) coordinates we need to resume the search, that is, to fetch the next page. This object is called the &#8220;bookmark&#8221;.</p>
<p>Given the (x, y) bookmark, how do we fetch the next page? In index terms, we might construct a prefix string &#8220;/$x/$y/&#8221;, and return the next rows after that in our index. Unfortunately App Engine doesn&#8217;t give us a low-level interface like that, so we have to use filters.</p>
<p>What kind of filters? We want all objects greater than or equal to our given &#8220;x&#8221;. But, for objects with the same value as &#8220;x&#8221;, we have to skip those less than our given &#8220;y&#8221;, because we have already seen them. Clearly we will need filters on both &#8220;x&#8221; and &#8220;y&#8221;, but woe, App Engine insists that no more than one distinct field can have a filter expression per query.[1]</p>
<p><a href="https://plus.google.com/103651231634018158746">Ryan Barrett</a> observed that <a href="https://groups.google.com/d/topic/google-appengine/7lr73iDhPN4/discussion">for a search with n sorted fields, you will need n queries to resume the search from a bookmark</a>. In other words, you need one query for each field.</p>
<p>What does this look like? In our example, we have two sorted fields. To resume the search, the first query will fix &#8220;x&#8221; and filter on &#8220;y&#8221;, with &#8220;y ascending&#8221;. The second query will filter on &#8220;x&#8221; with &#8220;x ascending, y ascending&#8221;.</p>
<p>What would that look like on our example index?</p>
<p><a href="http://www.johntantalo.com/blog/wp-content/uploads/2011/09/queries.gif"><img src="http://www.johntantalo.com/blog/wp-content/uploads/2011/09/queries.gif" alt="" title="queries" width="388" height="364" class="aligncenter size-full wp-image-164" /></a></p>
<p>Each shaded region is one query, that is, one trip to the datastore. The green objects are the current page. The orange object is the next bookmark. The blue objects are the old pages.</p>
<p>The first query is on a fixed &#8220;x&#8221; and filters &#8220;y&#8221;. The second query resumes where the first left off, and filters on &#8220;x&#8221;. Since the sort orders are consistent with the filters, we obtain a consistent view of the index.</p>
<p>On the fourth search, we happen to get lucky and find our bookmark on the first query, so we can skip the second query.</p>
<h2>In general</h2>
<p>If you&#8217;re sorting on n fields {f<sub>0</sub>, f<sub>2</sub>, &#8230; f<sub>n-1</sub>} you will need n queries {q<sub>0</sub>, q<sub>1</sub>, &#8230; q<sub>n-1</sub>}.</p>
<p>Query q<sub>i</sub> will filter f<sub>n-i</sub> and fix fields {f<sub>0</sub>, &#8230; f<sub>n-i-1</sub>}.</p>
<p>For n=2, query q<sub>0</sub> filters f<sub>1</sub> and fixes f<sub>0</sub>. Query q<sub>1</sub> filters f<sub>0</sub>.</p>
<h2>Why don&#8217;t you use cursors you slob?</h2>
<p>Cursors are great! Except, they don&#8217;t immediately answer the question, &#8220;Do we have a next page?&#8221; If you don&#8217;t care then by all means use cursors, they&#8217;re much easier to use than bookmarks.</p>
<p>Cursors in App Engine can&#8217;t look-ahead. Instead, you have to fetch one object with the query&#8217;s next cursor, rather than fetching an extra object in the original query.</p>
<p>On the other hand, cursors are allowed to perform queries which users cannot. Cursors can perform the &#8220;prefix string&#8221; trick described above. So, a cursor can do in one query what takes us two or more.</p>
<p>So which should you use? That probably depends on how many fields you are sorting on. For a single field, I prefer the look-ahead technique, because it only requires one trip to the datastore. For two fields, either technique requires (at most) two trips, although cursors are usually simpler. For more than two fields, cursors easily win.</p>
<p>[1] This requirement exists to prevent users from requesting filters which the datastore cannot satisfy by scanning consecutive rows in an index. For example, the filters &#8220;x > 2 and y > 3&#8243; can specify non-consecutive rows of an index that sorts &#8220;x&#8221; and &#8220;y&#8221; ascendingly.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johntantalo.com/blog/paginating-with-bookmarks-in-app-engine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Javascript Shebangs</title>
		<link>http://www.johntantalo.com/blog/javascript-shebangs/</link>
		<comments>http://www.johntantalo.com/blog/javascript-shebangs/#comments</comments>
		<pubDate>Mon, 20 Dec 2010 20:37:04 +0000</pubDate>
		<dc:creator>John Tantalo</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.johntantalo.com/blog/?p=141</guid>
		<description><![CDATA[Ringo, Narwhal, Node, and JavaScriptCore support executing scripts with a shebang. Here are some quick examples to get you started. Ringo #!/usr/bin/env ringo print("ringo"); Narwhal #!/usr/bin/env narwhal print("narwhal"); Node #!/usr/bin/env node require("sys").print("node\n"); JavaScriptCore #!/usr/bin/env jsc print("jsc"); JavaScriptCore nightly added support for shebangs on 6 December 2010. Since Node and JavaScriptCore are binaries, you can use [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://ringojs.org/">Ringo</a>, <a href="http://narwhaljs.org/">Narwhal</a>, <a href="http://nodejs.org/">Node</a>, and <a href="http://webkit.org/projects/javascript/">JavaScriptCore</a> support executing scripts with a <a href="http://en.wikipedia.org/wiki/Shebang_(Unix)">shebang</a>.</p>
<p>Here are some quick examples to get you started.</p>
<h2>Ringo</h2>
<p><code>
<pre>    #!/usr/bin/env ringo
    print("ringo");
</pre>
<p></code></p>
<h2>Narwhal</h2>
<p><code>
<pre>    #!/usr/bin/env narwhal
    print("narwhal");
</pre>
<p></code></p>
<h2>Node</h2>
<p><code>
<pre>    #!/usr/bin/env node
    require("sys").print("node\n");
</pre>
<p></code></p>
<h2>JavaScriptCore</h2>
<p><code>
<pre>    #!/usr/bin/env jsc
    print("jsc");
</pre>
<p></code></p>
<p>JavaScriptCore nightly added support for shebangs on <a href="https://bugs.webkit.org/show_bug.cgi?id=49576">6 December 2010</a>.</p>
<p>Since Node and JavaScriptCore are binaries, you can use the full path instead of <code>env</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johntantalo.com/blog/javascript-shebangs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Deploying JavaScript Modules</title>
		<link>http://www.johntantalo.com/blog/deploying-javascript-modules/</link>
		<comments>http://www.johntantalo.com/blog/deploying-javascript-modules/#comments</comments>
		<pubDate>Wed, 01 Dec 2010 17:08:25 +0000</pubDate>
		<dc:creator>John Tantalo</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://www.johntantalo.com/blog/?p=114</guid>
		<description><![CDATA[JavaScript is used in many different environments, and each environment has its own method for deploying modules. Some allow importing objects into a local namespace, but notably web browsers do not. So, what is the best way to write a module that can be safely deployed across different environments? Anonymous closure module pattern My example [...]]]></description>
			<content:encoded><![CDATA[<p>JavaScript is used in many different environments, and each environment has its own method for deploying modules. Some allow importing objects into a local namespace, but notably web browsers do not. So, what is the best way to write a module that can be safely deployed across different environments?</p>
<h3>Anonymous closure module pattern</h3>
<p>My example module will be implemented as an anonymous closure. It will have one public class and a private member.</p>
<p><code>
<pre>    (function () {
      var PublicClass = function () {};
      var PrivateMember = new Object();
    })();
</pre>
<p></code></p>
<p>I will incrementally add support for each environment by detecting whether that environment is present.</p>
<h3>Web browsers</h3>
<p>Web browsers do not support importing into a local namespace, so I simply add <i>PublicClass</i> to the global <i>window</i> namespace.</p>
<p><code>
<pre>    (function () {
      var PublicClass = function () {};
      var PrivateMember = new Object();

      if (typeof(window) !== 'undefined') {
        // browser
        window.PublicClass = PublicClass;
      }
    })();
</pre>
<p></code></p>
<p>Client must first include the module with a <i>script</i> HTML tag.</p>
<p><code>
<pre>    &lt;script type=&quot;text/javascript&quot; src=&quot;sample-module.js&quot;&gt;&lt;/script&gt;
    &lt;script type=&quot;text/javascript&quot;&gt;
      var instance = new PublicClass();
    &lt;/script&gt;
</pre>
<p></code></p>
<h3>CommonJS</h3>
<p><a href="http://www.commonjs.org/">CommonJS</a> is a pattern implemented by some server-side JavaScript engines such as <a href="http://nodejs.org/">Node</a> and <a href="http://narwhaljs.org/">Narwhal</a>. In this model, a module assigns its public interface to a special <i>exports</i> object.</p>
<p><code>
<pre>    (function () {
      var PublicClass = function () {};
      var PrivateMember = new Object();

      if (typeof(window) !== 'undefined') {
        // browser
        window.PublicClass = PublicClass;
      } else if (typeof(exports) !== 'undefined') {
        // commonjs
        exports.PublicClass = PublicClass;
      }
    })();
</pre>
<p></code></p>
<p>Clients <i>require</i> the module, which returns the module&#8217;s exports.</p>
<p><code>
<pre>    var PublicClass = require('./sample-module').PublicClass;
    var instance = new PublicClass();
</pre>
<p></code></p>
<h3>JavaScriptCore</h3>
<p><a href="http://webkit.org/projects/javascript/">JavaScriptCore</a> (or &#8220;jsc&#8221;) does not follow the CommonJS pattern. Instead, when a file is included with the <i>load</i> function, the last value in the file is returned to the caller.</p>
<p>I return an object literal from the anonymous function which simulates the <i>exports</i> object in CommonJS. Since the anonymous function is executed as the last statement in the file, the exports are returned to the client. This case doesn&#8217;t rely on any special variable such as <i>window</i> or <i>exports</i>, so I will make it default rather than detecting the JavaScriptCore environment.</p>
<p><code>
<pre>    (function () {
      var PublicClass = function () {};
      var PrivateMember = new Object();

      if (typeof(window) !== 'undefined') {
        // browser
        window.PublicClass = PublicClass;
      } else if (typeof(exports) !== 'undefined') {
        // commonjs
        exports.PublicClass = PublicClass;
      } else {
        // jsc (default)
        return {
          "PublicClass": PublicClass
        };
      }
    })();
</pre>
<p></code></p>
<p>Clients <i>load</i> the module, which returns the module&#8217;s exports.</p>
<p><code>
<pre>    var PublicClass = load('sample-module.js').PublicClass;
    var instance = new PublicClass();
</pre>
<p></code></p>
<h3>Why not use a global variable?</h3>
<p>There is another <a href="http://ajaxian.com/archives/a-javascript-module-pattern">JavaScript module pattern</a> that declares a global variable to contain the module&#8217;s public interface, as in this example.</p>
<p><code>
<pre>    var PublicClass = (function () {
      var PublicClass = function () {};
      var PrivateMember = new Object();
      return PublicClass;
    })();
</pre>
<p></code></p>
<p>This pattern will work perfectly in web browsers and JavaScriptCore, but it also pollutes JavaScriptCore&#8217;s global namespace. Since JavaScriptCore supports local imports, global variables should be avoided. Furthermore, this pattern does not support multiple public interfaces, e.g., a single anonymous closure that exports two public classes.</p>
<h3>Example: GraphJS</h3>
<p><a href="https://github.com/tantalor/graphjs/blob/master/lib/graph.js">GraphJS</a> is a JavaScript module of mine that uses the module deployment pattern I described. It works with Node, Narwhal, Ringo, JSC, and in web browsers.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johntantalo.com/blog/deploying-javascript-modules/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My screen workflow</title>
		<link>http://www.johntantalo.com/blog/my-screen-workflow/</link>
		<comments>http://www.johntantalo.com/blog/my-screen-workflow/#comments</comments>
		<pubDate>Thu, 05 Aug 2010 17:34:13 +0000</pubDate>
		<dc:creator>John Tantalo</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[screen]]></category>
		<category><![CDATA[ssh]]></category>

		<guid isPermaLink="false">http://www.johntantalo.com/blog/?p=105</guid>
		<description><![CDATA[I use GNU Screen to keep a few terminal windows open over a shared set of screen windows logged into a large number of other machines. Wrapper screen I log in to the machine that will host my screens and start the wrapper screen. screen -S wrapper -c .screenrc_wrapper The wrapper screen&#8217;s configuration just specifies [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.johntantalo.com/blog/wp-content/uploads/2010/08/screen.png"><img src="http://www.johntantalo.com/blog/wp-content/uploads/2010/08/screen.png" alt="" title="screen" width="125" height="456" class="alignright size-full wp-image-136" /></a>I use <a href="http://www.gnu.org/software/screen/">GNU Screen</a> to keep a few terminal windows open over a shared set of screen windows logged into a large number of other machines.</p>
<h2>Wrapper screen</h2>
<p>I log in to the machine that will host my screens and start the <code>wrapper</code> screen.</p>
<p><code>
<pre>  screen -S wrapper -c .screenrc_wrapper
</pre>
<p></code></p>
<p>The <code>wrapper</code> screen&#8217;s configuration just specifies the interrupt key.</p>
<p><code>
<pre>  escape ^Ww
</pre>
<p></code></p>
<p>I create a screen window in <code>wrapper</code> for each terminal window I want to use, as many as four. Each terminal window will run one of the <code>wrapper</code> windows.</p>
<h2>SSH agent</h2>
<p>I use <a href="http://unixwiz.net/techtips/ssh-agent-forwarding.html">SSH agent forwarding</a> to log in to my screen host, but if you don&#8217;t then you might need to run <code>ssh-agent</code> inside the <code>wrapper</code> screen before starting the <code>ssh</code> screen.</p>
<p><code>
<pre>  exec ssh-agent bash
  ssh-add
</pre>
<p></code></p>
<p>This is necessary for the next step where I <code>ssh</code> into a bunch of other machines. I have already <a href="http://pkeck.myweb.uga.edu/ssh/">installed my public key</a> on the destination machines.</p>
<h2>SSH screen</h2>
<p>I start the <code>ssh</code> screen from inside the <code>wrapper</code> screen.</p>
<p><code>
<pre>  screen -S ssh -c .screenrc_ssh
</pre>
<p></code></p>
<p>The <code>ssh</code> screen&#8217;s configuration creates a bunch of windows that <code>ssh</code> into other machines I want to work on. I like to have at least two windows for each machine.</p>
<p><code>
<pre>  escape `` 

  screen -t "host 1" ssh host1
  screen -t "host 1" ssh host1

  screen -t "host 2" ssh host2
  screen -t "host 2" ssh host2

  screen -t "host 3" ssh host3
  screen -t "host 3" ssh host3

  select 0
</pre>
<p></code></p>
<p>Inside the other <code>wrapper</code> windows, I attach to the running <code>ssh</code> screen.</p>
<p><code>
<pre>  screen -x ssh
</pre>
<p></code></p>
<p>At the start of the day, I open up a few terminal windows, log in into the screen server, and attach to the running <code>wrapper</code> screen. This is simplified with an alias.</p>
<p><code>
<pre>  alias wrapper='screen -x wrapper'
</pre>
<p></code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.johntantalo.com/blog/my-screen-workflow/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Short and sweet OAuth</title>
		<link>http://www.johntantalo.com/blog/short-and-sweet-oauth/</link>
		<comments>http://www.johntantalo.com/blog/short-and-sweet-oauth/#comments</comments>
		<pubDate>Sat, 23 Jan 2010 05:28:37 +0000</pubDate>
		<dc:creator>John Tantalo</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[oauth]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.johntantalo.com/blog/?p=94</guid>
		<description><![CDATA[I recently grew quite frustrated when I had to update Emend&#8217;s Twitter bot to use OAuth. There are, of course, readily available implementations of OAuth in python, even some specifically engineered for App Engine with lovely persistence and caching and KILL ME NOW. I gave up after a couple hours of staring at this nonsense. [...]]]></description>
			<content:encoded><![CDATA[<p>I recently grew quite frustrated when I had to update <a href="http://emendapp.com">Emend&#8217;s</a> Twitter bot to use <a href="http://oauth.net/">OAuth</a>.</p>
<p>There are, of course, <a href="http://oauth.googlecode.com/svn/code/python/oauth/oauth.py">readily available implementations of OAuth</a> in python, even some <a href="http://github.com/mikeknapp/AppEngine-OAuth-Library/raw/master/oauth.py">specifically engineered for App Engine</a> with lovely persistence and caching and KILL ME NOW.</p>
<p>I gave up after a couple hours of staring at this nonsense. I grew so displeased because my app doesn&#8217;t need 95% of what these libraries offer. I only need to <a href="http://oauth.net/core/1.0/#signing_process">sign requests</a> with a fixed <em>oauth_consumer_key</em>, <em>oauth_consumer_secret</em>, <em>oauth_token</em>, and <em>oauth_token_secret</em>. However, this simple task would require me to subclass or instantiate several object with Culver&#8217;s library, and I can&#8217;t even begin to fathom what I&#8217;d need to do with Knapp&#8217;s offering.</p>
<p>(Aside: if you want to authorize and build access tokens for your app, I highly recommend <a href="http://term.ie/oauth/example/client.php">this excellent OAuth test client</a>)</p>
<p>I finally teased apart the core function of signing requests, thanks in large part to the <a href="http://oauth.net/core/1.0/#anchor30">great reference example</a>. If all you need is to access a protected resource, this will get the job done with a single function call, no object-orientation required.</p>
<p><script src="http://gist.github.com/284452.js?file=oauth.py"></script></p>
<p><a href="http://gist.github.com/284452">Source code and unit test of short and sweet OAuth.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.johntantalo.com/blog/short-and-sweet-oauth/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Strip tags with html5lib</title>
		<link>http://www.johntantalo.com/blog/strip-tags-with-html5lib/</link>
		<comments>http://www.johntantalo.com/blog/strip-tags-with-html5lib/#comments</comments>
		<pubDate>Tue, 15 Dec 2009 04:14:37 +0000</pubDate>
		<dc:creator>John Tantalo</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[html5lib]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.johntantalo.com/blog/?p=82</guid>
		<description><![CDATA[There are a couple posts out there that discuss stripping tags with html5lib, but they seem intent on preserving the &#8220;acceptable elements&#8221; such as &#60;span&#62; and &#60;code&#62;. This is fine unless you really want to friggin&#8217; strip out the tags, like I needed for Emend. The following is my solution. Source code for stripping tags [...]]]></description>
			<content:encoded><![CDATA[<p>There are a couple posts <a href="http://code.google.com/p/html5lib/issues/detail?id=62">out</a> <a href="http://deathofagremmie.com/2009/04/12/using-html5lib-to-sanitize-user-input/">there</a> that discuss stripping tags with <a href="http://code.google.com/p/html5lib/"><em>html5lib</em></a>, but they seem intent on preserving the &#8220;acceptable elements&#8221; such as <code>&lt;span&gt;</code> and <code>&lt;code&gt;</code>.</p>
<p>This is fine unless you really want to <em>friggin&#8217; strip out the tags</em>, like I needed for <a href="http://emendapp.com">Emend</a>. The following is my solution.</p>
<p><script src="http://gist.github.com/256684.js?file=strip_tags.py"></script></p>
<p><a href="http://gist.github.com/256684">Source code for stripping tags with html5lib and unit test.</a></p>
<p>For example,</p>
<pre><code>&gt;&gt;&gt; from strip_tags import strip_tags
&gt;&gt;&gt; strip_tags('&lt;p&gt;foo&lt;/p&gt; &lt;script&gt;bar&lt;/script&gt;')
u'foo bar'</code></pre>
<p>Thanks go to <a href="http://edward.oconnor.cx/">Edward O’Connor</a> for pointing me towards <em>html5lib</em> in the first place. It&#8217;s a huge improvement over <a href="http://docs.python.org/library/htmlparser.html"><em>HTMLParser</em></a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johntantalo.com/blog/strip-tags-with-html5lib/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IPA TTS bookmarklet</title>
		<link>http://www.johntantalo.com/blog/ipa-tts-bookmarklet/</link>
		<comments>http://www.johntantalo.com/blog/ipa-tts-bookmarklet/#comments</comments>
		<pubDate>Tue, 06 Oct 2009 17:33:49 +0000</pubDate>
		<dc:creator>John Tantalo</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[bookmarklet]]></category>
		<category><![CDATA[ipa]]></category>
		<category><![CDATA[tts]]></category>

		<guid isPermaLink="false">http://www.johntantalo.com/blog/?p=70</guid>
		<description><![CDATA[Last modified 2 October 2011 I present the IPA (International Phonetic Alphabet) TTS (text-to-speech) bookmarklet. (Source) Bookmarklet: IPA TTS (drag to your bookmark bar) How to use: select any text that contains IPA and click on the bookmarklet. Wait a second for the iframe at the bottom of the page to load. Try these examples: [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Last modified <a href="https://gist.github.com/202523/8b3b7339bb37682d3233471f77cb54b44db948b1">2 October 2011</a></strong></p>
<p>I present the IPA (<a href="http://en.wikipedia.org/wiki/International_Phonetic_Alphabet">International Phonetic Alphabet</a>) TTS (<a href="http://en.wikipedia.org/wiki/Text-to-speech">text-to-speech</a>) <a href="http://en.wikipedia.org/wiki/Bookmarklet">bookmarklet</a>. (<a href="http://gist.github.com/202523">Source</a>)</p>
<p>Bookmarklet: <a href="javascript:%28function%20%28%29%20%7Bvar%20selection%20%3D%20window.getSelection%20%3F%20window.getSelection%28%29%20%3Adocument.getSelection%20%3F%20document.getSelection%28%29%20%3Adocument.selection%20%3F%20document.selection.createRange%28%29.text%20%3A%20%27%27%3Bif%20%28selection%29%20%7Bselection%20%3D%20String%28selection%29%3B%7Dif%20%28selection%29%20%7Bvar%20match%20%3D%20selection.match%28%27%5C%2F%28.%2A%29%5C%2F%27%29%3Bvar%20ipa%3Bif%20%28match%20%26%26%20match%5B1%5D%29%20%7Bipa%20%3D%20match%5B1%5D%3B%7Dif%20%28%21ipa%29%20%7Bipa%20%3D%20prompt%28%22Couldn%27t%20find%20any%20IPA.%20Type%20it%20in%20instead%3F%22%29%3B%7Dif%20%28ipa%29%20%7Bipa%20%3D%20ipa.replace%28%2F.%2Fg%2C%20function%20%28c%29%20%7Bif%20%28%2F%25u0%28...%29%2F.test%28escape%28c%29%29%29%20%7Breturn%20escape%28c%29.replace%28%2F%25u0%28...%29%2Fg%2C%20%27%26%23x%241%3B%27%29%3B%7D%20else%20%7Breturn%20c%3B%7D%7D%29%3Bvar%20request%20%3D%20%7Btxt%3A%20%27%3Cphoneme%20alphabet%3D%22ipa%22%20ph%3D%22%27%2Bipa%2B%27%22%3E%20%3C%2Fphoneme%3E%27%2Cvoice%3A%20%27crystal%27%7D%3Bvar%20iframe%20%3D%20document.createElement%28%27iframe%27%29%3Biframe.name%20%3D%20iframe.id%20%3D%20%22iframe%22%2Bnew%20Date%28%29.getTime%28%29%3Bdocument.body.appendChild%28iframe%29%3Bvar%20form%20%3D%20document.createElement%28%27form%27%29%3Bform.target%20%3D%20iframe.name%3Bform.method%20%3D%20%27post%27%3Bform.action%20%3D%20%27http%3A%2F%2F192.20.225.36%2Ftts%2Fcgi-bin%2Fnph-nvdemo%27%3Bform.acceptCharset%20%3D%20%22iso-8859-1%22%3Bform.style.display%20%3D%20%27none%27%3Bfor%20%28var%20name%20in%20request%29%20%7Bvar%20input%20%3D%20document.createElement%28%27input%27%29%3Binput.name%20%3D%20name%3Binput.value%20%3D%20request%5Bname%5D%3Bform.appendChild%28input%29%3B%7Ddocument.body.appendChild%28form%29%3Bform.submit%28%29%3B%7D%7D%20else%20%7Balert%28%22Select%20some%20IPA.%22%29%3B%7D%7D%29%28%29%0A">IPA TTS</a> (drag to your bookmark bar)</p>
<p>How to use: select any text that contains IPA and click on the bookmarklet. Wait a second for the iframe at the bottom of the page to load.</p>
<p>Try these examples: /ˌɪntəˈnæʃnəl/, /ˌɪntɚˈnæʃnəl/</p>
<h3>How does this work?</h3>
<p>The bookmark creates a POST request to the <a href="http://www2.research.att.com/~ttsweb/tts/demo.php">AT&#038;T Natural Voices® Text-to-Speech Demo</a> with the IPA text in <a href="http://en.wikipedia.org/wiki/Speech_Synthesis_Markup_Language">SSML</a>. The AT&#038;T demo has modest support for IPA, but often fails. If you know of another IPA TTS engine, please let me know or <a href="https://gist.github.com/202523">fork the bookmarklet and add it</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johntantalo.com/blog/ipa-tts-bookmarklet/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Things Babies Need</title>
		<link>http://www.johntantalo.com/blog/things-babies-need/</link>
		<comments>http://www.johntantalo.com/blog/things-babies-need/#comments</comments>
		<pubDate>Thu, 23 Jul 2009 20:48:51 +0000</pubDate>
		<dc:creator>John Tantalo</dc:creator>
				<category><![CDATA[Guest]]></category>
		<category><![CDATA[babies]]></category>
		<category><![CDATA[patents]]></category>

		<guid isPermaLink="false">http://www.johntantalo.com/blog/?p=45</guid>
		<description><![CDATA[Today&#8217;s guest post is by Chris Jagalla. &#8220;You cannot build character and courage by taking away man&#8217;s initiative and independence.&#8221; –Abraham Lincoln The foremost subject on which today&#8217;s babies lack direction is the ability to direct themselves. Too long have we coddled, pampered, and babied our nations babies. After all, if you give a baby [...]]]></description>
			<content:encoded><![CDATA[<p><i>Today&#8217;s guest post is by <a href="mailto:carrotpanic@yahoo.com">Chris Jagalla</a>.</i></p>
<blockquote><p>
&#8220;You cannot build character and courage by taking away man&#8217;s initiative and independence.&#8221;<br />
<br />–Abraham Lincoln
</p></blockquote>
<p>The foremost subject on which today&#8217;s babies lack direction is the ability to direct themselves. Too long have we coddled, pampered, and babied our nations babies. After all, if you give a baby a bottle, the baby will drink for a day, but if you teach the baby how to open up a miniature refrigerator, that very same baby will also drink for a day but also allow you to watch re-runs of Seinfeld in peace.</p>
<p>I present to you, the baby crib refrigerator! <a href="http://www.google.com/patents?id=7t-XAAAAEBAJ&#038;printsec=abstract&#038;zoom=4">(US Patent Application No. 11/248,929)</a></p>
<p><a href="http://www.google.com/patents?id=7t-XAAAAEBAJ&#038;zoom=4&#038;pg=PA1&#038;ci=135%2C608%2C715%2C510&#038;source=bookclip"><img src="http://www.google.com/patents?id=7t-XAAAAEBAJ&#038;pg=PA1&#038;img=1&#038;zoom=4&#038;hl=en&#038;sig=ACfU3U0npOKMWTyIwD3rbnsoEjyH0CJT3A&#038;ci=135%2C608%2C715%2C510&#038;edge=0"/></a></p>
<h3>From the Abstract</h3>
<blockquote><p>Before the parent goes to sleep for the night, they can prepare a snack, and store it overnight in the snack box. When the infant wakes up in the morning, they can retrieve the snack by themselves, after a few days&#8217; training, without crying. This will permit the parent to sleep longer, because they will not have to wake up prematurely for delivering the morning snack, and then wait until it is consumed.</p></blockquote>
<h3>Status of this patent</h3>
<p>Still pending, it has been rejected multiple times and is now awaiting appeal. The patent examiner cited the following two patents as prior art: <a href="http://www.google.com/patents?id=gXaNAAAAEBAJ&#038;printsec=abstract&#038;zoom=4">US Patent Application No. 10/044,362—Juvenile Stroller with Cooler</a> and <a href="http://www.google.com/patents?id=nWwsAAAAEBAJ&#038;printsec=abstract&#038;zoom=4">US Patent No. 4,545,211—Cold Box for Motor Vehicles</a></p>
<h3>Verdict</h3>
<p>Spare the fridge, spoil the child?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johntantalo.com/blog/things-babies-need/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

