<?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" xml:lang="en-US">
  <title>gohanlon.com - Home</title>
  <id>tag:gohanlon.com,2008:mephisto/</id>
  <generator version="0.8.0" uri="http://mephistoblog.com">Mephisto Drax</generator>
  
  <link href="http://gohanlon.com/" rel="alternate" type="text/html" />
  <updated>2008-06-04T04:25:13Z</updated>
  <link rel="self" href="http://feeds.feedburner.com/gohanlon" type="application/atom+xml" /><entry xml:base="http://gohanlon.com/">
    <author>
      <name>gohanlon</name>
    </author>
    <id>tag:gohanlon.com,2008-05-29:13</id>
    <published>2008-05-29T04:26:00Z</published>
    <updated>2008-06-04T04:25:13Z</updated>
    <category term="javascript" />
    <category term="named routes" />
    <category term="resources" />
    <category term="rest" />
    <category term="ruby on rails" />
    <link href="http://gohanlon.com/2008/5/29/javascript-named-routes" rel="alternate" type="text/html" />
    <title>Rails-JavaScript Named Routes (Re)Visited</title>
<content type="html">
            &lt;p&gt;Almost a year ago I was unable to find a plugin that did something that I considered rather basic—allow for easy URL generation from JavaScript based on routes defined in Rails. I hacked up a proof of concept albeit rough solution and &lt;a href="http://gohanlon.com/2007/7/15/using-rails-named-routes-from-client-side-javascript"&gt;posted it to this blog&lt;/a&gt;. Delightfully, Joshua Sierles ran with the idea, improved upon it, and &lt;a href="http://github.com/jsierles/js_named_routes/tree/master"&gt;published a plugin&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A year later and thanks in part to the ease of collaboration provided by &lt;a href="http://github.com"&gt;GitHub&lt;/a&gt;, I've formally paid my respects to Joshua's plugin by updating it for Rails 2.1, adding support for caching the generated javascript file, and a couple small features to make the javascript helpers behave a little more like the "real" Rails named route helpers.&lt;/p&gt;

&lt;h3&gt;What it does&lt;/h3&gt;

&lt;p&gt;Suppose that you had the following RESTful route defined in &lt;code&gt;routes.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;map.resources :posts
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then, you'd get these (and other) familiar-looking javascript URL helpers:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;posts_url() =&amp;gt; "http://localhost:3000/posts"
post_url({id: 3}) =&amp;gt; 'http://localhost:3000/posts/3'
post_path({id: 3}) =&amp;gt; '/posts/3'
formatted_post_path({id: 3, :format, 'xml'}) =&amp;gt; '/posts/3.xml'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The javascript generated by this plugin does not depend on any third-party javascript library.&lt;/p&gt;

&lt;h3&gt;Install&lt;/h3&gt;

&lt;p&gt;Assuming you are using Rails 2.1 RC1 or later, you can use the Rails &lt;code&gt;script/plugin install&lt;/code&gt; command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ cd RAILS_ROOT
$ script/plugin install git://github.com/jsierles/js_named_routes.git
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This plugin is targeted at Rails 2.1 and may not be compatible with other Rails versions without minor modifications.&lt;/p&gt;

&lt;h3&gt;Usage&lt;/h3&gt;

&lt;p&gt;At startup, a route for the plugin's all-important javascript generating &lt;code&gt;NamedRoutesController&lt;/code&gt; is dynamically injected. With the plugin installed, visit the following URL to inspect the provided javascript helpers:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;http://localhost:3000/javascripts/named_routes.js
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then, include the above javascript URL in your HTML &lt;code&gt;head&lt;/code&gt; tag (probably in &lt;code&gt;application.html.erb&lt;/code&gt; or some other layout file):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;%= javascript_include_tag :named_routes %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And you're done. Go have some fun!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// Mootools 1.2b
new Request({url: post_comments_path({post_id: 4}) }).post({
  post_id: 4, comment: {body: "something useful"}
});

// jQuery
$.post(post_comments_path({post_id: 4}), {
  post_id: 4, comment: {body: "something useful"}
});

// Prototype
new Ajax.Request(post_comments_path({post_id: 4}), {
  method: 'post',
  parameters: {post_id: 4, comment: {body: "something useful"} }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Just like in Rails, specified route segments that aren't part of the route will be added as query parameters:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;post_url({id: 3, extra: 'galen'}) =&amp;gt; 'http://localhost:3000/posts/3?extra=galen'
post_path({id: 3, extra: 'galen'}) =&amp;gt; '/posts/3?extra=galen'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This plugin uses page caching to cache the generated javascript routes, but lacks any intelligence for sweeping the cached file if you've made changes to your routes. That shouldn't be a problem if you are using Capistrano for production deployments because the cache is normally stored in &lt;code&gt;RAILS_ROOT/public&lt;/code&gt; which is not kept across deployments. Caching is normally disabled in development mode, but if you turn on caching you may need to manually clear the cached file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ cd RAILS_ROOT
$ rm public/javascripts/named_routes.js
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Alternatives&lt;/h3&gt;

&lt;p&gt;I'm pleased that there are at least two other plugins that also aim to satisfy the need to dynamically generate URLs based on Rails named routes: &lt;a href="http://code.google.com/p/lessjsroutes/"&gt;LessJsRoutes&lt;/a&gt; and &lt;a href="http://piano.altipla.no/pages/javascript_routes"&gt;JavaScript Routes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://code.google.com/p/lessjsroutes/"&gt;LessJsRoutes&lt;/a&gt; offers similar syntax to &lt;code&gt;js_named_routes&lt;/code&gt;. A notable difference is that the javascript routes file is built via a &lt;code&gt;rake&lt;/code&gt; task and therefore needs to be manually re-built whenever you make a change to your routes. LessJsRoutes also depends on either jQuery or Prototype, but perhaps only if you take advantage of their handy looking &lt;code&gt;_ajax&lt;/code&gt; helper methods (I haven't checked into this). They also support a more compact but still Rails-like syntax for specifying routes: &lt;code&gt;post_url(3)&lt;/code&gt; rather than &lt;code&gt;post_url({id: 3})&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://piano.altipla.no/pages/javascript_routes"&gt;JavaScript Routes&lt;/a&gt; (not to be confused with &lt;code&gt;js_named_routes&lt;/code&gt;) has a very different and more verbose syntax. While I personally prefer simpler and more Rails-like syntax, the plugin appears to be able to generate routes other than "named routes." Like LessJsRoutes, it also relies on a &lt;code&gt;rake&lt;/code&gt; task to manually build the javascript routes file.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://gohanlon.com/">
    <author>
      <name>gohanlon</name>
    </author>
    <id>tag:gohanlon.com,2008-04-29:8</id>
    <published>2008-04-29T06:50:00Z</published>
    <updated>2008-04-29T06:51:38Z</updated>
    <category term="jobs" />
    <link href="http://gohanlon.com/2008/4/29/hiring" rel="alternate" type="text/html" />
    <title>I'm Hiring!</title>
<content type="html">
            &lt;p&gt;Get in touch if you have interests in common with mine:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.ruby-lang.org"&gt;Ruby&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.rubyonrails.org"&gt;Ruby on Rails&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;AI (machine learning, classification, clustering)&lt;/li&gt;
		&lt;li&gt;Mac &lt;span class="caps"&gt;OS X&lt;/span&gt;&lt;/li&gt;
		&lt;li&gt;Linux (esp. &lt;a href="http://www.gentoo.org"&gt;Gentoo&lt;/a&gt;)&lt;/li&gt;
		&lt;li&gt;MySQL (and &lt;span class="caps"&gt;SQL&lt;/span&gt; in general)&lt;/li&gt;
		&lt;li&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt;/CSS (I love &lt;a href="http://www.transcendingcss.com"&gt;this book&lt;/a&gt;)&lt;/li&gt;
		&lt;li&gt;iPhone (Mobile Safari and &lt;span class="caps"&gt;SDK&lt;/span&gt;)&lt;/li&gt;
		&lt;li&gt;JavaScript (esp. &lt;a href="http://mootools.net"&gt;mootools&lt;/a&gt; and &lt;a href="http://jquery.com"&gt;jQuery&lt;/a&gt;)&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.ucsc.edu"&gt;UC Santa Cruz&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;If you’re a ferocious learner you don’t need to know Ruby, but you do need to have command of some language and the desire to learn Ruby. Same goes for Rails. Same pretty much goes for all of the above, but be ready to learn quickly.&lt;/p&gt;


	&lt;p&gt;Have projects of your own to sport? Awesome.&lt;/p&gt;


	&lt;p&gt;You’d be spending a portion of your time coworking with me on campus at &lt;span class="caps"&gt;UCSC&lt;/span&gt;, and the rest working from a location of your choosing. This is a part-time position and the pay is negotiable.&lt;/p&gt;


	&lt;p&gt;Introduce yourself by emailing me here: gohanlon at gmail dot com. Cheers!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://gohanlon.com/">
    <author>
      <name>gohanlon</name>
    </author>
    <id>tag:gohanlon.com,2008-04-28:9</id>
    <published>2008-04-28T22:21:00Z</published>
    <updated>2008-05-01T21:16:38Z</updated>
    <category term="leopard" />
    <category term="mac" />
    <category term="osx" />
    <category term="ruby" />
    <category term="wordnet" />
    <link href="http://gohanlon.com/2008/4/28/wordnet-with-ruby" rel="alternate" type="text/html" />
    <title>Installing Ruby-WordNet on Leopard</title>
<content type="html">
            &lt;p&gt;I recently decided to play around with &lt;a href="http://wordnet.princeton.edu/"&gt;WordNet&lt;/a&gt;, a lexical database of English. Naturally, I wanted to use Ruby and found the &lt;a href="http://www.deveiate.org/projects/Ruby-WordNet"&gt;Ruby-WordNet&lt;/a&gt; bindings. The install process was more involved than I expected.&lt;/p&gt;


	&lt;h2&gt;Install WordNet&lt;/h2&gt;


	&lt;p&gt;&lt;a href="http://wordnet.princeton.edu/obtain"&gt;Download&lt;/a&gt; and unpack the latest version of WordNet. (I installed &lt;a href="http://wordnet.princeton.edu/3.0/WordNet-3.0.tar.gz"&gt;WordNet-3.0.tar.gz&lt;/a&gt;.) Then, proceed with the usual build steps:&lt;/p&gt;


&lt;pre&gt;
$ cd ~src/WordNet-3.0
$ ./configure
$ make
$ sudo make install
&lt;/pre&gt;

	&lt;h2&gt;Install Berkeley DB&lt;/h2&gt;


	&lt;p&gt;I used &lt;a href="http://www.macports.org/"&gt;MacPorts&lt;/a&gt;, which was nice and simple:&lt;/p&gt;


&lt;pre&gt;
$ sudo port install db46
&lt;/pre&gt;

	&lt;h2&gt;Install Berkeley DB Ruby Bindings&lt;/h2&gt;


	&lt;p&gt;Download the latest release of &lt;a href="http://moulon.inra.fr/ruby/bdb.html"&gt;&lt;span class="caps"&gt;BDB&lt;/span&gt;&lt;/a&gt; via &lt;a href="ftp://moulon.inra.fr/pub/ruby/"&gt;&lt;span class="caps"&gt;FTP&lt;/span&gt; server&lt;/a&gt;. (I installed &lt;a href="ftp://moulon.inra.fr/pub/ruby/bdb-0.6.2.tar.gz"&gt;bdb-0.6.2.tar.gz&lt;/a&gt;.)&lt;/p&gt;


&lt;pre&gt;
$ cd ~src/bdb-0.6.2
&lt;/pre&gt;

	&lt;p&gt;Next, if you are using an Intel-based Mac, use this:&lt;/p&gt;


&lt;pre&gt;
$ env ARCHFLAGS="-arch i386" ruby extconf.rb --with-db-include=/opt/local/include/db46 --with-db-lib=/opt/local/lib/db46
&lt;/pre&gt;

	&lt;p&gt;Otherwise, if you’re using a &lt;span class="caps"&gt;PPC&lt;/span&gt;-based Mac:&lt;/p&gt;


&lt;pre&gt;
$ env ARCHFLAGS="-arch ppc" ruby extconf.rb --with-db-include=/opt/local/include/db46 --with-db-lib=/opt/local/lib/db46
&lt;/pre&gt;

	&lt;p&gt;For me, not specifying the architecture results in this general error:&lt;/p&gt;


&lt;pre&gt;
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.
...
extconf.rb:78: libdb not found (RuntimeError)
...
&lt;/pre&gt;

	&lt;p&gt;With more detailed error information in &lt;code&gt;~/src/bdb-0.6.2/mkmf.log&lt;/code&gt;:&lt;/p&gt;


&lt;pre&gt;
...
ld: symbol(s) not found for architecture ppc
...
&lt;/pre&gt;

	&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; In general, I’ve found that anything that I build using &lt;a href="http://www.ruby-doc.org/stdlib/libdoc/mkmf/rdoc/index.html"&gt;&lt;span class="caps"&gt;MKMF&lt;/span&gt;&lt;/a&gt; needs the &lt;code&gt;ARCHFLAGS&lt;/code&gt; environment variable. Also, note that some &lt;a href="http://rubygems.org/"&gt;RubyGems&lt;/a&gt; use &lt;span class="caps"&gt;MKMF&lt;/span&gt; to build native extensions, so &lt;code&gt;-arch&lt;/code&gt; is also required (i.e. &lt;code&gt;sudo env ARCHFLAGS="-arch i386" gem install mysql&lt;/code&gt;).&lt;/p&gt;


	&lt;p&gt;If everything went well you’ll have a &lt;code&gt;Makefile&lt;/code&gt; and can finish off the Berkeley DB Ruby bindings installation:&lt;/p&gt;


&lt;pre&gt;
$ make
$ sudo make install
&lt;/pre&gt;

	&lt;h2&gt;Install Ruby-WordNet&lt;/h2&gt;


	&lt;p&gt;&lt;a href="http://www.deveiate.org/projects/Ruby-WordNet"&gt;Download&lt;/a&gt; the latest version of Ruby-Wordnet (I installed &lt;a href="http://www.deveiate.org/code/Ruby-WordNet-0.0.4.tar.gz"&gt;Ruby-WordNet-0.0.4.tar.gz&lt;/a&gt;):&lt;/p&gt;


&lt;pre&gt;
$ cd ~src/Ruby-WordNet-0.0.4
$ ruby convertdb.rb /usr/local/WordNet-3.0/dict/
$ ruby test.rb
$ sudo ruby install.rb
&lt;/pre&gt;

	&lt;p&gt;I got one failure while running the tests, which I assumed to not be a huge problem.&lt;/p&gt;


	&lt;p&gt;You should now be able to run the examples:&lt;/p&gt;


&lt;pre&gt;
$ sudo ruby examples/distance.rb pine tree
The hypernym distance between pine and tree is: 3
&lt;/pre&gt;

	&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; To avoid having to &lt;code&gt;sudo&lt;/code&gt; to run your Ruby scripts that leverage WordNet, you will likely need to correct permissions to allow your user write access to the &lt;code&gt;ruby-wordnet&lt;/code&gt; database files. I do not recommend adding your user to the group &lt;code&gt;wheel&lt;/code&gt;, which exposes you to security vulnerabilities and/or prevent applications from loading plugins. For example, Safari won’t load plugins (&lt;code&gt;Input Manager&lt;/code&gt;s) if your user is a member of &lt;code&gt;wheel&lt;/code&gt;.&lt;/p&gt;


	&lt;h2&gt;Concluding Thoughts&lt;/h2&gt;


	&lt;p&gt;I have a strong suspicion that the Ruby community would benefit from using MySQL for the WordNet database. There are already some projects that port WordNet to a MySQL database, such as &lt;a href="http://wnsqlbuilder.sourceforge.net/"&gt;wordnet sql builder&lt;/a&gt;. With a reasonable amount of effort the schema could be altered to conform to ActiveRecord conventions, making WordNet much more accessible.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://gohanlon.com/">
    <author>
      <name>gohanlon</name>
    </author>
    <id>tag:gohanlon.com,2008-04-25:5</id>
    <published>2008-04-25T15:23:00Z</published>
    <updated>2008-05-03T18:25:41Z</updated>
    <category term="git" />
    <category term="mac" />
    <category term="osx" />
    <category term="textmate" />
    <link href="http://gohanlon.com/2008/4/25/textmate-for-git-commit-messages" rel="alternate" type="text/html" />
    <title>TextMate for Git Commit Messages</title>
<content type="html">
            &lt;p&gt;I prefer &lt;a href="http://www.vim.org"&gt;&lt;span class="caps"&gt;VIM&lt;/span&gt;&lt;/a&gt; for use with &lt;a href="http://git.or.cz"&gt;Git&lt;/a&gt; commands that require an editor (such as the commit message for &lt;code&gt;git commit&lt;/code&gt;). However, if you’d prefer to use &lt;a href="http://macromates.com"&gt;TextMate&lt;/a&gt; you can do the following:&lt;/p&gt;


&lt;pre&gt;
$ echo "GIT_EDITOR=\"mate -w\"" &amp;gt;&amp;gt; ~/.bash_login
$ source ~/.bash_login
&lt;/pre&gt;

	&lt;p&gt;That assumes that the &lt;code&gt;mate&lt;/code&gt; command is installed and findable in your &lt;code&gt;PATH&lt;/code&gt;. For more info, in TextMate select the &lt;code&gt;Help -&amp;gt; Terminal Usage...&lt;/code&gt; menu item.&lt;/p&gt;


	&lt;p&gt;The &lt;code&gt;EDITOR&lt;/code&gt; environment variable is used by many applications (including &lt;code&gt;git&lt;/code&gt;) that need the help of an editor. If you’d prefer to specify that TextMate be used with any such application, specify &lt;code&gt;EDITOR&lt;/code&gt; instead:&lt;/p&gt;


&lt;code&gt;
$ echo "EDITOR=\"mate -w\"" &amp;gt;&amp;gt; ~/.bash_login
&lt;/code&gt;
          </content>  </entry>
  <entry xml:base="http://gohanlon.com/">
    <author>
      <name>gohanlon</name>
    </author>
    <id>tag:gohanlon.com,2008-04-23:6</id>
    <published>2008-04-23T01:00:00Z</published>
    <updated>2008-04-23T06:12:17Z</updated>
    <category term="gentoo" />
    <category term="nginx" />
    <category term="rc-script" />
    <link href="http://gohanlon.com/2008/4/23/nginx-on-gentoo-rc-script" rel="alternate" type="text/html" />
    <title>Nginx on Gentoo RC Script</title>
<content type="html">
            &lt;p&gt;I build Nginx from source off of a fork/mirror so I can take advantage of a the &lt;a href="http://brainspl.at/articles/2007/11/09/a-fair-proxy-balancer-for-nginx-and-mongrel"&gt;fair proxy balancing policy&lt;/a&gt;. Buiding from source means crafting your own Gentoo rc script. Fortunately, the &lt;a href="http://sources.gentoo.org/viewcvs.py/gentoo-x86/www-servers/nginx/files/nginx?view=markup"&gt;Nginx rc script&lt;/a&gt; distributed through &lt;a href="http://www.gentoo.org/doc/en/handbook/handbook-x86.xml?part=2&amp;amp;#38;chap=1"&gt;Portage&lt;/a&gt; will work perfectly with a couple minor modifications.&lt;/p&gt;


	&lt;p&gt;You should only need to correct the path to the &lt;code&gt;nginx&lt;/code&gt; executable, which should probably be &lt;code&gt;/usr/local/sbin/nginx&lt;/code&gt; if you accepted the default build configurations:&lt;/p&gt;


&lt;pre&gt;
$ sudo which nginx
/usr/local/sbin/nginx
&lt;/pre&gt;

	&lt;p&gt;Download and edit the rc script to use correct path to &lt;code&gt;nginx&lt;/code&gt;:&lt;/p&gt;


&lt;pre&gt;
$ cd ~
$ curl -0 http://sources.gentoo.org/viewcvs.py/*checkout*/gentoo-x86/www-servers/nginx/files/nginx?rev=1.3 &amp;gt; nginx
$ vim nginx
&lt;/pre&gt;

	&lt;p&gt;Here are the changes that I made in the form of a patch:&lt;/p&gt;


&lt;pre&gt;
17c17
&amp;lt;         --exec /usr/sbin/nginx -- -c /etc/nginx/nginx.conf
---
&amp;gt;         --exec /usr/local/sbin/nginx -- -c /etc/nginx/nginx.conf
38c38
&amp;lt;     /usr/sbin/nginx -c /etc/nginx/nginx.conf -t
---
&amp;gt;     /usr/local/sbin/nginx -c /etc/nginx/nginx.conf -t
40a41
&amp;gt; 
&lt;/pre&gt;

	&lt;p&gt;Finally, install the rc script and configure Nginx to start at boot:&lt;/p&gt;


&lt;pre&gt;
$ sudo mv nginx /etc/init.d/
$ sudo chmod +x /etc/init.d/nginx
$ sudo rc-config add nginx default
$ sudo /etc/init.d/nginx start
$ rc-config show
&lt;/pre&gt;

	&lt;p&gt;Here’s the &lt;a href="http://git.localdomain.pl/?p=nginx.git;a=tree;hb=upstream_fair-0.6"&gt;fork with the fair proxy balancing patch&lt;/a&gt; (&lt;a href="http://git.localdomain.pl/?p=nginx.git;a=snapshot;h=upstream_fair-0.6"&gt;download snapshot&lt;/a&gt;).&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://gohanlon.com/">
    <author>
      <name>gohanlon</name>
    </author>
    <id>tag:gohanlon.com,2008-04-20:4</id>
    <published>2008-04-20T17:08:00Z</published>
    <updated>2008-04-28T22:23:56Z</updated>
    <category term="ai" />
    <category term="classification" />
    <category term="leopard" />
    <category term="libsvm" />
    <category term="mac" />
    <category term="osx" />
    <category term="ruby" />
    <link href="http://gohanlon.com/2008/4/20/installing-libsvm-on-leopard" rel="alternate" type="text/html" />
    <title>Installing LIBSVM on Leopard</title>
<content type="html">
            &lt;p&gt;&lt;a href="http://www.csie.ntu.edu.tw/~cjlin/libsvm"&gt;&lt;span class="caps"&gt;LIBSVM&lt;/span&gt;&lt;/a&gt; is a popular software library for performing document classification using &lt;a href="http://en.wikipedia.org/wiki/Support_vector_machine"&gt;support vector machines&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;One easy approach to installing &lt;span class="caps"&gt;LIBSVM&lt;/span&gt; on Mac &lt;span class="caps"&gt;OS X&lt;/span&gt; Leopard is to use the popular &lt;a href="http://www.macports.org/"&gt;MacPorts&lt;/a&gt; (&lt;a href="http://www.macports.org/install.php"&gt;download page&lt;/a&gt;). If you have MacPorts installed, you can install &lt;span class="caps"&gt;LIBSVM&lt;/span&gt; as shown below.&lt;/p&gt;


	&lt;p&gt;The &lt;code&gt;Portfile&lt;/code&gt; has recently been fixed, so be sure to sync like so:&lt;/p&gt;


&lt;pre&gt;
$ sudo port -v selfupdate
&lt;/pre&gt;

	&lt;p&gt;Install &lt;code&gt;libsvm&lt;/code&gt; already:&lt;/p&gt;


&lt;pre&gt;
$ sudo port install libsvm
&lt;/pre&gt;

	&lt;p&gt;Naturally, I’m particularly interested in using the &lt;a href="http://rubysvm.cilibrar.com/download"&gt;Ruby bindings for &lt;span class="caps"&gt;LIBSVM&lt;/span&gt;&lt;/a&gt;. I’m not completely satisfied with the method I used to get them built and installed, but I’ll write it up.&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;&lt;span class="caps"&gt;NOTE&lt;/span&gt;: The Portfile for &lt;span class="caps"&gt;LIBSVM&lt;/span&gt; &lt;del&gt;is currently&lt;/del&gt; was broken, but I contributed a very minor patch which updates the port to &lt;span class="caps"&gt;LIBSVM 2&lt;/span&gt;.86. The patch has been accepted by the maintainer and &lt;del&gt;will soon be&lt;/del&gt; has been rolled.&lt;/em&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://gohanlon.com/">
    <author>
      <name>gohanlon</name>
    </author>
    <id>tag:gohanlon.com,2007-10-08:2</id>
    <published>2007-10-08T15:03:00Z</published>
    <updated>2008-04-21T01:39:47Z</updated>
    <category term="ergonomics" />
    <category term="keyboards" />
    <category term="kinesis" />
    <link href="http://gohanlon.com/2007/10/8/kinesis-my-favorite-keyboard" rel="alternate" type="text/html" />
    <title>Kinesis: My Favorite Keyboard</title>
<content type="html">
            &lt;p&gt;Several years ago, I had wrist and finger pain from typing all day. I purchased a &lt;a href="http://www.kinesis-ergo.com/advantage_pro.htm"&gt;Kinesis ergo keyboard&lt;/a&gt; and the pain hasn’t returned since. It’s a super smart design.&lt;/p&gt;


	&lt;h2&gt;Keys conform to your hand&lt;/h2&gt;


	&lt;p&gt;The keys are set in a bowl so that each key is as close as can be to your finger tips.&lt;/p&gt;


	&lt;h2&gt;Opposable thumbs are useful&lt;/h2&gt;


	&lt;p&gt;Rather than only using your thumbs to press space bar, a cluster of keys is placed under each thumb. That means fewer keys that require straining your pinky to reach.&lt;/p&gt;


	&lt;h2&gt;Natural finger movement&lt;/h2&gt;


	&lt;p&gt;Keys are all vertically aligned, not diagonally like most keyboards. The keys are in the natural range of movement of your fingers, no need to move your wrist or yaw your third knuckle.&lt;/p&gt;


	&lt;h2&gt;Key remapping&lt;/h2&gt;


	&lt;p&gt;Keys can be remapped, so if you don’t like where a key in placed you can just swap it for another key. Personally, I’ve made very minimal use of this feature.&lt;/p&gt;


	&lt;h2&gt;Type numbers faster&lt;/h2&gt;


	&lt;p&gt;The keyboard doesn’t have a numeric keypad, which seems like a week point at first look. But with its smart design, 8 of the number keys rest under your fingertips compared to 4 when using a numeric keypad. Numeric calculations are a bit slower, as the operators aren’t as conveniently located as on a numeric keypad.&lt;/p&gt;


	&lt;p&gt;The keyboard does support a numeric keypad mode similar to what most laptops have, but I don’t tend to use it (perhaps I would if I spent more time typing calculations).&lt;/p&gt;


	&lt;h2&gt;Better your speed and technique&lt;/h2&gt;


	&lt;p&gt;The layout of the keys rewards good typing technique and penalizes bad habits. I broke several bad habits that I didn’t even notice I had.&lt;/p&gt;


	&lt;h2&gt;Minimal learning curve&lt;/h2&gt;


	&lt;p&gt;Before I purchased the Kinesis keyboard, I was split between learning the Dvorak layout or trying another alternative and expensive keyboard. I had previously tried the ill-fated &lt;a href="http://www.fingerworks.com"&gt;Fingerworks TouchStream LP&lt;/a&gt; which had a multi-month learning curve and universally reduces typing speed—yuck!&lt;/p&gt;


	&lt;p&gt;I was pleased that after a week I was up to my normal typing speed on the Kinesis keyboard. After the second week my typing speed jumped about 15 &lt;span class="caps"&gt;WPM&lt;/span&gt;.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://gohanlon.com/">
    <author>
      <name>gohanlon</name>
    </author>
    <id>tag:gohanlon.com,2007-07-15:1</id>
    <published>2007-07-15T04:54:00Z</published>
    <updated>2008-05-29T04:31:16Z</updated>
    <category term="javascript" />
    <category term="named routes" />
    <category term="ruby on rails" />
    <link href="http://gohanlon.com/2007/7/15/using-rails-named-routes-from-client-side-javascript" rel="alternate" type="text/html" />
    <title>Rails Named Routes from JavaScript</title>
<content type="html">
            &lt;p&gt;&lt;strong&gt;&lt;span class="caps"&gt;UPDATE 2&lt;/span&gt;:&lt;/strong&gt; Read the &lt;a href="http://gohanlon.com/2008/5/29/javascript-named-routes"&gt;latest information&lt;/a&gt; about the plugin.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;&lt;span class="caps"&gt;UPDATE&lt;/span&gt;:&lt;/strong&gt; Joshua Sierles has improved upon the concepts and code of this article and published an aptly named plugin: &lt;a href="http://github.com/jsierles/js_named_routes/tree/master"&gt;Named Routes in Javascript&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Last week a new JavaScript &lt;span class="caps"&gt;REST API&lt;/span&gt; called &lt;a href="http://giantrobots.thoughtbot.com/2007/4/2/jester-javascriptian-rest"&gt;Jester&lt;/a&gt; was announced over at &lt;a href="http://giantrobots.thoughtbot.com/"&gt;Giant Robots&lt;/a&gt;. It’s young, but I’m thoroughly impressed and am planning to put it thought its paces in a large project very soon. Go check it out if you’re using &lt;span class="caps"&gt;REST&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;Alas, not all of my projects are using &lt;span class="caps"&gt;REST&lt;/span&gt; (yet). Even when developing following the &lt;span class="caps"&gt;REST&lt;/span&gt; pattern, you most likely still occationally use Named Routes. Also, RESTful routes are basically automatically generated Named Routes, so this technique can be used with &lt;span class="caps"&gt;REST&lt;/span&gt; (but may require enhancement to support all the various RESTful route variations).&lt;/p&gt;


	&lt;p&gt;The Giant Robots folks have inspired me to write about a technique I’ve been using to use Rails Named Routes in JavaScript to prepare Ajax requests using Unobtrusive JavaScript techniques.&lt;/p&gt;


	&lt;p&gt;A word of caution: The following approach is both simple and naive—it is not intended to be a complete implementation of Rails Named Routes in JavaScript. The technique hasn’t been extensively tested, but it meets my needs (so far). &lt;span class="caps"&gt;YMMV&lt;/span&gt;.&lt;/p&gt;


	&lt;h2&gt;The Yucky Way&lt;/h2&gt;


	&lt;p&gt;Consider the following Named Routes (defined in &lt;code&gt;routes.rb&lt;/code&gt;):&lt;/p&gt;


&lt;pre&gt;
ActionController::Routing::Routes.draw do |map|
    ...    
    map.with_options :controller =&amp;gt; "story" do |story|
      story.create_story '/story/create/:milestone_id', :action =&amp;gt; "create" 
      story.move_story '/story/move/:id', :action =&amp;gt; "move" 
    end
    ...
end
&lt;/pre&gt;

	&lt;p&gt;One way to use a route on the client-side is to do something like the following in a view template:&lt;/p&gt;


&lt;pre&gt;
&amp;lt;html&amp;gt;
...
&amp;lt;script type="javascript"&amp;gt;
var move_story_url = '&amp;lt;%= move_story_url %&amp;gt;'
&amp;lt;/script&amp;gt;
...
&amp;lt;/html&amp;gt;
&lt;/pre&gt;

	&lt;p&gt;And then later use the &lt;code&gt;move_story_url&lt;/code&gt; variable to piece together a &lt;span class="caps"&gt;URL&lt;/span&gt; for an Ajax request:&lt;/p&gt;


&lt;pre&gt;
var story_id = ...
new Ajax.Request(move_story_url + "/" + story_id, {
  ...
})
&lt;/pre&gt;

	&lt;p&gt;Yuck. That defeats Rails’s routing goodness. Rails routes free the developer from putting &lt;span class="caps"&gt;URL&lt;/span&gt;’s and paths together by concatenating strings all over in their Ruby code. By putting &lt;span class="caps"&gt;URL&lt;/span&gt;’s and paths together by hand in JavaScript, the DRYness of defining a particular route in a single place is lost.&lt;/p&gt;


	&lt;p&gt;To further illustrate the problem, consider a route that has multiple identifiers:&lt;/p&gt;


&lt;pre&gt;
http://localhost:3000/blog/:blog_id/posts/:post_id
&lt;/pre&gt;

	&lt;p&gt;Detailed knowledge of the route is needed in your JavaScript:&lt;/p&gt;


&lt;pre&gt;
"http://localhost.com:3000/blog/" + blog_id + "/posts/" + post_id
&lt;/pre&gt;

	&lt;p&gt;Double yuck.&lt;/p&gt;


	&lt;h2&gt;The Happy Way&lt;/h2&gt;


	&lt;p&gt;First, include the following JavaScript file a view file (probably someplace global like &lt;code&gt;application.rhtml&lt;/code&gt;):&lt;/p&gt;


&lt;pre&gt;
&amp;lt;html&amp;gt;
...    
&amp;lt;script language="javascript" type="text/javascript" 
src="/named_routes_to_javascript"&amp;gt;&amp;lt;/script&amp;gt;
...
&amp;lt;/html&amp;gt;
&lt;/pre&gt;

	&lt;p&gt;where the above referenced JavaScript file is dynamically generated from the routes defined in &lt;code&gt;routes.rb&lt;/code&gt;, and contains a JavaScript function corresponding with each of your named routes.&lt;/p&gt;


	&lt;p&gt;Create a &lt;code&gt;Controller&lt;/code&gt; to handle request for the dynamically created JavaScript file:&lt;/p&gt;


&lt;pre&gt;
class NamedRoutesToJavascriptController &amp;lt; ApplicationController
  def generate
    headers['Content-Type'] = 'text/javascript'
    render :template =&amp;gt; "named_routes_to_javascript/generate", :layout =&amp;gt; false
  end
end
&lt;/pre&gt;

	&lt;p&gt;Create the &lt;code&gt;Template&lt;/code&gt; to render the JavaScript (&lt;code&gt;generate.rhtml&lt;/code&gt;):&lt;/p&gt;


&lt;pre&gt;
var host = "&amp;lt;%= "#{request.protocol}#{request.host_with_port}" %&amp;gt;" 

&amp;lt;% ActionController::Routing::Routes.named_routes().each do |name, route| -%&amp;gt;
function &amp;lt;%= name %&amp;gt;_url(overrides) {
  var options = {
  &amp;lt;% route.significant_keys.each do |key| -%&amp;gt;
    &amp;lt;%= key %&amp;gt;: &amp;lt;%= route.defaults[key].nil? ? "''" : "'#{route.defaults[key]}'" %&amp;gt;,
  &amp;lt;% end -%&amp;gt;
    xxx: null
  }
  Object.extend(options, overrides || {});

  return host+"&amp;lt;%= route.segments.collect(&amp;:to_s) %&amp;gt;"&amp;lt;% route.significant_keys.each do |key| -%&amp;gt;.replace(":&amp;lt;%= key %&amp;gt;", options.&amp;lt;%= key %&amp;gt;).replace("//", "/")&amp;lt;% end -%&amp;gt;
}
&amp;lt;% end -%&amp;gt;
&lt;/pre&gt;

	&lt;p&gt;Lastly, create the following route in &lt;code&gt;routes.rb&lt;/code&gt;:&lt;/p&gt;


&lt;pre&gt;
ActionController::Routing::Routes.draw do |map|
    ...
  map.named_routes_to_javascript 'named_routes_to_javascript', :controller =&amp;gt; "named_routes_to_javascript", :action =&amp;gt; "generate" 
  ...
end
&lt;/pre&gt;

	&lt;p&gt;The dynamically generated JavaScript looks like the following, with a function for each Named Route defined in &lt;code&gt;routes.rb&lt;/code&gt;:&lt;/p&gt;


&lt;pre&gt;
var host = "http://localhost:3000" 

function move_story_url(overrides) {
  var options = {
    id: '',
    controller: 'story',
    action: 'move',
    xxx: null
  }
  Object.extend(options, overrides || {});

  return host+"/story/move/:id/".replace(":id", options.id).replace("//", "/").replace(":controller", options.controller).replace("//", "/").replace(":action", options.action).replace("//", "/")
}

function create_story_url(overrrides) {
  // ...similar to above...
}
&lt;/pre&gt;

	&lt;p&gt;JavaScript snippets:&lt;/p&gt;


&lt;pre&gt;
&amp;gt;&amp;gt;&amp;gt; move_story_url({id: 5})
http://localhost:3000/story/move/5/

&amp;gt;&amp;gt;&amp;gt; create_story_url({milestone_id:73})
http://localhost:3000/story/create/73
&lt;/pre&gt;

	&lt;p&gt;And finally, an Ajax request becomes:&lt;/p&gt;


&lt;pre&gt;
var story_id = ...
new Ajax.Request(move_story_url({id: story_id}), {
  ...
})
&lt;/pre&gt;

	&lt;p&gt;No more knowledge of routes required within your JavaScript code—it just feels right.&lt;/p&gt;
          </content>  </entry>
</feed>
