<?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 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Mike Perham</title>
	
	<link>http://www.mikeperham.com</link>
	<description>On Ruby, software and the Internet</description>
	<lastBuildDate>Sat, 31 Dec 2011 04:32:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/mikeperham" /><feedburner:info uri="mikeperham" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Getting iChat to automatically reconnect</title>
		<link>http://feedproxy.google.com/~r/mikeperham/~3/fw6t-mAJHmo/</link>
		<comments>http://www.mikeperham.com/2011/12/30/getting-ichat-to-automatically-reconnect/#comments</comments>
		<pubDate>Sat, 31 Dec 2011 04:32:50 +0000</pubDate>
		<dc:creator>Mike Perham</dc:creator>
				<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.mikeperham.com/?p=757</guid>
		<description><![CDATA[I&#8217;ve noticed a problem with iChat for the last year or two: if your network drops, you stay Disconnected until you manually tell iChat to log back in. That&#8217;s pretty lame, my Comcast cable drops several times a day so I need something a little more robust than that. I found a workaround: use cron [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve noticed a problem with iChat for the last year or two: if your network drops, you stay Disconnected until you manually tell iChat to log back in.  That&#8217;s pretty lame, my Comcast cable drops several times a day so I need something a little more robust than that.  I found a workaround: use cron to do the work for you. Fire up a Terminal, run <code>crontab -e</code> and put this in it:</p>
<pre>
*/5 * * * * osascript -e 'tell application "System Events" to if (processes whose name is "iChat") exists then tell application "iChat" to log in'
</pre>
<p>This uses AppleScript to tell iChat to log in every 5 minutes.  Now if the network drops, you&#8217;ll only be disconnected a few minutes.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikeperham.com/2011/12/30/getting-ichat-to-automatically-reconnect/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.mikeperham.com/2011/12/30/getting-ichat-to-automatically-reconnect/</feedburner:origLink></item>
		<item>
		<title>Optimizing Heroku</title>
		<link>http://feedproxy.google.com/~r/mikeperham/~3/_Smo9N0BHT0/</link>
		<comments>http://www.mikeperham.com/2011/06/01/optimizing-heroku/#comments</comments>
		<pubDate>Wed, 01 Jun 2011 23:02:11 +0000</pubDate>
		<dc:creator>Mike Perham</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.mikeperham.com/?p=745</guid>
		<description><![CDATA[I spent some time recently playing with a trivial Rails 3 app using girl_friday and learned a few interesting things: Michael&#8217;s post on using Unicorn with Heroku is a fantastic idea and great way to improve the efficiency of your Heroku application&#8217;s web dynos. Heroku imposes a limit of 15 threads per Ruby process (there [...]]]></description>
			<content:encoded><![CDATA[<p>I spent some time recently playing with a trivial Rails 3 app using <a href="http://mperham.github.com/girl_friday">girl_friday</a> and learned a few interesting things:</p>
<ul>
<li>Michael&#8217;s post on <a href="http://michaelvanrooijen.com/articles/2011/06/01-more-concurrency-on-a-single-heroku-dyno-with-the-new-celadon-cedar-stack/">using Unicorn with Heroku</a> is a fantastic idea and great way to improve the efficiency of your Heroku application&#8217;s web dynos.</li>
<li>Heroku imposes a limit of 15 threads per Ruby process (there is an open question about this, it might just be a bug in the Heroku Cedar stack, which is still beta).  If you are using thin, you get 1 process and 15 threads per dyno.  If you are using Unicorn, you get 3 processes<sup>*</sup> and 45 threads.</li>
<li>girl_friday defaults to 5 threads per queue.  With the thread limit on Heroku, you&#8217;ll want to carefully ration the size of each queue.  girl_friday&#8217;s Rack status app can tell you at runtime which queues are busy and which are quiet for tuning purposes.</li>
<li>girl_friday can, in many cases, replace or dramatically reduce your need for separate worker dynos, saving you money.</li>
</ul>
<p>* Where 3 is based on the memory consumption of your application.  YMMV.</p>
<p>Unicorn appears to work great with girl_friday and Heroku&#8217;s free service level actually becomes useful for non-trivial applications with these optimizations.  Know any other tips?  Let me know!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikeperham.com/2011/06/01/optimizing-heroku/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://www.mikeperham.com/2011/06/01/optimizing-heroku/</feedburner:origLink></item>
		<item>
		<title>Threads Fibers Events and Actors</title>
		<link>http://feedproxy.google.com/~r/mikeperham/~3/2s5wglMKymk/</link>
		<comments>http://www.mikeperham.com/2011/05/19/threads-fibers-events-and-actors/#comments</comments>
		<pubDate>Fri, 20 May 2011 02:37:43 +0000</pubDate>
		<dc:creator>Mike Perham</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.mikeperham.com/?p=738</guid>
		<description><![CDATA[I presented (from 3000 miles away!) today at EMRubyConf. My talk, &#8220;Threads Fibers Events and Actors&#8220;, is a short 13min chat on current trends in Ruby scalability and concurrency. To summarize: Ruby&#8217;s threading has historically been terrible. So we turned to event-based systems like EventMachine but the reactor pattern brings its own set of drawbacks. [...]]]></description>
			<content:encoded><![CDATA[<p>I presented (from 3000 miles away!) today at <a href="//emrubyconf.com">EMRubyConf</a>.  My talk, &#8220;<a href="http://vimeo.com/23933313">Threads Fibers Events and Actors</a>&#8220;, is a short 13min chat on current trends in Ruby scalability and concurrency.  To summarize:</p>
<p>Ruby&#8217;s threading has historically been terrible.  So we turned to event-based systems like EventMachine but the reactor pattern brings its own set of drawbacks.  So we turned to Fibers to solve some of those problems but they bring along another set of drawbacks.  In the end though, all of this is a workaround for Ruby&#8217;s historically terrible threading implementation.  But what if Ruby&#8217;s threading didn&#8217;t suck?</p>
<p>JRuby has great threads.  Rubinius will soon have great threads.  Both have really matured into excellent, stable runtimes over the last year.  Make no mistake threads have issues too; locks and race conditions are notoriously hard to write well and Ruby code can&#8217;t be autoloaded safely in a multithreaded system.  The former is what Actors attempt to solve: making concurrency simpler and safer by passing messages rather than sharing mutable state and requiring locks.</p>
<p>I think the Ruby community needs to give threads another chance: ensure their gems are thread-safe and use Actors when needing to write safe multithreaded code.  <a href="https://github.com/tarcieri/celluloid">Celluloid</a> and the <a href="http://rubini.us/doc/en/systems/concurrency/">Rubinius Actor API</a> are two APIs which provide Actors to Ruby. My new gem <a href="http://mperham.github.com/girl_friday">girl_friday</a> leverages actors for safe concurrency.  The autoloading problem is the only hard problem remaining; I hope some time and effort can determine ways around this issue.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikeperham.com/2011/05/19/threads-fibers-events-and-actors/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		<feedburner:origLink>http://www.mikeperham.com/2011/05/19/threads-fibers-events-and-actors/</feedburner:origLink></item>
		<item>
		<title>Background Processing vs Message Queueing</title>
		<link>http://feedproxy.google.com/~r/mikeperham/~3/hu5VkcoKGtY/</link>
		<comments>http://www.mikeperham.com/2011/05/04/background-processing-vs-message-queueing/#comments</comments>
		<pubDate>Wed, 04 May 2011 21:28:47 +0000</pubDate>
		<dc:creator>Mike Perham</dc:creator>
				<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.mikeperham.com/?p=726</guid>
		<description><![CDATA[One common simplification I see engineers make is equating message queueing with background processing. This is what they are missing: message queueing is a superset of background processing. All message processing is done in the background but background processing does not have to be done via message queues. Take a simple use case: &#8220;I want [...]]]></description>
			<content:encoded><![CDATA[<p>One common simplification I see engineers make is equating message queueing with background processing.  This is what they are missing: <strong>message queueing is a superset of background processing</strong>.  All message processing is done in the background but background processing does not have to be done via message queues.  </p>
<p>Take a simple use case: &#8220;I want to send a welcome email when a user registers&#8221;.  Commonly you want to send this email in the background so it does not impact the user&#8217;s experience.  Do you need to install ActiveMQ, RabbitMQ or Resque to do this?  Certainly not.</p>
<p>Message queueing is a fundamental architectural pattern when building complex systems.  Your various system components might be written by different teams but they communicate through messages sent via queues.  One component can send a message to another component, saying &#8220;please send this email&#8221;.  But message queueing systems have their cost: they are complex because they are designed to be the foundation of your distributed system.  They must be deployed and monitored like the rest of your infrastructure; they must be reliable and highly available.</p>
<p>I think that a lot of people install a message queue to perform simple background processing; it doesn&#8217;t need to be that complicated.  The fundamental question to me is, &#8220;Am I communicating between different subsystems or just trying to spin off some work?&#8221;  The registration email use case comes up almost immediately when building nearly every website.  Consider also the case where you want to perform some action that might take 30-60 seconds and have the user&#8217;s browser poll for the result.  Spinning off a separate thread to perform this work is entirely sufficient and much simpler.  This is the reasoning behind my <a href="https://github.com/mperham/girl_friday">girl_friday</a> project.  I want a simple and reliable way to perform background processing without needing the complexity of an MQ system.  Let&#8217;s examine a few characteristics of girl_friday:</p>
<ul>
<li>In-process &#8211; your background processor is part of your Ruby application and has access to the exact same codebase as your webapp.  No need to share ActiveRecord models across projects via git or filesystem trickery.  No need to deploy or monitor a separate set of processes.</li>
<li>Threaded &#8211; huge memory savings because you don&#8217;t have to spin up other processes which load the exact same code.  Threads are notoriously tricky to get correct so girl_friday uses Actors for the equivalent behavior in a simpler and safer API.</li>
</ul>
<p>I have issues with the other contenders in the space:</p>
<ul>
<li>delayed_job &#8211; stores jobs in your RDBMS and polls for jobs which is a terribly unscalable idea.  Spins off processes instead of threads.</li>
<li>resque &#8211; forks a new process for every message.  Safe but memory hungry.</li>
</ul>
<p>The biggest caveat with girl_friday is threading, of course.  Typical Ruby deployments aren&#8217;t thread-friendly but I&#8217;d like to help change that.  Rainbows! is thread-friendly, as are all the JRuby app servers.  The <a href="http://github.com/mperham/girl_friday/wiki">girl_friday wiki</a> gives more specifics about features and usage.  Are there any other dimensions to the problem that I&#8217;m missing?  Any other projects that solve a similar problem?  Post a comment and let me know!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikeperham.com/2011/05/04/background-processing-vs-message-queueing/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://www.mikeperham.com/2011/05/04/background-processing-vs-message-queueing/</feedburner:origLink></item>
		<item>
		<title>Actors and Ruby</title>
		<link>http://feedproxy.google.com/~r/mikeperham/~3/DOU_biwE5OQ/</link>
		<comments>http://www.mikeperham.com/2011/04/23/actors-and-ruby/#comments</comments>
		<pubDate>Sat, 23 Apr 2011 22:58:04 +0000</pubDate>
		<dc:creator>Mike Perham</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.mikeperham.com/?p=721</guid>
		<description><![CDATA[I&#8217;ve spent the last month learning Rubinius&#8217;s Actor API for safer concurrency with threads. My entire career really has been focused on learning and building scalable and high performance infrastructure. My explorations with Fibers over the last year lead me to believe that they are essentially a workable hack to get around Ruby&#8217;s current issues [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve spent the last month learning Rubinius&#8217;s Actor API for safer concurrency with threads.  My entire career really has been focused on learning and building scalable and high performance infrastructure.  My explorations with Fibers over the last year lead me to believe that they are essentially a workable hack to get around Ruby&#8217;s current issues but not really something that developers should use widely.  Debugging is difficult and testing very difficult with any reactor-based system.</p>
<p>On the other hand, I do think Actors are a good step forward for concurrency by making Threads safer to utilize.  By the end of this year, we&#8217;ll have several Ruby VMs (JRuby, MacRuby, Rubinius) that can execute threads in parallel, allowing a single Ruby process to peg a multi-core machine; Actors will be helpful in building applications that can take advantage of this.</p>
<p>I&#8217;ve written two posts on the <a href="http://blog.carbonfive.com">Carbon Five</a> blog, the first covering <a href="http://blog.carbonfive.com/2011/04/19/concurrency-with-actors/">Actors in general</a> and the second covering my new, simple but full-featured <a href="http://blog.carbonfive.com/2011/04/20/asynchronous-processing-with-girl_friday/">asynchronous processing library, girl_friday</a>, which leverages Actors.  Take a look and let me know what you think!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikeperham.com/2011/04/23/actors-and-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.mikeperham.com/2011/04/23/actors-and-ruby/</feedburner:origLink></item>
		<item>
		<title>Node.js Roundup</title>
		<link>http://feedproxy.google.com/~r/mikeperham/~3/U8sEK64TCHA/</link>
		<comments>http://www.mikeperham.com/2011/03/18/node-js-roundup/#comments</comments>
		<pubDate>Fri, 18 Mar 2011 23:51:37 +0000</pubDate>
		<dc:creator>Mike Perham</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.mikeperham.com/?p=716</guid>
		<description><![CDATA[I just finished a three-part series of blog posts on Node.js over on the Carbon Five blog. JavaScript and Node are very different from Ruby and EventMachine, providing me lots to learn over the course of the last few weeks. Take a look; I hope you learn something too! Node.js, Part I: Overview Node.js, Part [...]]]></description>
			<content:encoded><![CDATA[<p>I just finished a three-part series of blog posts on Node.js over on the Carbon Five blog.  JavaScript and Node are very different from Ruby and EventMachine, providing me lots to learn over the course of the last few weeks.  Take a look; I hope you learn something too!</p>
<ul>
<li><a href="http://blog.carbonfive.com/2011/03/09/node-js-overview/">Node.js, Part I: Overview</a></li>
<li><a href="http://blog.carbonfive.com/2011/03/14/node-js-part-ii-spelunking-in-the-code/">Node.js, Part II: Spelunking in the Code</a></li>
<li><a href="http://blog.carbonfive.com/2011/03/18/node-js-part-iii-full-stack-application/">Node.js, Part III: Full Stack Application</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.mikeperham.com/2011/03/18/node-js-roundup/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.mikeperham.com/2011/03/18/node-js-roundup/</feedburner:origLink></item>
		<item>
		<title>The Dangers of Shortcuts</title>
		<link>http://feedproxy.google.com/~r/mikeperham/~3/5MbJVyZpXXE/</link>
		<comments>http://www.mikeperham.com/2011/03/01/the-dangers-of-shortcuts/#comments</comments>
		<pubDate>Tue, 01 Mar 2011 17:40:30 +0000</pubDate>
		<dc:creator>Mike Perham</dc:creator>
				<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.mikeperham.com/?p=704</guid>
		<description><![CDATA[MongoDB has amazing write performance. Node.js has great I/O concurrency. Telehash is an extremely efficient wire protocol. All three of these systems have a common theme: they take a shortcut in order to provide a leap in performance over existing systems. In MongoDB&#8217;s case, they don&#8217;t provide true durability so writes can be batched into [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://mongodb.org/">MongoDB</a> has amazing write performance.  <a href="http://nodejs.org/">Node.js</a> has great I/O concurrency.  <a href="http://www.telehash.org/">Telehash</a> is an extremely efficient wire protocol.  All three of these systems have a common theme: they take a shortcut in order to provide a leap in performance over existing systems.</p>
<ul>
<li>In MongoDB&#8217;s case, they don&#8217;t provide true durability so writes can be batched into a large set of writes when actually persisting to disk.  This gets them great performance but means they don&#8217;t provide true ACID transactions.  Side note: the latest release has a new <code>--dur</code> flag which gives true durability with the resultant loss in write performance.</li>
<li>For Node.js, the trade-off is in programming style: everything is done asynchronously so you have to learn an entirely new style of programming.  Great performance but great developer learning curve.</li>
<li>With Telehash, UDP is a more efficient network protocol than TCP by design.  TCP is essentially UDP with reliable delivery baked on top, so it suffers from round trip latency and the state required to track the current network packets in flight in order to ensure delivery.  You can use UDP but if a router drops a UDP packet, your application will never know.</li>
</ul>
<p>When you are looking at a new system that promises better performance or scalability than existing systems, ask yourself &#8220;what shortcuts did they take to get that performance or scalability?&#8221;  <strong>Sometimes those shortcuts are worth it but it is completely dependent on your own situation.</strong>  If you are writing a small, high-traffic network service, Node.js makes sense.  Writing a high volume of low-priority logging data with MongoDB makes sense.  I would argue there are very few instances where UDP is a good idea, realtime data streaming is the best case I can think of, off hand.  Part of being an engineer is learning when these shortcuts are unreasonable and what you are paying for that shortcut.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikeperham.com/2011/03/01/the-dangers-of-shortcuts/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.mikeperham.com/2011/03/01/the-dangers-of-shortcuts/</feedburner:origLink></item>
		<item>
		<title>Filling out PDF forms with JRuby</title>
		<link>http://feedproxy.google.com/~r/mikeperham/~3/5KpB0ZH6JQI/</link>
		<comments>http://www.mikeperham.com/2011/02/15/filling-out-pdf-forms-with-jruby/#comments</comments>
		<pubDate>Tue, 15 Feb 2011 21:10:25 +0000</pubDate>
		<dc:creator>Mike Perham</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.mikeperham.com/?p=699</guid>
		<description><![CDATA[I recently had to figure out how to programmatically fill out a PDF based on the form input from a Rails application. It looks like there&#8217;s nothing native to Ruby but there is a comprehensive PDF library called iText which will handle form duties. Using JRuby, we can access their Java API to fill out [...]]]></description>
			<content:encoded><![CDATA[<p>I recently had to figure out how to programmatically fill out a PDF based on the form input from a Rails application.  It looks like there&#8217;s nothing native to Ruby but there is a comprehensive PDF library called <a href="http://api.itextpdf.com/">iText</a> which will handle <a href="http://itextpdf.com/themes/keyword.php?id=247">form</a> duties.  Using JRuby, we can access their Java API to fill out the form pretty easily:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'java'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'iText-5.0.6.jar'</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">module</span> Pdf
  include_package <span style="color:#996600;">&quot;com.itextpdf.text.pdf&quot;</span>
  include_package <span style="color:#996600;">&quot;java.io&quot;</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">write</span>
    reader = PdfReader.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'application.pdf'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;
    stamper = PdfStamper.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>reader, FileOutputStream.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'completed.pdf'</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    form = stamper.<span style="color:#9900CC;">acro_fields</span>
    <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Form has these fields: #{form.fields.key_set.to_a}&quot;</span>
    form.<span style="color:#9900CC;">set_field</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;some_zipcode_field&quot;</span>, <span style="color:#996600;">&quot;94115&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    stamper.<span style="color:#9900CC;">close</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
Pdf.<span style="color:#9900CC;">write</span></pre></div></div>

<p>Obviously sample code, not production quality, etc.  Really the only hard/tedious part is mapping field names to Ruby object attribute values.  If you have a complex form, you may have tens or even hundreds of <code>set_field</code> calls.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikeperham.com/2011/02/15/filling-out-pdf-forms-with-jruby/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://www.mikeperham.com/2011/02/15/filling-out-pdf-forms-with-jruby/</feedburner:origLink></item>
		<item>
		<title>Moving On</title>
		<link>http://feedproxy.google.com/~r/mikeperham/~3/cFjiQFohqBQ/</link>
		<comments>http://www.mikeperham.com/2010/12/27/moving-on/#comments</comments>
		<pubDate>Mon, 27 Dec 2010 18:19:29 +0000</pubDate>
		<dc:creator>Mike Perham</dc:creator>
				<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://www.mikeperham.com/?p=685</guid>
		<description><![CDATA[Good news, everybody &#8212; I&#8217;m starting a new job in 2011! I&#8217;ve accepted a position at Carbon Five. While I enjoyed the challenges of starting a new business, I found the 60+ hr work weeks just unmaintainable with a new baby in the house. Carbon Five presents me many of the same challenges of Bootspring [...]]]></description>
			<content:encoded><![CDATA[<p>Good news, everybody &mdash; I&#8217;m starting a new job in 2011!  I&#8217;ve accepted a position at <a href="http://carbonfive.com">Carbon Five</a>.  While I enjoyed the challenges of starting a new business, I found the 60+ hr work weeks just unmaintainable with a new baby in the house.  Carbon Five presents me many of the same challenges of Bootspring (e.g. finding new clients, recruiting new developers, designing and developing great code for victory) without the tedious bits (e.g. working alone, administrivia, etc).  I&#8217;m very excited to meet and work with a new set of smart people and solve new problems in the coming year!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikeperham.com/2010/12/27/moving-on/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.mikeperham.com/2010/12/27/moving-on/</feedburner:origLink></item>
		<item>
		<title>Using RDoc</title>
		<link>http://feedproxy.google.com/~r/mikeperham/~3/actGw4Iel0c/</link>
		<comments>http://www.mikeperham.com/2010/12/16/using-rdoc/#comments</comments>
		<pubDate>Thu, 16 Dec 2010 15:55:29 +0000</pubDate>
		<dc:creator>Mike Perham</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.mikeperham.com/?p=673</guid>
		<description><![CDATA[One longstanding weakness with the Ruby community is subpar documentation. I think many Rubyists tend to look down on actual API documentation, preferring instead to just read source code directly. I&#8217;ve been guilty of this too and I think some of this is due simply to unfamiliarity with RDoc. Let&#8217;s change that now. Creating RDoc [...]]]></description>
			<content:encoded><![CDATA[<p>One longstanding weakness with the Ruby community is subpar documentation.  I think many Rubyists tend to look down on actual API documentation, preferring instead to just read source code directly.  I&#8217;ve been guilty of this too and I think some of this is due simply to unfamiliarity with RDoc.  Let&#8217;s change that now.</p>
<p><strong>Creating RDoc</strong></p>
<p>I&#8217;ve never found an easily accessible RDoc markup reference.  The only one I know of is unlinkable, buried at the bottom of the RDoc readme instead of front and center as it should be.  So I extracted the <a href='http://www.mikeperham.com/wp-content/uploads/2010/12/rdoc.html'>RDoc markup reference</a> for your reading pleasure.  Jan Varwig created a great <a href="http://jan.varwig.org/wp-content/uploads/2006/09/Rdoc%20Cheat%20Sheet.pdf">RDoc cheatsheet PDF</a> for local or offline access.</p>
<p>Next time you&#8217;re working on a gem, take 10 minutes to read the reference and document the main class for the gem.  It&#8217;ll make you a better Rubyist, I guarantee it.</p>
<p><strong>Generating RDoc</strong></p>
<p>Ok, so you&#8217;ve learned RDoc markup and your code is documented like a champ.  What do you do now?  You&#8217;ve got several choices:</p>
<ul>
<li>Generate rdoc by hand &#8211; the <code>rdoc</code> command ships with Ruby and by default generates all .rb files in or below the current directory.  You probably want something like <code>rdoc lib</code> to just include your project&#8217;s main Ruby code.</li>
<li>Integrate RDoc into Rake &#8211; Rake has an <a href="http://rake.rubyforge.org/classes/Rake/RDocTask.html">RDocTask</a> which can be configured for your project, so you can just run <code>rake rdoc</code>.</li>
</ul>
<p>Once generated, you can view the generated output at <code>doc/index.html</code>.</p>
<p><strong>Viewing RDoc</strong></p>
<p>Rubygems has built-in support for generating and viewing the RDoc for installed gems.  rdoc is generated when the gem is installed (using <code>gem install --no-rdoc [name]</code> skips the local rdoc generation).  You can then use <code>gem server</code> to view your local gem rdoc at <a href="http://localhost:8808">http://localhost:8808</a>.</p>
<p><strong>Check out YARD</strong></p>
<p><a href="http://yardoc.org">YARD</a> is an interesting project by Loren Segal to create a next generation Ruby documentation system.  <a href="http://rubydoc.info/docs/yard/file/docs/GettingStarted.md">Getting started with YARD</a> is well documented; try it out if you want an alternative to RDoc.  YARD&#8217;s syntax is a superset of RDoc&#8217;s so backwards compatibility should not be an issue.  The <a href="http://rubydoc.info/github/mperham/dalli/master/frames">generated documentation</a> looks pretty awesome (note the support for Markdown-formatted README files, which RDoc does not have).</p>
<p>The YARD team also created <a href="http://rubydoc.info/">RubyDoc.info</a>, which hosts documentation for popular gems and is a great resource for finding linkable documentation.</p>
<p>I hope this helps de-mystify rdoc for people.  Any other rdoc tips, please leave a comment.  Happy documenting!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikeperham.com/2010/12/16/using-rdoc/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://www.mikeperham.com/2010/12/16/using-rdoc/</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic page generated in 0.301 seconds. --><!-- Cached page generated by WP-Super-Cache on 2011-12-30 22:33:13 -->

