<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="en-US">
  <title>Atomic Spin - Home</title>
  <id>tag:spin.atomicobject.com,2010:mephisto/</id>
  <generator uri="http://mephistoblog.com" version="0.7.3">Mephisto Noh-Varr</generator>
  
  <link href="http://spin.atomicobject.com/" rel="alternate" type="text/html" />
  <updated>2010-03-03T19:55:18Z</updated>
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/atomic_spin" /><feedburner:info uri="atomic_spin" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><geo:lat>42.955944</geo:lat><geo:long>-85.644983</geo:long><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2Fatomic_spin" 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%2Ffeeds.feedburner.com%2Fatomic_spin" 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%2Ffeeds.feedburner.com%2Fatomic_spin" 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://feeds.feedburner.com/atomic_spin" 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%2Ffeeds.feedburner.com%2Fatomic_spin" 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%2Ffeeds.feedburner.com%2Fatomic_spin" 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%2Ffeeds.feedburner.com%2Fatomic_spin" 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.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2Fatomic_spin" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><entry xml:base="http://spin.atomicobject.com/">
    <author>
      <name>Michael Marsiglia</name>
      <uri>http://www.atomicobject.com/pages/Michael+Marsiglia</uri>
    </author>
    <id>tag:spin.atomicobject.com,2010-03-03:43096</id>
    <published>2010-03-03T19:53:00Z</published>
    <updated>2010-03-03T19:55:18Z</updated>
    <category term="Business of Software" />
    <category term="Project Management" />
    <category term="Tools" />
    <link href="http://feedproxy.google.com/~r/atomic_spin/~3/u8w6BQtTJvs/responsible-estimation-tool" rel="alternate" type="text/html" />
    <title>Responsible Estimation Tool</title>
<content type="html">
            &lt;p&gt;Many times during the sales process we are asked to give a &lt;a href="http://spin.atomicobject.com/2009/12/11/setting-the-budget"&gt;cost estimation&lt;/a&gt; based on our early understanding of an application’s core features. In order to responsibly and efficiently estimate, we conduct a &lt;a href="http://spin.atomicobject.com/2009/01/14/making-better-estimates-range-estimates"&gt;50/90 range analysis&lt;/a&gt;. We use this technique because we want to establish a responsible middle ground between our optimistic and pessimistic estimates. Our estimate is appropriately buffered for the risk we see in the defined tasks.&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://spin.atomicobject.com/assets/2010/3/3/5090.jpg?1267644142" alt="" /&gt;&lt;/p&gt;


	&lt;p&gt;This spreadsheet is the &lt;a href="http://spin.atomicobject.com/assets/2010/3/3/50-90_estimator.xls"&gt;tool&lt;/a&gt; that we use to conduct our analysis. Tasks can be estimated in any time duration that you choose (i.e. hours, days, weeks). At the start of a large project we generally estimate tasks in days or weeks.&lt;/p&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=u8w6BQtTJvs:PETfL3OTDCk:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=u8w6BQtTJvs:PETfL3OTDCk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=u8w6BQtTJvs:PETfL3OTDCk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=u8w6BQtTJvs:PETfL3OTDCk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=u8w6BQtTJvs:PETfL3OTDCk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=u8w6BQtTJvs:PETfL3OTDCk:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=u8w6BQtTJvs:PETfL3OTDCk:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=u8w6BQtTJvs:PETfL3OTDCk:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/atomic_spin/~4/u8w6BQtTJvs" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://spin.atomicobject.com/2010/03/03/responsible-estimation-tool</feedburner:origLink></entry>
  <entry xml:base="http://spin.atomicobject.com/">
    <author>
      <name>Carl Erickson</name>
      <uri>http://www.atomicobject.com/pages/Carl+Erickson</uri>
    </author>
    <id>tag:spin.atomicobject.com,2010-02-28:43008</id>
    <published>2010-02-28T22:36:00Z</published>
    <updated>2010-02-28T22:50:30Z</updated>
    <category term="Business of Software" />
    <link href="http://feedproxy.google.com/~r/atomic_spin/~3/sXzo6ZYSSQ8/startup-weekend-in-grand-rapids" rel="alternate" type="text/html" />
    <title>Startup Weekend in Grand Rapids</title>
<content type="html">
            &lt;p&gt;I attended the tail end of &lt;a href="http://wmi.startupweekend.org/"&gt;Startup Weekend&lt;/a&gt; at &lt;a href="http://workthefactory.com/"&gt;The Factory&lt;/a&gt; this weekend. Kudos to Michael Boyink and Aaron Schaap for organizing this in West Michigan. &lt;a href="http://www.marcnager.com/"&gt;Marc Nager&lt;/a&gt;, one of two people who run Startup Weekends all over the country, commented on the energy in the room and the incredible willingness of strangers to get behind ideas and work together. Evidently what we lack in VC we make up for in hard work and generosity.&lt;/p&gt;


	&lt;p&gt;The final pitches were pretty good considering that some of these ideas weren’t even hatched until Friday afternoon. An app for helping people keep track of things that need to get done even had a pretty functional backend implemented over the weekend. It was great to see eight teams and 40 or so people challenging the economic doom and gloom of our state, putting their ideas out there, listening to others, and taking action to make them real.&lt;/p&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=sXzo6ZYSSQ8:87gvcqBXDCc:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=sXzo6ZYSSQ8:87gvcqBXDCc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=sXzo6ZYSSQ8:87gvcqBXDCc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=sXzo6ZYSSQ8:87gvcqBXDCc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=sXzo6ZYSSQ8:87gvcqBXDCc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=sXzo6ZYSSQ8:87gvcqBXDCc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=sXzo6ZYSSQ8:87gvcqBXDCc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=sXzo6ZYSSQ8:87gvcqBXDCc:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/atomic_spin/~4/sXzo6ZYSSQ8" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://spin.atomicobject.com/2010/02/28/startup-weekend-in-grand-rapids</feedburner:origLink></entry>
  <entry xml:base="http://spin.atomicobject.com/">
    <author>
      <name>Matt Fletcher</name>
      <uri>http://www.atomicobject.com/pages/Matt+Fletcher</uri>
    </author>
    <id>tag:spin.atomicobject.com,2010-02-26:42943</id>
    <published>2010-02-26T22:42:00Z</published>
    <updated>2010-02-26T22:43:20Z</updated>
    <link href="http://feedproxy.google.com/~r/atomic_spin/~3/pYn2NabeD1A/git-deploy-to-three-servers-in-83-characters" rel="alternate" type="text/html" />
    <title>git-deploy to three servers in 83 characters</title>
<content type="html">
            &lt;p&gt;I smiled this morning when I typed this command to &lt;a href="http://github.com/mislav/git-deploy"&gt;git-deploy&lt;/a&gt; fresh code to three machines in quick succession.&lt;/p&gt;


&amp;lt;script src="http://gist.github.com/316265.js?file=gistfile1.txt"&gt;&amp;lt;/script&gt;

	&lt;p&gt;Sure, there’s nothing groundbreaking here that you can’t do with plenty of other tools. But it was still fun.&lt;/p&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=pYn2NabeD1A:a0Fjscaqep4:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=pYn2NabeD1A:a0Fjscaqep4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=pYn2NabeD1A:a0Fjscaqep4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=pYn2NabeD1A:a0Fjscaqep4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=pYn2NabeD1A:a0Fjscaqep4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=pYn2NabeD1A:a0Fjscaqep4:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=pYn2NabeD1A:a0Fjscaqep4:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=pYn2NabeD1A:a0Fjscaqep4:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/atomic_spin/~4/pYn2NabeD1A" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://spin.atomicobject.com/2010/02/26/git-deploy-to-three-servers-in-83-characters</feedburner:origLink></entry>
  <entry xml:base="http://spin.atomicobject.com/">
    <author>
      <name>Mike Swieton</name>
      <uri>http://www.atomicobject.com/pages/Mike+Swieton</uri>
    </author>
    <id>tag:spin.atomicobject.com,2010-02-24:42888</id>
    <published>2010-02-24T17:08:00Z</published>
    <updated>2010-02-24T21:12:19Z</updated>
    <link href="http://feedproxy.google.com/~r/atomic_spin/~3/r4Ri33DE7Ng/atomic-cookies" rel="alternate" type="text/html" />
    <title>Atomic Cookies</title>
<content type="html">
            &lt;p&gt;No, they won’t explode.&lt;/p&gt;


	&lt;p&gt;Resident cookie-master, &lt;a href="http://www.atomicobject.com/pages/Marissa+Christy"&gt;Marissa Christy,&lt;/a&gt; went the extra mile yesterday for the &lt;a href="http://spin.atomicobject.com/2010/02/24/all-input-is-evil-until-proven-otherwise-that-s-rule-number-one"&gt;SoftwareGR&lt;/a&gt; meeting. While our meetings always have great snacks, Marissa really raised the bar this time with Atomic Object logo cookies:&lt;/p&gt;


	&lt;p&gt;&lt;img title="Atomic Cookie" src="http://spin.atomicobject.com/assets/2010/2/24/cookies.jpg" alt="Atomic Object logo cookies" /&gt;&lt;/p&gt;


	&lt;p&gt;If you want some great snacks, and great information too, come to the next &lt;a href="http://www.softwaregr.org"&gt;SoftwareGR&lt;/a&gt; meeting.&lt;/p&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=r4Ri33DE7Ng:Xevrkr0OvWs:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=r4Ri33DE7Ng:Xevrkr0OvWs:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=r4Ri33DE7Ng:Xevrkr0OvWs:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=r4Ri33DE7Ng:Xevrkr0OvWs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=r4Ri33DE7Ng:Xevrkr0OvWs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=r4Ri33DE7Ng:Xevrkr0OvWs:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=r4Ri33DE7Ng:Xevrkr0OvWs:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=r4Ri33DE7Ng:Xevrkr0OvWs:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/atomic_spin/~4/r4Ri33DE7Ng" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://spin.atomicobject.com/2010/02/24/atomic-cookies</feedburner:origLink></entry>
  <entry xml:base="http://spin.atomicobject.com/">
    <author>
      <name>Mike Swieton</name>
      <uri>http://www.atomicobject.com/pages/Mike+Swieton</uri>
    </author>
    <id>tag:spin.atomicobject.com,2010-02-24:42887</id>
    <published>2010-02-24T16:34:00Z</published>
    <updated>2010-02-24T16:37:29Z</updated>
    <link href="http://feedproxy.google.com/~r/atomic_spin/~3/YDHkyEQzNzA/all-input-is-evil-until-proven-otherwise-that-s-rule-number-one" rel="alternate" type="text/html" />
    <title>"All input is evil until proven otherwise. That's rule number one."</title>
<summary type="html">&lt;p&gt;Yesterday SoftwareGR hosted Dr. Richard Enbody from &lt;span class="caps"&gt;MSU&lt;/span&gt;. He spoke about security, and
    he quoted the above security rule from the book Writing Secure Code by Michael Howard and David LeBlanc (&lt;a href="http://www.microsoft.com/mspress/books/sampchap/5957.aspx"&gt;sample chapter.&lt;/a&gt;)&lt;/p&gt;


	&lt;p&gt;The main topic of the talk was recent research performed by Richard’s team to develop a new security feature called Secure Bit.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;Yesterday SoftwareGR hosted Dr. Richard Enbody from &lt;span class="caps"&gt;MSU&lt;/span&gt;. He spoke about security, and
    he quoted the above security rule from the book Writing Secure Code by Michael Howard and David LeBlanc (&lt;a href="http://www.microsoft.com/mspress/books/sampchap/5957.aspx"&gt;sample chapter.&lt;/a&gt;)&lt;/p&gt;


	&lt;p&gt;The main topic of the talk was recent research performed by Richard’s team to develop a new security feature called Secure Bit.&lt;/p&gt;
&lt;p&gt;One of the biggest classes of vulnerabilities out there is the buffer overflow.
    Richard showed a list of vulnerabilities taken from &lt;span class="caps"&gt;CERT&lt;/span&gt;’s homepage the preceding day and showed us a slide full of recently discovered buffer
    overflows. He told us he’s always been able to fill a slide using just the first page.&lt;/p&gt;


	&lt;p&gt;Buffer overflows are caused by feeding the software some carefully crafted
    input that allows a malicious user to redirect the flow of execution. Richard’s
    research discovered that a vulnerability can be present even when the user
    can’t inject bad code – it turns out that taking over the execution is
    sufficient. &lt;a href="http://en.wikipedia.org/wiki/Buffer_overflow"&gt;Read more&lt;/a&gt; about buffer overflows on Wikipedia.&lt;/p&gt;


	&lt;p&gt;We heard about an interesting technique for finding these vulnerabilities:
    fuzzing. This is a way of partially automating an attack. It works by feeding
    the target software a randomized stream of inputs and waiting until a
    fault occurs. These faults (and the recent inputs) can be logged and analyzed to discover an attack – for both attacking systems and for fixing your own. Richard’s team developed an ingeniously simple defense against buffer
    overflows, called Secure Bit. It is a very simple algorithm:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Label all input as tainted.&lt;/li&gt;
		&lt;li&gt;Forbid jumps to a tainted address.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;This is accomplished with a combination of software and hardware changes.
    Richard adds a single bit to every word stored which indicates whether the
    input is tainted or not (called the secure bit). This addition can be done at
    the operating system level and is a relatively simple change. In the Linux
    kernel Richard’s team was able to make it happen in 4 lines of code. The jump
    protection is added at the hardware level in the processor. This was tested by
    making the change in a &lt;span class="caps"&gt;CPU&lt;/span&gt; emulator.
The simplicity of this approach means that the instruction set doesn’t have to
    change and the code stays binary-compatible. For this to be installed on a
    system, all it would need is the updated hardware and the kernel – no
    other software needs to be aware of it.&lt;/p&gt;


	&lt;p&gt;Richard’s test system ran Red Hat, and they tested out a number of known
    exploits against vulnerable targets and demonstrated that the Secure Bit
    approach does protect against malicious code execution.&lt;/p&gt;


	&lt;p&gt;Read all about it on &lt;a href="http://www.cse.msu.edu/~enbody/"&gt;Richard’s web site&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Software GR meets on the
    fourth Tuesday of the month from 6PM to 8PM at &lt;a href="http://www.atomicobject.com/pages/Find+Us"&gt;Atomic Object offices&lt;/a&gt;. The latest schedule can always be seen at &lt;a href="http://softwaregr.org"&gt;softwaregr.org&lt;/a&gt;. Meetings are
    always free and open to the public.&lt;/p&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=YDHkyEQzNzA:j_URFwoirLk:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=YDHkyEQzNzA:j_URFwoirLk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=YDHkyEQzNzA:j_URFwoirLk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=YDHkyEQzNzA:j_URFwoirLk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=YDHkyEQzNzA:j_URFwoirLk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=YDHkyEQzNzA:j_URFwoirLk:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=YDHkyEQzNzA:j_URFwoirLk:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=YDHkyEQzNzA:j_URFwoirLk:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/atomic_spin/~4/YDHkyEQzNzA" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://spin.atomicobject.com/2010/02/24/all-input-is-evil-until-proven-otherwise-that-s-rule-number-one</feedburner:origLink></entry>
  <entry xml:base="http://spin.atomicobject.com/">
    <author>
      <name>Patrick Bacon</name>
      <uri>http://www.atomicobject.com/pages/Patrick+Bacon</uri>
    </author>
    <id>tag:spin.atomicobject.com,2010-02-23:42853</id>
    <published>2010-02-23T01:59:00Z</published>
    <updated>2010-02-23T02:00:16Z</updated>
    <category term="Languages" />
    <category term="Technologies" />
    <category term="Tips" />
    <category term="Tools" />
    <link href="http://feedproxy.google.com/~r/atomic_spin/~3/8pnS7vG2QK0/better-java-with-google-collections" rel="alternate" type="text/html" />
    <title>Better Java with Google Collections</title>
<summary type="html">&lt;p&gt;Version 1.0 of the &lt;a href="http://code.google.com/p/google-collections/"&gt;Google Collections library&lt;/a&gt; was officially released December 30, 2009. I have been using the library for the past 6 months or so on a variety of Java projects, with great success. Today I gave a brown-bag talk to share with some interested &lt;a href="http://www.atomicobject.com/pages/Our+People"&gt;Atoms&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;I have included below the sample code I used as presentation material, in case others are interested.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;Version 1.0 of the &lt;a href="http://code.google.com/p/google-collections/"&gt;Google Collections library&lt;/a&gt; was officially released December 30, 2009. I have been using the library for the past 6 months or so on a variety of Java projects, with great success. Today I gave a brown-bag talk to share with some interested &lt;a href="http://www.atomicobject.com/pages/Our+People"&gt;Atoms&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;I have included below the sample code I used as presentation material, in case others are interested.&lt;/p&gt;
&lt;p&gt;Note: As I was putting this post together I read that Google Collections is now part of Google’s &lt;a href="http://code.google.com/p/guava-libraries/"&gt;guava-libraries&lt;/a&gt; project, which has not been officially released yet.&lt;/p&gt;


&amp;lt;script src="http://gist.github.com/311753.js?file=gistfile1.java"&gt;&amp;lt;/script&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=8pnS7vG2QK0:U3cEoWK3ajE:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=8pnS7vG2QK0:U3cEoWK3ajE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=8pnS7vG2QK0:U3cEoWK3ajE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=8pnS7vG2QK0:U3cEoWK3ajE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=8pnS7vG2QK0:U3cEoWK3ajE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=8pnS7vG2QK0:U3cEoWK3ajE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=8pnS7vG2QK0:U3cEoWK3ajE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=8pnS7vG2QK0:U3cEoWK3ajE:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/atomic_spin/~4/8pnS7vG2QK0" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://spin.atomicobject.com/2010/02/23/better-java-with-google-collections</feedburner:origLink></entry>
  <entry xml:base="http://spin.atomicobject.com/">
    <author>
      <name>Jeremy Anderson</name>
      <uri>http://www.atomicobject.com/pages/Jeremy+Anderson</uri>
    </author>
    <id>tag:spin.atomicobject.com,2010-02-17:42548</id>
    <published>2010-02-17T14:06:00Z</published>
    <updated>2010-02-17T14:13:56Z</updated>
    <link href="http://feedproxy.google.com/~r/atomic_spin/~3/NX0PtMj90S8/code-retreat-gr-recap" rel="alternate" type="text/html" />
    <title>Code Retreat GR Recap</title>
<content type="html">
            &lt;p&gt;On February 6th &lt;a href="http://www.atomicobject.com/pages/Jeremy+Anderson/" title="Jeremy Anderson"&gt;I&lt;/a&gt; hosted the first &lt;a href="http://coderetreat.ning.com/" title="Code Retreat"&gt;Code Retreat&lt;/a&gt; to hit West Michigan, and we really couldn't have asked for a nicer day for a Code Retreat.  Well, maybe a little bit warmer weather, but hey, it's February in Michigan, what do you expect?  So after a quick stop at Panera Bread to get some bagels, scones and muffins, I made my way down to &lt;a href="http://www.atomicobject.com/pages/Our+Historic+Building" title="Our Historic Building"&gt;Atomic Object HQ&lt;/a&gt; to start the coffee brewing in preparation for the attendees.  Shortly after sunrise, &lt;a href="http://agileshrugged.com/blog/" title="Agile Shrugged"&gt;Nayan Hajratwala&lt;/a&gt; showed up to help with any last minute preparations before everyone else showed up. &lt;/p&gt;

&lt;p&gt;&lt;img title="Code Retreaters pairing on Game of Life" src="http://spin.atomicobject.com/assets/2010/2/16/63951982.jpg" alt="Code Retreat GR" /&gt; &lt;/p&gt;

&lt;p&gt;Soon about 20 people from all parts of the region had showed up to practice TDD and learn with each other, including one guy who came all the way down from Marquette, MI just to attend.  He officially got the "I traveled the furthest" award for the day. We were also joined by &lt;a href="http://xprogramming.com/index.php" title="XProgramming"&gt;Ron Jeffries&lt;/a&gt; and &lt;a href="http://www.hendricksonxp.com/" title="Hendrickson XP"&gt;Chet Hendrickson&lt;/a&gt;, who had agreed to come and be my professional trouble makers for the day. Shortly after 9:00, once everyone had been sufficiently caffeinated, we decided to get started.  One of the attendees had mentioned something about &lt;a href="http://coreyhaines.com/" title="Corey Haines"&gt;Corey Haines&lt;/a&gt; putting together a &lt;a href="http://github.com/coreyhaines/practice_game_of_life" title="coreyhaines / practice_game_of_life @ github"&gt;set of Cucumber features&lt;/a&gt; at one of the previous Code Retreats in Chicago, so some of the pairs decided to give that a whirl.  After some yak shaving we managed to get through the first iteration of the morning and retrospected on what happened and continued on into the second iteration of the day.  &lt;/p&gt;

&lt;p&gt;My original plan was to just sort of float around, help facilitate, and observe everyone else pairing, however when I noticed Ron Jeffries didn't have a pair for the second iteration, I took the opportunity to pair with him.  Neither of us knew Cucumber very well, so we decided to give that a whirl. If ever you get the chance to pair with either Ron or Chet, don't think twice about it, just do it. Ron had at one point in the day managed to - as one participant described  "...[kick his] BDD mindset a bit out of place. . . " &lt;/p&gt;

&lt;p&gt;Before we knew it, lunch was upon us.  It turns out that Corey Haines was hosting another Code Retreat in Seattle that day, so we fired up Skype and greeted our fellow Code Retreaters on the west coast as they were just getting ready to start for the day.  Then we all proceeded to enjoy the taco bar that had been delivered for lunch and continued to retrospect on the days events so far.  When we were all finished stuffing our faces with Qdoba, Mike Sweiton and myself gave our participants a quick tour of Atomic Object HQ, showing off our open space, &lt;a href="http://spin.atomicobject.com/2010/02/08/information-radiators" title="Information Radiators"&gt;stoplight&lt;/a&gt;, CI server, and our embedded projects workbench.  &lt;/p&gt;

&lt;p&gt;Now that our food had a chance to settle, it was back to pairing for a few more iterations of Conway's Game of Life.  After one of the afternoon retrospectives, for a little bit of a distraction, we watched a video of someone implementing &lt;a href="http://www.youtube.com/watch?v=a9xAKttWgP4" title="Game of Life in APL"&gt;Conway's Game of Life in APL&lt;/a&gt;.  This was spawned by an email thread that circulated right before the Code Retreat about how to implement the &lt;a href="http://www.dyalog.com/dfnsdws/c_life.htm" title="Game of Life in single line of APL"&gt;Game of Life in a single line of APL&lt;/a&gt;, which still blows my mind.  &lt;/p&gt;

&lt;p&gt;Finally, by the time the end of the day had finally arrived, we had lost a few of our fellow coders and we were ready to call it a day. Those of us who were still left standing at the end of the day took a walk around the corner to &lt;a href="http://thegreenwell.com/" title="The Green Well"&gt;The Green Well&lt;/a&gt;, one of the many local establishments in the Eastown area, for some much needed unwinding. We continued to retrospect on the day's happenings over a few local microbrews and some delicious items from the menu.  All in all I would have to say this was a successful Code Retreat.  Everyone had a great time, we all got to pair program with some great folks we wouldn't normally get to pair with, and - most importantly - learning happened.  Though many of the Code Retreats in the past have used Java as their language of choice, in my opinion I think using Ruby for this Code Retreat was the right choice.  It afforded us much less yak shaving than would have probably been necessary had we been using Java.  I'm looking forward to hosting another Code Retreat later this year when the weather is a little warmer, and hopefully attending the upcoming &lt;a href="http://coderetreat.ning.com/xn/detail/2712512:Event:4161?xg_source=activity" title="Code Retreat Philadelphia"&gt;Code Retreat being hosted in Philadelphia&lt;/a&gt; by &lt;a href="http://sebastianlab.com/" title="Beards and Keyboards"&gt;Sebastian Hermida&lt;/a&gt;.&lt;/p&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=NX0PtMj90S8:V3Ca45frHMA:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=NX0PtMj90S8:V3Ca45frHMA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=NX0PtMj90S8:V3Ca45frHMA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=NX0PtMj90S8:V3Ca45frHMA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=NX0PtMj90S8:V3Ca45frHMA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=NX0PtMj90S8:V3Ca45frHMA:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=NX0PtMj90S8:V3Ca45frHMA:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=NX0PtMj90S8:V3Ca45frHMA:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/atomic_spin/~4/NX0PtMj90S8" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://spin.atomicobject.com/2010/02/17/code-retreat-gr-recap</feedburner:origLink></entry>
  <entry xml:base="http://spin.atomicobject.com/">
    <author>
      <name>Marissa Christy</name>
      <uri>http://www.atomicobject.com/pages/Marissa+Christy</uri>
    </author>
    <id>tag:spin.atomicobject.com,2010-02-08:42510</id>
    <published>2010-02-08T15:23:00Z</published>
    <updated>2010-02-08T18:39:35Z</updated>
    <category term="Agile Practices" />
    <category term="Business of Software" />
    <category term="Test Driven Development" />
    <link href="http://feedproxy.google.com/~r/atomic_spin/~3/qOzXI77VCDk/information-radiators" rel="alternate" type="text/html" />
    <title>Information Radiators</title>
<summary type="html">&lt;div&gt;
  &lt;div class="imagebox"&gt;
  &lt;div&gt;
    &lt;img src="http://spin.atomicobject.com/assets/2010/2/8/_MG_6764_1.jpg?1265639551" alt="stoplight" /&gt;
  &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

	&lt;p&gt;For a business that by definition occupies a highly technical domain, we have some relatively low-tech means of conveying information internally. Sure we e-mail, &lt;a href="http://www.twitter.com/atomicobject"&gt;Twitter&lt;/a&gt;, &lt;a href="http://spin.atomicobject.com/2010/01/30/yammer-time"&gt;Yammer&lt;/a&gt;, and even &lt;a href="http://www.skype.com/"&gt;Skype&lt;/a&gt; with each other on a regular basis, but we also make use of yarn, note cards, cork boards, and old traffic equipment. I’m talking about our &lt;em&gt;information radiators&lt;/em&gt;, objects around our office that align the team by sharing important information in a fun and hard-to-miss way.&lt;/p&gt;</summary><content type="html">
            &lt;div&gt;
  &lt;div class="imagebox"&gt;
  &lt;div&gt;
    &lt;img src="http://spin.atomicobject.com/assets/2010/2/8/_MG_6764_1.jpg?1265639551" alt="stoplight" /&gt;
  &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

	&lt;p&gt;For a business that by definition occupies a highly technical domain, we have some relatively low-tech means of conveying information internally. Sure we e-mail, &lt;a href="http://www.twitter.com/atomicobject"&gt;Twitter&lt;/a&gt;, &lt;a href="http://spin.atomicobject.com/2010/01/30/yammer-time"&gt;Yammer&lt;/a&gt;, and even &lt;a href="http://www.skype.com/"&gt;Skype&lt;/a&gt; with each other on a regular basis, but we also make use of yarn, note cards, cork boards, and old traffic equipment. I’m talking about our &lt;em&gt;information radiators&lt;/em&gt;, objects around our office that align the team by sharing important information in a fun and hard-to-miss way.&lt;/p&gt;
&lt;p&gt;Perhaps the best example of this is the large traffic light positioned in the center of our office. The stoplight is rigged to our continuous integration monitor (which displays the integration status of all active projects), displaying an aggregate of this information. A red light points out a problem, a yellow light shows that we’re processing a recent change, and a green light means that everything is running smoothly.&lt;/p&gt;


	&lt;p&gt;Another information radiator is our Atomic Spin Blog visitor tracker, a large cork board positioned in the center of our office. Each day, after our &lt;a href="http://spin.atomicobject.com/2009/07/07/10-reasons-we-have-daily-stand-up-meetings"&gt;stand up meeting&lt;/a&gt;, I update the chart for the previous day, making any appropriate “annotations,” like the primary source of traffic for that day. I also like to add people’s photos to the board when they create a new blog post. Last month, for instance, our shooting star &lt;a href="http://www.atomicobject.com/pages/Scott+Miller"&gt;Scott Miller&lt;/a&gt; literally jumped off the chart with his &lt;a href="http://spin.atomicobject.com/2010/01/04/faster-better-cheaper-tdd-wins-in-a-simple-experiment"&gt;post on &lt;span class="caps"&gt;TDD&lt;/span&gt;&lt;/a&gt;.
&lt;br&gt;&lt;/br&gt;
  &lt;div&gt;
  &lt;div class="imagebox"&gt;
  &lt;div&gt;
    &lt;img src="http://spin.atomicobject.com/assets/2010/2/8/corkboard.JPG?1265640121" alt="cork" /&gt;
  &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;/p&gt;


These information radiators are not intended to be a sole source of information. The stoplight follows our continuous integration monitor, and the blog board is a somewhat artistic interpretation of the information already stored in &lt;a href="http://www.google.com/analytics/"&gt;Google Analytics&lt;/a&gt;, annotations and all. But these visual and dynamic sources of information are not just about the “what” but also about the “how.” The stoplight is able to represent in a very simple way a company value – creating high-quality, ridiculously good, tested and working software at each step. It also provides an opportunity for us to talk about our development methods with visitors to the office. In the same vein, if someone has a hugely successful blog post, what is the best way to share that information? Spam the office with a company-wide email? Tell everyone to access the analytics account themselves and keep tabs? Or is it to get out a ladder so that you can tack a big yellow star near the ceiling? There is something about yarn and stars that just works.

 &lt;div&gt;
  &lt;div class="imagebox"&gt;
  &lt;div&gt;
    &lt;img src="http://spin.atomicobject.com/assets/2010/2/8/Millerstar.JPG?1265639824" alt="scott's star" /&gt;
  &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

	&lt;p&gt;And how do I know? People have told me. “I really want to blog now – so I can get a star.” Okay, so that was probably sarcastic, but the chart nevertheless has the power to encourage all of us to pay attention and contribute to the blog. It makes it very easy to represent – for instance – the fact that this month’s line is higher than last month’s line, or that so-and-so’s blog posts contributed to that success. The chart provides a connection between blogging effort and the popularity of our blog. And it makes me do &lt;em&gt;my&lt;/em&gt; job better and promote our blog like crazy.&lt;/p&gt;


	&lt;p&gt;In sum, the information radiators do more than radiate information. They do it in a way that – because it’s highly visual and fun – is able to rally the team and create excitement about the various goals and objectives we have as a company.&lt;/p&gt;


	&lt;p&gt;PS – Help me get a star by sharing this article!&lt;/p&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=qOzXI77VCDk:9VzaqBR_KJc:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=qOzXI77VCDk:9VzaqBR_KJc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=qOzXI77VCDk:9VzaqBR_KJc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=qOzXI77VCDk:9VzaqBR_KJc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=qOzXI77VCDk:9VzaqBR_KJc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=qOzXI77VCDk:9VzaqBR_KJc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=qOzXI77VCDk:9VzaqBR_KJc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=qOzXI77VCDk:9VzaqBR_KJc:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/atomic_spin/~4/qOzXI77VCDk" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://spin.atomicobject.com/2010/02/08/information-radiators</feedburner:origLink></entry>
  <entry xml:base="http://spin.atomicobject.com/">
    <author>
      <name>Marissa Christy</name>
      <uri>http://www.atomicobject.com/pages/Marissa+Christy</uri>
    </author>
    <id>tag:spin.atomicobject.com,2010-02-05:42429</id>
    <published>2010-02-05T17:05:00Z</published>
    <updated>2010-02-16T14:47:00Z</updated>
    <category term="Conferences" />
    <category term="Professional Development" />
    <category term="Technologies" />
    <link href="http://feedproxy.google.com/~r/atomic_spin/~3/r1pVgdjoMos/shawn-anderson-to-present-at-la-rubyconf-and-scale" rel="alternate" type="text/html" />
    <title>Shawn Anderson to present at LA RubyConf and SCALE</title>
<summary type="html">&lt;p&gt;Later this month, &lt;a href="http://www.atomicobject.com/pages/Shawn+Anderson"&gt;Shawn Anderson&lt;/a&gt; will be going back to Cali, his previous home, to make back-to-back presentations at two different conferences:  &lt;a href="http://larubyconf.com"&gt;LA RubyConf&lt;/a&gt; and &lt;a href="http://www.socallinuxexpo.org/scale8x/" title="Southern California Linux Expo"&gt;&lt;span class="caps"&gt;SCALE&lt;/span&gt;&lt;/a&gt; (the second time in two years). For both, he is presenting on developing 2D games using Ruby and open source tools (including a library that he wrote).&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;Later this month, &lt;a href="http://www.atomicobject.com/pages/Shawn+Anderson"&gt;Shawn Anderson&lt;/a&gt; will be going back to Cali, his previous home, to make back-to-back presentations at two different conferences:  &lt;a href="http://larubyconf.com"&gt;LA RubyConf&lt;/a&gt; and &lt;a href="http://www.socallinuxexpo.org/scale8x/" title="Southern California Linux Expo"&gt;&lt;span class="caps"&gt;SCALE&lt;/span&gt;&lt;/a&gt; (the second time in two years). For both, he is presenting on developing 2D games using Ruby and open source tools (including a library that he wrote).&lt;/p&gt;
&lt;p&gt;&lt;img title="Gamebox Logo" src="http://spin.atomicobject.com/assets/2010/2/5/logo.png?1265386748" /&gt;
From an early age, Shawn distinguished himself as one who enjoyed gaming. Unlike other kids who were “reading” or engaging in “outdoor sports,” Shawn was content to stay in and finish off King Hippo in &lt;em&gt;Punch-Out!&lt;/em&gt;. Over the last couple years he has renewed this early childhood interest. Since college, he has been using his free time to develop games in Ruby; he has even created his own library for gaming in Ruby – Gamebox. Gamebox was designed to spring board game development. It allows the developer to define business rules about a game very quickly without having to worry about resource loading, sound/music management, creating windows, or messing with viewports. Shawn says he wrote Gamebox  for two reasons: first, to aid in 48 hour game writing competitions and second, to allow him to write simple educational games for his kid(s). He is currently working on a game called Snelps &lt;span class="caps"&gt;RTS&lt;/span&gt; (noneducational, from what I’ve seen), and the slightly educational Free Radicals.

	&lt;p&gt;This workshop is intended for people who already know Ruby but are interested in writing games in Ruby.  At the end of the class the participants will have a basic understanding of how 2D games work and will have created a small space invaders clone with animation and sound.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://www.socallinuxexpo.org/scale8x/presentations/pew-pew-writing-games-ruby"&gt;Info for Shawn’s LA RubyConf Presentation&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://www.socallinuxexpo.org/scale8x/presentations/pew-pew-writing-games-rubyç"&gt;Info for Shawn’s &lt;span class="caps"&gt;SCALE&lt;/span&gt; Presentation&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://gamebox.rubyforge.org/docs/getting_started_rdoc.html"&gt;Getting Started with Gamebox&lt;/a&gt; (&lt;a href="http://github.com/shawn42/gamebox"&gt;Source Code&lt;/a&gt;)&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Snelps Screenshot:&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://spin.atomicobject.com/assets/2010/2/5/latest_screenshot_1.jpg?1265387162" alt="" /&gt;&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Free Radicals Screenshot:&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://spin.atomicobject.com/assets/2010/2/5/freeradicalssmall.jpeg?1265389333" alt="" /&gt;&lt;/p&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=r1pVgdjoMos:yCzMFsyhP3g:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=r1pVgdjoMos:yCzMFsyhP3g:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=r1pVgdjoMos:yCzMFsyhP3g:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=r1pVgdjoMos:yCzMFsyhP3g:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=r1pVgdjoMos:yCzMFsyhP3g:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=r1pVgdjoMos:yCzMFsyhP3g:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=r1pVgdjoMos:yCzMFsyhP3g:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=r1pVgdjoMos:yCzMFsyhP3g:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/atomic_spin/~4/r1pVgdjoMos" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://spin.atomicobject.com/2010/02/05/shawn-anderson-to-present-at-la-rubyconf-and-scale</feedburner:origLink></entry>
  <entry xml:base="http://spin.atomicobject.com/">
    <author>
      <name>Shawn Crowley</name>
      <uri>http://www.atomicobject.com/pages/Shawn+Crowley</uri>
    </author>
    <id>tag:spin.atomicobject.com,2010-02-01:42338</id>
    <published>2010-02-01T22:24:00Z</published>
    <updated>2010-02-02T13:50:48Z</updated>
    <category term="Agile Practices" />
    <category term="Business of Software" />
    <category term="Conferences" />
    <category term="Software Design" />
    <category term="UI/UX" />
    <link href="http://feedproxy.google.com/~r/atomic_spin/~3/yf2Db9RbvdE/beyond-ux-and-agile" rel="alternate" type="text/html" />
    <title>Beyond UX and Agile</title>
<content type="html">
            &lt;p&gt;Last weekend I had the privilege of attending a UX Agile Retreat at &lt;a href="http://www.cooper.com"&gt;Cooper&lt;/a&gt;. The retreat was an informal event where ~33 practitioners from the UX and Agile fields came together to discuss how we can better create effective and successful products. The event schedule was loosely defined and it self organized based on the trending topics. We used a variety of exercises and discussion techniques to voice our experiences, concerns and ideas to help build a vision of a better, collaborative future.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Where We’ve Been&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;The UX and Agile communities have been flirting with how they could integrate their practices more seamlessly and respectfully. Both groups respected one another yet remained uneasy about having to alter their respective approaches for an integrated vision and process. UX Designers were worried that some of their practices would be minimized or marginalized due to Agilistas’ strong belief of minimal upfront design. Fear existed that quality design would be sacrificed to the almighty iteration once an agile project was underway. Agilistas were worried about designers doing too much work up front without creating functioning software. Developers were ignorant of the UX Design process and the immense value it provides. Individuals, like &lt;a href="http://www.agileproductdesign.com/blog/"&gt;Jeff Patton&lt;/a&gt; and &lt;a href="http://www.linkedin.com/pub/lane-halley/0/17/358"&gt;Lane Halley&lt;/a&gt;, have been working very hard to increase knowledge and respect between the two groups. &lt;a href="http://www.andersramsay.com/"&gt;Anders Ramsey&lt;/a&gt; organized and dedicated himself to making last week’s event happen. He did an outstanding job. The UX and Agile camps are coming together because they recognize and respect each other’s dedication to the craft of creating high quality products.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Where We Are&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Most of our discussions during the retreat focused on vision, values and principles instead of outlining a strategy for collaboration. I’m glad the group was able to remain focused at such a high level because good process stems from alignment and a mutually shared vision.&lt;/p&gt;


	&lt;p&gt;We took a stand that the “Us and Them” mentality is dead and that we have to move forward as “We.” Management and business processes have kept our groups apart in the past due to a focus on efficiency and a misunderstanding of what it takes to create successful digital products. Management often times does not know how to ask us for what they want, nor do they know how to properly manage creative teams. We believe that we can create better products more efficiently by focusing on being effective. We believe that effectiveness is increased by working together closely.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;The Future&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;The new vision is forming. The retreat group is committed to evangelizing and furthering this vision. I left the retreat with strong feelings of alignment, momentum and excitement. We are the makers of amazing, complex things and we are taking a stand on how we’ll bring the dreams of others into the world. We’re building a case for businesses to employ design thinking at all levels, to focus on the satisfaction of their customers and and to let individuals who understand the creative process to manage it for effectiveness.&lt;/p&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=yf2Db9RbvdE:xkH4j1zh4uU:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=yf2Db9RbvdE:xkH4j1zh4uU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=yf2Db9RbvdE:xkH4j1zh4uU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=yf2Db9RbvdE:xkH4j1zh4uU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=yf2Db9RbvdE:xkH4j1zh4uU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=yf2Db9RbvdE:xkH4j1zh4uU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=yf2Db9RbvdE:xkH4j1zh4uU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=yf2Db9RbvdE:xkH4j1zh4uU:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/atomic_spin/~4/yf2Db9RbvdE" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://spin.atomicobject.com/2010/02/01/beyond-ux-and-agile</feedburner:origLink></entry>
  <entry xml:base="http://spin.atomicobject.com/">
    <author>
      <name>Matt Fletcher</name>
      <uri>http://www.atomicobject.com/pages/Matt+Fletcher</uri>
    </author>
    <id>tag:spin.atomicobject.com,2010-02-01:42144</id>
    <published>2010-02-01T13:11:00Z</published>
    <updated>2010-02-01T14:08:44Z</updated>
    <category term="Software Design" />
    <category term="Tips" />
    <category term="Tools" />
    <link href="http://feedproxy.google.com/~r/atomic_spin/~3/ZvJncACrxtU/the-case-for-embedding-jruby-complete-into-your-application" rel="alternate" type="text/html" />
    <title>The case for embedding jruby-complete into your application</title>
<content type="html">
            &lt;p&gt;Why in the world would you want to embed JRuby into your application instead of relying on a regular Ruby or JRuby installation? I can think of three reasons.&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;Note: this is a sister post to &lt;a href="http://spin.atomicobject.com/2010/02/01/running-a-ruby-application-with-jruby-complete"&gt;my description of the arguments needed to run JRuby via jruby-complete&lt;/a&gt;. Here I discuss the rationale for using JRuby like this.&lt;/em&gt;&lt;/p&gt;


	&lt;h3&gt;What’s the upside?&lt;/h3&gt;


	&lt;p&gt;&lt;strong&gt;You can bundle your Ruby runtime dependence into the application.&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;If you don’t know what I’m talking about here then you should probably stop reading right now. An old post by &lt;a href="http://errtheblog.com/posts/50-vendor-everything"&gt;Err the blog&lt;/a&gt; summarizes the “vendor everything” principle quite well:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;Quickly: fix it! Tell everyone to install the gem locally. Install the gem on your staging server. Carefully install the gem on your production server. Phew. Everyone’s got the same version, right? Right. Well, maybe. (At least the build works.)&lt;/p&gt;
	&lt;/blockquote&gt;


I like vendoring the Ruby runtime for several reasons:
	&lt;ol&gt;
	&lt;li&gt;I don’t want to ask my users to install anything outside of my application. I definitely don’t want to count on the end user having something installed. Depending on end users having a compatible version of Java is frustrating enough, let alone a JRuby installation. Depending on the JRuby installation can be annoying for developers as well. Take culerity as an example. You could spend a bunch of time screwing around with &lt;a href="http://github.com/langalex/culerity/issues#issue/13"&gt;getting your system-wide JRuby installation just right&lt;/a&gt;. Or you could &lt;a href="http://github.com/fletcherm/culerity"&gt;embed JRuby directly into culerity&lt;/a&gt; and be done with it.&lt;/li&gt;
		&lt;li&gt;I don’t need to worry about version incompatibilities between the various runtimes. Incompatibilities can mean features I depend on are unavailable, subtly different, or outright broken. An interesting example of “subtly different” came up in an application I recently developed. At one point the sort implementation in JRuby changed from a stable sort to an unstable sort. As far as I know, Ruby doesn’t guarantee sort stability one way or another, so the change was ok from a Ruby perspective. Not so much for me. It turns out my application assumed a stable sort. Had I been dependent on the user’s Ruby installation, my application may have been using either the stable or unstable sort implementation, which was a variance it could not tolerate. (I’m glad I had &lt;a href="http://spin.atomicobject.com/2010/01/29/testing-terminology"&gt;automated integration tests&lt;/a&gt; that revealed this problem to me. I eventually concluded that the application’s behavior was fine with either the stable or unstable sort.)&lt;/li&gt;
		&lt;li&gt;Using &lt;a href="http://code.google.com/p/jarjar/"&gt;JarJar&lt;/a&gt; and &lt;a href="http://spin.atomicobject.com/2008/07/02/rolling-a-jruby-desktop-application"&gt;a few tricks&lt;/a&gt; means you can distribute your Ruby application as a single jar file.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;&lt;strong&gt;Your application may need to run in a constrained environment where you can’t install much, but Java is available.&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;A couple of years ago I started development on a new application for monitoring PeopleSoft services. Installing Ruby on the servers I was deploying to was not an option. Java was already there to support PeopleSoft. Thank goodness JRuby 1.0 had just been released.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Managing one file is easier than managing many files.&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Copying around one jar file is easier than copying a directory with hundreds of files in it. Yeah, manipulating a directory isn’t always a pain, but the times where manipulating a big directory is a pain can be a &lt;em&gt;really big pain&lt;/em&gt;.&lt;/p&gt;


	&lt;h3&gt;What’s the downside?&lt;/h3&gt;


	&lt;p&gt;&lt;strong&gt;Your application gets bigger.&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;jruby-complete is currently (as of version 1.4.0) sitting at around 11.5 megabytes. Do I care? Nope. This can be annoying but it generally doesn’t bother me. Especially when my application is already measured in tens of megabytes.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Figuring out and typing the correct commands to run your application isn’t trivial.&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;This part sucks. Running commands through jruby-complete is tedious when you don’t have any help from something like Rake tasks. The &lt;span class="caps"&gt;JVM&lt;/span&gt; boot time sucks as well. For these reasons I don’t recommend using jruby-complete for everything: when running small, one-off scripts, there’s just too much overhead. Thankfully, when I do depend on jruby-complete, I’m already working on an application where I’m using Rake to automate all kinds of things. So running lengthly &lt;code&gt;java&lt;/code&gt; commands isn’t a big deal because my Rake support is already there.&lt;/p&gt;


	&lt;p&gt;Thankfully, &lt;a href="http://spin.atomicobject.com/2010/02/01/running-a-ruby-application-with-jruby-complete"&gt;this companion post&lt;/a&gt; is chock full of tips for alleviating the pain from those nasty commands.&lt;/p&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=ZvJncACrxtU:P4XdZ5NS9Kg:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=ZvJncACrxtU:P4XdZ5NS9Kg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=ZvJncACrxtU:P4XdZ5NS9Kg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=ZvJncACrxtU:P4XdZ5NS9Kg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=ZvJncACrxtU:P4XdZ5NS9Kg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=ZvJncACrxtU:P4XdZ5NS9Kg:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=ZvJncACrxtU:P4XdZ5NS9Kg:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=ZvJncACrxtU:P4XdZ5NS9Kg:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/atomic_spin/~4/ZvJncACrxtU" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://spin.atomicobject.com/2010/02/01/the-case-for-embedding-jruby-complete-into-your-application</feedburner:origLink></entry>
  <entry xml:base="http://spin.atomicobject.com/">
    <author>
      <name>Matt Fletcher</name>
      <uri>http://www.atomicobject.com/pages/Matt+Fletcher</uri>
    </author>
    <id>tag:spin.atomicobject.com,2010-02-01:42146</id>
    <published>2010-02-01T13:10:00Z</published>
    <updated>2010-02-06T22:50:20Z</updated>
    <category term="Technologies" />
    <category term="Tips" />
    <category term="Tools" />
    <link href="http://feedproxy.google.com/~r/atomic_spin/~3/5ocpiES4TUg/running-a-ruby-application-with-jruby-complete" rel="alternate" type="text/html" />
    <title>Running a Ruby application with jruby-complete</title>
<content type="html">
            &lt;p&gt;One of the great things about the JRuby project is that it’s easy to run Ruby programs without installing Ruby. In fact, you don’t even need to install JRuby. All you need is a &lt;span class="caps"&gt;JVM&lt;/span&gt; runtime and &lt;a href="http://jruby.org/download"&gt;jruby-complete&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://spin.atomicobject.com/assets/2010/1/26/jrubygiftsized.jpg" alt="" /&gt;&lt;/p&gt;


	&lt;h1&gt;Rationale&lt;/h1&gt;


	&lt;p&gt;Check out &lt;a href="http://spin.atomicobject.com/2010/02/01/the-case-for-embedding-jruby-complete-into-your-application"&gt;this other post&lt;/a&gt; for a discussion of my reasons for locking down your JRuby runtime. In summary, embedding jruby-complete gives you complete control of your Ruby runtime. That’s a good thing. The downside is that discovering and executing commands through jruby-complete can be a pain. The rest of this post describes how to ameliorate the pain.&lt;/p&gt;


	&lt;h1&gt;Running jruby-complete&lt;/h1&gt;


The base jruby-complete command is:
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;java -jar jruby-complete-1.4.0.jar&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

This gives you the same behavior as typing &lt;code&gt;ruby&lt;/code&gt; or &lt;code&gt;jruby&lt;/code&gt;.
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;java -jar jruby-complete-1.4.0.jar -e &amp;quot;puts 'Hello'&amp;quot;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

prints “Hello.” (Of course, this depends on what your jruby-complete jar is named. I usually put the version number in there so I know what it is. I expect anyone reading this to be able to figure out what their jar is named and fill it in appropriately. If this is a hurdle, then too bad for you.)
&lt;br /&gt;
&lt;br /&gt;
I lied.&lt;sup&gt;&lt;a href="#fn1"&gt;1&lt;/a&gt;&lt;/sup&gt; To get the same &lt;span class="caps"&gt;JVM&lt;/span&gt; heap and stack sizes as typing &lt;code&gt;jruby&lt;/code&gt;, you need to pass a couple of &lt;span class="caps"&gt;JVM&lt;/span&gt; options:
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;java -Xmx500m -Xss1024k -jar jruby-complete-1.4.0.jar -e &amp;quot;puts 'Hello'&amp;quot;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


Want to run irb? Try this:
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;java -Xmx500m -Xss1024k -jar jruby-complete-1.4.0.jar -e 'load &amp;quot;META-INF/jruby.home/bin/jirb&amp;quot;'&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;irb(main):&lt;span class="i"&gt;001&lt;/span&gt;:&lt;span class="i"&gt;0&lt;/span&gt;&amp;gt; puts &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;Hello&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;=&amp;gt; &lt;span class="pc"&gt;nil&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;irb(main):&lt;span class="i"&gt;002&lt;/span&gt;:&lt;span class="i"&gt;0&lt;/span&gt;&amp;gt; %&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


As you can see, the &lt;code&gt;java&lt;/code&gt; command is getting to be a pain. It’s time to introduce some rake tasks to help us out.
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="co"&gt;JRUBY_COMPLETE&lt;/span&gt; = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;jruby-complete-1.4.0.jar&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;JRUBY&lt;/span&gt; = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;java -Xmx500m -Xss1024k -jar &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;&lt;span class="co"&gt;JRUBY_COMPLETE&lt;/span&gt;&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;namespace &lt;span class="sy"&gt;:jruby&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  desc &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Run JRuby help&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  task &lt;span class="sy"&gt;:help&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    sh &lt;span class="s"&gt;&lt;span class="dl"&gt;%+&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;&lt;span class="co"&gt;JRUBY&lt;/span&gt;&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt; --help&lt;/span&gt;&lt;span class="dl"&gt;+&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  desc &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Run any command with JRuby&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  task &lt;span class="sy"&gt;:run&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    sh &lt;span class="s"&gt;&lt;span class="dl"&gt;%+&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;&lt;span class="co"&gt;JRUBY&lt;/span&gt;&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt; -e '&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;&lt;span class="co"&gt;ENV&lt;/span&gt;[&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;cmd&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;]&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;'&lt;/span&gt;&lt;span class="dl"&gt;+&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Now I can type &lt;code&gt;rake jruby:run cmd='puts "Hello"'&lt;/code&gt;. Shell escaping is becoming a real annoyance at this point. Thankfully, I’m usually not using jruby-complete to run silly little commands. By the time I’ve introduced a Rakefile I’ve got a real application with tasks oriented around testing and running it, so it’s rare that I’m using a task like &lt;code&gt;jruby:run&lt;/code&gt; very often.&lt;/p&gt;


Running my application may introduce a task that looks something like this:
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;task &lt;span class="sy"&gt;:run&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  sh &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;&lt;span class="co"&gt;JRUBY&lt;/span&gt;&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt; lib/application_bootstrap.rb&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


Running it:
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;fletcher-git/github/jruby-complete-example(master) rake run&lt;tt&gt;
&lt;/tt&gt;(in /Users/fletcher/git/github/jruby-complete-example)&lt;tt&gt;
&lt;/tt&gt;java -Xmx500m -Xss1024k -jar jruby-complete-1.4.0.jar lib/application_bootstrap.rb&lt;tt&gt;
&lt;/tt&gt;Hello from application_bootstrap&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


Of course, my application comes with RSpec specs. The standard jruby-complete distribution comes with RSpec built in. How can I use it? The &lt;code&gt;-S&lt;/code&gt; parameter runs files in JRuby’s bin directory:
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;  namespace &lt;span class="sy"&gt;:spec&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    desc &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Run RSpec against a specific file&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    task &lt;span class="sy"&gt;:run&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      raise &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;You need to specify a spec with spec=&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;if&lt;/span&gt; &lt;span class="r"&gt;not&lt;/span&gt; &lt;span class="co"&gt;ENV&lt;/span&gt;[&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;spec&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;]&lt;tt&gt;
&lt;/tt&gt;      sh &lt;span class="s"&gt;&lt;span class="dl"&gt;%+&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;&lt;span class="co"&gt;JRUBY&lt;/span&gt;&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt; -S spec -f specdoc &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;&lt;span class="co"&gt;ENV&lt;/span&gt;[&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;spec&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;]&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;+&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


Here’s a spec:
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;describe &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;John Galt&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  it &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;does not tolerate logical fallacies&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;A&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;.should == &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;A&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


Running it:
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;fletcher-git/github/jruby-complete-example(master) rake spec:run spec=spec/unit/objectivism_spec.rb&lt;tt&gt;
&lt;/tt&gt;(in /Users/fletcher/git/github/jruby-complete-example)&lt;tt&gt;
&lt;/tt&gt;java -Xmx500m -Xss1024k -jar jruby-complete-1.4.0.jar -S spec -f specdoc spec/unit/objectivism_spec.rb&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;John Galt&lt;tt&gt;
&lt;/tt&gt;- does not tolerate logical fallacies&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;Finished in 0.123 seconds&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;1 example, 0 failures&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


Is this more typing than the usual &lt;code&gt;spec spec/unit/objectivism_spec.rb&lt;/code&gt;? Yes. Do I care? No. I know how to use my shell.
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;fletcher-git/github/jruby-complete-example(master) which sp&lt;tt&gt;
&lt;/tt&gt;sp () {&lt;tt&gt;
&lt;/tt&gt;        rake spec:run spec=$@&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;fletcher-git/github/jruby-complete-example(master) sp spec/unit/objectivism_spec.rb&lt;tt&gt;
&lt;/tt&gt;(in /Users/fletcher/git/github/jruby-complete-example)&lt;tt&gt;
&lt;/tt&gt;java -Xmx500m -Xss1024k -jar jruby-complete-1.4.0.jar -S spec -f specdoc spec/unit/objectivism_spec.rb&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Alright, so now that my application has been built up, I might want to start compiling the .rb files into .class files. Here comes &lt;code&gt;jrubyc&lt;/code&gt;:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;rake/clean&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;namespace &lt;span class="sy"&gt;:jruby&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  output_directory = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;classes&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  directory output_directory&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="co"&gt;CLEAN&lt;/span&gt;.include output_directory&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  desc &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Compile Ruby files in lib&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  task &lt;span class="sy"&gt;:compile&lt;/span&gt; =&amp;gt; output_directory &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    sh &lt;span class="s"&gt;&lt;span class="dl"&gt;%+&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;&lt;span class="co"&gt;JRUBY&lt;/span&gt;&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt; -S jrubyc -p com/atomicobject -t &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="dl"&gt;#{&lt;/span&gt;output_directory&lt;span class="dl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt; lib&lt;/span&gt;&lt;span class="dl"&gt;+&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;fletcher-git/github/jruby-complete-example(master) rake jruby:compile&lt;tt&gt;
&lt;/tt&gt;(in /Users/fletcher/git/github/jruby-complete-example)&lt;tt&gt;
&lt;/tt&gt;mkdir -p classes&lt;tt&gt;
&lt;/tt&gt;java -Xmx500m -Xss1024k -jar jruby-complete-1.4.0.jar -S jrubyc -p com/atomicobject -t classes lib&lt;tt&gt;
&lt;/tt&gt;Compiling all in '/Users/fletcher/git/github/jruby-complete-example/lib'...&lt;tt&gt;
&lt;/tt&gt;Compiling lib/application_bootstrap.rb to class com/atomicobject/lib/application_bootstrap&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;fletcher-git/github/jruby-complete-example(master) rake jruby:run cmd='require &amp;quot;classes/com/atomicobject/lib/application_bootstrap&amp;quot;'&lt;tt&gt;
&lt;/tt&gt;(in /Users/fletcher/git/github/jruby-complete-example)&lt;tt&gt;
&lt;/tt&gt;java -Xmx500m -Xss1024k -jar jruby-complete-1.4.0.jar -e 'require &amp;quot;classes/com/atomicobject/lib/application_bootstrap&amp;quot;'&lt;tt&gt;
&lt;/tt&gt;Hello from application_bootstrap&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


Remember that since we’re executing a &lt;code&gt;java&lt;/code&gt; command, we can pass any typical &lt;span class="caps"&gt;JVM&lt;/span&gt; parameters before the &lt;code&gt;-jar&lt;/code&gt; parameter. We’ve done this for things like:
	&lt;ol&gt;
	&lt;li&gt;enabling antialiasing in Apple’s &lt;span class="caps"&gt;JVM&lt;/span&gt; via a Java property.&lt;/li&gt;
		&lt;li&gt;tweaking &lt;a href="https://substance.dev.java.net/"&gt;Substance’s&lt;/a&gt; widget behavior via a Java property.&lt;/li&gt;
		&lt;li&gt;enabling &lt;a href="http://www.yourkit.com/overview/index.jsp"&gt;Yourkit Java Profiler&lt;/a&gt; via the &lt;code&gt;-agentlib&lt;/code&gt; parameter.&lt;/li&gt;
		&lt;li&gt;including libraries and directories in the &lt;span class="caps"&gt;JVM&lt;/span&gt;’s classpath via the &lt;code&gt;-cp&lt;/code&gt; parameter.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Since these parameters need to be passed before the &lt;code&gt;-jar&lt;/code&gt; parameter, a more sophisticated method for setting up the JRuby command is needed than the constant I’ve used. A method like that is specific for your application and beyond the scope of this post, but is not be difficult to create.&lt;/p&gt;


	&lt;h1&gt;Conclusion&lt;/h1&gt;


	&lt;p&gt;There are an uncountable number of good things about JRuby and jruby-complete is one of them. A little help from scripts and your shell means you can build and run your application with a controlled Ruby runtime.&lt;/p&gt;


	&lt;h2&gt;Additional resources&lt;/h2&gt;


	&lt;ul&gt;
	&lt;li&gt;The Rakefile, jruby-complete, and other files used in this post are available in &lt;a href="http://github.com/fletcherm/jruby-complete-example"&gt;this GitHub project&lt;/a&gt;.&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://code.google.com/p/jarjar/"&gt;JarJar Links&lt;/a&gt; is an ant library that is useful for combining multiple jar files together.&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://spin.atomicobject.com/2008/07/02/rolling-a-jruby-desktop-application"&gt;I wrote a post a while ago&lt;/a&gt; about using JarJar to combine jruby-complete and other application dependences into a single file.&lt;/li&gt;
		&lt;li&gt;The &lt;a href="http://spin.atomicobject.com/2009/01/30/ruby-for-desktop-applications-yes-we-can"&gt;&lt;span class="caps"&gt;AGI&lt;/span&gt; Production Simulator&lt;/a&gt; is built using the jruby-complete commands described in this post as well as the above jar-rolling technique.&lt;/li&gt;
	&lt;/ul&gt;


&lt;ol&gt;
&lt;li&gt;
Replicating the true &lt;code&gt;jruby&lt;/code&gt; behavior is way, way beyond the scope of this post. Check out the &lt;code&gt;jruby&lt;/code&gt; script if you really care. Most of the time the &lt;span class="caps"&gt;JVM&lt;/span&gt; heap and stack sizes are the most important things to worry about.
&lt;a href="#fnref1" title="Jump back to footnote 1 in the text."&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

	&lt;p&gt;&lt;em&gt;Edit 2/6/2010: Reduced -e ‘load…’ parameters to -S&lt;/em&gt;&lt;/p&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=5ocpiES4TUg:HNUtqYysDyM:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=5ocpiES4TUg:HNUtqYysDyM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=5ocpiES4TUg:HNUtqYysDyM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=5ocpiES4TUg:HNUtqYysDyM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=5ocpiES4TUg:HNUtqYysDyM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=5ocpiES4TUg:HNUtqYysDyM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=5ocpiES4TUg:HNUtqYysDyM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=5ocpiES4TUg:HNUtqYysDyM:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/atomic_spin/~4/5ocpiES4TUg" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://spin.atomicobject.com/2010/02/01/running-a-ruby-application-with-jruby-complete</feedburner:origLink></entry>
  <entry xml:base="http://spin.atomicobject.com/">
    <author>
      <name>Michael Marsiglia</name>
      <uri>http://www.atomicobject.com/pages/Michael+Marsiglia</uri>
    </author>
    <id>tag:spin.atomicobject.com,2010-01-30:42286</id>
    <published>2010-01-30T17:04:00Z</published>
    <updated>2010-01-30T17:05:33Z</updated>
    <category term="Tools" />
    <link href="http://feedproxy.google.com/~r/atomic_spin/~3/-I-cmF5ly5Q/yammer-time" rel="alternate" type="text/html" />
    <title>Yammer Time</title>
<content type="html">
            &lt;p&gt;&lt;a href="http://www.atomicobject.com/"&gt;Atomic Object&lt;/a&gt; has been using &lt;a href="https://www.yammer.com/"&gt;Yammer&lt;/a&gt; internally for about a month. Yammer is enterprise level micro-blogging. Essentially, it is a private &lt;a href="http://twitter.com/"&gt;Twitter&lt;/a&gt; service.&lt;/p&gt;


	&lt;p&gt;Yammer has proven to be a great way to share information within our organization. Unlike Twitter, the service is restricted to our organization so the team can freely discuss internal projects, company tactics, and technology information. If any of the commentary is interesting to the outside world it is then broadcasted through the company twitter feed.&lt;/p&gt;


	&lt;p&gt;Our favorite part about Yammer is that it has provided a channel for our off-site Atoms to connect with the rest of the office. It has helped the team stay connected that much better, and is quickly replacing company wide emails.&lt;/p&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=-I-cmF5ly5Q:B3LEpBlwJSw:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=-I-cmF5ly5Q:B3LEpBlwJSw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=-I-cmF5ly5Q:B3LEpBlwJSw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=-I-cmF5ly5Q:B3LEpBlwJSw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=-I-cmF5ly5Q:B3LEpBlwJSw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=-I-cmF5ly5Q:B3LEpBlwJSw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=-I-cmF5ly5Q:B3LEpBlwJSw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=-I-cmF5ly5Q:B3LEpBlwJSw:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/atomic_spin/~4/-I-cmF5ly5Q" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://spin.atomicobject.com/2010/01/30/yammer-time</feedburner:origLink></entry>
  <entry xml:base="http://spin.atomicobject.com/">
    <author>
      <name>Carl Erickson</name>
      <uri>http://www.atomicobject.com/pages/Carl+Erickson</uri>
    </author>
    <id>tag:spin.atomicobject.com,2010-01-29:42256</id>
    <published>2010-01-29T15:35:00Z</published>
    <updated>2010-01-29T15:39:19Z</updated>
    <category term="Agile Practices" />
    <category term="System Testing" />
    <category term="Test Driven Development" />
    <link href="http://feedproxy.google.com/~r/atomic_spin/~3/cR3FTTV1AYk/testing-terminology" rel="alternate" type="text/html" />
    <title>Testing terminology</title>
<summary type="html">&lt;p&gt;Working with some new customers this year has given me fresh perspective on how confusing the terminology of the testing world can be. I think terms and definitions matters a lot, and not just because I’m a recovering academic. Several times recently I’ve found myself in a conversation taking a position in apparent opposition to my companion, only to eventually determine that we were in fact talking about the same thing. Or we might have been using the same words, but actually meaning very different things. I don’t know that the testing world is any more inconsistent in their terms than other technical fields, but it sure seems like it sometimes.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;Working with some new customers this year has given me fresh perspective on how confusing the terminology of the testing world can be. I think terms and definitions matters a lot, and not just because I’m a recovering academic. Several times recently I’ve found myself in a conversation taking a position in apparent opposition to my companion, only to eventually determine that we were in fact talking about the same thing. Or we might have been using the same words, but actually meaning very different things. I don’t know that the testing world is any more inconsistent in their terms than other technical fields, but it sure seems like it sometimes.&lt;/p&gt;
&lt;p&gt;The terms I prefer (and generally what Atomic developers use as well, though I’m sure we have some internal variation) are useful in the context of an agile development process. They’re also meaningful in more traditional testing cultures, though it’s quite likely that dedicated testers or “QA engineers” are performing the testing.&lt;/p&gt;


	&lt;p&gt;I have a simple taxonomy for the sorts of tests that developers create: unit, integration, and system. My friend and former colleague &lt;a href="http://www.cis.gvsu.edu/Staff/Staff.php?fname=Paul&amp;lname=Jorgensen"&gt;Paul Jorgensen&lt;/a&gt; taught this to me years ago and it’s worked quite well.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Unit&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Tests which validate that a single method or function performs as expected. These tests are almost always “state-based” testing, meaning they make assertions on the return value of a unit, or the change of state in the system.&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://spin.atomicobject.com/assets/2010/1/29/unittest_1.jpg?1264777549" alt="" /&gt;&lt;/p&gt;


	&lt;p&gt;Example from Ken Beck’s &lt;a href="http://www.amazon.com/Test-Driven-Development-Kent-Beck/dp/0321146530"&gt;Test-Driven Development&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Integration&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Tests which validate that multiple units or subsystems play well together. Software systems are the composition and integration of many small pieces of functionality. Integration tests may be state-based or interaction-based. Mocking libraries are often used for integration tests.&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://spin.atomicobject.com/assets/2010/1/29/integrationtest.jpg?1264777493" alt="" /&gt;&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;System&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Tests which validate that the system as a whole, from the perspective of the “end-user”, operates correctly. I put “end-user” in quotes, since that might mean other systems or hardware, depending on the project.&lt;/p&gt;


	&lt;p&gt;The unusual breadth of Atomic’s range of projects gives me a lot of examples to draw upon. To make the definitions above more concrete, I’ve included examples from web, desktop and embedded applications.&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://spin.atomicobject.com/assets/2010/1/29/systemtest_1.jpg?1264777519" alt="" /&gt;&lt;/p&gt;


	&lt;h3&gt;Examples&lt;/h3&gt;


	&lt;p&gt;&lt;strong&gt;Unit test examples&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;A function calculates the square of a floating point argument. A test for this function might include assertions that it returns 4.0 when given 2.0, 0.0 when given 0.0, 81.0 when given -9.0, etc.&lt;/p&gt;


	&lt;p&gt;A Ruby on Rails web app would have unit tests that confirm that the Model classes behave correctly.&lt;/p&gt;


	&lt;p&gt;An embedded application might have unit tests that verify computations, as above, or tests for the manipulations of registers.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Integration test examples&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;A running application written in an object-oriented language can be viewed as a series of messages sent between objects. An integration test in such an application would make assertions that the messages sent between objects were as expected (by name, frequency, parameters, etc).&lt;/p&gt;


	&lt;p&gt;Ruby on Rails supports and encourages integration tests. A Rails integration test validates that the Controller, View and Model operate properly together. This test isn’t a system test, by my definition, because it doesn’t include the client side (the browser).&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;System test examples&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Desktop applications are used by people. Most often today they have graphical user interfaces. A system test of such an application exercises the app from the user’s perspective. In other words, it pushes buttons, types into text fields, and makes assertions about what’s displayed or changed in the app.&lt;/p&gt;


	&lt;p&gt;System testing web apps requires driving the application through a browser, just like an end user would. Such tests exercise the browser, Javascript, &lt;span class="caps"&gt;HTTP&lt;/span&gt;, and the full stack of the server side code.&lt;/p&gt;


	&lt;p&gt;Every embedded application interacts with the world in some fashion. A system test for a speed controller on an automated guided vehicle, for instance, might inject an analog speed signal from a programmable test rig and validate the expected digital output to a motor controller.&lt;/p&gt;


	&lt;h3&gt;Other terms&lt;/h3&gt;


	&lt;p&gt;&lt;strong&gt;Regression&lt;/strong&gt; The term “regression tests” is a common misnomer. Regression means running all your tests every time you make a change, or every time you test. There are no separate, special types of tests that are regression tests. Automation obviously helps to do regression testing, since it dramatically reduces the cost compared to manual  regression testing.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Automated tests&lt;/strong&gt; Tests that can be run without any human intervention (other than starting the test runner). Applies to all levels of testing.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Exploratory testing&lt;/strong&gt; An exemplar of the context-driven school of testing, exploratory testing is a form of manual testing where the tester learns her way through the application making observations, finding bugs, and identifying interesting new test cases.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Acceptance tests&lt;/strong&gt; Tests, generally system tests, that are used as a contract between the development team and their customer. The customer agrees that the development team has satisfied the contract when the acceptance tests run clean. Acceptance tests are generally system-level tests and should probably be tied closely to requirements.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Functional tests&lt;/strong&gt; A synonym for system tests. Also a term used in the Rails community for integration tests that validate the interaction between Controller and View, isolated from the Model.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Non-functional tests&lt;/strong&gt; (My personal favorite.) Doesn’t refer to broken tests, just those that validate aspects of the product which have nothing to do with application functionality, such as installation, performance, upgradability, etc.&lt;/p&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=cR3FTTV1AYk:KzwelU4AviM:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=cR3FTTV1AYk:KzwelU4AviM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=cR3FTTV1AYk:KzwelU4AviM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=cR3FTTV1AYk:KzwelU4AviM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=cR3FTTV1AYk:KzwelU4AviM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=cR3FTTV1AYk:KzwelU4AviM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=cR3FTTV1AYk:KzwelU4AviM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=cR3FTTV1AYk:KzwelU4AviM:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/atomic_spin/~4/cR3FTTV1AYk" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://spin.atomicobject.com/2010/01/29/testing-terminology</feedburner:origLink></entry>
  <entry xml:base="http://spin.atomicobject.com/">
    <author>
      <name>Carl Erickson</name>
      <uri>http://www.atomicobject.com/pages/Carl+Erickson</uri>
    </author>
    <id>tag:spin.atomicobject.com,2010-01-27:42178</id>
    <published>2010-01-27T00:33:00Z</published>
    <updated>2010-01-27T15:53:25Z</updated>
    <category term="Tools" />
    <link href="http://feedproxy.google.com/~r/atomic_spin/~3/FarprQpiQpc/january-softwaregr-meeting-eric-sink-on-version-control" rel="alternate" type="text/html" />
    <title>January SoftwareGR meeting: Eric Sink on version control</title>
<summary type="html">&lt;p&gt;&lt;a href="http://www.ericsink.com/"&gt;Eric Sink&lt;/a&gt;, of &lt;a href="http://sourcegear.com/"&gt;Source Gear&lt;/a&gt; was January’s &lt;a href="http://softwaregr.org"&gt;SoftwareGR&lt;/a&gt; speaker. Twenty five or so people turned out for the meeting. Eric chose to speak on the topic that he’s passionate about: version control. This is a deeply nerdy interest and his wife is tired of the subject, evidently. Version control in a nutshell is undo &amp; history of change.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;&lt;a href="http://www.ericsink.com/"&gt;Eric Sink&lt;/a&gt;, of &lt;a href="http://sourcegear.com/"&gt;Source Gear&lt;/a&gt; was January’s &lt;a href="http://softwaregr.org"&gt;SoftwareGR&lt;/a&gt; speaker. Twenty five or so people turned out for the meeting. Eric chose to speak on the topic that he’s passionate about: version control. This is a deeply nerdy interest and his wife is tired of the subject, evidently. Version control in a nutshell is undo &amp; history of change.&lt;/p&gt;
&lt;p&gt;Eric started his career in scientific data visualization tools. Great fun, not much of a market. He worked at &lt;a href="http://en.wikipedia.org/wiki/Spyglass,_Inc"&gt;SpyGlass&lt;/a&gt;. (the origin of Internet Explorer), then founded SourceGear when SpyGlass switched to pursuing mobile browsers.&lt;/p&gt;


	&lt;p&gt;SourceGear has several version control products. TeamPrise, a client for Microsoft &lt;a href="http://en.wikipedia.org/wiki/Team_Foundation_Server"&gt;Team Foundation Server&lt;/a&gt; (TFS), was recently sold to Microsoft.&lt;/p&gt;


	&lt;p&gt;There are dozens of successful players in this industry. Some open source tools have millions of users, many successful commercial tools (&amp;gt; $1B market). It’s an unusual market this way, in that there isn’t a single, dominant player.&lt;/p&gt;


	&lt;p&gt;Eric identified several new, and powerful trends in version control: integration and distribution. The trend toward integration is happening in the enterprise. The trend toward &lt;span class="caps"&gt;DVCS&lt;/span&gt; is happening in the open source community.&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;Integration&lt;/b&gt; Integrating your version control tool with burndown charts, bug tracking, time tracking, project management, requirements, testing, builds, agile planning, etc, is where the enterprise is taking version control.&lt;/p&gt;


	&lt;p&gt;Eric included heterogeneous environment support (various IDEs, platforms, databases, etc) in the integration trend. The leaders in the integration field are Borland (via StarTeam), MS, Serena, and &lt;span class="caps"&gt;IBM&lt;/span&gt;/Rational.&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;Distribution&lt;/b&gt; Distributed version control (DVCS) doesn’t require a centralized server. Branching is so intrinsic to this approach it’s not called branching.&lt;/p&gt;


	&lt;p&gt;With distributed version control, everyone has a private workspace. You get much better performance (especially for distributed teams), since you’re committing locally. You get good flexibility, which is handy for large companies and complex situations.&lt;/p&gt;


	&lt;p&gt;With &lt;span class="caps"&gt;DVCS&lt;/span&gt; you’re committing before you merge. There is no longer a single authoritative version. This stops a lot of people (Eric said you shouldn’t let it stop you from learning about these tools). Several people offered advantages and personal testimonials of &lt;span class="caps"&gt;DVCS&lt;/span&gt; over traditional version control.&lt;/p&gt;


	&lt;p&gt;Examples of &lt;span class="caps"&gt;DVCS&lt;/span&gt; tools include BitKeeper, Git, Mercurial, and Bzr. BitKeeper got the Linux kernel (a major win), then had a very public falling out with that team (a major PR disaster). However, the BitKeeper disaster led to Git, and other important open source &lt;span class="caps"&gt;DVCS&lt;/span&gt; projects.&lt;/p&gt;


	&lt;p&gt;The enterprise has problems most of us don’t have. For example, Eric cited Cisco, with 15 terabytes in source control, and 50 developers writing perl scripts on top of ClearCase to serve 6000 users. That scale of problem is something the open source, distributed tools aren’t able to handle.&lt;/p&gt;


	&lt;p&gt;As interesting signs of change, Eric’s company lost a major retailer client to Collabnet + svn. This is a sign that the enterprise is becoming more open to open source tools. Another sign of change: Microsoft is supporting mercurial. That’s significant because mercurial is a &lt;span class="caps"&gt;DVCS&lt;/span&gt; licensed under the &lt;span class="caps"&gt;GPL&lt;/span&gt;, a double hatred for Microsoft.&lt;/p&gt;


	&lt;p&gt;Eric claimed major enterprise vendors (TFS, Perforce, and Rational) are trying to convert to &lt;span class="caps"&gt;DVCS&lt;/span&gt;. He predicted that these efforts are bound to failure. Integration and distribution are inherently opposed. Eric predicts the clash of these trends will be resolved by integrated, enterprise version control systems picking up just enough distributed features to make people happy.&lt;/p&gt;
          &lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=FarprQpiQpc:MJMeiD8dxck:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=FarprQpiQpc:MJMeiD8dxck:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=FarprQpiQpc:MJMeiD8dxck:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=FarprQpiQpc:MJMeiD8dxck:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=FarprQpiQpc:MJMeiD8dxck:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=FarprQpiQpc:MJMeiD8dxck:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?i=FarprQpiQpc:MJMeiD8dxck:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/atomic_spin?a=FarprQpiQpc:MJMeiD8dxck:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/atomic_spin?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/atomic_spin/~4/FarprQpiQpc" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://spin.atomicobject.com/2010/01/27/january-softwaregr-meeting-eric-sink-on-version-control</feedburner:origLink></entry>
</feed>
