<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss version="2.0">
  <channel>
    <title>code</title>
    <description>norbauer.com</description>
    <link>http://norbauer.com/notebooks/code</link>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/norbauer/code" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
      <title>Storing IP addresses as integers</title>
      <description>&lt;p&gt;Tying long sessions to an IP address is a good way to ensure some security for your users. But inevitably, you&amp;#8217;ll want to store that IP. While you could, of course, store it as a string, such as &lt;code&gt;"123.125.126.127"&lt;/code&gt; (called a &amp;#8220;dotted quad&amp;#8221;), some developers might prefer saving some space and storing it as a compact integer. There&amp;#8217;s a right way and a wrong way to do this. The wrong way is as follows:&lt;/p&gt;
&lt;pre&gt;'12.34.56.78'.sub('.', '').to_i&lt;/pre&gt;
&lt;p&gt;This is a bad idea because two IP addresses can result in the same integer: 12.34.56.78 and 123.4.56.78 are both valid IPs. The correct way is as follows:&lt;/p&gt;
&lt;pre&gt;'12.34.56.78'.split('.').collect(&amp;amp;:to_i).
              pack('C*').unpack('N').first&lt;/pre&gt;
&lt;p&gt;To understand this seemingly obfuscated train wreck, let&amp;#8217;s look at the data in this chain after each method call:&lt;/p&gt;
&lt;pre&gt;'12.34.56.78'.split('.'). #=&amp;gt; ['12', '34', '56', 78']
  collect(&amp;amp;:to_i).        #=&amp;gt; [12, 34, 56, 78]
  pack('C*').             #=&amp;gt; "\f\"8N"
  unpack('N').            #=&amp;gt; [203569230]
  first                   #=&amp;gt; 203569230
&lt;/pre&gt;
&lt;p&gt;Many developers are unfamiliar with pack and unpack. These allow you to create and extract data into and out of binary-packed strings. In the third method call, you&amp;#8217;ll see the result is &lt;code&gt;"\f\"8N"&lt;/code&gt;. This strange-looking string is really just 4 bytes of data, the numbers 12, 34, 56, and 78 in binary form, put into a string. We then unpack that 4-byte string into a 4-byte integer (with network byte order).&lt;/p&gt;
&lt;p&gt;This is also the same problem solved by the C library method &lt;code&gt;inet_aton&lt;/code&gt;, which is implemented as part of &lt;a href="http://www.ruby-doc.org/stdlib/libdoc/ipaddr/rdoc/classes/IPAddr.html"&gt;Ruby&amp;#8217;s &lt;code&gt;IPAddr&lt;/code&gt; class&lt;/a&gt;. Thus, there is a much simpler alternative:&lt;/p&gt;
&lt;pre&gt;require 'ipaddr'
IPAddr.new('12.34.56.78').to_i   #=&amp;gt; 203569230&lt;/pre&gt;
&lt;p&gt;But what fun is that!&lt;/p&gt;
&lt;p&gt;PS. Yes, you can have multi-line method chains simply by leaving the dot at the end of the line. Ruby then knows to look for a method call on the next line. Both snippets are valid Ruby! You should, of course, indent appropriately.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/norbauer/code/~4/K4i01QlUA9s" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 25 Sep 2009 21:44:45 +0000</pubDate>
      <link>http://norbauer.com/notebooks/code/notes/storing-ip-addresses-as-integers</link>
      <guid>http://norbauer.com/notebooks/code/notes/storing-ip-addresses-as-integers</guid>
    </item>
    <item>
      <title>Snow Leopard: Upgrading for Rails Developers</title>
      <description>&lt;p&gt;Upgrading to Snow Leopard is not as easy as Apple would lead you to believe; at least not if you&amp;#8217;re a Rails developer. Here are a few select errors you might have encountered:&lt;/p&gt;
&lt;pre&gt;uninitialized constant MysqlCompat::MysqlRes
dlopen(/Library/Ruby/Gems/1.8/gems/nokogiri-1.3.3/lib/nokogiri/nokogiri.bundle, 9): no suitable image found&lt;/pre&gt;
&lt;p&gt;These errors seems to stem because OS X is now fully 64-bit, and unfortunately, all your compiled libraries are 32-bit. Whoops!&lt;/p&gt;
&lt;p&gt;So, let&amp;#8217;s fix them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: These instructions are tailored for Intel 64-bit machines, as only 64-bit machines should have these issues. Any Intel Core 2 machines including recent Macbooks, Macbook Pros, and iMacs, and all Mac Pros should work fine with these instructions.&lt;/p&gt;
&lt;h4&gt;Install 64-bit MySQL&lt;/h4&gt;
&lt;p&gt;To fix the MySQL problem, you need install the &lt;a href="http://dev.mysql.com/get/Downloads/MySQL-5.1/mysql-5.1.35-osx10.5-x86_64.dmg/from/pick#mirrors"&gt;x86_64 version of MySQL&lt;/a&gt;. This will uninstall your old MySQL version, but will not migrate your databases. In order to migrate your data, first make sure MySQL is not running, then:&lt;/p&gt;
&lt;pre&gt;$ sudo mv /usr/local/mysql/data /usr/local/mysql/data.default
$ sudo mv /usr/local/mysql-oldversion/data /usr/local/mysql/data&lt;/pre&gt;
&lt;p&gt;Start up MySQL and your databases should be in tact.&lt;/p&gt;
&lt;h4&gt;Reinstall the MySQL gem&lt;/h4&gt;
&lt;p&gt;Now that you have the correct version of MySQL, you need to reinstall the latest MySQL gem. Make sure to uninstall your current MySQL gem first:&lt;/p&gt;
&lt;pre&gt;$ sudo gem uninstall mysql
$ sudo env ARCHFLAGS="-arch x86_64" gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config&lt;/pre&gt;
&lt;h4&gt;Re-install MacPorts&lt;/h4&gt;
&lt;p&gt;To fix nokogiri (and other gems with external dependencies), you&amp;#8217;ll need to fix your Macports install. Unfortunately, the only way to fix Macports is to completely reinstall it. You need to completely delete (or at least move) your /opt/local directory. Once that is done, download and install the latest version of &lt;a href="http://distfiles.macports.org/MacPorts/MacPorts-1.8.0-10.6-SnowLeopard.dmg"&gt;MacPorts for Snow Leopard&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You&amp;#8217;ll probably want to install two things pretty quickly: libxml2 for nokogiri and git-core:&lt;/p&gt;
&lt;pre&gt;$ sudo port install libxml2
$ sudo port install git-core +bash_completion +doc&lt;/pre&gt;
&lt;h4&gt;Re-install nokogiri (and other gems)&lt;/h4&gt;
&lt;p&gt;Any gem that has a compiled component will need to be reinstalled. nokogiri is just one of the libraries; others include ruby-debug, ruby-prof, and a lot of others. To fix them, just run this command:&lt;/p&gt;
&lt;pre&gt;$ sudo gem pristine --all&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/norbauer/code/~4/pHBeJR-ITKs" height="1" width="1"/&gt;</description>
      <pubDate>Sat, 29 Aug 2009 00:36:26 +0000</pubDate>
      <link>http://norbauer.com/notebooks/code/notes/snow-leopard-upgrading-for-rails-developers</link>
      <guid>http://norbauer.com/notebooks/code/notes/snow-leopard-upgrading-for-rails-developers</guid>
    </item>
    <item>
      <title>Symbol vs String performance</title>
      <description>&lt;p&gt;A more interesting metric to this discussion is the use of strings versus symbols. Fortunately, these types of discussions can easily be solved by benchmarks:&lt;/p&gt;
&lt;script src="http://gist.github.com/114989.js"&gt;&lt;/script&gt;&lt;p&gt;Results under Ruby 1.8.6:&lt;/p&gt;
&lt;pre&gt;
                           user     system      total        real    less no op
String instanciation   9.050000   0.010000   9.060000 (  9.057162)   5.921219
Symbol use             5.130000   0.000000   5.130000 (  5.131844)   1.995901
new String#to_sym     14.550000   0.020000  14.570000 ( 14.567466)   11.431523
const String#to_sym   11.960000   0.010000  11.970000 ( 11.967217)   8.831274
String const lookup    6.350000   0.010000   6.360000 (  6.358697)   3.222754
Symbol const lookup    6.400000   0.010000   6.410000 (  6.416395)   3.280452
No op                  3.130000   0.010000   3.140000 (  3.135943)   n/a
&lt;/pre&gt;
&lt;p&gt;Results under Ruby 1.9.1:&lt;/p&gt;
&lt;pre&gt;
                           user     system      total        real    less no op
String instanciation   9.170000   0.010000   9.180000 (  9.174451)   4.736163
Symbol use             4.920000   0.010000   4.930000 (  4.930031)   0.491743
new String#to_sym     18.080000   0.030000  18.110000 ( 18.087386)   13.649098
const String#to_sym   13.940000   0.030000  13.970000 ( 13.954099)   9.515811
String const lookup    4.920000   0.000000   4.920000 (  4.927497)   0.489209
Symbol const lookup    4.910000   0.020000   4.930000 (  4.921151)   0.482863
No op                  4.440000   0.000000   4.440000 (  4.438288)   n/a
&lt;/pre&gt;
&lt;p&gt;What do these results mean? Well, first you need to subtract out the &amp;#8220;no op&amp;#8221; results from all the others, which I&amp;#8217;ve added as a column above. We can now see that string instantiation takes about 90 nanoseconds, which means about 11000 string instantiations per millisecond. Are symbols faster? Considerably so. But the real lesson here is that these numbers are so small that no one in there right mind should spend time worrying about them.&lt;/p&gt;
&lt;p&gt;So please, &lt;a href="http://www.randomhacks.net/articles/2007/01/20/13-ways-of-looking-at-a-ruby-symbol"&gt;use symbols when you should use symbols, and otherwise use strings.&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/norbauer/code/~4/MTedlU-3GDw" height="1" width="1"/&gt;</description>
      <pubDate>Sun, 15 Feb 2009 23:00:20 +0000</pubDate>
      <link>http://norbauer.com/notebooks/code/notes/symbol-vs-string-performance</link>
      <guid>http://norbauer.com/notebooks/code/notes/symbol-vs-string-performance</guid>
    </item>
    <item>
      <title>Garbage collection thresholds in Ruby</title>
      <description>&lt;p&gt;I&amp;#8217;ve put together a &lt;a href="http://gist.github.com/64453"&gt;somewhat extensive&lt;/a&gt; collection of scripts and results from looking at how often objects get garbage collected in Ruby 1.8 and Ruby 1.9. Performance metrics are also provided running the script under various different environments, which I found quite fascinating. irb, for instance, is ridiculously slow. Granted, the vast majority of these scripts times are spent performing the very inefficient ObjectSpace calls, so the raw numbers should be taken with a grain of salt. The metrics are only interesting for comparison, and are of questionable use.&lt;/p&gt;
&lt;p&gt;This was instigated by a String versus Symbol discussion in #ruby on Freenode. The individual was primarily worried about memory usage, and these scripts confirm that strings will get garbage collected often and quickly.&lt;/p&gt;
&lt;p&gt;One thing to note is how Ruby 1.8 changes its thresholds for garbage collection under each environment, which may be based on the amount of objects in global space that it cannot garbage collect. Under Ruby 1.9, the results are bit more consistent, although this may be due to better metrics being available in Ruby 1.9.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/norbauer/code/~4/-RexnrNChFg" height="1" width="1"/&gt;</description>
      <pubDate>Sun, 15 Feb 2009 22:39:31 +0000</pubDate>
      <link>http://norbauer.com/notebooks/code/notes/garbage-collection-thresholds-in-ruby</link>
      <guid>http://norbauer.com/notebooks/code/notes/garbage-collection-thresholds-in-ruby</guid>
    </item>
    <item>
      <title>Now shipping internationally</title>
      <description>&lt;p&gt;By popular demand, we&amp;#8217;ve added shipping support for 32 additional countries to &lt;a href="http://rubyrags.com"&gt;RubyRags&lt;/a&gt;:&lt;/p&gt;
&lt;p style="text-align:center;"&gt;&lt;img src="http://norbauer.s3.amazonaws.com/6/rubyrags-shipping-map.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Our full country list is: Argentina, Australia, Austria, Belgium, Brazil, Canada, Denmark, Finland, France, Germany, Hungary, Iceland, India, Ireland, Italy, Japan, Luxembourg, Malaysia, Mexico, Netherlands, New Zealand, Norway, Poland, Portugal, Romania, Russian Federation, Singapore, Slovakia, Spain, Sweden, Switzerland, UK, &lt;span class="caps"&gt;USA&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;If your country isn&amp;#8217;t on the list, &lt;a href="http://norbauer.com/contact"&gt;contact us&lt;/a&gt; and let us know of your dissent!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/norbauer/code/~4/MFbJZ7X94dU" height="1" width="1"/&gt;</description>
      <pubDate>Sun, 15 Feb 2009 22:23:25 +0000</pubDate>
      <link>http://norbauer.com/notebooks/code/notes/now-shipping-internationally</link>
      <guid>http://norbauer.com/notebooks/code/notes/now-shipping-internationally</guid>
    </item>
    <item>
      <title>Remembering lighttpd, nginx, and the Internet as a pipe</title>
      <description>&lt;p&gt;We asked ourselves &lt;a href="/notebooks/code/notes/lighttpd-1-5-0-vaporware"&gt;a year ago&lt;/a&gt; if lighttpd 1.5.0 was vaporware. It seems that was nearly true. At that time, nginx, apache&amp;#8217;s mod_proxy_balancer, and haproxy were flourishing as Rails proxy solutions. The more recent introduction of Phusion Passenger (mod_rails) and Ruby Enterprise Edition, both excellent, free, and open-source products, has now driven most deployments (including our own) away from proxying altogether.&lt;/p&gt;
&lt;p&gt;There is&amp;#8212;or was&amp;#8212;generally two counter-arguments to Passenger. The first is the stability and performance argument, which is well understood and has been discussed at length. I believed it was well summarized by &lt;a href="http://blog.engineyard.com/2008/12/05/apache-passenger-vs-nginx-mongrel"&gt;Engine Yard&amp;#8217;s discussion on the topic.&lt;/a&gt; But this is not the argument I&amp;#8217;m not interested in.&lt;/p&gt;
&lt;p&gt;My early argument against mod_rails was complexity: first, by using Apache instead of a smaller, simpler web server, and second, using a platform that I don&amp;#8217;t comprehend and can&amp;#8217;t debug. This argument relates to an old article I wrote: that Rails applications&amp;#8212;and applications in general&amp;#8212;should &lt;a href="http://norbauer.com/notebooks/code/notes/acts_as_pipe-web"&gt;act like a pipe&lt;/a&gt;. (The original article, by James Duncan Davidson, is so old its only accessible through &lt;a href="http://web.archive.org/web/20060706054938/http://duncandavidson.com/essay/2006/06/webaspipe"&gt;archive.org&lt;/a&gt;). My presumption was that the same argument should apply to a 3rd-party mod_rails solution: I don&amp;#8217;t know anything about the app server, so if I have problems, I&amp;#8217;m screwed. How is this better than FastCGI?&lt;/p&gt;
&lt;p&gt;It is ironic, then, to note the success of Passenger in light of Rails&amp;#8217; history with FastCGI. The reason, as it turns out, basically comes down to two answers:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Passenger is easy to set up under Apache, and requires less configuration than under nginx&lt;/li&gt;
	&lt;li&gt;Passenger &lt;em&gt;always works&lt;/em&gt;, in my experience, and thus debugging problems is non-existent.&lt;/li&gt;
	&lt;li&gt;As a bonus, if you&amp;#8217;re using something like monit to ensure your app stays up, monitoring apache2 is a lot easier than individual mongrel processes.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So, better products are better, and users (including myself) will flock to them once they realize it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Future&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I do wonder, though, whether history will continue to repeat itself in this regard. Where will the next improvements be? What will be our theory (or justifications, as it seems to turn out) behind those improvements? Personally, I&amp;#8217;ve been &lt;a href="http://norbauer.com/notebooks/code/notes/why-threading-matters"&gt;eying threaded solutions&lt;/a&gt; for a long time, and given that mod_rails is a multi-process solution, perhaps threads will move things forward in the future. However, given that Ruby 1.9 is &lt;a href="http://www.igvita.com/2008/11/13/concurrency-is-a-myth-in-ruby/"&gt;still limited by the Global Interpreter Lock&lt;/a&gt;, we might not see a threaded answer for a while. The closest we&amp;#8217;ll come in the short term is JRuby. Could it be possible that JRuby is the future? Only time will tell.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/norbauer/code/~4/XNbI3hYrqd4" height="1" width="1"/&gt;</description>
      <pubDate>Sun, 15 Feb 2009 09:44:37 +0000</pubDate>
      <link>http://norbauer.com/notebooks/code/notes/remembering-lighttpd-nginx-and-the-internet-as-a-pipe</link>
      <guid>http://norbauer.com/notebooks/code/notes/remembering-lighttpd-nginx-and-the-internet-as-a-pipe</guid>
    </item>
    <item>
      <title>ls, colors, and Terminal.app</title>
      <description>&lt;p&gt;This isn&amp;#8217;t a Ruby thing but many of us spend a lot of time in Terminal.app, and I suspect few of you have taken the time to both enable colors and change your &lt;span class="caps"&gt;LSCOLORS&lt;/span&gt;, the setting which affects what colors &lt;code&gt;ls&lt;/code&gt; uses when in color mode.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Enable Colors in ls&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In order for ls to use colors at all, you need to set up an alias to turn colors on. To do this, open (or create) &lt;code&gt;.profile&lt;/code&gt; file in your home directory using your favorite text editor and add:&lt;/p&gt;
&lt;pre&gt;alias ls="ls -G"&lt;/pre&gt;
&lt;p&gt;Now open a new Terminal window and type &lt;code&gt;ls&lt;/code&gt;. You will see colors, hurray!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Make Colors Linux-like&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re used to Linux-like colors, you will appreciate this setting. This is what I use and it works particularly well on dark Terminal backgrounds (I use the &amp;#8220;Pro&amp;#8221; theme). I also check off &amp;#8220;Use bright colors for bold text&amp;#8221; under Terminal &amp;gt; Preferences &amp;gt; Settings. Again, add this to your &lt;code&gt;.profile&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;export LSCOLORS="ExGxBxDxCxEgEdxbxgxcxd"&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Customize Your Colors&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The values in &lt;span class="caps"&gt;LSCOLORS&lt;/span&gt; are codes corresponding to different colors for different types of files. The letter you use indicates which color to use, and the position in the string indicates what type of file should be that color. Each color comes in pairs &amp;#8211; a foreground color and a background color. Here is a list of color values:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;a = black&lt;/li&gt;
	&lt;li&gt;b = red&lt;/li&gt;
	&lt;li&gt;c = green&lt;/li&gt;
	&lt;li&gt;d = brown&lt;/li&gt;
	&lt;li&gt;e = blue&lt;/li&gt;
	&lt;li&gt;f = magenta&lt;/li&gt;
	&lt;li&gt;g = cyan&lt;/li&gt;
	&lt;li&gt;h = grey&lt;/li&gt;
	&lt;li&gt;A = dark grey&lt;/li&gt;
	&lt;li&gt;B = bold red&lt;/li&gt;
	&lt;li&gt;C = bold green&lt;/li&gt;
	&lt;li&gt;D = yellow&lt;/li&gt;
	&lt;li&gt;E = bold blue&lt;/li&gt;
	&lt;li&gt;F = magenta&lt;/li&gt;
	&lt;li&gt;G = cyan&lt;/li&gt;
	&lt;li&gt;H = white&lt;/li&gt;
	&lt;li&gt;x = default&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And here is a list of the positions in &lt;span class="caps"&gt;LSCOLORS&lt;/span&gt;:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;directory&lt;/li&gt;
	&lt;li&gt;symbolic link&lt;/li&gt;
	&lt;li&gt;socket&lt;/li&gt;
	&lt;li&gt;pipe&lt;/li&gt;
	&lt;li&gt;executable&lt;/li&gt;
	&lt;li&gt;block device&lt;/li&gt;
	&lt;li&gt;character device&lt;/li&gt;
	&lt;li&gt;executable with setuid set&lt;/li&gt;
	&lt;li&gt;executable with setguid set&lt;/li&gt;
	&lt;li&gt;directory writable by others, with sticky bit&lt;/li&gt;
	&lt;li&gt;directory writable by others, without sticky bit&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The default is &amp;#8220;exfxcxdxbxegedabagacad&amp;#8221;, which indicates blue foreground with default background for directories, magenta foreground with default background for symbolic links, etc.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/norbauer/code/~4/QQrfIMKay0I" height="1" width="1"/&gt;</description>
      <pubDate>Sat, 14 Jun 2008 21:12:21 +0000</pubDate>
      <link>http://norbauer.com/notebooks/code/notes/ls-colors-and-terminal-app</link>
      <guid>http://norbauer.com/notebooks/code/notes/ls-colors-and-terminal-app</guid>
    </item>
    <item>
      <title>Interview on the Ruby on Rails podcast.</title>
      <description>&lt;p&gt;The &lt;a href="http://podcast.rubyonrails.org"&gt;interview&lt;/a&gt; I did with the incredibly gracious and awesome &lt;a href="http://topfunky.com"&gt;Geoffrey Grosenbach&lt;/a&gt; (of Peepcasts) on the official Ruby on Rails podcast just went up.&lt;/p&gt;
&lt;p&gt;I talk a little bit about &lt;a href="http://norbauer.com"&gt;consulting at Norbauer Inc&lt;/a&gt;, a bit about &lt;a href="http://rubyrags.com"&gt;RubyRags&lt;/a&gt;, and I spend a bit of time kicking social networks in the nuts.&lt;/p&gt;
&lt;p&gt;Incidentally, I&amp;#8217;m proud to announce that we&amp;#8217;re now selling Peepcode shirts at RubyRags:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://rubyrags.com" style="margin:1px solid #ccc;padding:5px"&gt;&lt;img src="http://rubyrags.com/pictures/0000/0057/peepcode-tshirt.png" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/norbauer/code/~4/QsR8B5dgyFY" height="1" width="1"/&gt;</description>
      <pubDate>Sat, 03 May 2008 02:29:31 +0000</pubDate>
      <link>http://norbauer.com/notebooks/code/notes/interview-on-the-ruby-on-rails-podcast</link>
      <guid>http://norbauer.com/notebooks/code/notes/interview-on-the-ruby-on-rails-podcast</guid>
    </item>
    <item>
      <title>Alternative Ruby Implementations</title>
      <description>&lt;p&gt;Sorry to just link drop on ya&amp;#8217;ll, but if you haven&amp;#8217;t seen it, Charles Nutter of the JRuby team has published a writeup titled &lt;a href="http://headius.blogspot.com/2008/04/promise-and-peril-for-alternative-ruby.html"&gt;Promise and Perils for Alternative Ruby Impls&lt;/a&gt;. It provides an excellent analysis of 1.8, 1.9, JRuby, Rubinius, and the other Ruby interpreter projects out there, if only slightly biased for JRuby (understandably). If you have an interest in the future of Ruby, it is a recommended read.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/norbauer/code/~4/LYc_ZN8fR80" height="1" width="1"/&gt;</description>
      <pubDate>Mon, 28 Apr 2008 20:17:03 +0000</pubDate>
      <link>http://norbauer.com/notebooks/code/notes/alternative-ruby-implementations</link>
      <guid>http://norbauer.com/notebooks/code/notes/alternative-ruby-implementations</guid>
    </item>
    <item>
      <title>Rails 2.0 development finally meets Web 2.0</title>
      <description>&lt;p&gt;I know I am late to the show, but I&amp;#8217;d just like to say it is about time that Rails move off of Trac &amp;#8211; with the move to &lt;a href="http://weblog.rubyonrails.com/2008/4/15/rails-and-family-on-lighthouse"&gt;Lighthouse&lt;/a&gt; and &lt;a href="http://weblog.rubyonrails.com/2008/4/11/rails-premieres-on-github"&gt;Github&lt;/a&gt;, Rails development itself is now hosted on awesome Rails-based services. I know such migrations are not easy for such a large project so I just want to say thanks to the Rails team, and nice choices!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/norbauer/code/~4/P5MPN_AybnU" height="1" width="1"/&gt;</description>
      <pubDate>Sat, 19 Apr 2008 04:16:11 +0000</pubDate>
      <link>http://norbauer.com/notebooks/code/notes/rails-2-0-development-finally-meets-web-2-0</link>
      <guid>http://norbauer.com/notebooks/code/notes/rails-2-0-development-finally-meets-web-2-0</guid>
    </item>
    <item>
      <title>Strange analogy</title>
      <description>&lt;p&gt;Creating software is like eating a grapefruit (&lt;a href="http://xkcd.com/388/"&gt;Randall Munroe&amp;#8217;s favorite fruit&lt;/a&gt;). Sure, you can rush through it and you&amp;#8217;ll get some enjoyment out of the grapefruit bits, but if you take your time and patience, you will get much more out of it. Like all things, you reap what you sow.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/norbauer/code/~4/xgmo_rkiUAo" height="1" width="1"/&gt;</description>
      <pubDate>Thu, 17 Apr 2008 15:36:32 +0000</pubDate>
      <link>http://norbauer.com/notebooks/code/notes/strange-analogy</link>
      <guid>http://norbauer.com/notebooks/code/notes/strange-analogy</guid>
    </item>
    <item>
      <title>Gitsplosion</title>
      <description>&lt;p&gt;So Git has this charming habit of leaving directories intact when you use it to delete their content.  If you try to delete, say, vendor/rails, it will therefore leave a barren ghost-town of &lt;span class="caps"&gt;EDGE&lt;/span&gt; directories intact.&lt;/p&gt;
&lt;p&gt;This will cause the following, not-particularly-elucidating error whenever you try to do anything:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;
(in /Users/ryan/Sites/app_name)
rake aborted!
no such file to load -- /blah/blah/lib/initializer
/Users/ryan/Sites/app_name/rakefile:4
(See full trace by running task with --trace)
&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The solution is just a simple, friendly:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;rm -rf vendor/rails&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Then you&amp;#8217;ll be able to freeze again, and whatnot.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span class="caps"&gt;UPDATE&lt;/span&gt;&lt;/strong&gt; I have submitted &lt;a href="http://dev.rubyonrails.org/ticket/11590"&gt;a patch&lt;/a&gt; to Rails to make it less dumb about this (and actually check that Rails really exists rather than just checking for its directories.)  If you think this is a worthwhile patch, please go put a +1 in the ticket comments.&lt;/p&gt;
&lt;p&gt;Then once we can set it to &amp;#8220;Verified,&amp;#8221; maybe it&amp;#8217;ll be accepted in three years, just in time for Git to be supplanted by some other new nerd bauble.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/norbauer/code/~4/tYyESbJE5pE" height="1" width="1"/&gt;</description>
      <pubDate>Sat, 12 Apr 2008 22:44:20 +0000</pubDate>
      <link>http://norbauer.com/notebooks/code/notes/git-exploding-your-vendor-rails</link>
      <guid>http://norbauer.com/notebooks/code/notes/git-exploding-your-vendor-rails</guid>
    </item>
    <item>
      <title>Yet another Ruby framework and HTTP adapter</title>
      <description>&lt;p&gt;It&amp;#8217;s an exciting time to be Ruby or Rails developer as there are so many new and exciting things going on &amp;#8211; in fact, it&amp;#8217;s a lot to keep tabs on. Let&amp;#8217;s look at two issues: Ruby web frameworks and &lt;span class="caps"&gt;HTTP&lt;/span&gt; adapters.&lt;/p&gt;
&lt;p&gt;So, web frameworks, some of these you&amp;#8217;ve probably heard of:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.rubyonrails.org"&gt;Ruby on Rails&lt;/a&gt; &amp;#8211; You&amp;#8217;ve probably heard of this one.&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://camping.rubyforge.org/"&gt;Camping&lt;/a&gt; has been around for a while, and aims to be tiny and simple &amp;#8211; great when you&amp;#8217;re only building a few pages. Developed by the infamous &lt;a href="http://whytheluckystiff.net/"&gt;why&lt;/a&gt;.&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://merbivore.com/"&gt;Merb&lt;/a&gt; was created by &lt;a href="http://brainspl.at"&gt;Ezra&lt;/a&gt;, which now has many of the core Rails features, but less of the frills. It&amp;#8217;s fast and, &lt;a href="http://rubyjudo.com/2007/6/6/why-threading-matters"&gt;best of all, its thread-safe&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But, oh, there are so many more:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.nitroproject.org/"&gt;Nitro&lt;/a&gt; &amp;#8211; Been around a while now, but development stalled for a year or two.&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://rubywaves.com/"&gt;Ruby Waves&lt;/a&gt;, which claims to be highly flexible.&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://wuby.org/"&gt;Wuby&lt;/a&gt;, a tiny server+framework, which serves &lt;span class="caps"&gt;RHTML&lt;/span&gt; files, in a manner similar to &lt;span class="caps"&gt;PHP&lt;/span&gt;.&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://sinatrarb.com/"&gt;Sinatra&lt;/a&gt;, a &lt;span class="caps"&gt;REST&lt;/span&gt;-centric framework which uses a &lt;a href="http://en.wikipedia.org/wiki/Domain-specific_programming_language"&gt;&lt;span class="caps"&gt;DSL&lt;/span&gt;&lt;/a&gt; to make life simpler.&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://ramaze.net/"&gt;Ramaze&lt;/a&gt;, which is also very flexible, supporting a variety of ORMs, template engines, &lt;span class="caps"&gt;HTTP&lt;/span&gt; adapters, etc.&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://www.mackframework.com/"&gt;Mack&lt;/a&gt; is brand new, claiming to be highly modular and agile, as well as speedy. Their site is down but their &lt;a href="http://api.mackframework.com/"&gt;documentation&lt;/a&gt; is up.&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://maveric.rubyforge.org/"&gt;Maveric&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://vintage.devjavu.com/"&gt;Vintage&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://cerise.rubyforge.org/"&gt;Cerise&lt;/a&gt; &amp;#8211; Not recently maintained (2006).&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://enigo.com/projects/iowa/index.html"&gt;&lt;span class="caps"&gt;IOWA&lt;/span&gt;&lt;/a&gt; &amp;#8211; Not recently maintained (2004).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&amp;#8217;m sure I still missed some. Moving on the &lt;span class="caps"&gt;HTTP&lt;/span&gt; adapters &amp;#8211; these are the likes of WEBrick and Mongrel. It&amp;#8217;s good to keep up on these as they can often mean a boost in performance for your app, often regardless of your framework, thanks to the common interface provided by the &lt;a href="http://rack.rubyforge.org/"&gt;Rack library&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://ebb.rubyforge.org"&gt;Ebb&lt;/a&gt; is the newest to the show, touting fantastic performance as most of it is written in C. It can be a little tough to set up. It has support for Rails; for other frameworks, you&amp;#8217;ll have to roll your own interface.&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://code.macournoyer.com/thin/"&gt;Thin&lt;/a&gt; is quickly becoming the defacto standard (at least until ebb is further along)&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://swiftiply.swiftcore.org/mongrel.html"&gt;Swiftiply and Evented Mongrel&lt;/a&gt; was the first to improve Mongrel&amp;#8217;s performance.&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://mongrel.rubyforge.org/"&gt;Mongrel&lt;/a&gt; started it all.&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://fuzed.rubyforge.org/"&gt;Fuzed&lt;/a&gt; allows your Rails app to run with &lt;a href="http://yaws.hyber.org/"&gt;Yaws&lt;/a&gt;.&lt;/li&gt;
	&lt;li&gt;&lt;a href="http://www.modrails.com/"&gt;Passenger&lt;/a&gt; is &amp;#8220;mod_rails&amp;#8221; for Apache, which could be a big news. They are also working on &lt;a href="http://www.rubyenterpriseedition.com/"&gt;Ruby Enterprise Edition&lt;/a&gt;, which will be launched soon.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And you have already learned and adopted &lt;a href="http://git.or.cz/"&gt;git&lt;/a&gt;, right? Can&amp;#8217;t fall behind the times&amp;#8230;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/norbauer/code/~4/ssXZ2zN1D18" height="1" width="1"/&gt;</description>
      <pubDate>Sat, 12 Apr 2008 10:49:36 +0000</pubDate>
      <link>http://norbauer.com/notebooks/code/notes/yet-another-ruby-framework-and-http-adapter</link>
      <guid>http://norbauer.com/notebooks/code/notes/yet-another-ruby-framework-and-http-adapter</guid>
    </item>
    <item>
      <title>git: revert (reset) a single file</title>
      <description>&lt;p&gt;This one is hard to find out there so here it is. If you have an &lt;strong&gt;uncommitted&lt;/strong&gt; change (its only in your working copy) that you wish to revert (in &lt;span class="caps"&gt;SVN&lt;/span&gt; terms) to the copy in your latest commit, do the following:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git checkout filename&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This will checkout the file from &lt;span class="caps"&gt;HEAD&lt;/span&gt;, overwriting your change. This command is also used to checkout branches, and you could happen to have a file with the same name as a branch. All is not lost, you will simply need to type:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git checkout -- filename&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;You can also do this with files from other branches, and such. &lt;code&gt;man git-checkout&lt;/code&gt; has the details.&lt;/p&gt;
&lt;p&gt;The rest of the Internet will tell you to use &lt;code&gt;git reset --hard&lt;/code&gt;, but this resets &lt;strong&gt;all&lt;/strong&gt; uncommitted changes you&amp;#8217;ve made in your working copy. Type this with care.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/norbauer/code/~4/Tio8NU5QgtM" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 08 Apr 2008 07:38:10 +0000</pubDate>
      <link>http://norbauer.com/notebooks/code/notes/git-revert-reset-a-single-file</link>
      <guid>http://norbauer.com/notebooks/code/notes/git-revert-reset-a-single-file</guid>
    </item>
    <item>
      <title>Generating access keys</title>
      <description>&lt;p&gt;This is a somewhat obscure but very efficient way to generate access keys. Look ma, no loops!&lt;/p&gt;
&lt;p&gt;&lt;code lang="ruby"&gt;Array.new(16) { rand(256) }.pack('C*').unpack('H*').first&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This will generate a 32-length key, like &lt;code&gt;b3512f4972d314da94380e1a70e6814a&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This may look strange unless you&amp;#8217;ve used &lt;a href="http://www.ruby-doc.org/core/classes/Array.src/M002173.html"&gt;Array.new&lt;/a&gt;, &lt;a href="http://www.ruby-doc.org/core/classes/Array.src/M002245.html"&gt;Array#pack&lt;/a&gt;, and &lt;a href="http://www.ruby-doc.org/core/classes/String.src/M000775.html"&gt;String#unpack&lt;/a&gt; many times in the past. In the gaming world, I tended to deal with binary data on a regular basis, so &lt;code&gt;pack&lt;/code&gt; and &lt;code&gt;unpack&lt;/code&gt; became commonly-used weapons in my repertoire. They allow you to operate on binary data &amp;#8211; pack creates binary data (stored in a regular string) from an array of Ruby objects, and unpack takes binary data and creates Ruby objects in an array. If you think about it, you are dealing with binary data here: you&amp;#8217;re creating a random 128-bit (16-byte) key which you want in hex-format, so using pack and unpack do make sense. The parameters (&lt;code&gt;C*&lt;/code&gt; and &lt;code&gt;H*&lt;/code&gt;, in this case), are formats which indicate how to process the data.&lt;/p&gt;
&lt;p&gt;Very cool cats may want to create more-compact Base64 keys. Be aware that Base64 is case sensitive:&lt;/p&gt;
&lt;p&gt;&lt;code lang="ruby"&gt;[ Array.new(16) { rand(256) }.pack('C*') ].pack('m').chop&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This generates keys like &lt;code&gt;Gv5CJ68ptOZKVRvAFdzGpg==&lt;/code&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/norbauer/code/~4/OFsv2d3dFjk" height="1" width="1"/&gt;</description>
      <pubDate>Sun, 06 Apr 2008 09:15:49 +0000</pubDate>
      <link>http://norbauer.com/notebooks/code/notes/generating-access-keys</link>
      <guid>http://norbauer.com/notebooks/code/notes/generating-access-keys</guid>
    </item>
  </channel>
</rss>
