<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>Alex Young's weblog</title>
    <link>http://alexyoung.org</link>
    <description>Alex Young's notes on web development, music</description>
    <language>en-gb</language>
    <ttl>40</ttl>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/webdevelopernotes" type="application/rss+xml" /><feedburner:browserFriendly>This is an XML content feed. It is intended to be viewed in a newsreader or syndicated to another site, subject to copyright and fair use.</feedburner:browserFriendly><item>
      <title>Rails tutorial part 1</title>
      <description>&lt;p&gt;My Rails tutorial (part 1 of 4) has been published in &lt;a href="http://www.linuxformat.co.uk/modules.php?op=modload&amp;#38;name=NewArchives&amp;#38;issue=108"&gt;Linux Format 108&lt;/a&gt;.  It shows you how to build a Rails-powered photo gallery, by using basic techniques and popular plugins.&lt;/p&gt;


	&lt;p&gt;Grab it from your favourite newsagent and let me know what you think!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=CZvKcI"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=CZvKcI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=P4GwvI"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=P4GwvI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=ytmpeI"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=ytmpeI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/webdevelopernotes/~4/320875843" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 27 Jun 2008 00:04:06 BST</pubDate>
      <link>http://feeds.feedburner.com/~r/webdevelopernotes/~3/320875843/rails_tutorial_part_1</link>
      <dc:creator>Alex Young</dc:creator>
    <feedburner:origLink>http://alexyoung.org/articles/show/50/rails_tutorial_part_1</feedburner:origLink></item>
    <item>
      <title>We need to talk</title>
      <description>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/alex_young/2559688330/"&gt;&lt;img src="http://farm4.static.flickr.com/3261/2559688330_98ca9399ba_s.jpg" alt="" /&gt;&lt;/a&gt; &lt;a href="http://www.flickr.com/photos/helicoid/2567590471/"&gt;&lt;img src="http://farm4.static.flickr.com/3275/2567590471_3d5cc64bf6_s.jpg" alt="" /&gt;&lt;/a&gt; &lt;a href="http://www.flickr.com/photos/helicoid/2535435503/"&gt;&lt;img src="http://farm4.static.flickr.com/3279/2535435503_1a4553676e_s.jpg" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;ve been writing technical articles on this blog for 3 years, and never mentioned much about my personal or professional life.  Here&amp;#8217;s what&amp;#8217;s been going down:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;I recently got married, and had an incredible wedding on a rare sunny English day in Derbyshire&lt;/li&gt;
		&lt;li&gt;We honeymooned in Sardinia, and &lt;a href="http://flickr.com/photos/alex_young/sets/72157605485494858/"&gt;pictures speak louder than words&lt;/a&gt; in this case&lt;/li&gt;
		&lt;li&gt;I took my wife to dinner for her birthday last night, in a restaurant with an incredible view of the River Thames on a balmy London evening.  Never felt so good being in London before!&lt;/li&gt;
		&lt;li&gt;I&amp;#8217;ve been writing again, for a magazine based in the UK (more details soon)&lt;/li&gt;
		&lt;li&gt;I&amp;#8217;ve got about a million Rails articles in my head for this blog&lt;/li&gt;
		&lt;li&gt;My company, &lt;a href="http://helicoid.net"&gt;Helicoid&lt;/a&gt;, just commissioned some incredible illustrations from an artist who was a college friend of mine: check out &lt;a href="http://blog.helicoid.net/articles/2008/06/10/art_commission_wallpapers_by_craig_humpston"&gt;Craig&amp;#8217;s illustrations here&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;Helicoid&amp;#8217;s also got a few secret projects that will be released over the next few months.  I&amp;#8217;m programming them as usual but getting some design help from a friend, &lt;a href="http://thomasloudon.com/"&gt;Tom Loudon&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;Over the course of a year or two, I&amp;#8217;ve trained myself in Mac programming and built this: &lt;a href="http://flickr.com/photos/helicoid/2535435503/"&gt;http://flickr.com/photos/helicoid/2535435503/&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Oh, and by the way, If you&amp;#8217;re a Ruby or Mac developer and want to work with me on any of the &lt;a href="http://helicoid.net"&gt;Helicoid&lt;/a&gt; web applications, please &lt;a href="http://alexyoung.org/contact"&gt;get in touch&lt;/a&gt;.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=7jqNGI"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=7jqNGI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=W3PskI"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=W3PskI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=09QcbI"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=09QcbI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/webdevelopernotes/~4/309035689" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 10 Jun 2008 19:23:46 BST</pubDate>
      <link>http://feeds.feedburner.com/~r/webdevelopernotes/~3/309035689/we_need_to_talk</link>
      <dc:creator>Alex Young</dc:creator>
    <feedburner:origLink>http://alexyoung.org/articles/show/49/we_need_to_talk</feedburner:origLink></item>
    <item>
      <title>5 great mac tools for programmers</title>
      <description>&lt;h3&gt;Diff visualisation: Changes&lt;/h3&gt;


	&lt;p&gt;&lt;img src="http://www.box.net/shared/static/6soxjd0ow4.png" alt="" /&gt; &lt;img src="http://www.box.net/shared/static/1cyvvb8dcg.png" alt="" /&gt;&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://changesapp.com/"&gt;Changes&lt;/a&gt; is a fast and friendly diff tool.  You can quickly list files that have changed in a project, and view differences between files.  It also works with Subversion and Git (and several other version control systems), so it will fit right into your typical workflow.  Oh, and it also has a TextMate bundle.&lt;/p&gt;


	&lt;p&gt;Changes gets perhaps the highest accolade for a mac application: I like Changes so much it actually has a permanent place in my Dock.&lt;/p&gt;


	&lt;h3&gt;Performance analysis: Instruments&lt;/h3&gt;


	&lt;p&gt;&lt;a href="http://www.box.net/shared/static/iteg1rwg0w.png"&gt;&lt;img src="http://www.box.net/shared/static/lag4an4wg4.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://www.apple.com/macosx/developertools/instruments.html"&gt;Instruments&lt;/a&gt; comes with Leopard, so you might already have it on your machine.  It&amp;#8217;s a performance monitoring tool, which means you can attach it to a process and analyse various aspects of its performance.  This is incredibly useful if you&amp;#8217;re looking for memory leaks or working on OpenGL performance in native Mac applications.&lt;/p&gt;


	&lt;p&gt;You can even watch the performance of any processes that support DTrace, which means Ruby programmers can use this tool to inspect everything from &lt;span class="caps"&gt;CPU&lt;/span&gt; profiles to network usage.  The screenshot above is of a Ruby on Rails application.&lt;/p&gt;


	&lt;p&gt;Whilst we&amp;#8217;re on the subject of Leopard bundled applications, check out Dashcode as well.  It&amp;#8217;s indispensable if you want to quickly prototype a widget or iPhone web interface.&lt;/p&gt;


	&lt;h3&gt;Version control: GitNub and svnX&lt;/h3&gt;


	&lt;p&gt;I usually use Subversion through either TextMate&amp;#8217;s excellent bundle or the command line, but in sticky situationsI need to visualise things through a &lt;span class="caps"&gt;GUI&lt;/span&gt;.  That&amp;#8217;s when I reach for &lt;a href="http://www.lachoseinteractive.net/en/community/subversion/"&gt;svnX&lt;/a&gt;, which is a solid enough Cocoa &lt;span class="caps"&gt;SVN&lt;/span&gt; tool.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://github.com/Caged/gitnub/wikis/home"&gt;GitNub&lt;/a&gt; is a pretty new tool for working with Git, and is written with RubyCocoa.  It seems like they&amp;#8217;re working hard on it, so this could become the default tool for Mac Git users.  That is, unless there&amp;#8217;s something lurking in the shadows waiting to jump out&amp;#8230;&lt;/p&gt;


	&lt;h3&gt;Database visualisation: CocoaMySQL-SBG&lt;/h3&gt;


	&lt;p&gt;It&amp;#8217;s getting long in the tooth and doesn&amp;#8217;t get updated enough, but even so &lt;a href="http://www.theonline.org/cocoamysql/"&gt;CocoaMySQL-SBG&lt;/a&gt; is still my favourite Cocoa database tool.  I really wish something would come along with the pedigree of &lt;a href="http://www.panic.com/"&gt;Panic&amp;#8217;s&lt;/a&gt; software, but there&amp;#8217;s been a gap in the market for so long that I somehow doubt it.  While there are a few good Java or cross-platform multi-database clients out there, I want to see something with the elegance of &lt;a href="http://www.panic.com/coda/"&gt;Coda&lt;/a&gt; that will let me manipulate SQLite, MySQL and Postgres.&lt;/p&gt;


	&lt;h3&gt;Text editing: TextMate, Coda, Vim&lt;/h3&gt;


	&lt;p&gt;I&amp;#8217;ve &lt;a href="http://www.thinkvitamin.com/reviews/dev/textmate"&gt;already written a lot&lt;/a&gt; about &lt;a href="http://macromates.com/"&gt;TextMate&lt;/a&gt; over the years, needless to say it&amp;#8217;s one of the greatest Mac development tools.  If you&amp;#8217;re more into design or want an alternative, have a look at &lt;a href="http://www.panic.com/coda/"&gt;Coda&lt;/a&gt; from Panic.  And don&amp;#8217;t forget &lt;a href="http://www.vim.org/"&gt;Vim&lt;/a&gt;!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=YfVjeH"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=YfVjeH" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=RnJLCH"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=RnJLCH" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=5UgjVH"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=5UgjVH" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/webdevelopernotes/~4/299799459" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 28 May 2008 11:35:17 BST</pubDate>
      <link>http://feeds.feedburner.com/~r/webdevelopernotes/~3/299799459/5_great_mac_tools_for_programmers</link>
      <dc:creator>Alex Young</dc:creator>
    <feedburner:origLink>http://alexyoung.org/articles/show/48/5_great_mac_tools_for_programmers</feedburner:origLink></item>
    <item>
      <title>Rapid Rails Part 3: Desktop mastery</title>
      <description>&lt;p&gt;Welcome to &lt;em&gt;Rapid Rails Part 3: Desktop mastery&lt;/em&gt;, the third article in my series focussing on making Rails (and yourself) faster.&lt;/p&gt;


	&lt;p&gt;A good programmer recognises when to reuse and therefore reduce code.  A great programmer applies this tendency to their own workflow.  Whether you use an &lt;span class="caps"&gt;IDE&lt;/span&gt; or text editor, working with Rails can be made more pleasant and efficient by observing commonly performed tasks and simplifying them.&lt;/p&gt;


	&lt;p&gt;The examples given below have a heavy bias toward TextMate, Vim and Mac OS.  If you work in Windows or Linux, at the very least consider the following 10 ideas.&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Ensure you can invoke Rails scripts without leaving your editor&lt;/li&gt;
		&lt;li&gt;Run tests without leaving your editor&lt;/li&gt;
		&lt;li&gt;Keep documentation nearby and searchable&lt;/li&gt;
		&lt;li&gt;Make sure your database schema and data are only key presses away&lt;/li&gt;
		&lt;li&gt;Integrate source code management with your editor&lt;/li&gt;
		&lt;li&gt;Make switching between projects as easy as possible&lt;/li&gt;
		&lt;li&gt;Use snippets, completion and generators when possible&lt;/li&gt;
		&lt;li&gt;Master your text editor &amp;#8211; collect books, articles, blog posts&lt;/li&gt;
		&lt;li&gt;Learn how to extend your text editor&lt;/li&gt;
		&lt;li&gt;Code navigation&lt;/li&gt;
	&lt;/ol&gt;


	&lt;h2&gt;1. Ensure you can invoke Rails scripts without leaving your editor&lt;/h2&gt;


	&lt;p&gt;Repeatedly visiting the terminal to run Rails scripts quickly gets tiresome.  The TextMate Rails bundle allows you to call generator scripts and migrations by pressing &lt;code&gt;shift-ctrl-|&lt;/code&gt;.  Meanwhile &lt;a href="http://www.vim.org/scripts/script.php?script_id=1567"&gt;rails.vim&lt;/a&gt; provides somewhat abstracted access to these scripts.&lt;/p&gt;


	&lt;h2&gt;2. Run tests without leaving your editor&lt;/h2&gt;


	&lt;p&gt;Running tests in TextMate is as simple as pressing &lt;code&gt;cmd-r&lt;/code&gt; when you&amp;#8217;re viewing a test file.  To show a menu of types of tests to run, press &lt;code&gt;ctrl-\&lt;/code&gt;.  With rails.vim, you can use &lt;code&gt;:Rake&lt;/code&gt; with the appropriate tests.&lt;/p&gt;


	&lt;h2&gt;3. Keep documentation nearby and searchable&lt;/h2&gt;


	&lt;p&gt;TextMate provides &lt;em&gt;documentation for word&lt;/em&gt; using RDoc by pressing &lt;code&gt;ctrl-h&lt;/code&gt;, which should cut down your trips to &lt;a href="http://api.rubyonrails.org"&gt;http://api.rubyonrails.org&lt;/a&gt;.  Similarly, rails.vim has the &lt;code&gt;:Rdoc&lt;/code&gt; command.&lt;/p&gt;


	&lt;h2&gt;4. Make sure your database schema and data are only key presses away&lt;/h2&gt;


	&lt;p&gt;Hover over a model name in TextMate, then press &lt;code&gt;cmd-ctrl-shift-s&lt;/code&gt;&amp;#8212;this will show the schema for the model.  rails.vim provides integration with the &lt;a href="http://www.vim.org/scripts/script.php?script_id=356"&gt;dbext plugin&lt;/a&gt;.  This is from the rails.vim documentation:&lt;/p&gt;


&lt;blockquote&gt;
Then, you can use features like table name completion and commands like:

:Create database brablog_development
&lt;/blockquote&gt;

	&lt;h2&gt;5. Integrate source code management with your editor&lt;/h2&gt;


	&lt;p&gt;&lt;img src="http://www.box.net/shared/static/0xh5xqigwk.png" alt="" /&gt;&lt;/p&gt;


	&lt;p&gt;In TextMate, press &lt;code&gt;shift-ctrl-a&lt;/code&gt; to bring up the subversion bundle&amp;#8217;s menu.  The commit window is especially user-friendly.  Vim has &lt;a href="http://www.vim.org/scripts/script.php?script_id=90"&gt;vcscommand.vim&lt;/a&gt;&lt;/p&gt;


	&lt;h2&gt;6. Make switching between projects as easy as possible&lt;/h2&gt;


	&lt;p&gt;&lt;img src="http://www.box.net/shared/static/b4q9spq4gs.png" alt="" /&gt;&lt;/p&gt;


	&lt;p&gt;Stacks were added in Mac OS Leopard, and I find these a great way of grouping my TextMate projects for quick, spring-loaded access.  It&amp;#8217;s worth getting to know your editor&amp;#8217;s project management capabilities.  Even though it&amp;#8217;s tempting to use scratch projects (with TextMate this is usually done with &lt;code&gt;mate .&lt;/code&gt; in the terminal), carefully maintaining your own projects allows you to group files (differently to the file system) and maintain state.  Vim supports these features through &lt;a href="http://vim.sourceforge.net/scripts/script.php?script_id=69"&gt;project.vim&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Of course, there are many ways of quickly accessing projects.  Here&amp;#8217;s a few ideas:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Use &lt;a href="http://www.blacktree.com/"&gt;Quicksilver&lt;/a&gt; with TextMate&lt;/li&gt;
		&lt;li&gt;Create memorable shell aliases&lt;/li&gt;
		&lt;li&gt;Pin them to your Windows start menu, or add a folder&lt;/li&gt;
		&lt;li&gt;Use a &lt;a href="http://launchy.net/"&gt;Windows-compatible Start Menu replacement&lt;/a&gt; to find project files&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h2&gt;7. Use snippets, completion and generators when possible&lt;/h2&gt;


	&lt;p&gt;&lt;img src="http://www.box.net/shared/static/bq8guf6w4o.png" alt="" /&gt;&lt;/p&gt;


	&lt;p&gt;TextMate has loads of snippets.  You can access them by typing a phrase then pressing tab.  For example, &lt;code&gt;deft[tab]&lt;/code&gt; creates the outline for a unit test case.  To search TextMate snippets (or any of the keyboard shortcuts I&amp;#8217;ve detailed here), press ctrl-cmd-t to bring up the &lt;em&gt;select bundle item&lt;/em&gt; menu.  This can also be found by clicking on the &lt;em&gt;Bundles&lt;/em&gt; menu.&lt;/p&gt;


	&lt;p&gt;Also, don&amp;#8217;t forget to make the most of Rails generators.  Run &lt;code&gt;script/generate&lt;/code&gt; to see what&amp;#8217;s available.&lt;/p&gt;


	&lt;h2&gt;8. Master your text editor &amp;#8211; collect books, articles, blog posts&lt;/h2&gt;


	&lt;p&gt;O&amp;#8217;Reilly&amp;#8217;s Vim books helped me get to grips with Vim, I used to carry &lt;a href="http://www.oreilly.com/catalog/vipr/index.html"&gt;The vi Editor Pocket Reference&lt;/a&gt; around in my early days at university and my first job.  Searching through &lt;a href="http://vim.sourceforge.net/search.php"&gt;Vim&amp;#8217;s plugins&lt;/a&gt; can yield some useful finds, and there&amp;#8217;s even a &lt;a href="http://vim.wikia.com/wiki/Main_Page"&gt;Vim tips wiki&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://macromates.com/textmate/manual/"&gt;TextMate&amp;#8217;s manual&lt;/a&gt; and &lt;a href="http://wiki.macromates.com/Main/HomePage"&gt;Wiki&lt;/a&gt; are both great resources.&lt;/p&gt;


	&lt;p&gt;Another resource I can fully endorse is &lt;a href="http://peepcode.com/"&gt;Peep Code&lt;/a&gt;.  The &lt;a href="http://peepcode.com/products/textmate-for-rails-2"&gt;TextMate for Rails 2&lt;/a&gt; screencast is detailed and thorough, and comes complete with an indispensable cheatsheet &lt;span class="caps"&gt;PDF&lt;/span&gt;.&lt;/p&gt;


	&lt;h2&gt;9. Learn how to extend your text editor&lt;/h2&gt;


	&lt;p&gt;Vim&amp;#8217;s macros can take a bit of getting used to, but this article should set you straight:  &lt;a href="http://www.oreillynet.com/mac/blog/2006/07/more_vim_save_time_with_macros_1.html"&gt;More Vim: Save Time With Macros&lt;/a&gt;.  TextMate is a bit easier, but the power of TextMate&amp;#8217;s extensibility lies in the Bundle Editor (found in: Bundles, Bundle Editor, Show Bundle Editor.)&lt;/p&gt;


	&lt;p&gt;Many of TextMate&amp;#8217;s bundles are shell scripts or even ruby scripts, and there&amp;#8217;s a TextMate ruby library for integrating with the &lt;span class="caps"&gt;GUI&lt;/span&gt;.  You can also create your own snippets, which can be useful for quickly writing our your company&amp;#8217;s boilerplate file headers.  The TextMate &lt;a href="http://macromates.com/textmate/manual/bundles.html"&gt;manual entry on bundles&lt;/a&gt; is pretty in-depth.&lt;/p&gt;


	&lt;h2&gt;10. Code navigation&lt;/h2&gt;


	&lt;p&gt;Some of these features require &lt;a href="http://code.leadmediapartners.com/tools/rubyamp"&gt;RubyAMP&lt;/a&gt;.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;code&gt;cmd-t&lt;/code&gt; lets you quickly search and switch files&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;shift-cmd-f&lt;/code&gt; is Find in Project&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;shift-cmd-m&lt;/code&gt; skips to a method definition&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;cmd-ctrl-alt-f&lt;/code&gt; greps through the project, and is usually faster than Find in Project&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;cmd-alt-down arrow&lt;/code&gt; switches from an action to a view or model to unit test&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;shift-cmd-alt-down arrow&lt;/code&gt; brings up the &lt;em&gt;Go To&lt;/em&gt; menu&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;cmd-shift-t&lt;/code&gt; displays the symbol navigator&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;rails.vim has loads of equivalents, which uses &lt;code&gt;:A&lt;/code&gt; (alternate) and &lt;code&gt;:R&lt;/code&gt; (related) for easy jumping between files.&lt;/p&gt;


	&lt;h2&gt;Bonus Stage: Workflow-dependent desktops&lt;/h2&gt;


	&lt;p&gt;If you&amp;#8217;ve got Mac OS Leopard or Linux you&amp;#8217;ve probably tried out workspaces.  Why not set up a work-friendly space, with terminals, editors, and everything else all set up so you can access them easily?&lt;/p&gt;


	&lt;p&gt;Here are a few more ideas:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Use Mac OS&amp;#8217;s &lt;a href="http://automatorworld.com/"&gt;Automator&lt;/a&gt;.  Leopard introduced macro-like functionality, so creating workflows is even easier&lt;/li&gt;
		&lt;li&gt;Make the most of Quicklook in Mac OS&lt;/li&gt;
		&lt;li&gt;Use smart folders and folder actions (ideas: search for project files, or even search for files that have been tagged in some way)&lt;/li&gt;
		&lt;li&gt;Try using some widgets: &lt;a href="http://widgets.precisionis.com.au/"&gt;Dashboard&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h2&gt;Super-Secret Bonus Stage: Stop working&lt;/h2&gt;


	&lt;p&gt;Play more videogames.  You can use the excuse that you&amp;#8217;re researching their interfaces for ideas, it&amp;#8217;s the perfect crime!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=QJw9AmG"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=QJw9AmG" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=7eEAD9G"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=7eEAD9G" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=7Ady7oG"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=7Ady7oG" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/webdevelopernotes/~4/275026138" height="1" width="1"/&gt;</description>
      <pubDate>Mon, 21 Apr 2008 22:32:56 BST</pubDate>
      <link>http://feeds.feedburner.com/~r/webdevelopernotes/~3/275026138/rapid_rails_part_3_desktop_mastery</link>
      <dc:creator>Alex Young</dc:creator>
    <feedburner:origLink>http://alexyoung.org/articles/show/47/rapid_rails_part_3_desktop_mastery</feedburner:origLink></item>
    <item>
      <title>Rapid Rails Part 2: Rapid in the literal sense</title>
      <description>&lt;p&gt;This is part 2 of the &lt;em&gt;Rapid Rails&lt;/em&gt; series.  &lt;a href="http://alexyoung.org/articles/show/45/rapid_rails_part_1_commandline_mastery"&gt;Part 1&lt;/a&gt; featured tips on how to work more efficiently with Rails by making the most of the bundled and related command line tools.  This part discusses how to make your Rails application perform faster, with particular focus on server optimisation.  Why?  Because systems administration requires a very different skill set to programming, and I&amp;#8217;ve been often been expected to manage sysadmin tasks on my Rails contracts&amp;#8212;and I bet you have too!&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;ve included real-world examples from Linux, Lighttpd, Exim and MySQL because these are what I currently use on most of my servers.  If you&amp;#8217;re just starting out trying to boost your server performance there are some general principles for you, too.&lt;/p&gt;


	&lt;h2&gt;Rails application performance&lt;/h2&gt;


	&lt;p&gt;People new to Rails are often concerned about its performance in production.  In my experience, unless you&amp;#8217;re lucky enough to be dealing with a ridiculously popular site, you shouldn&amp;#8217;t have major performance issues.  However, at the very least you should do the following to every application you deploy:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Ensure database tables are indexed effectively&lt;/li&gt;
		&lt;li&gt;Employ caching&lt;/li&gt;
		&lt;li&gt;Identify expensive database queries and look for alternative approaches&lt;/li&gt;
		&lt;li&gt;Check sessions are managed appropriately for your application.  Using ActiveRecord sessions may improve performance&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;I&amp;#8217;ve previously discussed these basic application-based optimisations in &lt;a href="http://alexyoung.org/articles/show/19"&gt;Getting started with rails optimisation&lt;/a&gt;.&lt;/p&gt;


	&lt;h2&gt;Server software optimisation&lt;/h2&gt;


	&lt;p&gt;If your application performs well under tests, and benchmarks show it performs well, you might be left wondering if there&amp;#8217;s any other ways to squeeze more performance out of your server.  In all of the commercial Rails projects I&amp;#8217;ve been involved in, optimising server software got killer performance gains.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Most server software (especially databases and web servers) are very conservative about memory usage by default.  It&amp;#8217;s likely you have a lot spare since memory is more affordable than it used to be, so consider increasing caching where possible&lt;/li&gt;
		&lt;li&gt;If you&amp;#8217;re operating a service that sends out large volumes of emails, your &lt;span class="caps"&gt;MTA&lt;/span&gt; probably isn&amp;#8217;t configured to perform well under these conditions (especially by default)&lt;/li&gt;
		&lt;li&gt;Servers are often left configured in a state that &amp;#8220;works&amp;#8221;, rather than well-tested and verifiably solid&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;In general:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Track down some good books about your mail, web and database servers&lt;/li&gt;
		&lt;li&gt;Use system tools like &lt;code&gt;top&lt;/code&gt; and &lt;code&gt;iostat&lt;/code&gt; to identify any hardware bottlenecks&lt;/li&gt;
		&lt;li&gt;Turn on logging to record poor performance (MySQL can do this)&lt;/li&gt;
		&lt;li&gt;Slowly reconfigure software, observing its performance using monitoring tools&amp;#8212;don&amp;#8217;t paste in &amp;#8220;optimised&amp;#8221; configurations found second-hand on forums!&lt;/li&gt;
		&lt;li&gt;Put configuration files in version control, and add comments where possible&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Most server software has similar techniques to improve performance.  Things to look out for when you&amp;#8217;re scanning books and manuals are:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;Caching&lt;/strong&gt;: If you&amp;#8217;ve got a few gigabytes spare it&amp;#8217;s likely that you can increase cache and buffer sizes for practically anything&lt;/li&gt;
		&lt;li&gt;&lt;strong&gt;Cache optimisation&lt;/strong&gt;: It&amp;#8217;s important to get high cache hits, so check your software can display this information (MySQL will show you with &lt;code&gt;show status like 'qcache%';&lt;/code&gt;)&lt;/li&gt;
		&lt;li&gt;&lt;strong&gt;Parallelism&lt;/strong&gt;: Server software might be still running as single-threaded dinosaurs when they could increase parallelism to run through tasks faster (especially effective with the Exim &lt;span class="caps"&gt;MTA&lt;/span&gt;)&lt;/li&gt;
		&lt;li&gt;&lt;strong&gt;Additional software support&lt;/strong&gt;: Sometimes even the most mundane tasks can be made faster with additional software.  For example, &lt;span class="caps"&gt;FAM&lt;/span&gt; can be used to give lighttpd an extra boost by reducing stat system calls&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h2&gt;Monitoring&lt;/h2&gt;


	&lt;p&gt;It&amp;#8217;s no good tweaking configuration files if you can&amp;#8217;t prove you&amp;#8217;ve improved performance, and this is partly why I said configuration changes should be applied slowly over time.  The easiest way to get started monitoring your server is &lt;a href="http://www.cacti.net/"&gt;Cacti&lt;/a&gt;.  It&amp;#8217;s open source and will tell you a lot about what your server is doing.  Since it&amp;#8217;ll show you &lt;span class="caps"&gt;RRD&lt;/span&gt; graphs generated over time, it&amp;#8217;s easy to see if your configuration changes had any impact.&lt;/p&gt;


	&lt;p&gt;You&amp;#8217;ll also have a lot of monitoring options bundled with your software.  MySQL and Exim provide various binaries and logging features for monitoring performance.&lt;/p&gt;


	&lt;h2&gt;Practical server optimisation techniques&lt;/h2&gt;


	&lt;h3&gt;Memory, &lt;span class="caps"&gt;CPU&lt;/span&gt; and disk performance tuning&lt;/h3&gt;


	&lt;p&gt;The first tool to familiarise yourself with is &lt;code&gt;top&lt;/code&gt;.  By pressing &lt;code&gt;F&lt;/code&gt; you can select sort fields to analyse the processes running on your system.  This is a quick way to view the overall activity of a system.&lt;/p&gt;


	&lt;p&gt;To get an overall picture of system resources, &lt;code&gt;vmstat&lt;/code&gt; summarises memory, paging and &lt;span class="caps"&gt;CPU&lt;/span&gt; activity.  To generate results over time, run:&lt;/p&gt;


&lt;pre class="code"&gt;
vmstat 10 8

procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in    cs us sy id wa
 0  0    640 146956 3072880 863520    0    0    15    35    1     0  4  1 94  1
&lt;/pre&gt;

	&lt;p&gt;This will generate 8 results, with statistics taken every 10 seconds.  The vmstat man page explains each column.  If you think lack of memory is an issue pay attention to the &lt;code&gt;si&lt;/code&gt; and &lt;code&gt;so&lt;/code&gt; columns &amp;#8211; these represent page in and out, indicating where memory contents are being written to and read from the disk.&lt;/p&gt;


	&lt;p&gt;To keep track of disk performance, use &lt;code&gt;iostat&lt;/code&gt; to produce reports.  The format is similar to &lt;code&gt;vmstat&lt;/code&gt;, and the manual page details the columns.  Run &lt;code&gt;iostat -x&lt;/code&gt; and check if any disk has a high &lt;code&gt;%util&lt;/code&gt; result.  To see which process is responsible for saturating the disk, run &lt;code&gt;ps w&lt;/code&gt; and look for anything with a &lt;code&gt;D&lt;/code&gt; in the stat column.  It&amp;#8217;s likely that this process is blocking IO.&lt;/p&gt;


	&lt;p&gt;Practical scenario: When initially running &lt;code&gt;top&lt;/code&gt; to analyse a server, I noticed the Rails ruby processes were using far too much &lt;span class="caps"&gt;RAM&lt;/span&gt; on the system, simply because lighttpd had been set up to run too many processes through FastCGI.  Reducing the number of FastCGI processes improved performance because (according to &lt;code&gt;vmstat&lt;/code&gt;) the swap was being hit less.&lt;/p&gt;


	&lt;p&gt;If you&amp;#8217;re using Linux, &lt;code&gt;hdparm&lt;/code&gt; (for &lt;span class="caps"&gt;IDE&lt;/span&gt; devices) and &lt;code&gt;blockdev&lt;/code&gt; are useful tools if disk performance is an issue.  You can also benchmark any devices you found performing poorly in &lt;code&gt;iostat&lt;/code&gt;:&lt;/p&gt;


&lt;pre class="code"&gt;
hdparm -tT /dev/sda
&lt;/pre&gt;

	&lt;p&gt;Performance can often be increased by configuring drives with &lt;code&gt;hdparm&lt;/code&gt;, older Linux distros often ignored &lt;span class="caps"&gt;DMA&lt;/span&gt; settings which visibly reduces performance.  Here&amp;#8217;s a &lt;a href="http://gentoo-wiki.com/HOWTO_Use_hdparm_to_improve_IDE_device_performance"&gt;detailed write-up on hdparm&lt;/a&gt;.&lt;/p&gt;


	&lt;h3&gt;MySQL&lt;/h3&gt;


	&lt;p&gt;Optimising MySQL is in-depth, and full of quirks.  Settings vary between storage engines and MySQL versions too.  Things to look out for are:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Logging: Turn on &lt;code&gt;log-slow-queries&lt;/code&gt; so MySQL can help find slow queries&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://dev.mysql.com/doc/refman/5.0/en/query-cache.html"&gt;Query cache performance&lt;/a&gt;: Execute &lt;code&gt;show status like 'qcache%';&lt;/code&gt; in MySQL&amp;#8217;s console to get an overview of how the cache is behaving, setting &lt;code&gt;query_cache_size&lt;/code&gt; in my.cnf to larger values&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.mysqlperformanceblog.com/2007/11/03/choosing-innodb_buffer_pool_size/"&gt;innodb_buffer_pool_size&lt;/a&gt; can be increased depending on your situation&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;The &lt;a href="http://www.mysqlperformanceblog.com/"&gt;MySQL performance blog&lt;/a&gt; regularly discusses how to optimise MySQL in detail.&lt;/p&gt;


	&lt;h3&gt;Lighttpd&lt;/h3&gt;


	&lt;p&gt;Lighttpd&amp;#8217;s wiki includes details on how to &lt;a href="http://trac.lighttpd.net/trac/wiki/Docs%3APerformanceFastCGI"&gt;optimise for FastCGI&lt;/a&gt;, with monitoring too.  Beyond this, adding &lt;code&gt;server.stat-cache-engine = "simple"&lt;/code&gt; (or &lt;code&gt;fam&lt;/code&gt;) &lt;a href="http://trac.lighttpd.net/trac/wiki/Docs%3APerformance#stat-cache"&gt;can improve overall performance&lt;/a&gt;.&lt;/p&gt;


	&lt;h3&gt;Exim&lt;/h3&gt;


	&lt;p&gt;Exim is structured as a set of binaries and processes that handle each part of the mail delivery process.  This means that rather than dealing with one monolithic daemon process you&amp;#8217;re dealing with a distributed set of tools.  When sending out thousands of emails, don&amp;#8217;t just loop through your subscriber list and fire off thousands of mails with ActionMailer.  Exim will queue a certain number of mails per connection rather than immediately sending them with &lt;span class="caps"&gt;SMTP&lt;/span&gt;.  Also, threading will improve performance here by sending out batches in several threads.&lt;/p&gt;


	&lt;p&gt;General Exim performance tips are:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;code&gt;smtp_accept_queue_per_connection = integer&lt;/code&gt; can be increased to match your desired per-connection mail batch&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;remote_max_parallel = integer&lt;/code&gt; forks the delivery process a number of times up to the maximum&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;split_spool_directory&lt;/code&gt; splits message queues into subdirectories which can improve filesystem performance&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;connection_max_messages&lt;/code&gt; increases the number of messages sent to the same host in a single connection&lt;/li&gt;
		&lt;li&gt;Ensure &lt;code&gt;exim_tidydb&lt;/code&gt; is being run regularly with cron&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;To get a good idea of how these changes affect performance over time, generate reports with &lt;code&gt;eximstats&lt;/code&gt;:&lt;/p&gt;


&lt;pre class="code"&gt;
eximstats -txt /var/log/exim/main.log
&lt;/pre&gt;

	&lt;p&gt;Here&amp;#8217;s an example of running &lt;code&gt;exim_tidydb&lt;/code&gt; in &lt;code&gt;/etc/crontab&lt;/code&gt;:&lt;/p&gt;


&lt;pre class="code"&gt;
0 6 * * * /usr/sbin/exim_tidydb /var/spool/exim wait-remote_smtp &amp;gt; /dev/null 2&amp;gt;&amp;#38;1
0 6 * * * /usr/sbin/exim_tidydb /var/spool/exim retry &amp;gt; /dev/null 2&amp;gt;&amp;#38;1
&lt;/pre&gt;

	&lt;h2&gt;Final tips&lt;/h2&gt;


	&lt;p&gt;In general, change configuration settings one by one, monitoring as you go.  This can unfortunately require downtime for your site, but if you keep track of what you&amp;#8217;re doing it shouldn&amp;#8217;t be too visible to your site&amp;#8217;s visitors.  Try to identify any hardware bottlenecks before blaming software for your problems: if you know something is using up too much &lt;span class="caps"&gt;RAM&lt;/span&gt;, either buying more &lt;span class="caps"&gt;RAM&lt;/span&gt; or scaling back caching or other settings is better than wasting hours trying to optimise your application&amp;#8217;s code.&lt;/p&gt;


	&lt;h3&gt;Server optimisation summary checklist of guaranteed win&lt;/h3&gt;


	&lt;ul&gt;
	&lt;li&gt;Don&amp;#8217;t make multi configuration changes at once, observe the impact of each change&lt;/li&gt;
		&lt;li&gt;Use &lt;strong&gt;monitoring tools&lt;/strong&gt; to collect real evidence on performance changes&lt;/li&gt;
		&lt;li&gt;Use the tools that come with your server&amp;#8217;s software to gauge the overall state of hardware resource allocation, try to identify bottlenecks and potential causes&lt;/li&gt;
		&lt;li&gt;&lt;strong&gt;Don&amp;#8217;t accept defaults&lt;/strong&gt;: Study books on your server software and operating system to properly understand configuration changes&lt;/li&gt;
		&lt;li&gt;&lt;strong&gt;Be proactive&lt;/strong&gt;: Check with clients if you can book downtime for server maintenance, don&amp;#8217;t get caught out trying to improve performance on a live system&lt;/li&gt;
		&lt;li&gt;Consider using version control to track configuration file changes and share them between servers&lt;/li&gt;
	&lt;/ul&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=JcMmt0G"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=JcMmt0G" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=v6clpKG"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=v6clpKG" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=4C9cNAG"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=4C9cNAG" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/webdevelopernotes/~4/262110369" height="1" width="1"/&gt;</description>
      <pubDate>Tue,  1 Apr 2008 00:01:29 BST</pubDate>
      <link>http://feeds.feedburner.com/~r/webdevelopernotes/~3/262110369/rapid_rails_part_2_rapid_in_the_literal_sense</link>
      <dc:creator>Alex Young</dc:creator>
    <feedburner:origLink>http://alexyoung.org/articles/show/46/rapid_rails_part_2_rapid_in_the_literal_sense</feedburner:origLink></item>
    <item>
      <title>Rapid Rails Part 1: Command-line mastery</title>
      <description>&lt;p&gt;&lt;img src="http://www.box.net/shared/static/p0kuthy8g8.gif" alt="" /&gt;&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;Rapid Rails&lt;/em&gt; is a series of articles containing succinct tips to increase your productivity when working with &lt;a href="http://rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt;.  This is the first part, and shows you how to make the most of the command-line tools that come with Rails.&lt;/p&gt;


	&lt;h2&gt;Quickly generate migrations&lt;/h2&gt;


	&lt;p&gt;The Rails generator script (found inside an application&amp;#8217;s directory at &lt;code&gt;script/generate&lt;/code&gt;) allows you to quickly create templates for anything you need within Rails.  As well as models and controllers, you can also use it to write entire migrations:&lt;/p&gt;


&lt;pre class="code"&gt;
script/generate migration AddIPAddressToUsers ip_address:string
&lt;/pre&gt;

	&lt;p&gt;The field definition is specified as &lt;code&gt;field_name:type&lt;/code&gt;, and you can type in as many as you need for each migration.  To read Rails&amp;#8217; help on this feature, type:&lt;/p&gt;


&lt;pre class="code"&gt;
script/generate migration
&lt;/pre&gt;

	&lt;p&gt;This cuts down the hassle of changing database schemas around, and should be the nail in the coffin for lazy database schema manipulation with &lt;span class="caps"&gt;GUI&lt;/span&gt; tools.&lt;/p&gt;


	&lt;h3&gt;Get more generators&lt;/h3&gt;


	&lt;p&gt;People have written generators to create templates for sophisticated applications, providing a great way of rapidly prototyping an application: &lt;a href="http://wiki.rubyonrails.org/rails/pages/AvailableGenerators"&gt;Rails wiki generator list&lt;/a&gt;.&lt;/p&gt;


	&lt;h2&gt;What was I doing last week?&lt;/h2&gt;


	&lt;p&gt;The Rakefile that comes with Rails contains a handy way of searching for comments with phrases including &lt;span class="caps"&gt;TODO&lt;/span&gt; and &lt;span class="caps"&gt;FIXME&lt;/span&gt;:&lt;/p&gt;


&lt;pre class="code"&gt;
rake notes
rake notes:fixme
rake notes:optimize
rake notes:todo
&lt;/pre&gt;

	&lt;p&gt;An additional benefit of this is it can increase your understanding of recent code changes, especially when combined with version control logs.&lt;/p&gt;


	&lt;h3&gt;More Rake house-keeping tools&lt;/h3&gt;


	&lt;p&gt;To list all of the rake tasks, type &lt;code&gt;rake --tasks&lt;/code&gt;.  A few tasks I often use are:&lt;/p&gt;


&lt;pre class="code"&gt;
rake tmp:cache:clear
rake log:clear
rake routes
rake db:sessions:create # Creates a migration for ActiveRecord sessions
&lt;/pre&gt;

	&lt;h2&gt;Get help (and how to cheat)&lt;/h2&gt;


	&lt;p&gt;Getting ruby library help in the command-line is usually &lt;code&gt;ri&lt;/code&gt;&amp;#8217;s job:&lt;/p&gt;


&lt;pre class="code"&gt;
ri FileUtils#cp
&lt;/pre&gt;

	&lt;p&gt;The all-round maverick genius Mauricio Fernandez decided ri was too slow, and built &lt;a href="http://eigenclass.org/hiki.rb?making+ruby+ri+faster"&gt;FastRI&lt;/a&gt;.  Not only is it faster than RI, but it can also work in a distributed fashion with Rinda.  It&amp;#8217;s easy to install and use:&lt;/p&gt;


&lt;pre class="code"&gt;
sudo gem install fastri
fastri-server &amp;#38;
fri FileUtils#cp
&lt;/pre&gt;

	&lt;p&gt;If this isn&amp;#8217;t enough help, why not use cheat sheets from the command-line?&lt;/p&gt;


&lt;pre class="code"&gt;
sudo gem install cheat
cheat rails_console
&lt;/pre&gt;

	&lt;p&gt;These Ruby-focussed cheat sheets are intuitive, with plenty of tips for those things you can&amp;#8217;t be blamed for forgetting.&lt;/p&gt;


	&lt;h2&gt;Testing and command-line flags&lt;/h2&gt;


	&lt;p&gt;If you&amp;#8217;re running a unit test and there&amp;#8217;s a problem with one test, just run a single test with &lt;code&gt;-n&lt;/code&gt;:&lt;/p&gt;


&lt;pre class="code"&gt;
ruby test/unit/user_test.rb -n test_authenticate
&lt;/pre&gt;

	&lt;p&gt;There&amp;#8217;s more flags too, just run a test with -h:&lt;/p&gt;


&lt;pre class="code"&gt;
ruby test/unit/user_test.rb -h
&lt;/pre&gt;

	&lt;h2&gt;Debugging&lt;/h2&gt;


	&lt;p&gt;If you&amp;#8217;re really stuck, you can breakpoint and trace to your heart&amp;#8217;s content by installing ruby-debug:&lt;/p&gt;


&lt;pre class="code"&gt;
sudo gem install ruby-debug
&lt;/pre&gt;

	&lt;p&gt;ruby-debug is a more pleasant with &lt;code&gt;autoeval&lt;/code&gt; set, so create a text file called .rdebugrc in your home directory and add:&lt;/p&gt;


&lt;pre class="code"&gt;
set autolist
set autoeval
set autoreload
&lt;/pre&gt;

	&lt;p&gt;Now, run rdebug with a ruby script:&lt;/p&gt;


&lt;pre class="code"&gt;
rdebug script/server
&lt;/pre&gt;

	&lt;p&gt;Add a breakpoint (obviously set this to something meaningful within your application) and continue execution:&lt;/p&gt;


&lt;pre class="code"&gt;
b app/controllers/application.rb:10
&lt;/pre&gt;

	&lt;p&gt;The script should now halt at your breakpoint.  To read more, check out &lt;a href="http://www.datanoise.com/ruby-debug/"&gt;rdebug&amp;#8217;s home&lt;/a&gt; and a handy &lt;a href="http://cheat.errtheblog.com/s/rdebug/"&gt;rdebug cheat sheet&lt;/a&gt; (or type cheat rdebug).&lt;/p&gt;


	&lt;h2&gt;Reduce password entries during development&lt;/h2&gt;


	&lt;p&gt;If your application uses a version control system on a remote server over &lt;span class="caps"&gt;SSH&lt;/span&gt;, consider creating &lt;span class="caps"&gt;SSH&lt;/span&gt; keys to cut down password entries.  To do this securely, use ssh-agent.  Read more here: &lt;a href="http://www.sshkeychain.org/mirrors/SSH-with-Keys-HOWTO/"&gt;&lt;span class="caps"&gt;SSH&lt;/span&gt; with Keys &lt;span class="caps"&gt;HOWTO&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;h2&gt;Speed up your development server: Mongrel and Thin&lt;/h2&gt;


	&lt;p&gt;Mongrel and Thin are great alternatives to the built in Rails web server, and are both faster.  To install use &lt;code&gt;sudo gem install mongrel&lt;/code&gt; or &lt;code&gt;sudo gem install thin&lt;/code&gt; (they&amp;#8217;re both fast, thin appears to be slightly faster.)  Then run one of the following commands from your application&amp;#8217;s directory:&lt;/p&gt;


&lt;pre class="code"&gt;
mongrel_rails start
&lt;/pre&gt;

	&lt;p&gt;Or:&lt;/p&gt;


&lt;pre class="code"&gt;
thin start
&lt;/pre&gt;

	&lt;p&gt;Rails now automatically runs mongrel with &lt;code&gt;script/server&lt;/code&gt;.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=sEpnmgF"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=sEpnmgF" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=lxUrJOF"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=lxUrJOF" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=tWOiZyF"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=tWOiZyF" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/webdevelopernotes/~4/259272892" height="1" width="1"/&gt;</description>
      <pubDate>Thu, 27 Mar 2008 22:04:23 GMT</pubDate>
      <link>http://feeds.feedburner.com/~r/webdevelopernotes/~3/259272892/rapid_rails_part_1_commandline_mastery</link>
      <dc:creator>Alex Young</dc:creator>
    <feedburner:origLink>http://alexyoung.org/articles/show/45/rapid_rails_part_1_commandline_mastery</feedburner:origLink></item>
    <item>
      <title>Rails plugin testing guide</title>
      <description>&lt;p&gt;This article is an introduction to testing Rails plugins.  It&amp;#8217;s a relatively lengthy post, so if you&amp;#8217;re reading this in an &lt;span class="caps"&gt;RSS&lt;/span&gt; reader flag it and come back when you&amp;#8217;re not too busy.  It follows the &amp;#8220;taxonomy&amp;#8221; style of my previous plugin article, &lt;a href="http://alexyoung.org/articles/show/40/a_taxonomy_of_rails_plugins"&gt;A taxonomy of Rails plugins&lt;/a&gt;, where examples are used from open source software.&lt;/p&gt;


	&lt;p&gt;Knowledge of both unit and functional testing is assumed.  The following topics are covered:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Testing plugins outside Rails applications&lt;/li&gt;
		&lt;li&gt;Creating models and fixtures to test with ActiveRecord plugins&lt;/li&gt;
		&lt;li&gt;Managing a test database schema&lt;/li&gt;
		&lt;li&gt;Testing ActionPack plugins&lt;/li&gt;
		&lt;li&gt;Automating with Rake&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h2&gt;Testing plugins outside Rails applications&lt;/h2&gt;


	&lt;p&gt;Testing plugins that are tied to a Rails application is straightforward, and it&amp;#8217;s tempting to leave things this way.  If you need to distribute your plugin to developers working outside your project, or wish to open source it, you may have to do a little bit of work to create a miniature Rails environment to test in.  The upside of this extra effort is that it also forces you to think about the plugin in generic terms, often resulting in better design and cleaner encapsulation.&lt;/p&gt;


	&lt;h2&gt;Test directory layout&lt;/h2&gt;


	&lt;p&gt;Most plugins use a test directory layout that is similar to Rails:&lt;/p&gt;


&lt;pre&gt;
test/
  fixtures/
  functional/
  lib/
  unit/
  test_helper.rb
  Rakefile
&lt;/pre&gt;

	&lt;p&gt;Many plugins use &lt;code&gt;fixtures/&lt;/code&gt; for both test data and test ActiveRecord models.  Some plugins drop &lt;code&gt;unit/&lt;/code&gt; and &lt;code&gt;functional/&lt;/code&gt;.&lt;/p&gt;


	&lt;h2&gt;Testing ActiveRecord plugins&lt;/h2&gt;


	&lt;p&gt;If your plugin extends ActiveRecord, you need to create a suitable environment:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Require the ActiveRecord gem (and it the fixtures library)&lt;/li&gt;
		&lt;li&gt;Setup an ActiveRecord connection.  Using in-memory or sqlite databases can minimise configuration requirements&lt;/li&gt;
		&lt;li&gt;Load the schema&lt;/li&gt;
		&lt;li&gt;Load the fixtures&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Each unit test that requires ActiveRecord will have to do each of these things, so it&amp;#8217;s probably best to wrap them all in a class.  &lt;a href="http://rock.errtheblog.com/will_paginate"&gt;will_paginate&lt;/a&gt; does this by having &lt;code&gt;test/lib/activerecord_test_case.rb&lt;/code&gt; (this mocks Rails&amp;#8217; unit test behaviour) and &lt;code&gt;test/lib/activerecord_test_connector.rb&lt;/code&gt; (this manages ActiveRecord).  Tests that need ActiveRecord functionality then require &lt;code&gt;test/lib/activerecord_test_case.rb&lt;/code&gt;.&lt;/p&gt;


	&lt;p&gt;Another option is to try &lt;a href="http://wiki.pluginaweek.org/Plugin_test_helper"&gt;Plugin Test Helper&lt;/a&gt;, but be sure to carefully read the &lt;span class="caps"&gt;API&lt;/span&gt; before using it: it expects your plugin&amp;#8217;s tests to be laid out in a specific way.&lt;/p&gt;


	&lt;h3&gt;Bringing up ActiveRecord&lt;/h3&gt;


	&lt;p&gt;Getting access to a database with &lt;code&gt;ActiveRecord::Base.establish_connection&lt;/code&gt; is simple:&lt;/p&gt;


&lt;code&gt;
&lt;pre class="code"&gt;
  require 'rubygems'
  require 'active_record'

  ActiveRecord::Base.establish_connection({
    :adapter =&amp;gt; 'sqlite3',
    :dbfile =&amp;gt; 'test.db'
  })
&lt;/pre&gt;
&lt;/code&gt;

	&lt;p&gt;It may be advisable to loop through a few database adapter types, seeing as people will have different libraries available in their development environments.   Good candidates are: sqlite3, sqlite and memory.&lt;/p&gt;


	&lt;h3&gt;Schema magagement&lt;/h3&gt;


	&lt;p&gt;The easiest and most portable way to define your test database schema is by using &lt;code&gt;ActiveRecord::Schema&lt;/code&gt;.  For example:&lt;/p&gt;


&lt;code&gt;
&lt;pre class="code"&gt;
  ActiveRecord::Schema.define do
    create_table "users", :force =&amp;gt; true do |t|
      t.column "name",  :text
      t.column "email", :text
    end
  end
&lt;/pre&gt;
&lt;/code&gt;

	&lt;p&gt;A good place to put this is &lt;code&gt;test/fixtures/schema.rb&lt;/code&gt;.  This file can be opened with &lt;code&gt;load&lt;/code&gt; in a suitable schema loading method called before running tests that require ActiveRecord.&lt;/p&gt;


	&lt;h3&gt;Fixtures&lt;/h3&gt;


	&lt;p&gt;Seeing as most plugins will only require a few models, it&amp;#8217;s acceptable to load all of the fixtures before testing.  &lt;code&gt;Fixtures.create_fixtures&lt;/code&gt; can be called like this:&lt;/p&gt;


&lt;code&gt;
&lt;pre class="code"&gt;
  require 'active_record'
  require 'active_record/fixtures'

  Fixtures.create_fixtures('your test fixture path', ActiveRecord::Base.connection.tables)
&lt;/pre&gt;
&lt;/code&gt;

	&lt;h2&gt;Testing ActionPack plugins&lt;/h2&gt;


	&lt;p&gt;Testing controllers and helpers is easier than ActiveRecord.  To test a controller:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;require action_controller and action_controller/test_process&lt;/li&gt;
		&lt;li&gt;Create some routes&lt;/li&gt;
		&lt;li&gt;Create a unit test class&lt;/li&gt;
		&lt;li&gt;Create a controller class&lt;/li&gt;
		&lt;li&gt;Write the tests in the same style as Rails functional tests&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;To test helpers,  the most obvious approach is to &lt;code&gt;include&lt;/code&gt; your plugin&amp;#8217;s helper class inside a unit test, and test each helper method.  Since some helpers might expect models you might need to bring up ActiveRecord too, but you could create mock objects with a library like &lt;a href="http://mocha.rubyforge.org/"&gt;mocha&lt;/a&gt; or in some cases by creating suitable &lt;code&gt;OpenStruct&lt;/code&gt; objects.&lt;/p&gt;


	&lt;h2&gt;Automation with Rake&lt;/h2&gt;


	&lt;p&gt;Most plugins that provide tests also include a Rakefile to automate running their test suite and generating documentation.  Here&amp;#8217;s a perfectly valid example from a plugin I picked at random, &lt;a href="http://svn.techno-weenie.net/projects/plugins/restful_authentication/"&gt;restful_authentication&lt;/a&gt;.&lt;/p&gt;


&lt;code&gt;
&lt;pre class="code"&gt;
require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'

desc 'Default: run unit tests.'
task :default =&amp;gt; :test

desc 'Test the restful_authentication plugin.'
Rake::TestTask.new(:test) do |t|
  t.libs &amp;lt;&amp;lt; 'lib'
  t.pattern = 'test/**/*_test.rb'
  t.verbose = true
end

desc 'Generate documentation for the restful_authentication plugin.'
Rake::RDocTask.new(:rdoc) do |rdoc|
  rdoc.rdoc_dir = 'rdoc'
  rdoc.title    = 'RestfulAuthentication'
  rdoc.options &amp;lt;&amp;lt; '--line-numbers' &amp;lt;&amp;lt; '--inline-source'
  rdoc.rdoc_files.include('README')
  rdoc.rdoc_files.include('lib/**/*.rb')
end
&lt;/pre&gt;
&lt;/code&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=ECvO1xE"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=ECvO1xE" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=akdDxeE"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=akdDxeE" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=vAYIGbE"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=vAYIGbE" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/webdevelopernotes/~4/229219171" height="1" width="1"/&gt;</description>
      <pubDate>Mon,  4 Feb 2008 23:55:00 GMT</pubDate>
      <link>http://feeds.feedburner.com/~r/webdevelopernotes/~3/229219171/rails_plugin_testing_guide</link>
      <dc:creator>Alex Young</dc:creator>
    <feedburner:origLink>http://alexyoung.org/articles/show/44/rails_plugin_testing_guide</feedburner:origLink></item>
    <item>
      <title>Some Ruby on Rails plugin stats</title>
      <description>&lt;p&gt;There are now almost 1000 entries in the main resource for Ruby on Rails plugins, &lt;a href="http://agilewebdevelopment.com/plugins"&gt;Agile Web Development&amp;#8217;s Plugins Directory&lt;/a&gt;.  Of these, 596 have repositories listed that are accessible.  I wanted to see how many of these plugins came with some form of tests, so I created a spider (using a &lt;a href="http://rubyforge.org/projects/spider/"&gt;web spider library&lt;/a&gt;) and performed some basic analysis on each repository.&lt;/p&gt;


	&lt;p&gt;After reading a few magazines, and watching two entire TV shows, the spider came back with a result: &lt;strong&gt;54% of the plugins have tests&lt;/strong&gt;.&lt;/p&gt;


	&lt;p&gt;It&amp;#8217;s amazing to think that there&amp;#8217;s almost 1000 plugins in one directory, and a good proportion have tests amongst those I could easily analyse.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=qDWS2LE"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=qDWS2LE" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=jOqpYoE"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=jOqpYoE" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=g3d5NYE"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=g3d5NYE" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/webdevelopernotes/~4/228651523" height="1" width="1"/&gt;</description>
      <pubDate>Mon,  4 Feb 2008 02:04:49 GMT</pubDate>
      <link>http://feeds.feedburner.com/~r/webdevelopernotes/~3/228651523/some_ruby_on_rails_plugin_stats</link>
      <dc:creator>Alex Young</dc:creator>
    <feedburner:origLink>http://alexyoung.org/articles/show/43/some_ruby_on_rails_plugin_stats</feedburner:origLink></item>
    <item>
      <title>Start using Test Driven Development today</title>
      <description>&lt;p&gt;&lt;a href="http://insider.helicoid.net/articles/show/6/protip_start_using_test_driven_development_today"&gt;Start using Test Driven Development today&lt;/a&gt; is a post I wrote over on my company&amp;#8217;s blog.  It covers how &lt;span class="caps"&gt;TDD&lt;/span&gt; has improved my work since I started &lt;a href="http://helicoid.net"&gt;Helicoid Limited&lt;/a&gt;, and how you can start using &lt;span class="caps"&gt;TDD&lt;/span&gt; right now.&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Learn how to write basic tests in your chosen language – don’t worry about fully learning the test framework, start by copying examples&lt;/li&gt;
		&lt;li&gt;When adding a new feature, start by creating tests first. Write code to satisfy these tests&lt;/li&gt;
		&lt;li&gt;Refactor old code to work well with automated tests&lt;/li&gt;
		&lt;li&gt;Write test data carefully and patiently, using this as a design technique for exploring the quality of your data modelling&lt;/li&gt;
		&lt;li&gt;Find a mocking library so you can write encapsulated tests that don’t require external resources&lt;/li&gt;
		&lt;li&gt;Find a tool for producing coverage reports in your chosen language&lt;/li&gt;
		&lt;li&gt;Investigate automated testing triggered when deploying/releasing code&lt;/li&gt;
	&lt;/ol&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=GMz3v6D"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=GMz3v6D" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=WTRaaBD"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=WTRaaBD" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=1HWmIMD"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=1HWmIMD" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/webdevelopernotes/~4/219069859" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 18 Jan 2008 21:05:40 GMT</pubDate>
      <link>http://feeds.feedburner.com/~r/webdevelopernotes/~3/219069859/start_using_test_driven_development_today</link>
      <dc:creator>Alex Young</dc:creator>
    <feedburner:origLink>http://alexyoung.org/articles/show/42/start_using_test_driven_development_today</feedburner:origLink></item>
    <item>
      <title>10 essential ruby gems</title>
      <description>&lt;p&gt;Despite leaving it for a while, I&amp;#8217;m going to continue my previous article, &amp;#8220;A taxonomy of Rails plugins&amp;#8221;, relatively soon.  I&amp;#8217;ve been inspired by the excellent plugins by &lt;a href="http://errfree.com/"&gt;errfree&lt;/a&gt; and come up with a few ideas of my own during the heavy workload of 2007.  In particular, I&amp;#8217;d like to clarify testing Rails plugins.  But more of that in the near future.&lt;/p&gt;


	&lt;p&gt;For now, have a look at &lt;a href="http://insider.helicoid.net/articles/show/2/10_essential_ruby_gems"&gt;10 essential ruby gems&lt;/a&gt;.  It&amp;#8217;s hosted on my company&amp;#8217;s new blog, where you&amp;#8217;ll eventually find more articles by me with a greater emphasis on web design.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=zKyEA1D"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=zKyEA1D" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=xUSBgID"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=xUSBgID" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/webdevelopernotes?a=Icx12ID"&gt;&lt;img src="http://feeds.feedburner.com/~f/webdevelopernotes?i=Icx12ID" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/webdevelopernotes/~4/212902617" height="1" width="1"/&gt;</description>
      <pubDate>Tue,  8 Jan 2008 01:07:05 GMT</pubDate>
      <link>http://feeds.feedburner.com/~r/webdevelopernotes/~3/212902617/10_essential_ruby_gems</link>
      <dc:creator>Alex Young</dc:creator>
    <feedburner:origLink>http://alexyoung.org/articles/show/41/10_essential_ruby_gems</feedburner:origLink></item>
  </channel>
</rss>
