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

<channel>
	<title>gnuu.org</title>
	<atom:link href="http://gnuu.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://gnuu.org</link>
	<description>my word against yours, fight.</description>
	<lastBuildDate>Fri, 18 Dec 2009 06:11:40 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Visualizing Class Relationships with YARD and InfoVis</title>
		<link>http://gnuu.org/2009/12/18/visualizing-class-relationships/</link>
		<comments>http://gnuu.org/2009/12/18/visualizing-class-relationships/#comments</comments>
		<pubDate>Fri, 18 Dec 2009 05:30:36 +0000</pubDate>
		<dc:creator>Loren Segal</dc:creator>
				<category><![CDATA[post]]></category>
		<category><![CDATA[class diagram]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[visualization]]></category>
		<category><![CDATA[yard]]></category>

		<guid isPermaLink="false">http://gnuu.org/?p=361</guid>
		<description><![CDATA[Note: This post requires an HTML5 capable browser. FF3.5+, Safari, Chrome (or any WebKit browser) will do the trick. That should cover most of my readers.
I love visualization toolkits, so when I found out about the JS visualization toolkit InfoVis, I had to play with it. Generally the first thing that comes to mind when [...]]]></description>
			<content:encoded><![CDATA[<p class="note"><strong>Note:</strong> This post requires an HTML5 capable browser. FF3.5+, Safari, Chrome (or any WebKit browser) will do the trick. That should cover most of my readers.</p>
<p>I love visualization toolkits, so when I found out about the JS visualization toolkit <a href="http://thejit.org">InfoVis</a>, I had to play with it. Generally the first thing that comes to mind when visualizing data is class model relationships, so I figured I’d write another snippet to export data from <a href="http://yardoc.org">YARD</a> into a JS-friendly format and see how it looked. This time, I’ll spare the show-and-tell and just do the showing, since the code to export this data is fairly trivial.</p>
<p>I basically used the few examples from the site but plugged in class relationship data from Ruby libraries to get the following visualization of YARD in particular:</p>
<h2>Visualization 1: Simple Tree View</h2>
<p><iframe src="/yardviz/viz1.html" width="605" height="605" frameborder="0"></iframe></p>
<p>Pretty simple, we can also make it look a little fancier:</p>
<h2>Visualization 2: Polar Tree View</h2>
<p><iframe src="/yardviz/viz2.html" width="605" height="605" frameborder="0"></iframe></p>
<h2>Visualization 3: Coupling</h2>
<p>It then occurred to me that visualizations like these (weighted graphs in particular) would be a good way to visualize class coupling in your library. I experimented with the concept by generating a weighted graph, but it seems InfoVis&#8217; RGraph class (which they demo a weighted graph with) isn&#8217;t really that great at really visualizing the weights, also it doesn&#8217;t seem to support weighted graphs. The end result shows some interesting data, but it&#8217;s not exactly great to really view coupling.</p>
<p class="note"><strong>Note:</strong> FF doesn&#8217;t seem to like this one. Don&#8217;t be surprised if it doesn&#8217;t work.</p>
<p><iframe src="/yardviz/viz3.html" width="605" height="605" frameborder="0"></iframe></p>
<p>Those are the visualizations I played with. There&#8217;s a <a href="/yardviz">nicer version here</a> that lets you see visualizations for Ruby&#8217;s core lib and Rails in addition to YARD&#8217;s, plus it has some extra niceties like showing methods in the current highlighted class on the side (not enough space to show it on my blog). Check it out.</p>
<p>Thanks to <strong>Josh Martin</strong> for pointing out InfoVis today, by the way.</p>]]></content:encoded>
			<wfw:commentRss>http://gnuu.org/2009/12/18/visualizing-class-relationships/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using yri for Ruby Core Classes</title>
		<link>http://gnuu.org/2009/12/15/using-yri-for-ruby-core-classes/</link>
		<comments>http://gnuu.org/2009/12/15/using-yri-for-ruby-core-classes/#comments</comments>
		<pubDate>Tue, 15 Dec 2009 22:55:44 +0000</pubDate>
		<dc:creator>Loren Segal</dc:creator>
				<category><![CDATA[post]]></category>
		<category><![CDATA[0.5.1]]></category>
		<category><![CDATA[core]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[gem]]></category>
		<category><![CDATA[stdlib]]></category>
		<category><![CDATA[yard]]></category>
		<category><![CDATA[yardoc]]></category>
		<category><![CDATA[yri]]></category>

		<guid isPermaLink="false">http://gnuu.org/2009/12/15/using-yri-for-ruby-core-classes/</guid>
		<description><![CDATA[This functionality requires a couple of changes made in 0.5.1 (released today), so be sure to update yard to the latest release.
You can now use yri with Ruby core classes. This is relatively old news (as of yesterday) since YARD can now parse core classes, but Ruby source is generally not available on all installs, [...]]]></description>
			<content:encoded><![CDATA[<p class="note">This functionality requires a couple of changes made in 0.5.1 (released today), so be sure to update yard to the latest release.</p>
<p>You can now use yri with Ruby core classes. This is relatively old news (as of yesterday) since YARD can now parse core classes, but Ruby source is generally not available on all installs, so building the .yardoc database is not always an option.</p>
<p>In YARD 0.5.1 (released today), instead of downloading and parsing the Ruby source manually, you can now download a pre-built gem containing the .yardoc files for a bunch of Ruby versions (1.8.6, 1.8.7, 1.9.1). Simply use:</p>
<pre>$ gem install yard-doc-core</pre>
<p>You should now be able to use something like <tt>yri String#split</tt>. By default this will install docs for 1.9.1, but if you need docs for a specific version of Ruby, add <tt>-v VERSION</tt> to your gem install command:</p>
<pre>$ gem install yard-doc-core -v 1.8.7</pre>
<p>The stdlib package (<tt>yard-doc-stdlib</tt>) will be coming soon.</p>]]></content:encoded>
			<wfw:commentRss>http://gnuu.org/2009/12/15/using-yri-for-ruby-core-classes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Announcing The Longest YARD: 0.5.0</title>
		<link>http://gnuu.org/2009/12/14/announcing-the-longest-yard-0-5-0/</link>
		<comments>http://gnuu.org/2009/12/14/announcing-the-longest-yard-0-5-0/#comments</comments>
		<pubDate>Tue, 15 Dec 2009 01:17:12 +0000</pubDate>
		<dc:creator>Loren Segal</dc:creator>
				<category><![CDATA[post]]></category>
		<category><![CDATA[0.5.0]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby 1.9]]></category>
		<category><![CDATA[tool]]></category>
		<category><![CDATA[yard]]></category>

		<guid isPermaLink="false">http://gnuu.org/2009/12/14/announcing-the-longest-yard-0-5-0/</guid>
		<description><![CDATA[YARD 0.5.0 (“The Longest”) was just released today. It features a bunch of new things, but some of the most awesome are:

Support for documenting native Ruby C code 
Incremental file parsing and HTML generation 
Improved yri tool with support for linking gems 

Support for Documenting Native Ruby C Code
This one was certainly a long time [...]]]></description>
			<content:encoded><![CDATA[<p>YARD 0.5.0 (<em>“The Longest”</em>) was just released today. It features a bunch of new things, but some of the most awesome are:</p>
<ol>
<li>Support for documenting native Ruby C code </li>
<li>Incremental file parsing and HTML generation </li>
<li>Improved yri tool with support for linking gems </li>
</ol>
<h2>Support for Documenting Native Ruby C Code</h2>
<p>This one was certainly a long time coming. YARD has always planned to support native Ruby code. This was probably the last &quot;big&quot; feature that RDoc could do and YARD could not. Now, YARD can.</p>
<p>The best part of this feature is that YARD can now parse Ruby&#8217;s core codebase and the stdlib, meaning <a href="http://yardoc.org">yardoc.org</a> can now host Ruby-core docs. And it now does: <a href="http://yardoc.org/docs/ruby-core">http://yardoc.org/docs/ruby-core</a>. The stdlib will be added soon.</p>
<h2>Incremental file parsing and HTML generation</h2>
<p>One annoying thing about documenting code with YARD for larger projects is the time it takes to generate HTML. This makes the documentation development cycle slow for previewing small documentation changes. YARD 0.5.0 introduces incremental parsing and HTML generation to parse and generate HTML for only the files that were modified since the last running of <tt>yardoc</tt>, which makes for super-fast previews. To use the incremental parsing feature, simply add <tt>-c</tt> or <tt>--use-cache</tt> and YARD will use the available .yardoc cache.</p>
<pre>$ yardoc --use-cache</pre>
<h2>Improved yri tool with support for linking gems</h2>
<p>The <tt>yri</tt> tool that bundled with YARD prior to this release only worked for the .yardoc file in the local directory. In YARD 0.5.0, <tt>yri</tt> will now perform a lookup on all installed gems on your system. To use this, you&#8217;ll first need to build the .yardoc files for your gems, and you can do this with <tt>yardoc --build-gems</tt>. After that, you can use yri as normal:</p>
<pre>$ yri JSON#load</pre>
<h2>More?</h2>
<p>You can see more new toys in the <a href="http://yardoc.org/docs/yard/file:WhatsNew.md">What’s New</a> document on <a href="http://yardoc.org">yardoc.org</a>. You can also install YARD:</p>
<pre>$ gem install yard</pre>
<p>Enjoy!</p>]]></content:encoded>
			<wfw:commentRss>http://gnuu.org/2009/12/14/announcing-the-longest-yard-0-5-0/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The Three Issues Keeping Me Off Chrome</title>
		<link>http://gnuu.org/2009/12/07/the-three-issues-keeping-me-off-chrome/</link>
		<comments>http://gnuu.org/2009/12/07/the-three-issues-keeping-me-off-chrome/#comments</comments>
		<pubDate>Mon, 07 Dec 2009 21:45:24 +0000</pubDate>
		<dc:creator>Loren Segal</dc:creator>
				<category><![CDATA[post]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[ui]]></category>
		<category><![CDATA[webkit]]></category>

		<guid isPermaLink="false">http://gnuu.org/?p=350</guid>
		<description><![CDATA[Important Note: at least 90% of this is subjective and opinionated. You might love everything Chrome has to offer. I&#8217;d rather have a browser that can offer the best to everyone and not force its own opinions on its users.
Chrome is an awesome browser. I mean, it’s WebKit, it’s V8, it’s super fast. My problem [...]]]></description>
			<content:encoded><![CDATA[<p class="note">Important Note: at least 90% of this is subjective and opinionated. You might love everything Chrome has to offer. I&#8217;d rather have a browser that can offer the best to everyone and not force its own opinions on its users.</p>
<p>Chrome is an awesome browser. I mean, it’s WebKit, it’s V8, it’s super fast. My problem with Chrome, as with every single Google product ever, is the UI. It&#8217;s extremely opinionated, and imposes a non-standard UI that simply rubs me the wrong way</p>
<p>Google likes to break rules. Unfortunately the best UI’s are ones that follow many rules and break only the ones that really need breaking. Apple has an OS that touts UI uniformity to the near extremes, and this works extremely well among reviews and critics alike. Google should be taking advice from companies like these, not attempting to blaze their own trail; they certainly don’t have the credibility in UX to set any trends. So what are my problems? There are three, and they are as follows:</p>
<p><!-- more --><br />
<h2>Problem 1: The Tabs</h2>
<p>Chrome has this obsession with putting tabs on top of the address bar. While this is an interesting UI choice, there’s no real benefit, and there are a few noticeable losses. Firstly, you lose out on long titles, even when the tab is active, because Chrome completely ignores the standard Windows/OSX titlebar concept (yes, it sucks on OSX too):</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Long titles are for wimps" border="0" alt="Long titles are for wimps" src="http://gnuu.org/wp-content/uploads/2009/12/image.png" width="406" height="98" /></p>
<p>The only way to get the full title is to hover over the tab, waiting there for your mouse to show you something you could have read three times by now. Sure, this is really a minor issue in itself, but what’s the real benefit? The aesthetics are not nice enough to justify a breaking of the rules here. Simply put, this UI is being tailored to their Chrome OS, not to <em>my</em> OS. In OSX it looks even more broken, because of the dead gray space and window control buttons on the left side:</p>
<p>&#160;<img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="This just looks weird." border="0" alt="This just looks weird." src="http://gnuu.org/wp-content/uploads/2009/12/Screenshot20091207at3.57.41PM.png" width="600" height="94" /> </p>
<p>I should also point out, Apple tried &#8220;tabs on top&#8221; in Safari 4.0 beta and then reverted the change. Google should have taken the hint.</p>
<p>You may have also noticed that 10-12 pixels of dead vertical space above the tabs that don’t go away (more pronounced in Vista/7). We’ll get back to that one later.</p>
<h2>Problem 2: No Dedicated Search Bar</h2>
<p>Yes, the address bar doubles as a search bar. I get that. But it’s not what I want. There is something beneficial about being able to have your search terms separated from your current address:</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Dedicated Search Bar" border="0" alt="Dedicated Search Bar" src="http://gnuu.org/wp-content/uploads/2009/12/image1.png" width="600" /> </p>
<p>This matters when I delve into long searches spanning multiple search results or pages, because I still have my search terms safely stowed away. I might realize, “hey, those aren’t quite the right keywords”, or even, “wow, this page is awesome, what did I search to get here?” – all that information will be available without digging in my history. It’s also great if I want to start back at square one, since I don’t have to re-type my search term or navigate backwards. Oh, and I didn’t even begin to mention the search extension support you get for free with a dedicated search bar.</p>
<p>You might like a combined address/search bar. I don’t. The thing is, there should be extensibility support for those of us that don’t. Unfortunately, Google’s extensions have no provisions to make any modifications to the UI besides <a href="https://tools.google.com/chrome/intl/en/themes/index.html">horribly ugly, useless and limited theming support</a>. Again, there’s no real justification for changing the standard browser layout here except the <em>extremely minimal</em> benefit of extra simplicity, and there at least a few drawbacks.</p>
<h2>Problem 3: No Dedicated Status Bar</h2>
<p>This one&#8217;s probably controversial, but I want a dedicated status bar too. I <em>like</em> having a status bar. It shows me when my page is loading, it tells me what I’m hovering over, but best of all, <strong><em>it does it without being visually disruptive</em></strong>. </p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Get out of my face, status bar." border="0" alt="Get out of my face, status bar." src="http://gnuu.org/wp-content/uploads/2009/12/Screenshot20091207at4.27.33PM.png" width="308" height="56" /> </p>
<p>The justification for this one is touted as “<em>Look Ma, now you have 12 extra pixels of vertical space!!”</em>. Great, I’ll add it back to the 12 pixels of vertical space you wasted with the tabs:</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="DEAD SPACE BE HERE" border="0" alt="DEAD SPACE BE HERE" src="http://gnuu.org/wp-content/uploads/2009/12/image2.png" width="175" height="105" /> </p>
<p>I just don’t buy this. Websites aren’t optimized for vertical space. In what situation have you thought, “damn, I wish I just had twelve more pixels so I could read that last line of text, now I have to scroll!”?</p>
<p>But even if you actually are like that, status bars have actual functional benefits <em>beyond</em> giving you the URL of a link. My Firefox status bar has plenty of “status”-like information for me:</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="What a real status bar looks like" border="0" alt="What a real status bar looks like" src="http://gnuu.org/wp-content/uploads/2009/12/image3.png" width="463" height="40" /> </p>
<p>Sure, the “Done” is somewhat pointless, but the rest of it is not. Plus, I imagine as Chrome extensions become more prevalent, they will need somewhere to put their “status information” too. The idea that the only use of a status bar is to show hovered links is a naive way of looking at the UI, and it shows you really don’t understand what the purpose of a status bar is in the first place.</p>
<h2>They Would Fix It, But They Can&#8217;t</h2>
<p>As mentioned before, the extension support in Chrome makes no provisions for modifying the UI. It might just be a product of its new-ness, but I’ve yet to see any official response from Google on these issues, so I’m doubtful anything will be done. In fact, from the stance they took on justifying the UI when it initially came out, I’d say these UX features are steadfast design decisions and are unlikely to change. Until then, I’m “stuck” with the slower, more bloated, Firefox (on Windows; Safari serves me just fine on OSX).</p>]]></content:encoded>
			<wfw:commentRss>http://gnuu.org/2009/12/07/the-three-issues-keeping-me-off-chrome/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Auto-Generated ER Diagrams of Popular Rails Projects</title>
		<link>http://gnuu.org/2009/11/30/auto-generated-er-diagrams-of-popular-rails-projects/</link>
		<comments>http://gnuu.org/2009/11/30/auto-generated-er-diagrams-of-popular-rails-projects/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 04:53:00 +0000</pubDate>
		<dc:creator>Loren Segal</dc:creator>
				<category><![CDATA[post]]></category>
		<category><![CDATA[er diagram]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[uml]]></category>
		<category><![CDATA[yard]]></category>
		<category><![CDATA[yuml]]></category>

		<guid isPermaLink="false">http://gnuu.org/?p=335</guid>
		<description><![CDATA[I discovered yUML.me today. It’s a really awesome project and allows you to hotlink UML class, activity or use-case diagrams on any page. All of the UML data is in the URL itself, so it’s real easy to embed these images anywhere without JS or API’s. I’ve always wanted to use YARD to generate ER [...]]]></description>
			<content:encoded><![CDATA[<p>I discovered <a href="http://yuml.me">yUML.me</a> today. It’s a really awesome project and allows you to hotlink UML class, activity or use-case diagrams on any page. All of the UML data is in the URL itself, so it’s real easy to embed these images anywhere without JS or API’s. I’ve always wanted to use <a href="http://yardoc.org">YARD</a> to generate <a href="http://en.wikipedia.org/wiki/Entity-relationship_model">ER diagrams</a> programmatically, and I figured this would be a great way to test out the service.</p>
<p>Since I don’t write many Rails apps, I figured I’d select some of the most popular open source rails apps out there and generate ER diagrams for those. It turned out to be an interesting exercise in visualizing database structures of some of the projects people use day to day. </p>
<p>The projects I chose were: <a href="http://github.com/parasew/instiki">Instiki</a>, <a href="http://github.com/qrush/gemcutter">Gemcutter</a>, <a href="http://github.com/desaperados/seed">Seed</a>, <a href="http://github.com/radiant/radiant">Radiant</a>, <a href="http://github.com/emk/mephisto">Mephisto</a>, <a href="http://github.com/insoshi/insoshi">Insoshi</a> and <a href="http://github.com/railsdog/spree">Spree</a>. The results range from awesome to scary, but you can judge for yourselves.</p>
<h3>Results</h3>
<h4>Instiki</h4>
<p>Nice and simple. Maybe too simple?</p>
<p><img src="http://yuml.me/diagram/scruffy/class/[Web]++-*[Page],[Web]++-*[WikiFile],[Web]++-*[Revision],[Page]++-*[Revision],[Page]++-*[WikiReference],[Page]1--Current Revision-1[Revision]" /></p>
<h4>Gemcutter</h4>
<p>Here’s a nice one. Sufficiently complex but still easy to follow. I should point out at this point that dashed lines refer to has-many-through relationships (with the attr name as the arrow label.</p>
<p><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" src="http://yuml.me/diagram/scruffy/class/[User]++-*[Rubygem],[User]-Rubygems-.-*[Rubygem],[User]++-*[Ownership],[User]++-*[Subscription],[Version]++-*[Dependency],[Version]++-*[Download],[Rubygem]++-*[Ownership],[Rubygem]-Users-.-*[User],[Rubygem]++-*[Subscription],[Rubygem]++-*[Version],[Rubygem]1--1[Linkset],[Dependency]1--1[Rubygem]" /></p>
<h4>Seed</h4>
<p>This is probably the cleanest one. The use of STI in the models really makes this look nice.</p>
<p><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" src="http://yuml.me/diagram/scruffy/class/[Page]++-*[Article],[Page]++-*[Newsitem],[Page]++-*[Post],[Page]++-*[Component],[Page]++-*[Event],[Role]*--*[User],[Article]++-*[Image],[Article]++-*[Document],[Article]^-[Newsitem],[Password]1--1[User],[Component]1--Source-1[Page],[Component]++-*[Document],[Article]^-[Post],[Post]++-*[Comment]" /></p>
<h4>Radiant</h4>
<p>Simple, but those recursive relationships look a little messy, don’t they? I guess it would look better if the layout was done right. Note that those labels again refer to the attribute name.</p>
<p><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" src="http://yuml.me/diagram/scruffy/class/[User]1--Created By-1[User],[User]1--Updated By-1[User],[Layout]++-*[Page],[Layout]1--Created By-1[User],[Layout]1--Updated By-1[User],[Snippet]1--Created By-1[User],[Snippet]1--Updated By-1[User],[PagePart]1--1[Page],[Page]^-[EnvDumpPage],[Page]^-[FileNotFoundPage],[Page]++-Part-*[PagePart],[Page]1--Created By-1[User],[Page]1--Updated By-1[User]" width="590" height="410" /></p>
<h4>Mephisto</h4>
<p>Manageable.</p>
<p><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" src="http://yuml.me/diagram/scruffy/class/[Tag]++-*[Tagging],[Site]++-*[Section],[Site]++-*[Article],[Site]++-*[Comment],[Site]++-*[Event],[Site]++-*[CachedPage],[Site]++-*[Asset],[Site]++-*[Membership],[Site]-Users-.-*[User],[User]++-*[Article],[User]++-*[Membership],[User]++-*[Site],[Asset]++-*[AssignedAsset],[Event]1--1[User],[Content]1--1[User],[Content]1--1[Site],[Tagging]1--1[Taggable],[Section]++-*[AssignedSection],[Content]^-[Article],[Content]^-[Comment],[Comment]1--1[Article],[Comment]1--1[Event],[Article]++-*[AssignedSection],[Article]++-*[Section],[Article]++-*[Event],[Article]++-*[AssignedAsset],[Article]++-*[Asset]" width="590" height="792" /></p>
<h4>Insoshi</h4>
<p>Now we&#8217;re getting crazy. yUML is starting to fail on us.</p>
<p>Click the image to see the madness</p>
<p><a style="border: 0" href="http://yuml.me/diagram/scruffy/class/[Post]++-*[Activity],[Blog]++-Post-*[BlogPost],[Photo]++-*[Activity],[Event]++-*[EventAttendee],[Event]-People-.-*[Person],[Event]++-*[Comment],[Event]++-*[Activity],[Topic]1--1[Person],[Topic]++-Post-*[ForumPost],[Topic]++-*[Activity],[Forum]++-*[Topic],[Forum]++-*[Post],[Person]1--1[Blog],[Person]++-*[EmailVerification],[Person]++-*[Comment],[Person]++-*[Connection],[Person]++-*[Contact],[Person]++-*[Photo],[Person]-Contacts-.-*[Contact],[Person]++-*[Feed],[Person]++-*[Activity],[Person]++-*[PageView],[Person]++-*[Gallery],[Person]++-*[Event],[Person]++-*[EventAttendee],[Person]-Events-.-*[Event],[Comment]1--1[Commentable],[Comment]1--Commenter-1[Person],[Comment]1--1[Post],[Comment]++-*[Activity],[Gallery]++-*[Photo],[Gallery]++-*[Activity],[Activity]1--1[Item],[Activity]++-*[Feed],[Post]^-[BlogPost],[BlogPost]1--1[Blog],[BlogPost]++-*[Comment],[Thumbnail]1--1[Photo],[Connection]1--Contact-1[Person],[Connection]++-*[Activity],[Post]^-[ForumPost],[ForumPost]1--1[Topic],[ForumPost]1--1[Person],[Person]^-[AllPerson],[Conversation]++-*[Message],[Communication]^-[Message],[Message]1--Sender-1[Person],[Message]1--Recipient-1[Person]"><img src="http://yuml.me/diagram/scruffy/class/[Post]++-*[Activity],[Blog]++-Post-*[BlogPost],[Photo]++-*[Activity],[Event]++-*[EventAttendee],[Event]-People-.-*[Person],[Event]++-*[Comment],[Event]++-*[Activity],[Topic]1--1[Person],[Topic]++-Post-*[ForumPost],[Topic]++-*[Activity],[Forum]++-*[Topic],[Forum]++-*[Post],[Person]1--1[Blog],[Person]++-*[EmailVerification],[Person]++-*[Comment],[Person]++-*[Connection],[Person]++-*[Contact],[Person]++-*[Photo],[Person]-Contacts-.-*[Contact],[Person]++-*[Feed],[Person]++-*[Activity],[Person]++-*[PageView],[Person]++-*[Gallery],[Person]++-*[Event],[Person]++-*[EventAttendee],[Person]-Events-.-*[Event],[Comment]1--1[Commentable],[Comment]1--Commenter-1[Person],[Comment]1--1[Post],[Comment]++-*[Activity],[Gallery]++-*[Photo],[Gallery]++-*[Activity],[Activity]1--1[Item],[Activity]++-*[Feed],[Post]^-[BlogPost],[BlogPost]1--1[Blog],[BlogPost]++-*[Comment],[Thumbnail]1--1[Photo],[Connection]1--Contact-1[Person],[Connection]++-*[Activity],[Post]^-[ForumPost],[ForumPost]1--1[Topic],[ForumPost]1--1[Person],[Person]^-[AllPerson],[Conversation]++-*[Message],[Communication]^-[Message],[Message]1--Sender-1[Person],[Message]1--Recipient-1[Person]" width="590" height="616" /></a></p>
<h4>Spree</h4>
<p>This one isn&#8217;t exactly fair. I think the amount of complexity here is a little out of the scope of a single UML diagram. It&#8217;s fun to look at, though.</p>
<p>Click the image to see the madness</p>
<p><a style="border: 0" href="http://yuml.me/diagram/scruffy/class/[Zone]++-*[ZoneMember],[Zone]++-*[TaxRate],[Zone]++-*[ShippingMethod],[User]++-*[Order],[User]*--*[Role],[User]1--Ship Addres-1[Addres],[User]1--Bill Addres-1[Addres],[Asset]1--1[Viewable],[Asset]^-[Image],[Order]++-*[StateEvent],[Order]++-*[LineItem],[Order]++-*[InventoryUnit],[Order]++-*[Payment],[Order]++-*[CreditcardPayment],[Order]1--1[Checkout],[Order]1--1[BillAddres],[Order]++-*[Shipment],[Order]++-*[Adjustment],[Order]++-*[Charge],[Order]++-*[Credit],[Order]++-*[ShippingCharge],[Order]++-*[TaxCharge],[Order]++-*[CouponCredit],[Order]++-Non Zero Charge-*[Charge],[State]1--1[ZoneMember],[State]1--1[Zone],[Coupon]++-*[CouponCredit],[Variant]++-*[InventoryUnit],[Variant]++-*[LineItem],[Variant]++-*[Image],[Country]++-*[State],[Country]1--1[ZoneMember],[Country]1--1[Zone],[Address]1--1[Country],[Address]1--1[State],[Address]++-*[Checkout],[Address]++-*[Shipment],[Product]++-*[ProductOptionType],[Product]++-*[OptionType],[Product]++-*[ProductProperty],[Product]++-*[Image],[Product]1--1[TaxCategory],[Product]*--*[Taxon],[Product]1--1[ShippingCategory],[Product]1--Master-1[Variant],[Product]++-*[Variant],[Product]++-Variants Including Master-*[Variant],[Shipment]1--1[Addres],[Shipment]1--1[ShippingCharge],[Property]++-*[ProductProperty],[Property]++-*[Product],[Checkout]1--Bill Addres-1[Addres],[Checkout]1--Shipments-.-1[Shipment],[Taxonomy]++-*[Taxon],[Taxonomy]1--Root-1[Taxon],[Prototype]*--*[Property],[LineItem]1--1[Product],[Adjustment]1--1[AdjustmentSource],[Calculator]1--1[Calculable],[Preference]1--1[Owner],[Preference]1--1[Group],[Creditcard]1--1[Checkout],[Creditcard]1--1[Addres],[Creditcard]++-*[CreditcardPayment],[StateEvent]1--1[User],[OptionType]++-*[OptionValue],[OptionType]++-*[ProductOptionType],[OptionType]*--*[Prototype],[ZoneMember]1--1[Zoneable],[TaxCategory]++-*[TaxRate],[OptionValue]*--*[Variant],[ProductGroup]++-*[ProductScope],[ShippingMethod]++-*[ShippingRate],[ShippingMethod]++-*[Shipment],[ShippingCategory]++-*[ShippingRate],[Configuration]^-[AppConfiguration],[Payment]^-[CreditcardPayment],[CreditcardPayment]++-*[CreditcardTxn],[Adjustment]^-[Charge],[Adjustment]^-[Credit],[Charge]^-[TaxCharge],[Credit]^-[CouponCredit],[Charge]^-[ShippingCharge]"><img src="http://yuml.me/diagram/scruffy/class/[Zone]++-*[ZoneMember],[Zone]++-*[TaxRate],[Zone]++-*[ShippingMethod],[User]++-*[Order],[User]*--*[Role],[User]1--Ship Addres-1[Addres],[User]1--Bill Addres-1[Addres],[Asset]1--1[Viewable],[Asset]^-[Image],[Order]++-*[StateEvent],[Order]++-*[LineItem],[Order]++-*[InventoryUnit],[Order]++-*[Payment],[Order]++-*[CreditcardPayment],[Order]1--1[Checkout],[Order]1--1[BillAddres],[Order]++-*[Shipment],[Order]++-*[Adjustment],[Order]++-*[Charge],[Order]++-*[Credit],[Order]++-*[ShippingCharge],[Order]++-*[TaxCharge],[Order]++-*[CouponCredit],[Order]++-Non Zero Charge-*[Charge],[State]1--1[ZoneMember],[State]1--1[Zone],[Coupon]++-*[CouponCredit],[Variant]++-*[InventoryUnit],[Variant]++-*[LineItem],[Variant]++-*[Image],[Country]++-*[State],[Country]1--1[ZoneMember],[Country]1--1[Zone],[Address]1--1[Country],[Address]1--1[State],[Address]++-*[Checkout],[Address]++-*[Shipment],[Product]++-*[ProductOptionType],[Product]++-*[OptionType],[Product]++-*[ProductProperty],[Product]++-*[Image],[Product]1--1[TaxCategory],[Product]*--*[Taxon],[Product]1--1[ShippingCategory],[Product]1--Master-1[Variant],[Product]++-*[Variant],[Product]++-Variants Including Master-*[Variant],[Shipment]1--1[Addres],[Shipment]1--1[ShippingCharge],[Property]++-*[ProductProperty],[Property]++-*[Product],[Checkout]1--Bill Addres-1[Addres],[Checkout]1--Shipments-.-1[Shipment],[Taxonomy]++-*[Taxon],[Taxonomy]1--Root-1[Taxon],[Prototype]*--*[Property],[LineItem]1--1[Product],[Adjustment]1--1[AdjustmentSource],[Calculator]1--1[Calculable],[Preference]1--1[Owner],[Preference]1--1[Group],[Creditcard]1--1[Checkout],[Creditcard]1--1[Addres],[Creditcard]++-*[CreditcardPayment],[StateEvent]1--1[User],[OptionType]++-*[OptionValue],[OptionType]++-*[ProductOptionType],[OptionType]*--*[Prototype],[ZoneMember]1--1[Zoneable],[TaxCategory]++-*[TaxRate],[OptionValue]*--*[Variant],[ProductGroup]++-*[ProductScope],[ShippingMethod]++-*[ShippingRate],[ShippingMethod]++-*[Shipment],[ShippingCategory]++-*[ShippingRate],[Configuration]^-[AppConfiguration],[Payment]^-[CreditcardPayment],[CreditcardPayment]++-*[CreditcardTxn],[Adjustment]^-[Charge],[Adjustment]^-[Credit],[Charge]^-[TaxCharge],[Credit]^-[CouponCredit],[Charge]^-[ShippingCharge]" width="590" height="351" /></a></p>
<h3>How?</h3>
<p>All of these diagrams were generated automatically with a simple <a href="http://yardoc.org">YARD</a> handler and piped into <a href="http://yuml.me">yUML</a>. The code is on gist:</p>
<p> <script src="http://gist.github.com/246017.js"></script></p>]]></content:encoded>
			<wfw:commentRss>http://gnuu.org/2009/11/30/auto-generated-er-diagrams-of-popular-rails-projects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Generate YARD Docs for Your Gem</title>
		<link>http://gnuu.org/2009/11/21/generate-yard-docs-for-your-gem/</link>
		<comments>http://gnuu.org/2009/11/21/generate-yard-docs-for-your-gem/#comments</comments>
		<pubDate>Sat, 21 Nov 2009 06:42:00 +0000</pubDate>
		<dc:creator>Loren Segal</dc:creator>
				<category><![CDATA[post]]></category>

		<guid isPermaLink="false">http://gnuu.org/2009/11/21/generate-yard-docs-for-your-gem/</guid>
		<description><![CDATA[A little tidbit that most people don’t know about is that since 0.2.3.5, YARD can actually be used in place of RDoc to generate documentation when a gem is installed. All you need to do is add the following to your .gemspec:
SPEC = Gem::Specification.new do &#124;s&#124;
  ...
  s.has_rdoc = 'yard'
end
If you use BlueCloth [...]]]></description>
			<content:encoded><![CDATA[<p>A little tidbit that most people don’t know about is that since 0.2.3.5, YARD can actually be used in place of RDoc to generate documentation when a gem is installed. All you need to do is add the following to your <tt>.gemspec</tt>:</p>
<pre class="sh_ruby">SPEC = Gem::Specification.new do |s|
  ...
  s.has_rdoc = 'yard'
end</pre>
<p class="note">If you use BlueCloth or another lib to do your markdown processing, you&#8217;ll need to add that as a dependency to your gem.</p>
<p>And with that, YARD will generate docs when your gem is installed if YARD is on the user&#8217;s system. This works with RubyGems 1.3.1+. Best part of all, it integrates perfectly seamlessly with your RubyGems doc server. <tt>gem server</tt> will show YARD docs for the rdoc link of your project.</p>
<h3>Comments</h3>
<div id="disqus_thread"></div>
<p><script>disqus_developer = 1</script><script type="text/javascript" src="http://disqus.com/forums/gnuu/embed.js"></script></p>]]></content:encoded>
			<wfw:commentRss>http://gnuu.org/2009/11/21/generate-yard-docs-for-your-gem/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Customizing YARD Templates</title>
		<link>http://gnuu.org/2009/11/18/customizing-yard-templates/</link>
		<comments>http://gnuu.org/2009/11/18/customizing-yard-templates/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 18:20:38 +0000</pubDate>
		<dc:creator>Loren Segal</dc:creator>
				<category><![CDATA[post]]></category>

		<guid isPermaLink="false">http://gnuu.org/?p=283</guid>
		<description><![CDATA[I usually sift over this little snippet of an extension when I give talks on YARD. I haven&#8217;t written it down until now because the templating system was pretty much up in the air for the last year or so. Now that the new templating system in YARD is out, I can finally explain in [...]]]></description>
			<content:encoded><![CDATA[<p>I usually sift over this little snippet of an extension when I give talks on YARD. I haven&#8217;t written it down until now because the templating system was pretty much up in the air for the last year or so. Now that the new templating system in YARD is out, I can finally explain in detail how simple it is to customize the existing YARD templates, or even create your own.</p>
<p><!-- more --></p>
<h2 id="the_use_case">The Use Case</h2>
<p>To show how it&#8217;s done, we&#8217;ll be implementing the following use case: we have a set of tests (RSpec syntax) that we want integrated and mentioned in our documentation. For those who haven&#8217;t used it, RSpec allows use to write our tests in the format:</p>
<pre class="sh_ruby">describe ClassName do
  describe '#method' do
    it "should behave like this" { ... }
    it "should behave like that" { ... }
  end
end
</pre>
<p>This syntax makes it very easy to integrate this information into our docs. We would want our <code>ClassName#method</code> method to list the following &#8220;Specifications&#8221;:</p>
<ul>
<li>should behave like this</li>
<li>should behave like that</li>
</ul>
<p>YARD does this in a two step process: the first is data processing (where source code is parsed) and the second is the template rendering (when our HTML docs are generated). I&#8217;ll be listing the code for the data processing but we&#8217;ll be mostly skimming over it as the focus of this article is on the templates.</p>
<h2 id="processing_the_specification_data">Processing the Specification Data</h2>
<p>The crux of our plugin is the following code. It parses through our RSpec tests, grabs and stores the necessary information for our templates:</p>
<p class="note">File listing: rspec_plugin.rb</p>
<pre class="sh_ruby">YARD::Templates::Engine.register_template_path Pathname.new(YARD::ROOT).join('..', 'templates_custom')
YARD::Parser::SourceParser.parser_type = :ruby18

class RSpecDescribeHandler &lt; YARD::Handlers::Ruby::Legacy::Base
  MATCH = /\Adescribe\s+(.+?)\s+(do|\{)/
  handles MATCH

  def process
    objname = statement.tokens.to_s[MATCH, 1].gsub(/["']/, '')
    obj = {:spec =&gt; owner ? (owner[:spec] || "") : ""}
    obj[:spec] += objname
    parse_block :owner =&gt; obj
  end
end

class RSpecItHandler &lt; YARD::Handlers::Ruby::Legacy::Base
  MATCH = /\Ait\s+['"](.+?)['"]\s+(do|\{)/
  handles MATCH

  def process
    return if owner.nil?
    obj = P(owner[:spec])
    return if obj.is_a?(Proxy)

    (obj[:specifications] ||= []) &lt;&lt; {
      :name =&gt; statement.tokens.to_s[MATCH, 1],
      :file =&gt; parser.file,
      :line =&gt; statement.line,
      :source =&gt; statement.block.to_s
    }
  end
end
</pre>
<p>The first line registers our custom template path for when we override our templates (later on). This can also be specified at the command line (we will see that method too). We also have to set the parser to use the legacy parser API. We can write this to support the Ruby-1.9-only parser as well, but I want to keep it universal and simple (the legacy API works in both 1.8 and 1.9). There is also a command line switch to enable the legacy parser.</p>
<p>It&#8217;s likely that you can get a general sense of what the rest of the code does. Basically, it builds up the object name whenever it reads a &#8220;describe&#8221; statement, and attaches any &#8220;it&#8221; statements to the object that it&#8217;s currently pointing to. We can now access these specifications in our templates from the <code>specifications</code> attribute we set on the object.</p>
<p>This file will be loaded into yard when we call <code>yardoc</code> and the data will be collected and rendered properly. We will see the exact command arguments later.</p>
<h2 id="a_crash_course_in_the_templates_api">A Crash Course in the Templates API</h2>
<p>The new template system in YARD allows for users to non-intrusively modify existing templates by (literally) &#8220;mixing in&#8221; features from other templates and overriding behaviour at a very granular level. In our case, we want to inject a segment of HTML (or plaintext) in the middle of the existing YARD templates, but we don&#8217;t want to directly modify the templates. </p>
<p>Each template is represented by a directory inside one of our template paths. It is also represented by a logical module automatically defined in code for us. For instance, the template at the path &#8220;default/method&#8221; will be managed by the module <code>YARD::Templates::Engine::Template__default_method</code>. We can use this module to define helpers and most importantly mix in (or inherit) other templates in order to override behaviour.</p>
<p>Inside each directory sits an optional <code>setup.rb</code> file which defines the body of our logical module. This is where we can include (literally) other templates. This is also where we define our &#8220;sections&#8221;. Sections (kind of like partials) are what make up the template. A <code>setup.rb</code> file will generally have an <code>#init</code> method which calls <code>sections</code> to set the list of sections the template uses. A section can either be a method, .erb file or another template. Basically, when our template is rendered, the resulting String will be the result of running each individual section. A standard <code>setup.rb</code> file looks like:</p>
<pre class="sh_ruby">def init
  sections :section1, :section2, ...
end

def optional_helper_method; ... end
</pre>
<p class="note">If section1 and section2 are not defined methods, they will be rendered as erb files with the filenames of section1.erb and section2.erb respectively.</p>
<p>You might now see how we can override and add custom data by &#8220;inheriting&#8221; such a template and then modifying the sections list like so:</p>
<pre class="sh_ruby">def init
  super
  sections.push :mysection
end
</pre>
<p>We could also insert our section into the middle by using some YARD extensions to the Array class:</p>
<pre class="sh_ruby">def init
  super
  sections.place(:mysection).before(:section2)
end
</pre>
<p>This is essentially what we will be doing with our RSpec templates.</p>
<h2 id="creating_the_templates">Creating the Templates</h2>
<p>Using that basic overview above, we will be modifying the <code>"default/method_details"</code> template in YARD by overriding it in our own custom template path, inserting our section in the init method and adding the necessary .erb file. The directory structure will look like this:</p>
<p><img src="http://gnuu.org/wp-content/uploads/2009/10/directory_structure.png" alt="Directory Structure" title=""></p>
<p>You can see our setup.rb file and specs.erb files. Notice that we are defining the template for multiple formats, html and text. YARD looks for the template at &#8220;template/FORMAT&#8221; to support multiple formats for a template. As mentioned above, any directory, including subdirectories, is a template. In addition, any subdirectory will automatically inherit the parent directory template, which is incidentally where our setup.rb resides. This allows us to define the sections used by all our formats at once.</p>
<p>One extra trick not mentioned in the previous section is that we are following the exact directory structure of the YARD templates themselves. Whenever a template is found in another template path with a matching directory structure, it is also automatically included (or inherited from). So by registering our custom template path and following the same structure, we are implicitly inheriting all of the templates and have the ability to override them with classic Ruby OOP.</p>
<p>Okay, enough with the confusion, here is the code for the three files in the above diagram: </p>
<p class="note">File listing: setup.rb</p>
<pre class="sh_ruby">def init
  super
  sections.last.place(:specs).before(:source)
end
</pre>
<p>You may notice this is almost exactly what we saw in the crash course. We override an included template, which in our case is the template sitting in YARD&#8217;s <code>templates/default/method_list</code>.</p>
<p>Now for the erb files:</p>
<p class="note">Fie listing: templates_custom/default/method_details/html/specs.erb</p>
<pre class="sh_ruby">&lt;% if object[:specifications] %&gt;
&lt;div class="tags"&gt;
  &lt;h3&gt;Specifications:&lt;/h3&gt;
  &lt;ul class="see"&gt;
    &lt;% for spec in object[:specifications] %&gt;
      &lt;li&gt;&lt;%= spec[:name] %&gt;
        &lt;div class="source_code"&gt;
          &lt;table&gt;
            &lt;tr&gt;
              &lt;td&gt;
                &lt;pre class="lines"&gt;

&lt;%= spec[:source].split("\n").size.times.to_a.map {|i| spec[:line] + i }.join("\n") %&gt;&lt;/pre&gt;
              &lt;/td&gt;
              &lt;td&gt;
                &lt;pre class="code"&gt;&lt;span class="info file"&gt;# File '&lt;%= h spec[:file] %&gt;', line &lt;%= spec[:line] %&gt;&lt;/span&gt;

&lt;%= html_syntax_highlight format_source(spec[:source]) %&gt;&lt;/pre&gt;
              &lt;/td&gt;
            &lt;/tr&gt;
          &lt;/table&gt;
        &lt;/div&gt;
      &lt;/li&gt;
    &lt;% end %&gt;
  &lt;/ul&gt;
&lt;/div&gt;
&lt;% end %&gt;
</pre>
<p>To support the plaintext format (used by the <code>yri</code> tool), we can add the following:</p>
<p class="note">File listing: templates_custom/default/method_details/text/specs.erb</p>
<pre class="sh_ruby">&lt;% if object[:specifications] %&gt;

Specifications:
---------------

&lt;% for spec in object[:specifications] %&gt;
&lt;%= indent wrap("- " + spec[:name]) %&gt;
&lt;% end %&gt;
&lt;% end %&gt;
</pre>
<p>Both templates are fairly straightforward. Let&#8217;s use them!</p>
<h2 id="putting_it_all_together">Putting it All Together</h2>
<p>We now have our <code>rspec_plugin.rb</code> and our <code>templates_custom</code> directory sitting somewhere. We can generate YARD documentation for our code and specs using the command</p>
<pre>$ yardoc -e rspec_plugin 'lib/**/*.rb' 'spec/**/*.rb'</pre>
<p>This loads our <code>rspec_plugin.rb</code> file and uses the handler to parse our specs (after parsing our regular code). It then uses the registered template path (<code>templates_custom</code>, defined in our .rb file) to find our overridden templates. </p>
<p>I mentioned earlier that we can specify the template path in the command line and tell YARD to use the legacy parser. Here&#8217;s how:</p>
<pre>$ yardoc --legacy -e rspec_plugin -p templates_custom 'lib/**/*.rb' 'spec/**/*.rb'</pre>
<p>Our docs should now have an extra section in them. Here&#8217;s what YARD&#8217;s <code><a href="http://yardoc.org/docs/yard/YARD/Templates/Engine.render">YARD::Templates::Engine.render</a></code> method looks like with specifications:</p>
<p><img src="http://gnuu.org/wp-content/uploads/2009/10/specdoc.png" alt="Documentation with RSpec Specifications" title=""></p>
<h2>Packaging as a Plugin</h2>
<p>Until now we&#8217;ve been manually loading our ruby script &#8216;rspec_plugin.rb&#8217; whenever we call yardoc. This is simple for per-project customization, but when you want to use multiple customizations, it becomes difficult. YARD 0.4.x adds support for plugins by auto-loading any gem starting with the prefix <tt>yard-</tt>. This means we can <a href="http://blogs.cocoondev.org/crafterm/archives/004653.html">create a gem</a> for our code, install it and have YARD load our plugin when it boots up. For example, this plugin can be found by running the following command</p>
<pre>$ sudo gem install yard-rspec --source http://gemcutter.org</pre>
<p>Now, whenever you run yardoc or yri, YARD will automatically document RSpec code. Just remember to add <tt>spec/**/*.rb</tt> to your file path. We can now see our text templates in action:</p>
<pre>$ yri ClassName#method</pre>
<h2>Conclusion</h2>
<p>This method of template customization in YARD can be applied to many other situations and is what makes it far more powerful than RDoc when it comes to properly documenting Ruby code. The other great part about YARD templates is that multiple plugins can make independent modifications to a template with very little conflict. This RSpec plugin can be used in tandem with your own custom plugins and you wouldn&#8217;t have to rewrite either one in order to use them together.</p>
<p>Now go, create your own awesome templates!</p>
<p class="note">Source code for the yard-rspec plugin can be found on GitHub at <a href="http://github.com/lsegal/yard-spec-plugin">http://github.com/lsegal/yard-spec-plugin</a></p>]]></content:encoded>
			<wfw:commentRss>http://gnuu.org/2009/11/18/customizing-yard-templates/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>YARD 0.4.0 (The Whole Nine) Released Today</title>
		<link>http://gnuu.org/2009/11/15/yard-0-4-0-the-whole-nine/</link>
		<comments>http://gnuu.org/2009/11/15/yard-0-4-0-the-whole-nine/#comments</comments>
		<pubDate>Sun, 15 Nov 2009 18:04:33 +0000</pubDate>
		<dc:creator>Loren Segal</dc:creator>
				<category><![CDATA[post]]></category>
		<category><![CDATA[developer tools]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[release]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby 1.9]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[yard]]></category>

		<guid isPermaLink="false">http://gnuu.org/?p=317</guid>
		<description><![CDATA[YARD 0.4.0 (codenamed The Whole Nine) was just released today. It’s by far the biggest release since I started writing YARD in 2007. For those who don’t know, YARD is a Ruby documentation tool that surpasses the features of RDoc to bring much richer docs and extensibility to documenteurs. There’s plenty of new features to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://yardoc.org">YARD 0.4.0</a> (codenamed The Whole Nine) was just released today. It’s by far the biggest release since I started writing YARD in 2007. For those who don’t know, YARD is a Ruby documentation tool that surpasses the features of RDoc to bring much richer docs and extensibility to documenteurs. There’s plenty of new features to discuss and plenty of new toys to show off (new templates, live doc server with user comments, new APIs, plugin support), so let’s get started.</p>
<p> </p>]]></content:encoded>
			<wfw:commentRss>http://gnuu.org/2009/11/15/yard-0-4-0-the-whole-nine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Get Ruby 1.9, Rails, MySQL and UTF-8 to Work Together</title>
		<link>http://gnuu.org/2009/11/06/ruby19-rails-mysql-utf8/</link>
		<comments>http://gnuu.org/2009/11/06/ruby19-rails-mysql-utf8/#comments</comments>
		<pubDate>Sat, 07 Nov 2009 02:01:33 +0000</pubDate>
		<dc:creator>Loren Segal</dc:creator>
				<category><![CDATA[post]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby 1.9]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[unicode]]></category>
		<category><![CDATA[utf-8]]></category>

		<guid isPermaLink="false">http://gnuu.org/2009/11/06/get-ruby-1-9-rails-mysql-and-utf-8-to-work-together/</guid>
		<description><![CDATA[Update: You can also try out my fork of mysql-ruby that is properly encoding aware. It doesn&#8217;t just convert everything to UTF-8, but rather to your default encoding, so make sure to set your LANG!
Here&#8217;s a quick little hack to get MySQL 2.8.1 using UTF-8 in Rails 2.3.4 and Ruby 1.9.1.
Filename: lib/mysql_utf8.rb


Put that snippet in [...]]]></description>
			<content:encoded><![CDATA[<p class="note"><strong>Update:</strong> You can also try out my <a href="http://github.com/lsegal/mysql-ruby">fork of mysql-ruby</a> that is properly encoding aware. It doesn&#8217;t just convert everything to UTF-8, but rather to your default encoding, so make sure to <a href="http://gnuu.org/2009/11/02/ruby-1-9-encoding-issues-again/">set your LANG</a>!</p>
<p>Here&#8217;s a quick little hack to get MySQL 2.8.1 using UTF-8 in Rails 2.3.4 and Ruby 1.9.1.</p>
<p class="note">Filename: lib/mysql_utf8.rb</p>
<p><script src="http://gist.github.com/228455.js"></script></p>
<p><!--
<pre class="sh_ruby">class Mysql::Result
  def encode(value, encoding = &#8220;utf-8&#8243;)
    String === value ? value.force_encoding(encoding) : value
  end

  def each_utf8(&#038;block)
    each_orig do |row|
      yield row.map {|col| encode(col) }
    end
  end
  alias each_orig each
  alias each each_utf8

  def each_hash_utf8(&#038;block)
    each_hash_orig do |row|
      row.each {|k, v| row[k] = encode(v) }
      yield(row)
    end
  end
  alias each_hash_orig each_hash
  alias each_hash each_hash_utf8
end</pre>
<p>--></p>
<p>Put that snippet in your Rails project (I used <tt>lib/mysql_utf8.rb</tt>) and load it in your environment.</p>
<p>That's all. Now your queries should use Unicode:</p>
<pre class="sh_ruby">$ ./script/console
Loading development environment (Rails 2.3.4)
&gt;&gt; u = User.find(1)
=&gt; #&lt;User id: 1, name: &quot;Test&quot;, ...&gt;
&gt;&gt; u.name.encoding
=&gt; #&lt;Encoding:ASCII-8BIT&gt;
&gt;&gt; require 'lib/mysql_utf8'
=&gt; []
&gt;&gt; u = User.find(1)
=&gt; #&lt;User id: 1, name: &quot;Test&quot;, ...&gt;
&gt;&gt; u.name.encoding
=&gt; #&lt;Encoding:UTF-8&gt;</pre>
<p>Note that if you have BLOB types in MySQL you’ll need to force_encoding back to another type. You could do this in your model.</p>]]></content:encoded>
			<wfw:commentRss>http://gnuu.org/2009/11/06/ruby19-rails-mysql-utf8/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Ruby 1.9 Encoding Issues, Again.</title>
		<link>http://gnuu.org/2009/11/02/ruby-1-9-encoding-issues-again/</link>
		<comments>http://gnuu.org/2009/11/02/ruby-1-9-encoding-issues-again/#comments</comments>
		<pubDate>Tue, 03 Nov 2009 04:45:39 +0000</pubDate>
		<dc:creator>Loren Segal</dc:creator>
				<category><![CDATA[post]]></category>
		<category><![CDATA[encoding]]></category>
		<category><![CDATA[problems]]></category>
		<category><![CDATA[ruby 1.9]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[unicode]]></category>

		<guid isPermaLink="false">http://gnuu.org/2009/11/02/ruby-1-9-encoding-issues-again/</guid>
		<description><![CDATA[I covered Ruby 1.9 encodings a while back on my blog, but apparently I left out a few other major issues. I noticed these just recently, when running 1.9 on a new environment. It turns out, tweaking your environment is all it takes to fix most of the issues, and I had already done this [...]]]></description>
			<content:encoded><![CDATA[<p>I covered Ruby 1.9 encodings <a href="http://gnuu.org/2009/02/02/ruby-19-common-problems-pt-1-encoding/">a while back</a> on my blog, but apparently I left out a few other major issues. I noticed these just recently, when running 1.9 on a new environment. It turns out, tweaking your environment is all it takes to fix most of the issues, and I had already done this on my main machine.</p>
<p>So here we go, the issue:</p>
<h3>You’re using Rails, and you see this:</h3>
<blockquote><p>invalid byte sequence in US-ASCII</p>
</blockquote>
<p>You might also see:</p>
<blockquote><p>incompatible character encodings: ASCII-8BIT and UTF-8</p>
</blockquote>
<p>That happens <em>all the time</em> when trying to get <a href="http://yard.soen.ca">YARD</a> to parse Rails source. It also happens when your ERB templates and your DB data have mismatched encodings.</p>
<h3>The Problem</h3>
<p> Ruby has multiple default encoding values: internal (the default encoding for new String objects), external (the default encoding for file data), and script (the default encoding of the content of Ruby scripts). When dealing with IO, you need to make sure both your internal and external encodings match up, especially since Ruby defaults to ASCII-7BIT and not UTF-8. The “script” encoding problems were covered in my <a href="http://gnuu.org/2009/02/02/ruby-19-common-problems-pt-1-encoding/">last blog post</a> on the subject.&#160;<br />
<h3>The Fix</h3>
<p>All you need to do is tweak your environment variables (your region / language may differ):</p>
<pre>$ export LANG=en_US.UTF-8</pre>
<p>Now Ruby will use UTF-8 for your external encodings: </p>
<pre>$ LANG=en_US.ASCII-7BIT irb19
&gt;&gt; __ENCODING__
=&gt; #&lt;Encoding:US-ASCII&gt;
$ LANG=en_US.UTF-8 irb19
&gt;&gt; __ENCODING__
=&gt; #&lt;Encoding:UTF-8&gt;</pre>
<p>Note, this doesn’t cover your default_internal, but usually this will be handled for you. And if you can’t set your ENV, you can set this stuff right in Ruby:</p>
<pre class="sh_ruby">Encoding.default_internal, Encoding.default_external = ['utf-8'] * 2</pre>
<p>This sets both your default internal and external encodings. </p>
<p>Now when Rails (well, ERB) tries to read files on disk, it will default to UTF-8 rather than ASCII, and your UTF-8 data from the DB will work just fine.</p>
<p>If you have this problem the other way around (your DB is ASCII), just reverse everything I said.</p>]]></content:encoded>
			<wfw:commentRss>http://gnuu.org/2009/11/02/ruby-1-9-encoding-issues-again/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
