<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Union Station</title>
	
	<link>http://www.engineyard.com/blog</link>
	<description>News from Engine Yard and the voices of our people.</description>
	<pubDate>Thu, 02 Jul 2009 17:03:38 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://www.engineyard.com/feed/" type="application/rss+xml" /><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Fwww.engineyard.com%2Ffeed%2F" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Fwww.engineyard.com%2Ffeed%2F" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Fwww.engineyard.com%2Ffeed%2F" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://www.engineyard.com/feed/" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Fwww.engineyard.com%2Ffeed%2F" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Fwww.engineyard.com%2Ffeed%2F" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Fwww.engineyard.com%2Ffeed%2F" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://www.plusmo.com/add?url=http%3A%2F%2Fwww.engineyard.com%2Ffeed%2F" src="http://plusmo.com/res/graphics/fbplusmo.gif">Subscribe with Plusmo</feedburner:feedFlare><feedburner:feedFlare href="http://www.thefreedictionary.com/_/hp/AddRSS.aspx?http%3A%2F%2Fwww.engineyard.com%2Ffeed%2F" src="http://img.tfd.com/hp/addToTheFreeDictionary.gif">Subscribe with The Free Dictionary</feedburner:feedFlare><feedburner:feedFlare href="http://www.bitty.com/manual/?contenttype=rssfeed&amp;contentvalue=http%3A%2F%2Fwww.engineyard.com%2Ffeed%2F" src="http://www.bitty.com/img/bittychicklet_91x17.gif">Subscribe with Bitty Browser</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsalloy.com/?rss=http%3A%2F%2Fwww.engineyard.com%2Ffeed%2F" src="http://www.newsalloy.com/subrss3.gif">Subscribe with NewsAlloy</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Fwww.engineyard.com%2Ffeed%2F" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><feedburner:feedFlare href="http://mix.excite.eu/add?feedurl=http%3A%2F%2Fwww.engineyard.com%2Ffeed%2F" src="http://image.excite.co.uk/mix/addtomix.gif">Subscribe with Excite MIX</feedburner:feedFlare><feedburner:feedFlare href="http://download.attensa.com/app/get_attensa.html?feedurl=http%3A%2F%2Fwww.engineyard.com%2Ffeed%2F" src="http://www.attensa.com/blogs/attensa/WindowsLiveWriter/BadgeredintoBadges_10C02/attensa_feed_button5.gif">Subscribe with Attensa for Outlook</feedburner:feedFlare><feedburner:feedFlare href="http://www.webwag.com/wwgthis.php?url=http%3A%2F%2Fwww.engineyard.com%2Ffeed%2F" src="http://www.webwag.com/images/wwgthis.gif">Subscribe with Webwag</feedburner:feedFlare><feedburner:feedFlare href="http://www.podcastready.com/oneclick_bookmark.php?url=http%3A%2F%2Fwww.engineyard.com%2Ffeed%2F" src="http://www.podcastready.com/images/podcastready_button.gif">Subscribe with Podcast Ready</feedburner:feedFlare><feedburner:feedFlare href="http://www.flurry.com/pushRssFeed.do?r=fb&amp;url=http%3A%2F%2Fwww.engineyard.com%2Ffeed%2F" src="http://www.flurry.com/images/flurry_rss_logo2.gif">Subscribe with Flurry</feedburner:feedFlare><feedburner:feedFlare href="http://www.wikio.com/subscribe?url=http%3A%2F%2Fwww.engineyard.com%2Ffeed%2F" src="http://www.wikio.com/shared/img/add2wikio.gif">Subscribe with Wikio</feedburner:feedFlare><feedburner:feedFlare href="http://www.dailyrotation.com/index.php?feed=http%3A%2F%2Fwww.engineyard.com%2Ffeed%2F" src="http://www.dailyrotation.com/rss-dr2.gif">Subscribe with Daily Rotation</feedburner:feedFlare><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
		<title>Rubinius: The Book Tour</title>
		<link>http://feedproxy.google.com/~r/engineyard/~3/lbBp9Iyp7KA/</link>
		<comments>http://www.engineyard.com/blog/2009/rubinius-the-book-tour/#comments</comments>
		<pubDate>Thu, 02 Jul 2009 16:00:11 +0000</pubDate>
		<dc:creator>Brian Ford</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[garbage collector]]></category>

		<category><![CDATA[LLVM]]></category>

		<category><![CDATA[rspec]]></category>

		<category><![CDATA[Rubinius]]></category>

		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[rubyspec]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=1424</guid>
		<description><![CDATA[Rubinius, which you've no doubt heard lots about over the last few years, is an implementation of the Ruby language written from scratch using cutting edge technology and the best industry research. Based on the questions we've received over the past few months, it's clear that a lot of folks are looking to learn more about the technologies behind the project. This is exciting because with so much written in Ruby, Rubinius positively begs Ruby developers to experiment and explore.]]></description>
			<content:encoded><![CDATA[<p>This year continues to be a hot one for the <a href="http://ruby-lang.org">Ruby programming language</a>. The <a href="http://bit.ly/eweek-ruby-use">use of Ruby is growing</a>, excitement is mounting for the release of Rails 3.0, and development of Ruby 1.9 and the alternative implementations is moving along quickly. It makes sense: bringing more value to your customers in less time with fewer resources is an obvious plus, and Ruby&#8217;s a great way to make that happen.</p>
<p><a href="http://rubini.us">Rubinius</a>, which you&#8217;ve no doubt heard lots about over the last few years, is an implementation of the Ruby language written from scratch using cutting edge technology and the best industry research. Based on the questions we&#8217;ve received over the past few months, it&#8217;s clear that a lot of folks are looking to learn more about the technologies behind the project. This is exciting because with so much written in Ruby, Rubinius positively <em>begs</em> Ruby developers to experiment and explore.</p>
<p>In this post I&#8217;ll describe each of the basic parts of Rubinius, and provide some helpful links to books that I&#8217;ve found particularly useful in understanding how Rubinius is built.</p>
<p>
<span id="more-1424"></span></p>
<h2>Bytecode Virtual Machine (VM)</h2>
<p><strong></strong>Similar to Java, Rubinius runs your Ruby source code by first compiling it to bytecode and then executing that bytecode on the virtual machine. It&#8217;s reasonable to think of a virtual machine as a CPU written in software. Virtual machines can be optimized to run very fast, which is one of the advantages over an interpreter like that used in Ruby 1.8.</p>
<p>A great deal of research on virtual machines has been done in the past 30 years, starting with Smalltalk and SELF and continuing with Java. <a href="http://blog.fallingsnow.net">Evan&#8217;s</a> first prototype of Rubinius was written in Ruby and based on the Smalltalk-80 virtual machine. Understanding something about virtual machines is definitely the gateway to modern programming language implementations.</p>
<blockquote><p><strong>The Books:</strong></p>
<ul>
<li><a href="http://bit.ly/virtual-machines-book"><em>Virtual Machines: Versatile Platforms for Systems and Processes</em></a></li>
<li><a href="http://bit.ly/smalltalk-80"><em>Smalltalk-80: The Language and its Implementation</em></a></li>
</ul>
</blockquote>
<h2>Bytecode Compiler</h2>
<p><strong></strong>Compilers are one of the most useful tools in computer science and have probably been researched more than any other area since the 1950s.</p>
<p>The Rubinius bytecode compiler is written entirely in Ruby. Every method defined in your Ruby source code is compiled into an instance of the CompiledMethod class. The compiled method contains a list of bytecodes that essentially provides a blueprint for how to carry out the computation described in the source code.</p>
<blockquote><p><strong>The Books:</strong></p>
<ul>
<li><a href="http://bit.ly/engineering-a-compiler-book"><em>Engineering A Compiler</em></a></li>
<li><a href="http://bit.ly/dragon-book"><em>Compilers: Principles, Techniques, and Tools</em></a></li>
<li><a href="http://bit.ly/advanced-compiler-design"><em>Advanced Compiler Design and Implementation</em></a></li>
</ul>
</blockquote>
<h2>Ruby Core Library</h2>
<p><strong></strong>Almost all programming languages provide a library with useful data structures and other facilities. Some of the Ruby core library classes include Array, Hash, String, Regexp, Range, Float, Fixnum, Bignum, and Thread.</p>
<p>In Rubinius, this is again written almost entirely in Ruby with some VM-specific parts. For example, adding two Fixnums requires special VM support because Ruby as a language has no constructs for telling a CPU to access memory locations, treat them as machine integers, and add them together.</p>
<p>The <em>algorithm</em> is one of the most fundamental ideas in computer science. Basically, it is an ordered set of steps to perform to solve a problem or do some calculation. Data structures, like Array in the core library, are implemented using various algorithms. The algorithm used must provide the correct answer and must be reasonably efficient.</p>
<p>Working with the Rubinius core library is probably the easiest way to get involved since it&#8217;s in Ruby! If you have experience with <a href="http://rspec.info">RSpec</a> in your Ruby or Rails projects, you&#8217;ll feel right at home using <a href="http://rubyspec.org">RubySpec</a> to work on the core library BDD-style.</p>
<blockquote><p><strong>The Books:</strong></p>
<ul>
<li><a href="http://bit.ly/algorithm-design-manual"><em>The Algorithm Design Manual, 2nd Edition</em></a></li>
</ul>
</blockquote>
<h2>Garbage Collector</h2>
<p>Taking out the garbage is a fact of life. Rubinius includes a precise, generational garbage collector with a moving semi-space collector for the young generation and an implementation of the <a href="http://bit.ly/immix-garbage-collector">Immix Mark-Region garbage collector</a> for the mature generation.</p>
<p>The performance of the garbage collector can have a big impact on how fast your code runs. With the change to the Immix collector and some improvements to the young generation, the percentage of time Rubinius spends in the garbage collector during a full RubySpec run dropped from nearly 50% to around 10%. Further improvement in this area is possible.</p>
<blockquote><p><strong>The Books:</strong></p>
<ul>
<li><a href="http://bit.ly/garbage-collection-book"><em>Garbage Collection: Algorithms for Automatic Dynamic Memory Management</em></a></li>
</ul>
</blockquote>
<h2>JIT Compiler</h2>
<p><strong></strong>A Just-in-time compiler generates native machine code from your source code <em>while</em> your program is running. Typically, the JIT compiles the code based on feedback about which parts are getting used the most. The parts that have been JIT compiled often run quite a bit faster than the VM. However, in a language as dynamic as Ruby, the JIT compiler can usually produce much more efficient code after the VM has run and gathered information about the code.</p>
<p>Rubinius uses the <a href="http://llvm.org">LLVM Compiler Toolkit</a> to implement the JIT compiler. The basic concepts from the compiler books above all apply here. Also, see the detailed <a href="http://llvm.org/docs/">LLVM documentation</a>.</p>
<p>That&#8217;s it for the book tour intro to Rubinius. I&#8217;ll be giving a more detailed talk at OSCON 2009 titled <a href="http://en.oreilly.com/oscon2009/public/schedule/detail/8480">Rubinius 1.0: The Ruby VM That Could</a>. Hope to see you there, or visit us in the <strong>#rubinius</strong> channel on irc.freenode.net to get involved!</p>
<img src="http://feeds.feedburner.com/~r/engineyard/~4/lbBp9Iyp7KA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.engineyard.com/blog/2009/rubinius-the-book-tour/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.engineyard.com/blog/2009/rubinius-the-book-tour/</feedburner:origLink></item>
		<item>
		<title>6 Steps To Refactoring Rails (for Mere Mortals)</title>
		<link>http://feedproxy.google.com/~r/engineyard/~3/XH836HiUGms/</link>
		<comments>http://www.engineyard.com/blog/2009/6-steps-to-refactoring-rails-for-mere-mortals/#comments</comments>
		<pubDate>Mon, 29 Jun 2009 16:00:33 +0000</pubDate>
		<dc:creator>Yehuda Katz</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[ActionController]]></category>

		<category><![CDATA[ActionView]]></category>

		<category><![CDATA[Agile Development]]></category>

		<category><![CDATA[edge]]></category>

		<category><![CDATA[Rails]]></category>

		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=1387</guid>
		<description><![CDATA[Since December, Rails has undergone a fairly significant internal refactoring in quite a number of areas. While it was quite tricky at first, we've started to hone a process for diving into a new area of the codebase and emerging some time later with a much improved area that does basically the same thing.]]></description>
			<content:encoded><![CDATA[<p>Since December, Rails has undergone a fairly significant internal refactoring in quite a number of areas. While it was quite tricky at first, we mere mortals have started to hone a process for diving into a new area of the codebase and emerging some time later with a much improved area that does basically the same thing. Here&#8217;s the approach we&#8217;ve adopted and advocate:</p>
<p><strong>First, refactoring needs to be refactoring, <em>not</em> revision.</strong> By that I mean that while you are in the process of invasively improving some code, it is not the appropriate time to <em>also</em> change the functionality of that code. If you do both at the same time, it will be difficult to track down whether a bug in the code is the result of refactoring or functionality changes.</p>
<p>We&#8217;ve held fast to this requirement for the Rails 3 work Carl and I have been doing, which has resulted in an <a href="http://intertwingly.net/blog/2009/06/13/Rails-Edge-Very-Stable-Lately">extremely stable edge</a>, despite making fairly invasive changes.</p>
<p><strong>Second, any kind of significant refactoring without tests is folly</strong>. The first thing you should do is take a look at the test suite for the area in question and beef it up if necessary.</p>
<p>Thankfully, Rails has a fairly reasonable test suite, and the addition of Sam Ruby&#8217;s <a href="http://intertwingly.net/blog/2009/05/15/Keeping-Up-With-Rails">Agile Web Development on Rails test suite</a> has provided an additional level of confidence in the changes we&#8217;re making.</p>
<p><strong>Third, once you&#8217;re ready to dive in, read through the code carefully</strong>. It can be tempting to just go in and hack away at a particularly egregious part of the codebase, but you&#8217;ll frequently be changing code that exists for a reason.</p>
<p>Something I&#8217;ve noticed both in Rails applications and in Rails itself is that code that looks very strange at the beginning of a period of refactoring tends to exist for a reason.</p>
<p><strong>Fourth, as you proceed, make very small changes, then run the full test suite after every change. </strong>Commit often. What you want to look for is cases where the boundary APIs around the code you&#8217;re writing are messy (so you have multiple ways in to a particular class or area of code where one would suffice).</p>
<p>One Rails example would be rendering a template in ActionView from ActionController. When I started in December, ActionController called into ActionView using a number of public and private APIs, so making any changes around those boundaries was very tricky. Some things we wanted to do, like <a href="http://yehudakatz.com/2009/06/18/and-the-pending-tests-they-shall-pass/">improve the way layouts were selected</a>, was too complex because of the number of ways templates and layouts were rendered.</p>
<p>The very first thing I did in the early days of the merge was work toward reducing the number of ways that ActionController told ActionView to render a template. In the end, we settled on just a single API: <code>render_template_from_controller</code>, which takes a Template object from the template to render, and a Template object for the layout. Once this was done, it became a lot easier to make changes on either side of the boundary, without fear that a small change in ActionView could break any number of things in ActionController.</p>
<p>Of course, this assumes that you understand what your boundaries <strong>are</strong>. This is something that&#8217;s learned over time, but a fundamental requirement in good refactoring is having functionality broken up into units that are easy to understand, with small surface area. This is commonly achieved using classes, which is a good starting point, but Ruby has other tricks up its sleeve as you get more advanced, like judicious use of modules (and the new Rails <code>ActiveSupport::Concern</code>).</p>
<p><strong>Fifth, once you have reasonable boundaries, dive in and start making changes.</strong> A pretty good rule of thumb is to clean up cases where a public API has started being used for private, internal use. This might mean that changing the internals of your code breaks the public functionality (which, again, should be sacrosanct during this process). Have a zero-tolerance policy for failing tests as you make small changes, especially as you separate out public and private functionality.</p>
<p>One example of this in Rails was extensive usage of ActionView&#8217;s public render method by private functionality. As a result, the public render method had snippets of code inside to handle special cases (like <code>render :file</code> taking a Template object). The solution in this case was to extract out the private functionality, and have the public <code>render</code> method as well as the private internals call the new extracted methods. This ensures that internal functionality is kept internally, where it can be refactored more easily.</p>
<p><strong>Sixth, don&#8217;t be afraid to <code>git reset --hard</code> if you find yourself sinking into quicksand,</strong> with rising confusion due to changes you made. Over the course of working with Rails, I&#8217;ve lost an hour or more at a time to changes made too rapidly and carelessly, and the only advice I can give is to give up on ratholes as early as you notice them.</p>
<p>So that&#8217;s it. Six easy steps to refactoring Rails.</p>
<img src="http://feeds.feedburner.com/~r/engineyard/~4/XH836HiUGms" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.engineyard.com/blog/2009/6-steps-to-refactoring-rails-for-mere-mortals/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.engineyard.com/blog/2009/6-steps-to-refactoring-rails-for-mere-mortals/</feedburner:origLink></item>
		<item>
		<title>Pair-Programming Should Be Co-Programming</title>
		<link>http://feedproxy.google.com/~r/engineyard/~3/-oNyGAy-DeY/</link>
		<comments>http://www.engineyard.com/blog/2009/pair-programming-should-be-co-programming/#comments</comments>
		<pubDate>Thu, 25 Jun 2009 14:00:12 +0000</pubDate>
		<dc:creator>Joe Arnold</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[agile]]></category>

		<category><![CDATA[co-programming]]></category>

		<category><![CDATA[Extreme Programming]]></category>

		<category><![CDATA[pair-programming]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=1276</guid>
		<description><![CDATA[Optimize your pair-programming environments not for a "driver" and "navigator," but for co-programming. A good co-programming environment should reduce the friction for any task. Create a shared environment where the pair can fully immerse themselves in the problem at hand. Make it easy for a member of the pair to 'fork' off and not interrupt flow. Remove any obstacles that get in the way of completing each other's sentences.]]></description>
			<content:encoded><![CDATA[<p>Back in 2005 a pair of Stanford students asked me if they could observe the pair-programming environment at the company I was working for. They were working on a project to challenge the notion that two people pair-programming had separate roles of &#8220;driver&#8221; and &#8220;navigator&#8221;  a common notion of how pair-programming should work at the time.  Back then, we had a traditional pair-programming setup: 1 desk, 1 keyboard and mouse, 1 computer and (of course) 2 people. What they observed was downright painful!</p>
<p>As one example, they recorded a session where someone was verbally dictating syntax and keyboard actions to their pair:</p>
<blockquote><p><strong>Hugh</strong>: So…<br />
<strong>Ilya</strong>: Parenthesis. So percent, getNewArgs… [Hugh types.]<br />
Exactly. So save off those two lines in the new method.<br />
<strong>Hugh</strong>: Uh…<br />
<strong>Ilya</strong>: Right…down, down, down, there we go.<br />
<strong>Hugh</strong>: So we…<br />
<strong>Ilya</strong>: So, percent getNewArgs equals percent args [Hugh<br />
types this line to terminal.] Uh, I think that&#8217;s it.<br />
<strong>Hugh</strong>: This?<br />
<strong>Ilya</strong>: Yeah, that&#8217;s all we want to do. Get rid of the blank line<br />
and close the new.</p>
<p class="footnote"><em>From a pair programming session revealing the perils where one person &#8220;drives&#8221; while the other &#8220;navigates.&#8221; Excerpt from &#8220;<a href="http://www.ipd.uka.de/Tichy/uploads/folien/134/chongSocialDynamicsofPairProgrammingICSE07.pdf">The Social Dynamics of Pair Programming</a>&#8220;</em></p>
<p><em></em></p></blockquote>
<p>This was clearly the wrong way to go about pair-programming. &#8220;Driver&#8221; and &#8220;navigator&#8221; was turning out to be closer to &#8220;driver&#8221; and &#8220;back-seat driver&#8221; and like all experiences of back-seat driving, it could be frustrating for the driver, and generally unproductive. What we&#8217;ve found at Engine Yard is that it&#8217;s far better to optimize the pair-programming environment not for a &#8220;driver&#8221; and &#8220;navigator,&#8221; but for <strong>co-programming</strong>.</p>
<p><img class="alignnone size-full wp-image-1284" src="http://www.engineyard.com/blog?getfile=1284" alt="Jon Crosby and Ezra Zygmuntowicz pair-programming at Engine Yard" width="480" height="322" /> <em></em></p>
<p><em>Jon Crosby and Ezra Zygmuntowicz pair-programming</em></p>
<p>A good co-programming environment should reduce the friction for any task, and has three rules:</p>
<ol>
<li>Create a shared environment, where the pair can fully immerse itself in the problem at hand.</li>
<li>Make it easy for a member of the pair to &#8216;fork&#8217; off and not interrupt flow.</li>
<li>Remove any obstacles that get in the way of completing each other&#8217;s <span style="text-decoration: line-through;">syntaxes</span> sentences.</li>
</ol>
<p><strong>The Engine Yard Pair-Programming Setup</strong></p>
<p><strong>Two keyboard and mouse sets:</strong> This alone dramatically improves a pairing environment. Often we see one member of the pair &#8216;hovering&#8217; over the keyboard &#8212; a non-verbal cue indicating that they want to take over. It&#8217;s amazing how effective code can be in expressing an idea over a verbal description or notepad sketches. No more oral syntax descriptions!</p>
<p><strong>Dedicated pair-workstations:</strong> Identical workstations with identical configurations, including editor. We use iMacs with nice big screens. Similar environments make it easy for pair switch-up. Everyone is familiar with the environment on the pair-stations, so there is no re-learning a new environment depending on who you happen to be pairing with.</p>
<p><strong>3-Computer Setup:</strong> Each pair brings their laptop to dock alongside the pairing station. This enables any pair to perform research, and kick-off long running processes, without losing context on the dedicated workstation. While it takes more discipline to stay on task, we think it&#8217;s worth the flexibility.</p>
<p>I don&#8217;t claim that this is the perfect environment for all situations; but it&#8217;s something that works well for us.</p>
<img src="http://feeds.feedburner.com/~r/engineyard/~4/-oNyGAy-DeY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.engineyard.com/blog/2009/pair-programming-should-be-co-programming/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.engineyard.com/blog/2009/pair-programming-should-be-co-programming/</feedburner:origLink></item>
		<item>
		<title>Introduction to BDD with Cucumber</title>
		<link>http://feedproxy.google.com/~r/engineyard/~3/1si2T6h2iNY/</link>
		<comments>http://www.engineyard.com/blog/2009/cucumber-introduction/#comments</comments>
		<pubDate>Tue, 23 Jun 2009 14:00:38 +0000</pubDate>
		<dc:creator>Dave Astels</dc:creator>
		
		<category><![CDATA[Flex]]></category>

		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[agile]]></category>

		<category><![CDATA[Agile Development]]></category>

		<category><![CDATA[BDD]]></category>

		<category><![CDATA[behaviour driven development]]></category>

		<category><![CDATA[cucumber]]></category>

		<category><![CDATA[gherkin]]></category>

		<category><![CDATA[Lolcode]]></category>

		<category><![CDATA[LOLZ]]></category>

		<category><![CDATA[rspec]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[TDD]]></category>

		<category><![CDATA[Test Driven Development]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=1324</guid>
		<description><![CDATA[Cucumber is a framework for writing and executing high level descriptions of your software’s functionality.  Call these tests, examples, specifications, whatever&#8230; it doesn’t matter too much. What I&#8217;m talking about has traditionally been called functional, integration, and/or system tests.  In XP terms this includes tests called Story Tests, Customer Tests, and/or Acceptance Tests.
One [...]]]></description>
			<content:encoded><![CDATA[<p><a rel="nofollow" href="http://cukes.info/">Cucumber</a> is a framework for writing and executing high level descriptions of your software’s functionality.  Call these tests, examples, specifications, whatever&#8230; it doesn’t matter too much. What I&#8217;m talking about has traditionally been called functional, integration, and/or system tests.  In XP terms this includes tests called Story Tests, Customer Tests, and/or Acceptance Tests.</p>
<p>One of Cucumber&#8217;s most compelling features is that it provides the ability to write these descriptions using plain text in your native language.  Cucumber’s language, Gherkin, is usable in a growing variety of human languages, including <a rel="nofollow" href="http://lolcode.com/">LOLZ</a>. The advantage of this is that these feature descriptions can be written and/or understood by non-technical people involved in the project.</p>
<p>One important thing to keep in mind is that Cucumber is NOT a replacement for RSpec, test/unit, etc.  It is not a low level testing/specification framework.</p>
<p>Cucumber plays a central role in a development approach called <a rel="nofollow" href="http://behaviour-driven.org/">Behaviour Driven Development</a> (BDD).</p>
<h4>A Bit About BDD</h4>
<p>Dan North describes BDD as “writing software that matters” [in <a rel="nofollow" href="http://www.pragprog.com/titles/achbd/the-rspec-book">The RSpec Book</a>] and outlines 3 principles:</p>
<ol>
<li><strong>Enough is enough</strong>: do as much planning, analysis, and design as you need, but no more.</li>
<li><strong>Deliver stakeholder value</strong>: everything you do should deliver value or increase your ability to do so.</li>
<li><strong>It’s a behavior</strong>: everyone involved should have the same way of talking about the system and what it <em>does</em>.</li>
</ol>
<p>BDD in its grandest sense is about communication and viewing your software as a system with behaviour.  BDD tools such as RSpec and Cucumber strive to enable you to describe the behavior of your software in a very understandable way:  understandable to everyone involved.<span id="more-1324"></span></p>
<h4>Features</h4>
<p>A feature is something that your software does (or should do), and generally corresponds to a user story and a way to tell when it’s finished and that it works.</p>
<p>The general format of a feature is:</p>
<blockquote>
<pre>Feature: &lt;short description&gt;
  &lt;story&gt;
  &lt;scenario 1&gt;
  ...
  &lt;scenario n&gt;</pre>
</blockquote>
<p>Within the definition of a feature you can provide a plain text description of the story.  You can use any format for this, but having some sort of template makes it easier to see the important bits of information with a quick glance.  Once of the more common template is discussed by Mike Cohn [in <a rel="nofollow" href="http://www.mountaingoatsoftware.com/books/2-user-stories-applied">User Stories Applied</a>]:</p>
<blockquote>
<pre>As a &lt;role&gt;
I want &lt;feature&gt;
so that &lt;business value&gt;</pre>
</blockquote>
<p>This format focuses us on three important questions:</p>
<ul>
<li> Who’s using the system?</li>
<li> What are they doing?</li>
<li> Why do they care?</li>
</ul>
<p>Here’s a sample story:</p>
<blockquote>
<pre>As a code-breaker
I want to start a game
So that I can break the code</pre>
</blockquote>
<p>That defines who the user is <em>(a code-breaker)</em>, what they want to do <em>(start a game)</em> and why <em>(be able to break the code)</em>.<!--more--></p>
<h4>Scenarios</h4>
<p>A feature is defined by one or more scenarios.  A scenario is a sequence of steps through the feature that exercises one path.  Cucumber uses the BDD style that Dan North put forth with his jBehave project: <em>given</em>-<em>when</em>-<em>then</em>.</p>
<p>A scenario is made up of 3 sections related to the 3 types of steps:</p>
<ol>
<li> <strong><em>Given</em></strong>: This sets up preconditions, or context, for the scenario.  It works much like the <code>setup</code> in xUnit and <code>before</code> blocks in RSpec.</li>
<li> <strong><em>When</em></strong>: This is what the feature is talking about, the action, the behaviour that we’re focused on.</li>
<li> <strong><em>Then</em></strong>: This checks postconditions… it verifies that the right thing happen in the <em>When</em> stage.</li>
</ol>
<p>The general form of a scenario is:</p>
<blockquote>
<pre>Scenario: &lt;description&gt;
  &lt;step 1&gt;
  …
  &lt;step n&gt;</pre>
</blockquote>
<p>Following our example, here’s a scenario:</p>
<blockquote>
<pre>Scenario: start game
  Given I am not yet playing
  When I start a new game
  Then the game should say “Welcome to CodeBreaker”
  And the game should say “Enter guess:”</pre>
</blockquote>
<p>One thing to note is the last line.  Notice the <em>And</em>.  <em>And</em> can be used in any of the three sections.  It serves as a nice shorthand for repeating the <em>Given</em>, <em>When</em>, or <em>Then</em>. And stands in for whatever the most recent explicitly named step was: <em>Given</em>, <em>When</em>, or <em>Then</em>. The last two lines above could have been:</p>
<blockquote>
<pre>Then the game should say “Welcome to CodeBreaker”
Then the game should say “Enter guess:”</pre>
</blockquote>
<p>That doesn’t read nearly as well, though.  Similarly, if you want to state a negative <em>Then</em> step, you can use <em>But</em> in place of <em>Then</em>, for example:</p>
<blockquote>
<pre>Then the game should say “Welcome to CodeBreaker”
But the game should not say “Save the cheerleader, save the world”</pre>
</blockquote>
<p>While there are no constraints on the number or order of steps, it is generally best to keep scenarios as simple as possible and have multiple simple scenarios.  The closer your scenarios conform to the <em>given</em>-<em>when</em>-<em>then</em> format, the better.</p>
<h4>Implementing Steps</h4>
<p>So here&#8217;s our feature:</p>
<blockquote>
<pre>Feature: code-breaker starts game
  As a code-breaker
  I want to start a game
  So that I can break the code
  Scenario: start game
    Given I am not yet playing
    When I start a new game
    Then the game should say “Welcome to CodeBreaker”
    And the game should say “Enter guess:”</pre>
</blockquote>
<p>If you run that you’ll see an echo of the feature followed by (using Cucumber 0.3.11):</p>
<blockquote>
<pre>1 scenario (1 undefined)
4 steps (4 undefined)
0m0.001s
You can implement step definitions for undefined steps with these snippets:
Given /^I am not yet playing$/ do
  pending
end
When /^I start a new game$/ do
  pending
end
Then /^the game should say “Welcome to CodeBreaker”$/ do
  pending
end
Then /^the game should say “Enter guess:”$/ do
  pending
end</pre>
</blockquote>
<p>The next step (pardon the pun) is to define what each of our steps mean.  When we executed our feature with no steps defined, Cucumber gave us skeletons for the undefined steps (see above). If we put those in the file features/step_definitions/codebreaker.rb and run it again, we get:</p>
<blockquote>
<pre>1 scenario (1 pending)
4 steps (3 skipped, 1 pending)</pre>
</blockquote>
<p>As you can see from above, the basic structure of a step definition is the keyword (i.e. <em>Given</em>, <em>When</em>, or <em>Then</em>) followed by a regular expression and a block of Ruby code.  The regular expression is used to identify the desired step implementation.  The step text in scenarios is matched against the regular expressions of appropriate (i.e. <em>given</em>, <em>when</em>, or <em>then</em>) step implementations to find the one to use. When a match is found, the substrings matching any groups in the regular expression are used as arguments to the block which is then evaluated.  The result of that evaluation is discarded.  Note that these arguments are <strong>always</strong> strings.  If you need them converted to other types, it&#8217;s up to you to do that conversion in the block.  These groups and parameters have knowledge of position (i.e.. group 1 is used as the first parameter, group 2 as the second, and so on).</p>
<p>Notice that the suggested steps are completely concrete.  While that is fine some of the time, you will generally want to refactor steps and make them more generic and reusable. Notice that there are two <em>then</em> step definitions that are much the same:</p>
<blockquote>
<pre>Then /^the game should say “Welcome to CodeBreaker”$/ do
end
Then /^the game should say “Enter guess:”$/ do
end</pre>
</blockquote>
<p>The difference is the string inside quotes <em>(using quotes or similar delimiters is very handy for matching the groups)</em>.  We can factor that out into a regex group:</p>
<blockquote>
<pre>Then /^the game should say “(.*)”$/ do |message|
end</pre>
</blockquote>
<p>Our <em>given</em> step could be:</p>
<blockquote>
<pre>Given /^I am not yet playing$/ do
  @game = Codebreaker::Game.new
end</pre>
</blockquote>
<p>Next is the <em>when</em> step:</p>
<blockquote>
<pre>When /^I start a new game$/ do
end</pre>
</blockquote>
<p>This might be implemented as:</p>
<blockquote>
<pre>When /^I start a new game$/ do
    @messages = @game.start
end</pre>
</blockquote>
<p>Now we have the variable <code>@messages</code> that can be used in subsequent steps.</p>
<p>Recall how we left our <em>then</em> step definition:</p>
<blockquote>
<pre>Then /^the game should say “(.*)”$/ do |message|
end</pre>
</blockquote>
<p>We can now fill this in:</p>
<blockquote>
<pre>Then /^the game should say “(.*)”$/ do |message|
  @messages.should include(message)
end</pre>
</blockquote>
<p>You can use whatever method of verification you want in the <em>then</em> steps: rspec, test/unit, shoulda, etc.  I happen to prefer RSpec.</p>
<p>Earlier I mentioned that Cucumber supports various languages including LOLZ.  Here’s a feature in LOLZ:</p>
<blockquote>
<pre>OH HAI: STUFFING
 MISHUN: CUCUMBR
    I CAN HAZ IN TEH BEGINNIN 3 CUCUMBRZ
    WEN I EAT 2 CUCUMBRZ
    DEN I HAZ 2 CUCUMBERZ IN MAH BELLY
    AN IN TEH END 1 CUCUMBRZ KTHXBAI</pre>
</blockquote>
<p>And the step implementations:</p>
<blockquote>
<pre>ICANHAZ /^IN TEH BEGINNIN (\d+) CUCUMBRZ$/ do |n|
  @basket = Basket.new(n.to_i)
end
WEN /^I EAT (\d+) CUCUMBRZ$/ do |n|
  @belly = Belly.new
  @belly.eat(@basket.take(n.to_i))
end
DEN /^I HAZ (\d+) CUCUMBERZ IN MAH BELLY$/ do |n|
  @belly.cukes.should == n.to_i
end
DEN /^IN TEH END (\d+) CUCUMBRZ KTHXBAI$/ do |n|
  @basket.cukes.should == n.to_i
end</pre>
</blockquote>
<p>And that&#8217;s all there is to understanding the basics of Cucumber.</p>
<img src="http://feeds.feedburner.com/~r/engineyard/~4/1si2T6h2iNY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.engineyard.com/blog/2009/cucumber-introduction/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.engineyard.com/blog/2009/cucumber-introduction/</feedburner:origLink></item>
		<item>
		<title>A Quick Primer on Sharding for Ruby on Rails</title>
		<link>http://feedproxy.google.com/~r/engineyard/~3/Ub2N9aoMvTw/</link>
		<comments>http://www.engineyard.com/blog/2009/a-quick-primer-on-sharding-for-ruby-on-rails/#comments</comments>
		<pubDate>Thu, 18 Jun 2009 14:00:33 +0000</pubDate>
		<dc:creator>Greg Nokes</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Database sharding]]></category>

		<category><![CDATA[Filesystem sharding]]></category>

		<category><![CDATA[Rails Performance]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[Scalability]]></category>

		<category><![CDATA[Scaling Rails]]></category>

		<category><![CDATA[Scaling Ruby on Rails]]></category>

		<category><![CDATA[sharding]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=1316</guid>
		<description><![CDATA[If your application is filesystem IOPS heavy, filesystem sharding might be the route that you want to look at. Basically you add more hardware disk arrays, and split the reads and writes between them. You need to inject some logic into the save and open functions in your application so that it knows which filesystem each file is to be saved to and opened from. ]]></description>
			<content:encoded><![CDATA[<p>Sharding is usually the final strategy to reach for when scaling a Ruby on Rails app: <a href="http://www.engineyard.com/blog/2009/5-tips-to-scale-your-ror-application/">caching, offloading, and data segmentation</a> are usually the first strategies to implement when scaling your application (they&#8217;re usually easier). </p>
<p>It probably sounds obvious, but it&#8217;s always important to find out what part of your application needs help before you start re-architecting. If you&#8217;re having issues with your database, and you build a spiffy disk sharding scheme, you&#8217;ve just fixed a problem that doesn&#8217;t exist. So, doing the proper discovery will allow you to allocate your efforts for best effect.</p>
<p>Finding your performance hotspots is very important in this process. A hotspot is a point in the architecture where you&#8217;re running at high percentages of capacity, or where your application is spending a lot of time. Hotspots are where the flames start. Knowing your points of pain allow you to triage correctly, and to know how to best spend your developers&#8217; time. Using a combination of resource monitoring (like nagios) and performance introspection (like New Relic) is essential to identifying your Ruby on Rails hotspots.</p>
<p>One of the things to keep in mind is that this process is ongoing. When you clear out one hotspot generally another one will pop up to take its place as you grow. You might be optimizing disk reads and writes one week, and be neck deep in a SQL re-write the next.</p>
<p>If you have a proper staging setup, you can build estimates against generated traffic. This can give you a (blurry) view into what the next hotspot might be. A good process is to capture an hour or so worth of traffic on the live site, and replay it two, three, or more times faster against the staging environment. You want the traffic to be as real as possible. You can even go further and do a formal load test using a tool like <a href="http://www.browsermob.com" rel="nofollow">browsermob.</a></p>
<h2>When to go deep, and when to go long</h2>
<p>After you have killed all of the hotspots you can, and added all the resources you can afford, it&#8217;s time to look at the next level. Usually this is when you start to see people thinking about sharding of some manner. There are three major types of sharding at the moment - File System, Database and Application. I&#8217;ll touch on each of these topics, starting with the highest level, and hardest.</p>
<p><strong>Ruby on Rails Application Sharding?</strong></p>
<p>Application sharding is the most extreme, provides the most benefit and is the hardest to accomplish. There are several ways to accomplish application sharding.</p>
<p>If you can split your users amongst several vertical groups, you can basically install copies of the application for each segment. This method assumes that users in each group will not need to interact.</p>
<p>For example, if you can segment your user base into three groups who do not really interact, you can simply provision 3 environments and install 3 separate copies of the application. An example of this might be a site hosting application. Each site hosted will not need much (if any) interaction with the other sites hosted. This is by far the easiest method of sharding your application.</p>
<p>You can also look at abstracting any shared logic into a back end service accessible via API. The rule of thumb there is to have each back end application do one thing, and do one thing very quickly. Service oriented architectures (SOA) get this by design.</p>
<p>Alternatively, you can also look at this from a business logic viewpoint. If you can cut your application into portions (say, photos, chat and games for a social site) you can create smaller applications to handle photos, chat and games as well as the shared authentication and user information storage parts. Have the photos, chat and games applications leverage the back end authentication and user information applications to read and write shared information.</p>
<p>This gives us several advantages. For the back end application you can remove all unneeded code (i.e., if you are not going to need provide views, then remove ActionView), plugins and gems. Keep the app as light as possible, and give each of the application shards on dedicated resources (i.e., their own databases).</p>
<p>Another advantage of this approach is that you can start to optimize your hardware spend. If your chat application is 1/2 as intensive as your photo and games applications, it&#8217;s far easier to assign resources in a targeted fashion and maximize returns. In a monolithic application, if the photo application breaks, or needs more resources the entire stack is affected. With sharding, you get some buffering from some site wide issues, and the ability to assign resources exactly where they&#8217;re needed. The big drawback is that it&#8217;s not easy.</p>
<p><strong>Database Sharding</strong></p>
<p>This is another step that can be looked at in certain circumstances. If the amount of data you need to process is so large, or the number of transactions is sinking your Database, you can look into database sharding. Basically, you take your database and break the schema up among several Database servers. There are tools in most major RDBMS&#8217;s which will allow you to take care of this. Informing the application where the data is might be complex depending on which RDBMS you use.</p>
<p><strong>Filesystem Sharding</strong></p>
<p>If your application is file system IOPS heavy, file system sharding might be the route that you want to look at. Basically you add more hardware disk arrays, and split the reads and writes between them. You need to inject some logic into the save and open functions in your application so that it knows which file system each file is to be saved to and opened from. Usually you can create a hash of the file name, and key off the first couple of characters in the hash. If you&#8217;re interested, you can read our more detailed dive into <a href="http://www.engineyard.com/docs/EY_Filesystem_Sharding_Tactics_and_Processes.pdf">file system sharding</a>.</p>
<p><strong>That&#8217;s No Moon!</strong></p>
<p>Scaling can be a daunting task if you put it off too long. It can mean the difference between a successful business and one that dies. Don&#8217;t let that scare you however. Taken in small, bite sized chunks it&#8217;s certainly an achievable goal. Make sure that you are working on the right problems, and make sure that you are doing a little throughout the lifespan of your application.</p>
<p>And keep in mind, Scaling is a Discipline, not a Goal. What works great for 20 users:</p>
<p><code>users = User.find(:all)<br />
  for user in users<br />
    if user.name = &#8220;fred&#8221;<br />
      user.make_happy<br />
    end<br />
  end</code></p>
<p>may not work as well with 2000, or 20,000. So do the work it takes to make your application work today, and keep in mind the changes you&#8217;ll have to make, and the challenges you&#8217;ll face tomorrow.</p>
<img src="http://feeds.feedburner.com/~r/engineyard/~4/Ub2N9aoMvTw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.engineyard.com/blog/2009/a-quick-primer-on-sharding-for-ruby-on-rails/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.engineyard.com/blog/2009/a-quick-primer-on-sharding-for-ruby-on-rails/</feedburner:origLink></item>
		<item>
		<title>Getting Started With JRuby</title>
		<link>http://feedproxy.google.com/~r/engineyard/~3/AodV5_E5lHc/</link>
		<comments>http://www.engineyard.com/blog/2009/getting-started-with-jruby/#comments</comments>
		<pubDate>Mon, 15 Jun 2009 16:48:46 +0000</pubDate>
		<dc:creator>Engine Yard</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[jruby]]></category>

		<category><![CDATA[Support]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=1332</guid>
		<description><![CDATA[Last week, Engine Yard announced they would soon support running JRuby in their cloud environment. I think I speak for the whole JRuby community when I say how excited we are about this new possibility. JRuby has proven itself a top-notch, production-quality Ruby implementation, and the Engine Yard announcement really made us feel proud of what we've accomplished.]]></description>
			<content:encoded><![CDATA[<p><em>In the wake of our recent announcement of JRuby support, we have a guest post from <a href="http://blog.headius.com/">Charlie Nutter</a> of the JRuby team on getting starting with JRuby:</em></p>
<p>&#8220;Last week, Engine Yard announced they would soon support running JRuby in their cloud environment. I think I speak for the whole JRuby community when I say how excited we are about this new possibility. JRuby has proven itself a top-notch, production-quality Ruby implementation, and the Engine Yard announcement really made us feel proud of what we&#8217;ve accomplished. It also got us thinking about what JRuby really means for Engine Yard customers.</p>
<p>JRuby is, simply put, Ruby on top of the Java virtual machine. While this means you get the benefits of the JVM&#8217;s world-class garbage collectors, libraries, and optimizations, it does not mean you have to know Java to use JRuby. We&#8217;ve worked very hard to make JRuby look and feel &#8220;just like Ruby.&#8221; So much so, that these days basically all pure-Ruby libraries should &#8220;just work&#8221; out of the box. Rails runs great, and there&#8217;s dozens of production users out there reaping the benefits of JRuby&#8217;s outstanding memory management, native threads (actually running in parallel!), and excellent performance&#8230;all of which we continue to improve with every release. JRuby at Engine Yard means you&#8217;ll also be able to take advantage of Engine Yard Ruby and Rails expertise, along with the assurances that your application will &#8220;just work&#8221; in their cloud.</p>
<p>So how do you get started with JRuby? Easy!</p>
<ul>
<li>Download JRuby from <a href="http://www.jruby.org" rel="nofollow">http://www.jruby.org</a>. JRuby 1.3.0 is the current release, but you can feel comfortable testing out either 1.3.0 or 1.2.0: the previous release several folks already have in production.</li>
<li>Unpack it somewhere convenient. You don&#8217;t have to install it as root, but you can if you like. And you can have as many separate JRuby installs as you want, alongside any standard Ruby installs already on your system.</li>
<li>Put JRuby&#8217;s &#8220;bin&#8221; directory somewhere in your PATH, so you can run the &#8220;jruby&#8221; command easily.</li>
</ul>
<p>That&#8217;s it! You&#8217;re ready to try it out!</p>
<p><span id="more-1332"></span></p>
<p>Depending on how you have your PATH set up, you can either run &#8220;gem&#8221; to install RubyGems (if JRuby&#8217;s &#8220;gem&#8221; comes earlier in the path than standard Ruby), or you can run &#8220;jruby -S gem&#8221; to force JRuby&#8217;s copy to run (this will work for anything else in JRuby&#8217;s bin dir, too). A few gems you&#8217;ll probably want to know about:</p>
<ul>
<li>Rails works great! Just &#8220;gem install rails&#8221; or &#8220;jruby -S gem install rails&#8221; and you&#8217;re nearly there.</li>
<li>ActiveRecord is also well-supported in JRuby, but you&#8217;ll need to install the JDBC-based (Java&#8217;s DB API) adapters. So for mysql, you want &#8220;gem install activerecord-jdbcmysql-adapter&#8221; and &#8220;jdbcmysql&#8221; as your adapter type in database.yml. For sqlite3 there&#8217;s &#8220;activerecord-jdbcsqlite3-adapter&#8221;, and so on.</li>
<li>Gems that have native extensions (C code, usually indicated by RubyGems trying to build something on install) will not work in JRuby. Usually there&#8217;s an equivalent library, either a port of the C version, a wrapper around the actual C library, or a Java version. <a href="http://www.jruby.org" rel="nofollow">jruby.org</a> provides a good list of commonly-used extensions and their equivalents on JRuby, or you can check <a href="http://isitjruby.org" rel="nofollow">isitjruby.org</a> to see if your favorite extension is supported or has an alternative.</li>
</ul>
<p>We&#8217;ll be publishing more information about how to get up and running with JRuby, especially if you have native dependencies, over the next couple weeks. And of course you can join the JRuby mailing lists or visit our IRC channel #jruby on FreeNode any time. There&#8217;s never been a better time to try JRuby!&#8221;</p>
<img src="http://feeds.feedburner.com/~r/engineyard/~4/AodV5_E5lHc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.engineyard.com/blog/2009/getting-started-with-jruby/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.engineyard.com/blog/2009/getting-started-with-jruby/</feedburner:origLink></item>
		<item>
		<title>What is RubySpec?</title>
		<link>http://feedproxy.google.com/~r/engineyard/~3/ZiZH6kcUbIA/</link>
		<comments>http://www.engineyard.com/blog/2009/what-is-rubyspec/#comments</comments>
		<pubDate>Thu, 11 Jun 2009 15:00:28 +0000</pubDate>
		<dc:creator>Brian Ford</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[duck typing]]></category>

		<category><![CDATA[jruby]]></category>

		<category><![CDATA[rspec]]></category>

		<category><![CDATA[Rubinius]]></category>

		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[rubyspec]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=1205</guid>
		<description><![CDATA[RubySpec has been well-known in the community of Ruby implementers for almost two years. Every major Ruby implementation is using it. However, many Ruby programmers are just learning about it. RubySpec has a lot to contribute to the larger Ruby community.]]></description>
			<content:encoded><![CDATA[<p>You might think that <em>What is the meaning of life?</em> is a tough question. But here&#8217;s one that will give it a run for its money: <em>What is Ruby?</em></p>
<p>Ok sure, that comparison is hyperbole, but bear with me. Try this out in your irb session:</p>
<pre><code>&gt;&gt; Float("0.5") == "0.5".to_f
=&gt; true
</code></pre>
<p>That&#8217;s reasonable enough. Imagine if it <em>weren&#8217;t</em> true! But did you know that the Float() method converted the <code>"0.5"</code> text string to a Float object without calling the string&#8217;s to_f() method?</p>
<p>What is the definition of Ruby in this situation? Is it that Float() returns a Float object for a validly formatted text string or that Float() does so without calling the string&#8217;s to_f() method? Let&#8217;s investigate the situation a bit more.</p>
<p>In Ruby, if you define an arbitrary object that you want to behave like a Float object, you define a to_f() method for your object. Then Float() will call that method on your object:</p>
<pre><code>&gt;&gt; s = "0.5"
=&gt; "0.5"
&gt;&gt; def s.to_f() 42 end
=&gt; nil
&gt;&gt; floaty = Object.new
=&gt; #&lt;Object:0x5eb190&gt;
&gt;&gt; def floaty.to_f() 0.5 end
=&gt; nil
&gt;&gt; Float(floaty) == Float(s)
=&gt; true
</code></pre>
<p>Now that <em>is</em> surprising. A lot of the elegance of Ruby comes from generally everything being an object. In some sense, <code>floaty</code> and <code>"0.5"</code> are just objects, so why does the Float() method treat them differently?</p>
<p>More importantly, should you rely on Float() <em>not</em> calling your string&#8217;s to_f() method, or is that merely an implementation detail of MRI (Matz&#8217;s Ruby Implementation)? This is the dilemma faced repeatedly by every alternative Ruby implementation.</p>
<p>Fortunately, we have a powerful tool to assist us.</p>
<p>The <a href="http://rubyspec.org">RubySpec project</a> is writing an <em>executable</em> definition of the Ruby programming language using <a href="http://rspec.info">RSpec-style</a> specs. The tremendous utility of the specs is that alternate Ruby implementations can run them to determine if they are building a compatible Ruby engine.</p>
<p>Presently, the specs contain over 33,000 precisely defined facets of Ruby behavior. The specs cover Ruby behavior across different platforms, operating systems, and versions of the Ruby language. The goal is to ensure that Ruby applications written to use the core Ruby features covered by the specs will run the same on any Ruby implementation.</p>
<p>RubySpec has been well-known in the community of Ruby implementers for almost two years. Every major Ruby implementation is using it. However, many Ruby programmers are just learning about it. RubySpec has a lot to contribute to the larger Ruby community. Recently, I explain some ideas about this in an <a href="http://blog.rubybestpractices.com/posts/gregory/006-brian-ford-rubyspec.html">interview</a> with <a href="http://blog.rubybestpractices.com/about/gregory.html">Gregory Brown</a>. Greg is starting a project, called <a href="http://pledgie.com/campaigns/4640">Unity</a>, to make the information contained in the RubySpecs more accessible to everyone.</p>
<p>Contributing to RubySpec is a great way to learn more about the Ruby programming language. At the same time, your contribution helps the alternate Ruby implementations and the Ruby ecosystem. In the past couple of weeks, contributors have added tons of fixes to the specs for Ruby 1.8.7 and 1.9. Check out their excellent work at the RubySpec <a href="http://github.com/rubyspec/rubyspec/tree/master">Github repository</a>.</p>
<p>I&#8217;ll be <a href="http://opensourcebridge.org/sessions/13">speaking about RubySpec</a> at the upcoming <a href="http://opensourcebridge.org/">Open Source Bridge</a> conference June 17-19. If you have questions about RubySpec that you&#8217;d like me to address, please leave a comment.</p>
<img src="http://feeds.feedburner.com/~r/engineyard/~4/ZiZH6kcUbIA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.engineyard.com/blog/2009/what-is-rubyspec/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.engineyard.com/blog/2009/what-is-rubyspec/</feedburner:origLink></item>
		<item>
		<title>BigDecimal Vulnerability in Ruby 1.8.6 and 1.8.7</title>
		<link>http://feedproxy.google.com/~r/engineyard/~3/A4tzZILbDj0/</link>
		<comments>http://www.engineyard.com/blog/2009/bigdecimal-vulnerability-in-ruby-186-and-187/#comments</comments>
		<pubDate>Wed, 10 Jun 2009 16:06:33 +0000</pubDate>
		<dc:creator>Joe Arnold</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[1.8.6]]></category>

		<category><![CDATA[BigDecimal]]></category>

		<category><![CDATA[DoS]]></category>

		<category><![CDATA[Rails]]></category>

		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[rubyspec]]></category>

		<category><![CDATA[security vulnerability]]></category>

		<category><![CDATA[Solo]]></category>

		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=1267</guid>
		<description><![CDATA[Yesterday, the first security vulnerability since Engine Yard took over maintenance of Ruby 1.8.6 was reported. It is a Denial of Service vulnerability in BigDecimal, by which an attacker can cause a segmentation fault by providing a very large number as input. ActiveRecord relies on BigDecimal, but this is not Rails specific.
Today, as part of our [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday, the first security vulnerability since Engine Yard took over maintenance of Ruby 1.8.6 was reported. It is a <a href="http://www.ruby-lang.org/en/news/2009/06/09/dos-vulnerability-in-bigdecimal/" rel="nofollow">Denial of Service vulnerability in BigDecimal</a>, by which an attacker can cause a segmentation fault by providing a very large number as input. ActiveRecord relies on BigDecimal, but this is not Rails specific.</p>
<p>Today, as part of our <a href="http://www.engineyard.com/blog/2009/engineyard_ruby186_maintenance/">maintainer role for 1.8.6</a>, we published a fix as part of <a href="ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.6-p369.tar.gz" rel="nofollow">Ruby 1.8.6 patch-level 369</a> and as a part of <a href="ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p173.tar.gz" rel="nofollow">Ruby 1.8.7 patch-level 173</a>.</p>
<p>The issue was initially discovered and fixed in the Ruby 1.9.1 trunk. We backported the fix to 1.8.6 by writing a test, watching it fail, then making it pass (the same way we always do). As part of our test-driven approach, Kirk Haines then added a <a href="http://github.com/rubyspec/rubyspec/commit/95c0abbe07bf350f83d2454eb080b0bd315d59d4" rel="nofollow">test</a> in <a href="http://rubyspec.org/" rel="nofollow">RubySpec</a> to test for the condition. We ran the test suite on OSX, RedHat Enterprise 3, CentOS 4, 32 and 64 bit <a href="http://www.engineyard.com/solo">Engine Yard Solo</a> instances, and an Engine Yard Slice to verify the fix.</p>
<p>Engine Yard customers have been notified about the vulnerability via email with instructions on how to upgrade. Engine Yard Solo customers can get the new, patched version of Ruby 1.8.6 simply by <a href="http://www.grabup.com/uploads/9c78be6e8b72d9c0e6ee7240fb874cf3.png?direct" rel="nofollow">redeploying</a> their environments. In the future, new Engine Yard deployments will automatically get the new version.</p>
<img src="http://feeds.feedburner.com/~r/engineyard/~4/A4tzZILbDj0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.engineyard.com/blog/2009/bigdecimal-vulnerability-in-ruby-186-and-187/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.engineyard.com/blog/2009/bigdecimal-vulnerability-in-ruby-186-and-187/</feedburner:origLink></item>
		<item>
		<title>New Solo Release—Server Monitoring, Self-Managed vhost Templates</title>
		<link>http://feedproxy.google.com/~r/engineyard/~3/XrnYHJgKHPE/</link>
		<comments>http://www.engineyard.com/blog/2009/new-solo-release%e2%80%94server-monitoring-server-alerts-self-managed-vhost-templates/#comments</comments>
		<pubDate>Mon, 08 Jun 2009 21:50:46 +0000</pubDate>
		<dc:creator>Ezra Zygmuntowicz</dc:creator>
		
		<category><![CDATA[Solo]]></category>

		<category><![CDATA[Deployment]]></category>

		<category><![CDATA[Monitoring]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=1206</guid>
		<description><![CDATA[Today we&#8217;ve shipped a new release of Engine Yard Solo. This release includes a ton of bug fixes, but also contains a killer new feature.

We&#8217;ve enabled server monitoring for all customers!

Once you enable this new feature by hitting &#8216;Deploy&#8217; in your dashboard to sync our recipes, you will have full server monitoring enabled for a [...]]]></description>
			<content:encoded><![CDATA[<p>Today we&#8217;ve shipped a new release of <a title="Engine Yard Solo" href="http://www.engineyard.com/solo">Engine Yard Solo</a>. This release includes a ton of bug fixes, but also contains a killer new feature.</p>

<p>We&#8217;ve enabled server monitoring for <strong>all</strong> customers!</p>

<p>Once you enable this new feature by hitting &#8216;Deploy&#8217; in your dashboard to sync our recipes, you will have full server monitoring enabled for a number of important stats:</p>


<ul>
<li>Load Average</li>
<li>Free Memory</li>
<li>IO-Wait</li>
<li>Swap Used</li>
<li>Free Disk Space for <span class="caps">EBS </span>volumes</li>
</ul>



<p><a rel="nofollow" href="http://ey-ec2.s3.amazonaws.com/alerting.png"><img src="http://ey-ec2.s3.amazonaws.com/alerting.png" alt="Engine Yard Solo server alerts report" width="400" /></a></p>

<p>We will start collecting server alerts for you and displaying them in your dashboard. This is a great feature to give you much more insight into what your slices are doing and how healthy they are. The alerts screen gives you an at-a-glance place to see the health of your deployments &#8212; if the top of each section is green you know you are in good shape. If the top of each alert section is yellow or red &#8212; you know there may be some issues to look into and what the issues are!</p>

<p>We&#8217;ve also released a way for you to tell our automation system that you have local edits to certain config files that you do not want us to stomp on or touch. This is especially important for some apache or nginx vhost files. Before this change there was no way for your local edits to survive a &#8216;Deploy&#8217; of our recipes. Now if you want to keep a config file with your own edits you just have to rename it with &#8216;keep.&#8217; prepended to the name.</p>

<p>For example, say you want to edit the nginx vhost for your application that lives at <code>/data/nginx/servers/myapp.conf</code>. If you make changes to this file, all you need to do is rename it to <code>/data/nginx/servers/keep.myapp.conf</code>, and we will never touch that file again until you rename it back or remove it. This gives you the power to make customizations to your vhost configs without us stepping on them later. And since your vhosts are stored on your /data partition, which is an <span class="caps">EBS </span>device, your changes will even persist across terminate/create events as long as you mount the same volumes when you boot your environment back up.</p>

<p>I think these features make the platform much more useful and I hope you enjoy using them.</p><img src="http://feeds.feedburner.com/~r/engineyard/~4/XrnYHJgKHPE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.engineyard.com/blog/2009/new-solo-release%e2%80%94server-monitoring-server-alerts-self-managed-vhost-templates/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.engineyard.com/blog/2009/new-solo-release%e2%80%94server-monitoring-server-alerts-self-managed-vhost-templates/</feedburner:origLink></item>
		<item>
		<title>Http Digest Auth: Vulnerability in Rails 2.3.1/2</title>
		<link>http://feedproxy.google.com/~r/engineyard/~3/JzrdIJkBpHc/</link>
		<comments>http://www.engineyard.com/blog/2009/http-digest-auth-vulnerability-in-rails-2312/#comments</comments>
		<pubDate>Fri, 05 Jun 2009 00:28:16 +0000</pubDate>
		<dc:creator>Engine Yard</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Add new tag]]></category>

		<category><![CDATA[http digest auth]]></category>

		<category><![CDATA[Rails]]></category>

		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[security alert]]></category>

		<category><![CDATA[security vulnerability]]></category>

		<guid isPermaLink="false">http://www.engineyard.com/blog/?p=1197</guid>
		<description><![CDATA[If you are using Ruby on Rails 2.3.1 or 2.3.2,  using http *digest* authentication and setting the username / password via hash, then you will be affected by this vulnerability. This vulnerability allows users to bypass http authentication without a valid password.
Please read the full posting on the Rails Security Group for more details and [...]]]></description>
			<content:encoded><![CDATA[<p>If you are using Ruby on Rails 2.3.1 or 2.3.2,  using http *digest* authentication and setting the username / password via hash, then you will be affected by this vulnerability. This vulnerability allows users to bypass http authentication without a valid password.</p>
<p>Please read the <a rel="nofollow" href="http://groups.google.com/group/rubyonrails-security/browse_thread/thread/20e17a978d2ccbd3?hl=en">full posting on the Rails Security Group</a> for more details and the appropriate workaround to implement in your code, until the official fix is available in the 2.3.3 release.</p>
<p>(Engine Yard customers have already been contacted via email about this vulnerability).</p>
<img src="http://feeds.feedburner.com/~r/engineyard/~4/JzrdIJkBpHc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.engineyard.com/blog/2009/http-digest-auth-vulnerability-in-rails-2312/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.engineyard.com/blog/2009/http-digest-auth-vulnerability-in-rails-2312/</feedburner:origLink></item>
	</channel>
</rss>
