<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="http://feeds.feedblitz.com/feedblitz_rss.xslt"?><rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
 xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0"> <channel><title>Atomic Spin</title> <atom:link href="http://spin.atomicobject.com/feed/?redirect=false&#038;r=1&#038;fbz=0" rel="self" type="application/rss+xml" /><link>http://spin.atomicobject.com</link> <description>Atomic Object's Blog on Software Design &amp; Development</description> <lastBuildDate>Sun, 19 May 2013 02:28:27 +0000</lastBuildDate> <language>en-US</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency>
<image>
	<url>https://s3.amazonaws.com/users.feedblitz.com/11ccaefebf470d493a858839c60c2ba7/AO-wordmark-color-smaller.png</url>
	<title>Atomic Spin</title>
	<link>http://spin.atomicobject.com</link>
</image>
<item>
<feedburner:origLink>http://spin.atomicobject.com/2013/05/18/time-based-estimates-are-for-suckers-size-based-is-the-way-to-go/</feedburner:origLink><title>Time-Based Estimates Are for Suckers! (Size-based Is the Way to Go)</title><link>http://feeds.feedblitz.com/~/41299301/0/atomicspin~TimeBased-Estimates-Are-for-Suckers-Sizebased-Is-the-Way-to-Go/</link> <comments>http://feeds.feedblitz.com/~/41299301/0/atomicspin~TimeBased-Estimates-Are-for-Suckers-Sizebased-Is-the-Way-to-Go/#comments</comments> <pubDate>Sat, 18 May 2013 15:00:11 +0000</pubDate> <dc:creator>David Crosby</dc:creator> <category><![CDATA[Estimating]]></category> <category><![CDATA[Project Management]]></category> <category><![CDATA[agile]]></category> <category><![CDATA[agile project management]]></category> <category><![CDATA[glsec]]></category> <category><![CDATA[size-based estimating]]></category> <guid
isPermaLink="false">http://spin.atomicobject.com/?p=96775</guid> <description><![CDATA[<p><p>I gave a talk entitled &#8220;Time-Based Estimates Are For Suckers! Size-based is The Way to Go&#8221; at this year&#8217;s <a
href="http://glsec.softwaregr.org/">GLSEC</a> on April 29.  It&#8217;s meant as a call to action for those who haven&#8217;t made the leap to size-based estimation, or who have been beaten back by some of the challenges you&#8217;ll encounter when trying, such as:</p><p><a
href="http://feeds.feedblitz.com/~/41299301/0/atomicspin~TimeBased-Estimates-Are-for-Suckers-Sizebased-Is-the-Way-to-Go/" class="more-link">Read more on Time-Based Estimates Are for Suckers! (Size-based Is the Way to Go) <span
class="meta-nav">&#187;</span></a></p></p><p>The post <a
href="http://feeds.feedblitz.com/~/41299301/0/atomicspin~TimeBased-Estimates-Are-for-Suckers-Sizebased-Is-the-Way-to-Go/">Time-Based Estimates Are for Suckers! (Size-based Is the Way to Go)</a> appeared first on <a
href="http://spin.atomicobject.com">Atomic Spin</a>.</p>]]>
&lt;div style=&quot;clear:both;padding-top:0.2em;&quot;&gt;&lt;a title=&quot;Add to Any&quot; href=&quot;http://feeds.feedblitz.com/_/26/41299301/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/addtoany20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to FaceBook&quot; href=&quot;http://feeds.feedblitz.com/_/2/41299301/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/fbshare20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Share on Google+&quot; href=&quot;http://feeds.feedblitz.com/_/30/41299301/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/googleplus20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to LinkedIn&quot; href=&quot;http://feeds.feedblitz.com/_/16/41299301/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/linkedin20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Tweet This&quot; href=&quot;http://feeds.feedblitz.com/_/24/41299301/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/twitter20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by email&quot; href=&quot;http://feeds.feedblitz.com/_/19/41299301/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/email20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by RSS&quot; href=&quot;http://feeds.feedblitz.com/_/20/41299301/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/rss20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;&lt;h3 style=&quot;clear:left;padding-top:10px&quot;&gt;Related Stories&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/04/12/agile-team-epic/&quot;&gt;Tear Down the Walls! (part duex): Reorganizing Teams Around Epics&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/03/11/software-team-management/&quot;&gt;5 Techniques to Get the Most Out of Your Software Team&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/01/31/defining-in-progress/&quot;&gt;Defining &amp;#8220;In Progress&amp;#8221;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;/div&gt;</description> <content:encoded><![CDATA[<div style="clear:left"><p>I gave a talk entitled &#8220;Time-Based Estimates Are For Suckers! Size-based is The Way to Go&#8221; at this year&#8217;s <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~glsec.softwaregr.org/">GLSEC</a> on April 29.  It&#8217;s meant as a call to action for those who haven&#8217;t made the leap to size-based estimation, or who have been beaten back by some of the challenges you&#8217;ll encounter when trying, such as:</p><ul><li>Breaking things down by value, not by task</li><li>Thinking in terms of &#8220;size&#8221; (not time)</li><li>Making estimates</li></ul><p>I did this because, even though we&#8217;re all a bunch of Agile know-it-alls by now, and estimation is a remedial topic from 10 years ago, there are still plenty of people who haven&#8217;t been introducted to size-based estimation. Besides, making the switch from time-based estimation to size-based isn&#8217;t as easy as some of the books and blogs out there make it sound.</p><p><span
id="more-96775"></span>(Nevertheless, I didn&#8217;t design the talk to actually teach the skills needed to fully implement size-based estimation and planning. For a better-articulated discussion on how complexity-based estimates actually work and on why and how to start using them, see Carl&#8217;s talk on <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~www.atomicobject.com/pages/Making+Better+Estimates">Making Better Estimates</a>.)</p><p>As a tail on the conversation, I prepared some common high-level concerns and roadblocks to discuss, but the audience in the room provided plenty of same-level questions. A good example was, &#8220;How does all this data-driven re-estimation help me when I&#8217;ve got a fixed timeline that cannot change?&#8221; Answer: &#8220;This is one of the best tools to know if you&#8217;re going to get done on time; your manager will thank you for sharing that information early.&#8221;</p><p>I also had a brief tangent where I had to admit that Atomic does, in fact, use time-based &#8220;Aggressive-but-possible/Highly-probable&#8221; estimates during the sales process, when sketching high-level time-and-money estimates, since it assists with bidding and budget setting. But these estimates are then decomposed further using size-based tools for tracking and management.</p><p>Some common questions I didn&#8217;t get to in the talk:</p><ul><li>When is a story &#8220;done&#8221;? (When the customer says so, or when you&#8217;re able to demonstrate the value has been added.)</li><li>Should estimate and track points for bugs? (Depends on what your customer is planning around; bugs aren&#8217;t scope, but they take time. Best to tackle them regularly and let them affect overall velocity.)</li><li>Will customers accept estimates given in points? (Maybe eventually, but don&#8217;t force anyone to understand or accept your point scale.  Instead, derive an estimated duration and be ready to explain how size and velocity create that information.)</li></ul><p>I actually hope to continue the discussion. Size-based estimation — far from being old-hat or a close topic — is still the kernel of any great software project management process, and it still takes care and effort to keep the furnace stoked with good input.</p><p>Here are the slides from the presentation:
<br
/> <script async class="speakerdeck-embed" data-id="a8ed94909960013093f04a89cb7a0315" data-ratio="0.725212464589235" src="http://spin.atomicobject.com//speakerdeck.com/assets/embed.js"></script>
<br
/> &nbsp;</p><p>The post <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~spin.atomicobject.com/2013/05/18/time-based-estimates-are-for-suckers-size-based-is-the-way-to-go/">Time-Based Estimates Are for Suckers! (Size-based Is the Way to Go)</a> appeared first on <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~spin.atomicobject.com">Atomic Spin</a>.</p><Img align="left" border="0" height="1" width="1" style="border:0;float:left;margin:0;padding:0" hspace="0" src="http://feeds.feedblitz.com/~/i/41299301/0/atomicspin">
</div>]]>
&lt;div style=&quot;clear:both;padding-top:0.2em;&quot;&gt;&lt;a title=&quot;Add to Any&quot; href=&quot;http://feeds.feedblitz.com/_/26/41299301/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/addtoany20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to FaceBook&quot; href=&quot;http://feeds.feedblitz.com/_/2/41299301/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/fbshare20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Share on Google+&quot; href=&quot;http://feeds.feedblitz.com/_/30/41299301/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/googleplus20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to LinkedIn&quot; href=&quot;http://feeds.feedblitz.com/_/16/41299301/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/linkedin20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Tweet This&quot; href=&quot;http://feeds.feedblitz.com/_/24/41299301/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/twitter20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by email&quot; href=&quot;http://feeds.feedblitz.com/_/19/41299301/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/email20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by RSS&quot; href=&quot;http://feeds.feedblitz.com/_/20/41299301/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/rss20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;&lt;h3 style=&quot;clear:left;padding-top:10px&quot;&gt;Related Stories&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/04/12/agile-team-epic/&quot;&gt;Tear Down the Walls! (part duex): Reorganizing Teams Around Epics&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/03/11/software-team-management/&quot;&gt;5 Techniques to Get the Most Out of Your Software Team&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/01/31/defining-in-progress/&quot;&gt;Defining &amp;#8220;In Progress&amp;#8221;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;/div&gt;</content:encoded> <wfw:commentRss>http://feeds.feedblitz.com/~/41299301/0/atomicspin~TimeBased-Estimates-Are-for-Suckers-Sizebased-Is-the-Way-to-Go/feed/</wfw:commentRss> <slash:comments>0</slash:comments></item>
<item>
<feedburner:origLink>http://spin.atomicobject.com/2013/05/17/tend-build-system/</feedburner:origLink><title>Not Tending to &#8220;The Build&#8221; – A Common Anti-Pattern</title><link>http://feeds.feedblitz.com/~/41259876/0/atomicspin~Not-Tending-to-The-Build-%e2%80%93-A-Common-AntiPattern/</link> <comments>http://feeds.feedblitz.com/~/41259876/0/atomicspin~Not-Tending-to-The-Build-%e2%80%93-A-Common-AntiPattern/#comments</comments> <pubDate>Fri, 17 May 2013 12:00:15 +0000</pubDate> <dc:creator>Greg Williams</dc:creator> <category><![CDATA[Embedded Software]]></category> <category><![CDATA[Project Planning]]></category> <category><![CDATA[Risk]]></category> <category><![CDATA[Testing]]></category> <category><![CDATA[c]]></category> <category><![CDATA[embedded]]></category> <guid
isPermaLink="false">http://spin.atomicobject.com/?p=95705</guid> <description><![CDATA[<p><p><img
src="http://d37rcl8t6g8sj5.cloudfront.net/wp-content/uploads/Weak-Link.jpg" alt="Weak-Link" width="590" height="393" class="alignnone size-full wp-image-96953" /></p><p><em><strong>The Build</strong></em> is an essential cog of any software project, but it is most often maintained by identified &#8220;experts.&#8221; This needs to stop. Agile depends on shared code ownership and understanding of the system — all parts of the system.</p><p><a
href="http://feeds.feedblitz.com/~/41259876/0/atomicspin~Not-Tending-to-The-Build-%e2%80%93-A-Common-AntiPattern/" class="more-link">Read more on Not Tending to &#8220;The Build&#8221; – A Common Anti-Pattern <span
class="meta-nav">&#187;</span></a></p></p><p>The post <a
href="http://feeds.feedblitz.com/~/41259876/0/atomicspin~Not-Tending-to-The-Build-%e2%80%93-A-Common-AntiPattern/">Not Tending to &#8220;The Build&#8221; – A Common Anti-Pattern</a> appeared first on <a
href="http://spin.atomicobject.com">Atomic Spin</a>.</p>]]>
&lt;div style=&quot;clear:both;padding-top:0.2em;&quot;&gt;&lt;a title=&quot;Add to Any&quot; href=&quot;http://feeds.feedblitz.com/_/26/41259876/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/addtoany20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to FaceBook&quot; href=&quot;http://feeds.feedblitz.com/_/2/41259876/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/fbshare20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Share on Google+&quot; href=&quot;http://feeds.feedblitz.com/_/30/41259876/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/googleplus20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to LinkedIn&quot; href=&quot;http://feeds.feedblitz.com/_/16/41259876/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/linkedin20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Tweet This&quot; href=&quot;http://feeds.feedblitz.com/_/24/41259876/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/twitter20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by email&quot; href=&quot;http://feeds.feedblitz.com/_/19/41259876/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/email20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by RSS&quot; href=&quot;http://feeds.feedblitz.com/_/20/41259876/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/rss20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;&lt;h3 style=&quot;clear:left;padding-top:10px&quot;&gt;Related Stories&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/04/16/googlemock-custom-return-values/&quot;&gt;Working with Custom Return Values in GoogleMock&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/09/budget-extensions-are-a-smell/&quot;&gt;Budget Extensions Are a &amp;#8220;Smell&amp;#8221;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/04/22/raspberry-pi-wireless-communication/&quot;&gt;Wireless Communication Between Raspberry Pi and Your Computer&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;/div&gt;</description> <content:encoded><![CDATA[<div style="clear:left"><p><img
src="http://d37rcl8t6g8sj5.cloudfront.net/wp-content/uploads/Weak-Link.jpg" alt="Weak-Link" width="590" height="393" class="alignnone size-full wp-image-96953" /></p><p><em><strong>The Build</strong></em> is an essential cog of any software project, but it is most often maintained by identified &#8220;experts.&#8221; This needs to stop. Agile depends on shared code ownership and understanding of the system — all parts of the system.</p><h2>Consequences of Ignoring the Build</h2><p>Most sufficiently-sized projects use a <a
title="Continuous Integration" href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~en.wikipedia.org/wiki/Continuous_integration" target="_blank">continuous integration system</a> and some amount of configuration and/or code to make them work. If only a subset of individuals understands and maintains this system, it will likely not be kept up to snuff to meet the growing demands of the project.</p><p><span
id="more-95705"></span>I have experienced the effects of an insufficiently-maintained build system on numerous projects in the past. The risk of the build system getting in the way is especially high in the case of static languages (like C/C++). These compiled language project frequently require a lot of non-standard setup and complex build and/or packaging requirements (including compilers, linkers, tests, simulation, and static analysis tools).</p><p>Continuous integration systems, which use <em><strong>The Build,</strong></em> are invaluable for regression testing. Although, if the understanding of how the system works is compartmentalized, the overall health of the project will most likely suffer.</p><h2>Where Things Go Wrong</h2><p>The most disheartening aspect of this problem is that <em><strong>The Build</strong></em> is indeed <em><strong>code</strong></em>, just like the <em><strong>real</strong></em> code that developers write every day. While the code that makes it into the product being developed usually has mandates on its quality, structure, maintainability, and testing, code in the build system is too often not held to this high standard.</p><p>As a result, the build system suffers, tech-debt grows and eventually comes back around to bite you. And thanks to Murphy&#8217;s Law, it usually rears its ugly head at the worst possible time.</p><p>Not maintaining the code and/or services that comprise the build environment is a recipe for disaster. <a
title="These intermittent test failures will not stand, man" href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~spin.atomicobject.com/2012/04/27/intermittent-test-failures" target="_blank">Instabilities in the build</a> and the need to continuously tend to specific areas of the build environment are red flags that technical debt exists and is not being dealt with properly.</p><p>Spreading the understanding and ownership of <em><strong>The Build</strong> </em>will have very beneficial effects on any project — most notably, sanity of the developers and all involved in delivering the product. Treat it with the same respect and the rest of your code base. You will not regret it!</p><p>Does your team tend to the build environment over the course of a project? Or does your team and/or management wait for the system to fall apart before addressing the resultant issues?
<br
/> &nbsp;</p><p>The post <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~spin.atomicobject.com/2013/05/17/tend-build-system/">Not Tending to &#8220;The Build&#8221; – A Common Anti-Pattern</a> appeared first on <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~spin.atomicobject.com">Atomic Spin</a>.</p><Img align="left" border="0" height="1" width="1" style="border:0;float:left;margin:0;padding:0" hspace="0" src="http://feeds.feedblitz.com/~/i/41259876/0/atomicspin">
</div>]]>
&lt;div style=&quot;clear:both;padding-top:0.2em;&quot;&gt;&lt;a title=&quot;Add to Any&quot; href=&quot;http://feeds.feedblitz.com/_/26/41259876/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/addtoany20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to FaceBook&quot; href=&quot;http://feeds.feedblitz.com/_/2/41259876/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/fbshare20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Share on Google+&quot; href=&quot;http://feeds.feedblitz.com/_/30/41259876/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/googleplus20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to LinkedIn&quot; href=&quot;http://feeds.feedblitz.com/_/16/41259876/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/linkedin20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Tweet This&quot; href=&quot;http://feeds.feedblitz.com/_/24/41259876/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/twitter20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by email&quot; href=&quot;http://feeds.feedblitz.com/_/19/41259876/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/email20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by RSS&quot; href=&quot;http://feeds.feedblitz.com/_/20/41259876/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/rss20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;&lt;h3 style=&quot;clear:left;padding-top:10px&quot;&gt;Related Stories&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/04/16/googlemock-custom-return-values/&quot;&gt;Working with Custom Return Values in GoogleMock&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/09/budget-extensions-are-a-smell/&quot;&gt;Budget Extensions Are a &amp;#8220;Smell&amp;#8221;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/04/22/raspberry-pi-wireless-communication/&quot;&gt;Wireless Communication Between Raspberry Pi and Your Computer&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;/div&gt;</content:encoded> <wfw:commentRss>http://feeds.feedblitz.com/~/41259876/0/atomicspin~Not-Tending-to-The-Build-%e2%80%93-A-Common-AntiPattern/feed/</wfw:commentRss> <slash:comments>0</slash:comments></item>
<item>
<feedburner:origLink>http://spin.atomicobject.com/2013/05/16/case-for-sitting/</feedburner:origLink><title>Is There a Case to Be Made for Sitting?</title><link>http://feeds.feedblitz.com/~/41215347/0/atomicspin~Is-There-a-Case-to-Be-Made-for-Sitting/</link> <comments>http://feeds.feedblitz.com/~/41215347/0/atomicspin~Is-There-a-Case-to-Be-Made-for-Sitting/#comments</comments> <pubDate>Thu, 16 May 2013 12:00:15 +0000</pubDate> <dc:creator>Mary O'Neill</dc:creator> <category><![CDATA[Workplace]]></category> <category><![CDATA[ergonomics]]></category> <category><![CDATA[stand up desk]]></category> <category><![CDATA[standing]]></category> <guid
isPermaLink="false">http://spin.atomicobject.com/?p=96675</guid> <description><![CDATA[<p><p><img
class="alignnone size-full wp-image-96842" alt="Slanted" src="http://d37rcl8t6g8sj5.cloudfront.net/wp-content/uploads/old-chair.jpg" width="590" height="393" /></p><p>In a previous post, I explored the question: <a
href="http://spin.atomicobject.com/2012/09/26/is-your-chair-your-enemy/">Is your chair your enemy?</a>, based in part on the many recent articles, research reports, and infographics claiming that the simple act of <a
href="http://visual.ly/sitting-killing-you-0">sitting is killing you</a>.</p><p><a
href="http://feeds.feedblitz.com/~/41215347/0/atomicspin~Is-There-a-Case-to-Be-Made-for-Sitting/" class="more-link">Read more on Is There a Case to Be Made for Sitting? <span
class="meta-nav">&#187;</span></a></p></p><p>The post <a
href="http://feeds.feedblitz.com/~/41215347/0/atomicspin~Is-There-a-Case-to-Be-Made-for-Sitting/">Is There a Case to Be Made for Sitting?</a> appeared first on <a
href="http://spin.atomicobject.com">Atomic Spin</a>.</p>]]>
&lt;div style=&quot;clear:both;padding-top:0.2em;&quot;&gt;&lt;a title=&quot;Add to Any&quot; href=&quot;http://feeds.feedblitz.com/_/26/41215347/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/addtoany20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to FaceBook&quot; href=&quot;http://feeds.feedblitz.com/_/2/41215347/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/fbshare20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Share on Google+&quot; href=&quot;http://feeds.feedblitz.com/_/30/41215347/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/googleplus20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to LinkedIn&quot; href=&quot;http://feeds.feedblitz.com/_/16/41215347/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/linkedin20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Tweet This&quot; href=&quot;http://feeds.feedblitz.com/_/24/41215347/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/twitter20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by email&quot; href=&quot;http://feeds.feedblitz.com/_/19/41215347/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/email20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by RSS&quot; href=&quot;http://feeds.feedblitz.com/_/20/41215347/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/rss20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;&lt;h3 style=&quot;clear:left;padding-top:10px&quot;&gt;Related Stories&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/04/29/internal-communication-atomic/&quot;&gt;Keep the Information Flowing: Internal Communication at Atomic Object&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/04/09/sustainability-at-atomic-object/&quot;&gt;Sustainability at Atomic Object&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/03/22/3d-printer-atomic-object/&quot;&gt;Atomic Object Gets a 3D Printer&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;/div&gt;</description> <content:encoded><![CDATA[<div style="clear:left"><p><img
class="alignnone size-full wp-image-96842" alt="Slanted" src="http://d37rcl8t6g8sj5.cloudfront.net/wp-content/uploads/old-chair.jpg" width="590" height="393" /></p><p>In a previous post, I explored the question: <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~spin.atomicobject.com/2012/09/26/is-your-chair-your-enemy/">Is your chair your enemy?</a>, based in part on the many recent articles, research reports, and infographics claiming that the simple act of <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~visual.ly/sitting-killing-you-0">sitting is killing you</a>.</p><p>But I recently read <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~www.fastcompany.com/user/david-zax">David Zax&#8217;s</a> FastCompany article, <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~www.fastcompany.com/3000635/defense-sitting">In Defense of Sitting</a>, a humorous counter argument (<em>“Sitting may kill you. But at least you’ll die doing something you love.”</em>) to the widely-published judgement that standing while at task is surely the key to eternal life.</p><blockquote><p>What the summer of 1975 did for sharks, what the fall of 2001 did for anthrax, the last few years have been doing for that seemingly innocuous object: the chair.</p></blockquote><p><span
id="more-96675"></span>Seeking inspiration of the “Great Standing Writers” like <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~en.wikipedia.org/wiki/Ernest_Hemingway">Ernest Hemingway</a> and <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~en.wikipedia.org/wiki/Philip_Roth">Philip Roth</a>, Zax decided to try working while standing, but things didn’t go well:</p><blockquote><p>The first thing I noticed about my standing desk was that it wasn’t particularly comfortable. It was also the second thing I noticed, and the third thing I noticed.</p></blockquote><p>Zax also talked to some furniture designers and learned that it is not necessarily sitting that&#8217;s bad for us, but sitting <strong><em>still</em></strong>. <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~www.hermanmiller.com/">Herman Miller</a> has researched the health benefits of dynamic sitting. One of their seating research papers, <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~www.hermanmiller.com/content/hermanmiller/english/research/solution-essays/sitting-can-be-good-for-the-circulatory-system.html">Sitting Can Be Good for the Circulatory System</a>, identifies the need for chairs that help users move:</p><blockquote><p>One approach to promoting movement in a work chair would be to design one with a dynamic seat and backrest. Doing so would require a surface that automatically conforms to a sitter’s micro-movements and distributes weight evenly. This would allow the seat to take on the greater burden of supporting more weight while providing stability. It would also reduce seated pressure and increase blood circulation to improve oxygen flow and decrease heart rate.</p></blockquote><p>While the jury is still out on whether or not sitting will actually kill us, we’ll continue to benefit from a variety of postures and overall movement as we work. And David Zax reminded me that a good sense of humor helps too.</p><p>The post <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~spin.atomicobject.com/2013/05/16/case-for-sitting/">Is There a Case to Be Made for Sitting?</a> appeared first on <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~spin.atomicobject.com">Atomic Spin</a>.</p><Img align="left" border="0" height="1" width="1" style="border:0;float:left;margin:0;padding:0" hspace="0" src="http://feeds.feedblitz.com/~/i/41215347/0/atomicspin">
</div>]]>
&lt;div style=&quot;clear:both;padding-top:0.2em;&quot;&gt;&lt;a title=&quot;Add to Any&quot; href=&quot;http://feeds.feedblitz.com/_/26/41215347/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/addtoany20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to FaceBook&quot; href=&quot;http://feeds.feedblitz.com/_/2/41215347/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/fbshare20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Share on Google+&quot; href=&quot;http://feeds.feedblitz.com/_/30/41215347/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/googleplus20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to LinkedIn&quot; href=&quot;http://feeds.feedblitz.com/_/16/41215347/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/linkedin20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Tweet This&quot; href=&quot;http://feeds.feedblitz.com/_/24/41215347/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/twitter20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by email&quot; href=&quot;http://feeds.feedblitz.com/_/19/41215347/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/email20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by RSS&quot; href=&quot;http://feeds.feedblitz.com/_/20/41215347/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/rss20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;&lt;h3 style=&quot;clear:left;padding-top:10px&quot;&gt;Related Stories&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/04/29/internal-communication-atomic/&quot;&gt;Keep the Information Flowing: Internal Communication at Atomic Object&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/04/09/sustainability-at-atomic-object/&quot;&gt;Sustainability at Atomic Object&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/03/22/3d-printer-atomic-object/&quot;&gt;Atomic Object Gets a 3D Printer&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;/div&gt;</content:encoded> <wfw:commentRss>http://feeds.feedblitz.com/~/41215347/0/atomicspin~Is-There-a-Case-to-Be-Made-for-Sitting/feed/</wfw:commentRss> <slash:comments>0</slash:comments></item>
<item>
<feedburner:origLink>http://spin.atomicobject.com/2013/05/15/html5-date-input-ember-js/</feedburner:origLink><title>HTML5 Date Inputs and Ember.js</title><link>http://feeds.feedblitz.com/~/41178929/0/atomicspin~HTML-Date-Inputs-and-Emberjs/</link> <comments>http://feeds.feedblitz.com/~/41178929/0/atomicspin~HTML-Date-Inputs-and-Emberjs/#comments</comments> <pubDate>Wed, 15 May 2013 12:00:14 +0000</pubDate> <dc:creator>Karlin Fox</dc:creator> <category><![CDATA[Tools]]></category> <category><![CDATA[Web]]></category> <category><![CDATA[emberjs]]></category> <guid
isPermaLink="false">http://spin.atomicobject.com/?p=96407</guid> <description><![CDATA[<p><p><img
src="http://d37rcl8t6g8sj5.cloudfront.net/wp-content/uploads/ember_date.png" alt="ember_date" width="500" class="aligncenter size-full wp-image-96408" /></p><p>My team recently needed a date picker in our web app. We wrote tests and implemented a simple text field first as scaffolding. Call it <a
href="http://c2.com/cgi/wiki?YouArentGonnaNeedIt"><span
class="caps">YAGNI</span></a> if you want — we really just weren&#8217;t excited about choosing from the long list of time-forgotten, unlovable JavaScript date picker widgets out there.</p><p><a
href="http://feeds.feedblitz.com/~/41178929/0/atomicspin~HTML-Date-Inputs-and-Emberjs/" class="more-link">Read more on HTML5 Date Inputs and Ember.js <span
class="meta-nav">&#187;</span></a></p></p><p>The post <a
href="http://feeds.feedblitz.com/~/41178929/0/atomicspin~HTML-Date-Inputs-and-Emberjs/">HTML5 Date Inputs and Ember.js</a> appeared first on <a
href="http://spin.atomicobject.com">Atomic Spin</a>.</p>]]>
&lt;div style=&quot;clear:both;padding-top:0.2em;&quot;&gt;&lt;a title=&quot;Add to Any&quot; href=&quot;http://feeds.feedblitz.com/_/26/41178929/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/addtoany20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to FaceBook&quot; href=&quot;http://feeds.feedblitz.com/_/2/41178929/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/fbshare20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Share on Google+&quot; href=&quot;http://feeds.feedblitz.com/_/30/41178929/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/googleplus20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to LinkedIn&quot; href=&quot;http://feeds.feedblitz.com/_/16/41178929/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/linkedin20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Tweet This&quot; href=&quot;http://feeds.feedblitz.com/_/24/41178929/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/twitter20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by email&quot; href=&quot;http://feeds.feedblitz.com/_/19/41178929/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/email20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by RSS&quot; href=&quot;http://feeds.feedblitz.com/_/20/41178929/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/rss20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;&lt;h3 style=&quot;clear:left;padding-top:10px&quot;&gt;Related Stories&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/12/dynamic-ember-js-binding-observers/&quot;&gt;Dynamic Binding in Ember.js Using Observers&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/13/javascript-front-end-grunt/&quot;&gt;Build a Rich JavaScript Front End with Grunt&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/08/pair-programming-teleport/&quot;&gt;Effortless Pair Programming with Teleport&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;/div&gt;</description> <content:encoded><![CDATA[<div style="clear:left"><p><img
src="http://d37rcl8t6g8sj5.cloudfront.net/wp-content/uploads/ember_date.png" alt="ember_date" width="500" class="aligncenter size-full wp-image-96408" /></p><p>My team recently needed a date picker in our web app. We wrote tests and implemented a simple text field first as scaffolding. Call it <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~c2.com/cgi/wiki?YouArentGonnaNeedIt"><span
class="caps">YAGNI</span></a> if you want — we really just weren&#8217;t excited about choosing from the long list of time-forgotten, unlovable JavaScript date picker widgets out there.</p><h2>Surprises from Chrome</h2><p>The next day while we were pairing, we opened up Chrome, hit our app, and noticed that our new &#8220;date&#8221; field had magically turned into a fully-functional date picker!</p><p>We were puzzled. We started looking at commit logs, wondering if another teammate had snuck in a little treat without us noticing. Then I tried the app in Firefox&#8230; and the date picker disappeared.</p><p><span
id="more-96407"></span>As it turns out, Chrome automatically adds a date picker to input elements with a type attribute of &#8220;date.&#8221; It&#8217;s been in there for a while, but we&#8217;d never noticed. It&#8217;s one of a longer list of new input types in HTML5 that Chrome has implemented, while Firefox has not.</p><h2>Why Ember?</h2><p>My team chose <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~emberjs.com">Ember.js</a> to help us build a web app on top of a <span
class="caps">REST</span>-based <span
class="caps">JSON</span>+HAL <span
class="caps">API</span>. Our next task then was to figure out how to integrate this gift horse into our app.</p><p>I like Ember.js for two reasons: I trust their team, and I like the decoupled, testable style of their architecture. It&#8217;s still a small enough framework that our team can solve most problems by looking through the source code or by running simple examples (or, sometimes, by asking <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~spin.atomicobject.com/2013/04/14/effortless-abstraction-ember/">fellow Atoms</a> who&#8217;ve been using Ember longer than we have).</p><p>As it happens, our app expects a typical (for us weirdos in the US anyway) MM/DD/YYYY date format. We are using <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~momentjs.com">moment.js</a> to convert a user&#8217;s entry into a preferred <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/iso8601">ISO8601</a> format for storage in CouchDB, so we started with a simple Ember view and a template helper to make our date picker and date display easy. The View was kickstarted with the <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~jsbin.com/epadin/1/edit">results</a> of <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~discuss.emberjs.com/t/example-building-a-date-input-field/674/6">this thread</a> on the Ember Discourse page. We used Modernizr to help detect browser support and adjust the expected input format accordingly, so if you&#8217;re in Firefox, you&#8217;re just going to get a text field. If you&#8217;re in Chrome, you can haz a date picker.</p><p>The resulting model property is a bonafide Moment object, which in our case converts cleanly when <span
class="caps">JSON</span>.stringify is called on the way to our <span
class="caps">API</span>.</p><p>Here&#8217;s the resulting view class (in CoffeeScript of course.) Good luck with your Ember app!</p><p><script src="https://gist.github.com/5449814.js"></script><noscript><pre><code class="language-coffeescript coffeescript"># Usage:
# {{App.DateField dateBinding=&quot;date&quot;}} # Where &quot;date&quot; points to a Moment.js object
App.DateField = Ember.TextField.extend
  type: 'date'
  hasFocus: false
  placeholderBinding: 'dateFormat'
  dateFormat:(-&gt;
    if Modernizr.inputtypes.date then 'YYYY-MM-DD' else 'MM/DD/YYYY'
  ).property()
  init: -&gt;
    @_super()
    @updateValue()
  updateDate: (-&gt;
    ms = moment.utc(@get('value'), @get('dateFormat'))
    @set('date', ms) if ms and ms.isValid()
  ).observes('value')
  updateValue: (-&gt;
    return if @get('hasFocus')
    date = @get('date')
    if date
      @set('value', if moment.isMoment(date) then date.utc().format(@get('dateFormat')) else moment.utc(date))
  ).observes('date')
  focusIn: -&gt;
    @set('hasFocus', true)
  focusOut: -&gt;
    @set('hasFocus', false)
    @updateValue()
</code></pre></noscript>
<br
/> &nbsp;</p><p>The post <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~spin.atomicobject.com/2013/05/15/html5-date-input-ember-js/">HTML5 Date Inputs and Ember.js</a> appeared first on <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~spin.atomicobject.com">Atomic Spin</a>.</p><Img align="left" border="0" height="1" width="1" style="border:0;float:left;margin:0;padding:0" hspace="0" src="http://feeds.feedblitz.com/~/i/41178929/0/atomicspin">
</div>]]>
&lt;div style=&quot;clear:both;padding-top:0.2em;&quot;&gt;&lt;a title=&quot;Add to Any&quot; href=&quot;http://feeds.feedblitz.com/_/26/41178929/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/addtoany20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to FaceBook&quot; href=&quot;http://feeds.feedblitz.com/_/2/41178929/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/fbshare20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Share on Google+&quot; href=&quot;http://feeds.feedblitz.com/_/30/41178929/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/googleplus20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to LinkedIn&quot; href=&quot;http://feeds.feedblitz.com/_/16/41178929/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/linkedin20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Tweet This&quot; href=&quot;http://feeds.feedblitz.com/_/24/41178929/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/twitter20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by email&quot; href=&quot;http://feeds.feedblitz.com/_/19/41178929/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/email20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by RSS&quot; href=&quot;http://feeds.feedblitz.com/_/20/41178929/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/rss20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;&lt;h3 style=&quot;clear:left;padding-top:10px&quot;&gt;Related Stories&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/12/dynamic-ember-js-binding-observers/&quot;&gt;Dynamic Binding in Ember.js Using Observers&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/13/javascript-front-end-grunt/&quot;&gt;Build a Rich JavaScript Front End with Grunt&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/08/pair-programming-teleport/&quot;&gt;Effortless Pair Programming with Teleport&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;/div&gt;</content:encoded> <wfw:commentRss>http://feeds.feedblitz.com/~/41178929/0/atomicspin~HTML-Date-Inputs-and-Emberjs/feed/</wfw:commentRss> <slash:comments>0</slash:comments></item>
<item>
<feedburner:origLink>http://spin.atomicobject.com/2013/05/14/managing-email-good-habits/</feedburner:origLink><title>Kick Your Bad Email Habits</title><link>http://feeds.feedblitz.com/~/41140677/0/atomicspin~Kick-Your-Bad-Email-Habits/</link> <comments>http://feeds.feedblitz.com/~/41140677/0/atomicspin~Kick-Your-Bad-Email-Habits/#comments</comments> <pubDate>Tue, 14 May 2013 12:00:31 +0000</pubDate> <dc:creator>Shawn Crowley</dc:creator> <category><![CDATA[Miscellaneous]]></category> <category><![CDATA[productivity]]></category> <guid
isPermaLink="false">http://spin.atomicobject.com/?p=96601</guid> <description><![CDATA[<p><p>I&#8217;ve been an email addict for a long time, but I&#8217;ve been working to replace my old, bad habits with new ones. I&#8217;ve discovered that managing email <i>well</i> can dramatically improve my productivity.</p><p><a
href="http://feeds.feedblitz.com/~/41140677/0/atomicspin~Kick-Your-Bad-Email-Habits/" class="more-link">Read more on Kick Your Bad Email Habits <span
class="meta-nav">&#187;</span></a></p></p><p>The post <a
href="http://feeds.feedblitz.com/~/41140677/0/atomicspin~Kick-Your-Bad-Email-Habits/">Kick Your Bad Email Habits</a> appeared first on <a
href="http://spin.atomicobject.com">Atomic Spin</a>.</p>]]>
&lt;div style=&quot;clear:both;padding-top:0.2em;&quot;&gt;&lt;a title=&quot;Add to Any&quot; href=&quot;http://feeds.feedblitz.com/_/26/41140677/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/addtoany20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to FaceBook&quot; href=&quot;http://feeds.feedblitz.com/_/2/41140677/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/fbshare20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Share on Google+&quot; href=&quot;http://feeds.feedblitz.com/_/30/41140677/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/googleplus20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to LinkedIn&quot; href=&quot;http://feeds.feedblitz.com/_/16/41140677/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/linkedin20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Tweet This&quot; href=&quot;http://feeds.feedblitz.com/_/24/41140677/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/twitter20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by email&quot; href=&quot;http://feeds.feedblitz.com/_/19/41140677/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/email20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by RSS&quot; href=&quot;http://feeds.feedblitz.com/_/20/41140677/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/rss20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;&lt;h3 style=&quot;clear:left;padding-top:10px&quot;&gt;Related Stories&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/11/makerbot-replicator-2-issues/&quot;&gt;Replicator 2 Teething Issues&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/07/career-advice-for-success/&quot;&gt;Getting the Best Career Advice at Any Age/Stage&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/03/technology-mundane-amazing/&quot;&gt;Technology Has Become Mundane, and that&amp;#8217;s Amazing&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;/div&gt;</description> <content:encoded><![CDATA[<div style="clear:left"><p>I&#8217;ve been an email addict for a long time, but I&#8217;ve been working to replace my old, bad habits with new ones. I&#8217;ve discovered that managing email <i>well</i> can dramatically improve my productivity.</p><h2>Old Habits (Letting my email manage me)</h2><p>I get about 2,000 work-related emails every month (I&#8217;ve nearly given up on my personal email account), and my historical approach to keeping an empty inbox was to be <i>always</i> checking and responding to my email.</p><p>I&#8217;d frequently check email:</p><ul><li>first thing upon waking up</li><li>right before commuting to work</li><li>first thing upon getting to work</li><li>in between meetings or scheduled sessions</li><li>during any free moments or waiting periods</li><li>right before I left work</li><li>while eating lunch or dinner with others</li><li>as a car passenger during family errands</li><li>right before I went to sleep</li><li>in the middle of the night if I woke up</li></ul><p><span
id="more-96601"></span><div
id="attachment_96874" class="wp-caption alignright" style="width: 170px"><a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~d37rcl8t6g8sj5.cloudfront.net/wp-content/uploads/MailboxInboxZero.png"><img
src="http://d37rcl8t6g8sj5.cloudfront.net/wp-content/uploads/MailboxInboxZero.png" alt="Managing Email with Mailbox Inbox Zero" width="160" height="240" class="size-full wp-image-96874" /></a><p
class="wp-caption-text">My empty Mailbox inbox. I wish life could always be this good.</p></div>At work I&#8217;d keep my Gmail notifier going so I could see what was coming in and respond as soon as possible. When a mail came in, I&#8217;d frequently interrupt what I was doing to jump on the email. I&#8217;d usually keep my email browser tab open during the day. Occasionally I&#8217;d find myself coming up for air from email and realize that I had gotten pulled into email because I had looked at my web browser for a different, unrelated task.</p><p>It&#8217;s a little embarrassing to admit, but there were times I&#8217;d check email on my phone and feel a sense of loneliness or anxiety if no new messages had come in. I was so addicted to email that I didn&#8217;t realize its corrosive effect on my productivity and energy levels.</p><h2>A Forced Experiment</h2><p>About a month ago, I took a trip to <a
title="Mammoth Cave National Park" href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~www.nps.gov/maca/index.htm" target="_blank">Mammoth Cave National Park</a> and found that I had no cell reception. The <a
title="Mammoth Cave Hotel" href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~mammothcavehotel.com/" target="_blank">Mammoth Cave Hotel</a> had limited WiFi access only available in the lobby.</p><p>The limited internet connection forced me to batch my email interaction to 1-2 concentrated sessions per day. I was struck by the mental impact of batching email up instead checking it throughout the day. I was more present with others and focused during the day because I was not preoccupied with potential distractions in my inbox. When I did check email, I felt I had more energy to power through the entire batch more effectively and efficiently.</p><p>During the same trip, I read Harvard Business Review&#8217;s <a
title="Getting the Right Work Done" href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~www.amazon.com/Guide-Getting-Harvard-Business-Review/dp/142218711X" target="_blank">Guide to Getting the Right Work Done</a> and discovered two great sections on email:</p><ol><li>Simplify Your E-mail by Gina Trapini</li><li>Eight E-mail Overload Experiments by Alexandra Samuel</li></ol><h2>New Habits (Managing email on my terms)</h2><p>Back at work, I&#8217;m now trying to establish the following email habits:</p><ul><li>Ruthlessly set filters for any newsletters or lists I don&#8217;t actively read (I have 67 new delete filters after ~1 month).</li><li>Process email in batches (I usually check before lunch, before going home, and in the evening).</li><li>When processing batches, quickly follow up or put the response task on my todo list in priority with my other tasks.</li><li>Steer clear of lengthy conversations with &#8220;reply all&#8221; chains. If something is important enough for a group discussion, we should schedule an in-person group discussion.</li><li>Stop replying to every email I get.</li><li>Be more conscious of the email I send and reduce the amount of email I generate.</li><li>Communicate more by phone. It&#8217;s amazing how much more you can convey quickly on the phone, even if it&#8217;s through a voicemail.</li><li>Do the most important tasks of my day in the morning and don&#8217;t check email before my allocated priority time block is done. I&#8217;ve realized that if someone needs me urgently, they can call or text me.</li><li>I don&#8217;t keep my email open in a browser tab, and I&#8217;ve turned off my email notifier.</li></ul><p>My new email habits have me feeling happier and more productive. I seem to be getting more work done at work — and in less time. I&#8217;m spending less time at night or on the weekends getting my priority work done.</p><p>Are you addicted to email? Do you believe email has a negative impact on your productivity? Please share your stories or solutions.
<br
/> &nbsp;</p><p>The post <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~spin.atomicobject.com/2013/05/14/managing-email-good-habits/">Kick Your Bad Email Habits</a> appeared first on <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~spin.atomicobject.com">Atomic Spin</a>.</p><Img align="left" border="0" height="1" width="1" style="border:0;float:left;margin:0;padding:0" hspace="0" src="http://feeds.feedblitz.com/~/i/41140677/0/atomicspin">
</div>]]>
&lt;div style=&quot;clear:both;padding-top:0.2em;&quot;&gt;&lt;a title=&quot;Add to Any&quot; href=&quot;http://feeds.feedblitz.com/_/26/41140677/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/addtoany20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to FaceBook&quot; href=&quot;http://feeds.feedblitz.com/_/2/41140677/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/fbshare20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Share on Google+&quot; href=&quot;http://feeds.feedblitz.com/_/30/41140677/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/googleplus20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to LinkedIn&quot; href=&quot;http://feeds.feedblitz.com/_/16/41140677/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/linkedin20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Tweet This&quot; href=&quot;http://feeds.feedblitz.com/_/24/41140677/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/twitter20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by email&quot; href=&quot;http://feeds.feedblitz.com/_/19/41140677/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/email20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by RSS&quot; href=&quot;http://feeds.feedblitz.com/_/20/41140677/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/rss20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;&lt;h3 style=&quot;clear:left;padding-top:10px&quot;&gt;Related Stories&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/11/makerbot-replicator-2-issues/&quot;&gt;Replicator 2 Teething Issues&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/07/career-advice-for-success/&quot;&gt;Getting the Best Career Advice at Any Age/Stage&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/03/technology-mundane-amazing/&quot;&gt;Technology Has Become Mundane, and that&amp;#8217;s Amazing&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;/div&gt;</content:encoded> <wfw:commentRss>http://feeds.feedblitz.com/~/41140677/0/atomicspin~Kick-Your-Bad-Email-Habits/feed/</wfw:commentRss> <slash:comments>0</slash:comments></item>
<item>
<feedburner:origLink>http://spin.atomicobject.com/2013/05/13/javascript-front-end-grunt/</feedburner:origLink><title>Build a Rich JavaScript Front End with Grunt</title><link>http://feeds.feedblitz.com/~/41103689/0/atomicspin~Build-a-Rich-JavaScript-Front-End-with-Grunt/</link> <comments>http://feeds.feedblitz.com/~/41103689/0/atomicspin~Build-a-Rich-JavaScript-Front-End-with-Grunt/#comments</comments> <pubDate>Mon, 13 May 2013 12:00:21 +0000</pubDate> <dc:creator>Al Scott</dc:creator> <category><![CDATA[Tools]]></category> <category><![CDATA[build system]]></category> <category><![CDATA[coffeescript]]></category> <category><![CDATA[frontend]]></category> <category><![CDATA[grunt]]></category> <category><![CDATA[javascript]]></category> <guid
isPermaLink="false">http://spin.atomicobject.com/?p=96549</guid> <description><![CDATA[<p><p>I recently started doing a lot more standalone JavaScript front end development, often using CoffeeScript, less, jade, or other modern web stack components. Compiling assets like these is pretty much a solved problem when they are being delivered from a server side web stack like Rails, but I found myself in need of a JavaScript-based solution for statically compiling, serving, and testing my code.</p><p><a
href="http://feeds.feedblitz.com/~/41103689/0/atomicspin~Build-a-Rich-JavaScript-Front-End-with-Grunt/" class="more-link">Read more on Build a Rich JavaScript Front End with Grunt <span
class="meta-nav">&#187;</span></a></p></p><p>The post <a
href="http://feeds.feedblitz.com/~/41103689/0/atomicspin~Build-a-Rich-JavaScript-Front-End-with-Grunt/">Build a Rich JavaScript Front End with Grunt</a> appeared first on <a
href="http://spin.atomicobject.com">Atomic Spin</a>.</p>]]>
&lt;div style=&quot;clear:both;padding-top:0.2em;&quot;&gt;&lt;a title=&quot;Add to Any&quot; href=&quot;http://feeds.feedblitz.com/_/26/41103689/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/addtoany20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to FaceBook&quot; href=&quot;http://feeds.feedblitz.com/_/2/41103689/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/fbshare20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Share on Google+&quot; href=&quot;http://feeds.feedblitz.com/_/30/41103689/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/googleplus20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to LinkedIn&quot; href=&quot;http://feeds.feedblitz.com/_/16/41103689/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/linkedin20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Tweet This&quot; href=&quot;http://feeds.feedblitz.com/_/24/41103689/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/twitter20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by email&quot; href=&quot;http://feeds.feedblitz.com/_/19/41103689/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/email20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by RSS&quot; href=&quot;http://feeds.feedblitz.com/_/20/41103689/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/rss20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;&lt;h3 style=&quot;clear:left;padding-top:10px&quot;&gt;Related Stories&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/12/dynamic-ember-js-binding-observers/&quot;&gt;Dynamic Binding in Ember.js Using Observers&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/08/pair-programming-teleport/&quot;&gt;Effortless Pair Programming with Teleport&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/05/ruby-chipmunk-gem-6130/&quot;&gt;Chipmunk Gem, version 6.1.3.0.rc1&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;/div&gt;</description> <content:encoded><![CDATA[<div style="clear:left"><p>I recently started doing a lot more standalone JavaScript front end development, often using CoffeeScript, less, jade, or other modern web stack components. Compiling assets like these is pretty much a solved problem when they are being delivered from a server side web stack like Rails, but I found myself in need of a JavaScript-based solution for statically compiling, serving, and testing my code.</p><p>I first looked into <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~https://github.com/ricardobeat/cake-flour">simple solutions involving node Cakefiles</a> and static site generators like <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~https://github.com/jnordberg/wintersmith">wintersmith</a>, but I found these solutions lacked the power and flexibility I needed. At this point, through an obscure comment in a Google Talk thread about wintersmith, I heard my first reference to <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~gruntjs.com/">Grunt</a>. <span
id="more-96549"></span></p><h2>Grunt</h2><p><a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~gruntjs.com/"><img
src="http://d37rcl8t6g8sj5.cloudfront.net/wp-content/uploads/gruntjs.jpg" alt="gruntjs" width="250" height="304" class="alignright size-full wp-image-96828" /></a>The front page of Grunt immediately looked promising, offering support for CoffeeScript, handlebars, jade, JSHint, and less — a significant portion of the tech our team was using. The <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~gruntjs.com/plugins">plugins page</a> revealed a list several hundred items long. Since every technology needed for my project at the time had at least one plugin on the list, I decided to dive into Grunt.</p><p>Fortunately for me, Grunt tasks are very consistent and easy to configure, and Grunt itself has excellent documentation. Configuring Grunt in fact only requires two files: a <code>package.json</code> file specifying which Grunt plugins you are using, and a <code>Gruntfile.js</code> or <code>Gruntfile.coffee</code> file to configure each task.</p><h2>A Simple Example</h2><p>Let&#8217;s look at a simple grunt configuration to compile CoffeeScript files into JavaScript. We can use the <code>grunt-contrib-coffee</code> plugin to do this (the contrib in the name indicates that that particular plugin is maintained by the Grunt team.). First off, we need to put the appropriate dependencies into our package.json file.</p><h3>package.json</h3><div
class="wp_syntax"><table><tr><td
class="code"><pre class="javascript" style="font-family:monospace;">&nbsp;
<span style="color: #009900;">&#123;</span>
  <span style="color: #3366CC;">&quot;name&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;my-project-name&quot;</span><span style="color: #339933;">,</span>
  <span style="color: #3366CC;">&quot;version&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;0.1.0&quot;</span><span style="color: #339933;">,</span>
  <span style="color: #3366CC;">&quot;dependencies&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">&quot;grunt&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;latest&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;grunt-contrib-coffee&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;latest&quot;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div><p>Here we declare the only two dependencies we need: the latest versions of Grunt, and the contrib-coffee plugin.</p><h3>Gruntfile.coffee</h3><p>Now we can configure the coffee task in our Gruntfile.coffee. I prefer to use CoffeeScript for my Gruntfile because it is supported by Grunt out of the box and it makes the configuration much more concise:</p><div
class="wp_syntax"><table><tr><td
class="code"><pre class="coffeescript" style="font-family:monospace;">&nbsp;
module.<span style="color: black;">exports</span> = <span style="color: black;">&#40;</span>grunt<span style="color: black;">&#41;</span> <span style="color: #66cc66;">-&gt;</span>
  grunt.<span style="color: black;">initConfig</span>
    coffee<span style="color: #66cc66;">:</span>
      all<span style="color: #66cc66;">:</span>
        options<span style="color: #66cc66;">:</span>
          bare<span style="color: #66cc66;">:</span> <span style="color: #0000cd;">true</span>
        files<span style="color: #66cc66;">:</span> <span style="color: black;">&#91;</span>
          src<span style="color: #66cc66;">:</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;./app/src/**/*.coffee&quot;</span><span style="color: black;">&#93;</span>
          dest<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;./public/js/app.js&quot;</span>
        <span style="color: black;">&#93;</span>
&nbsp;
    grunt.<span style="color: black;">loadNpmTasks</span> <span style="color: #483d8b;">&quot;grunt-contrib-coffee&quot;</span></pre></td></tr></table></div><p>There&#8217;s a lot of information in the above configuration, so lets take an in-depth look at it. The first line simply defines an entry point for the Grunt object to be inserted into our configuration via nodejs&#8217;s module system. The second line calls Grunt&#8217;s initconfig method, which takes a Grunt configuration object as an argument.</p><p>The next section is our CoffeeScript task configuration. We start by defining a subtask <code>all</code>. While we don&#8217;t strictly have to do this because we only have a single subtask right now, it will make it easier to add other subtasks later. Within this configuration, we have two sections, <code>options</code> and <code>files</code>. As you would probably expect, <code>options</code> is where you set predefined configuration options for the task, and <code>files</code> is where you define the files that the task will operate on.</p><p>In our config, we are setting the <code>bare</code> option to true, which tells the CoffeeScript compiler to not wrap its output in a function.</p><p>The <code>files</code> section specifies an array with one item, an object with a <code>src</code> and <code>dest</code> parameter. As you can see in our <code>src</code> parameter, Grunt supports file glob syntax out of the box, allowing you to dynamically define which files you want to target. Since our dest is only one file, the coffee task also implicitly knows that it needs to concatenate all of the source files it finds into a single output file.</p><p>The last line simple loads the contrib coffee task from our our installed node_modules.</p><p>That&#8217;s all that is needed to configure a simple, automated build process for your CoffeeScript Source. Running <code>grunt coffee:all</code> from the command line will execute our defined task.</p><h2>A More Comprehensive Example</h2><p>Unfortunately, doing simple CoffeeScript compilation is rarely the only thing you need to do to build a complex client side project. So let&#8217;s look at a more complete configuration for an AngularJS project I&#8217;m working on in my spare time. First, the Gruntfile.</p><h3>Gruntfile.coffee</h3><div
class="wp_syntax"><table><tr><td
class="code"><pre class="coffeescript" style="font-family:monospace;">&nbsp;
module.<span style="color: black;">exports</span> = <span style="color: black;">&#40;</span>grunt<span style="color: black;">&#41;</span> <span style="color: #66cc66;">-&gt;</span>
  grunt.<span style="color: black;">initConfig</span>
    appDir<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;./app&quot;</span>
    srcDir<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= appDir %&gt;/src&quot;</span>
    contentDir<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= appDir %&gt;/content&quot;</span>
    templateDir<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= appDir %&gt;/templates&quot;</span>
    vendorDir<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= appDir %&gt;/vendor&quot;</span>
    cssDir<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= appDir %&gt;/stylesheets&quot;</span>
    testDir<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;./test&quot;</span>
&nbsp;
    buildDir<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;./tmp/build&quot;</span>
    outputDir<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;./public&quot;</span></pre></td></tr></table></div><p>Here we start our Grunt config the same way we did before. Immediately after that, we create some aliases for various directories we will be using. These aliases, as you can see, can be referenced in the Grunt configuration using underscore style template placeholders: <code>&lt;%= %&gt;</code>.</p><div
class="wp_syntax"><table><tr><td
class="code"><pre class="coffeescript" style="font-family:monospace;">&nbsp;
    <span style="color: #808080; font-style: italic;"># Javascript compilation tasks</span>
    <span style="color: #808080; font-style: italic;"># Essentially we want everything in the vendor,</span>
    <span style="color: #808080; font-style: italic;"># templates, and src directories to end up in</span>
    <span style="color: #808080; font-style: italic;"># one big JS file in that order.</span>
&nbsp;
    coffee<span style="color: #66cc66;">:</span>
      options<span style="color: #66cc66;">:</span>
        bare<span style="color: #66cc66;">:</span> <span style="color: #0000cd;">true</span>
&nbsp;
      all<span style="color: #66cc66;">:</span>
        files<span style="color: #66cc66;">:</span> <span style="color: black;">&#91;</span>
          expand<span style="color: #66cc66;">:</span> <span style="color: #0000cd;">true</span><span style="color: #66cc66;">,</span>
          src<span style="color: #66cc66;">:</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;&lt;%= srcDir %&gt;/**/*.coffee&quot;</span><span style="color: black;">&#93;</span>
          dest<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= buildDir %&gt;&quot;</span>
          ext<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;.js&quot;</span>
        <span style="color: black;">&#93;</span>
&nbsp;
      changed<span style="color: #66cc66;">:</span>
        files<span style="color: #66cc66;">:</span> <span style="color: black;">&#91;</span>
          expand<span style="color: #66cc66;">:</span> <span style="color: #0000cd;">true</span>
          src<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= grunt.regarde.changed %&gt;&quot;</span>
          dest<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= buildDir %&gt;&quot;</span>
          ext<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;.js&quot;</span>
        <span style="color: black;">&#93;</span>
&nbsp;
    jade<span style="color: #66cc66;">:</span>
      options<span style="color: #66cc66;">:</span>
        client<span style="color: #66cc66;">:</span> <span style="color: #0000cd;">true</span>
        compileDebug<span style="color: #66cc66;">:</span> <span style="color: #0000cd;">false</span>
        namespace<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;APPLICATION_TEMPLATES&quot;</span>
        processName<span style="color: #66cc66;">:</span> <span style="color: black;">&#40;</span>path<span style="color: black;">&#41;</span> <span style="color: #66cc66;">-&gt;</span>
          path
            .<span style="color: black;">replace</span><span style="color: black;">&#40;</span><span style="color: #66cc66;">/^</span>.<span style="color: #66cc66;">*</span>\btemplates\<span style="color: #66cc66;">//,</span> <span style="color: #483d8b;">&quot;&quot;</span><span style="color: black;">&#41;</span>
            .<span style="color: black;">replace</span><span style="color: black;">&#40;</span><span style="color: #66cc66;">/</span>\..<span style="color: #66cc66;">*</span>$<span style="color: #66cc66;">/,</span> <span style="color: #483d8b;">&quot;&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
      all<span style="color: #66cc66;">:</span>
        files<span style="color: #66cc66;">:</span> <span style="color: black;">&#91;</span>
          expand<span style="color: #66cc66;">:</span> <span style="color: #0000cd;">true</span>
          src<span style="color: #66cc66;">:</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;&lt;%= templateDir %&gt;/**/*.jade&quot;</span><span style="color: black;">&#93;</span>
          dest<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= buildDir %&gt;&quot;</span>
          ext<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;.js&quot;</span>
          <span style="color: black;">&#93;</span>
&nbsp;
      changed<span style="color: #66cc66;">:</span>
        files<span style="color: #66cc66;">:</span> <span style="color: black;">&#91;</span>
          expand<span style="color: #66cc66;">:</span> <span style="color: #0000cd;">true</span>
          src<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= grunt.regarde.changed %&gt;&quot;</span>
          dest<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= buildDir %&gt;&quot;</span>
          ext<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;.js&quot;</span>
        <span style="color: black;">&#93;</span>
&nbsp;
    concat<span style="color: #66cc66;">:</span>
      js<span style="color: #66cc66;">:</span>
        src<span style="color: #66cc66;">:</span> <span style="color: black;">&#91;</span> <span style="color: #808080; font-style: italic;"># Order matters, at some point we should use requireJS or something to fix that</span>
          <span style="color: #483d8b;">&quot;&lt;%= vendorDir %&gt;/**/*.js&quot;</span><span style="color: #66cc66;">,</span>
          <span style="color: #483d8b;">&quot;&lt;%= buildDir %&gt;/&lt;%= templateDir %&gt;/**/*.js&quot;</span><span style="color: #66cc66;">,</span>
          <span style="color: #483d8b;">&quot;&lt;%= buildDir %&gt;/&lt;%= srcDir %&gt;/*.js&quot;</span><span style="color: #66cc66;">,</span>
          <span style="color: #483d8b;">&quot;&lt;%= buildDir %&gt;/&lt;%= srcDir %&gt;/modules/**/*.js&quot;</span><span style="color: #66cc66;">,</span>
          <span style="color: #483d8b;">&quot;&lt;%= buildDir %&gt;/&lt;%= srcDir %&gt;/directives/**/*.js&quot;</span><span style="color: #66cc66;">,</span>
          <span style="color: #483d8b;">&quot;&lt;%= buildDir %&gt;/&lt;%= srcDir %&gt;/services/**/*.js&quot;</span><span style="color: #66cc66;">,</span>
          <span style="color: #483d8b;">&quot;&lt;%= buildDir %&gt;/&lt;%= srcDir %&gt;/filters/**/*.js&quot;</span><span style="color: #66cc66;">,</span>
          <span style="color: #483d8b;">&quot;&lt;%= buildDir %&gt;/&lt;%= srcDir %&gt;/controllers/**/*.js&quot;</span><span style="color: #66cc66;">,</span>
        <span style="color: black;">&#93;</span>
        dest<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= outputDir %&gt;/js/app.js&quot;</span></pre></td></tr></table></div><p>Now we&#8217;ve defined our javascript build tasks. These compile our CoffeeScript and jade sources into javascript files in a temporary build directory. Then our <code>concat</code> task concatenates our 3rd party vendor javascript, as well as our newly created javascript sources, into one large javascript file. Take particular note of the <code>changed</code> configuration blocks in the CoffeeScript and jade tasks; they will be explained shortly.</p><div
class="wp_syntax"><table><tr><td
class="code"><pre class="coffeescript" style="font-family:monospace;">&nbsp;
    <span style="color: #808080; font-style: italic;"># LESS compilation</span>
    less<span style="color: #66cc66;">:</span>
      options<span style="color: #66cc66;">:</span>
        paths<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= cssDir %&gt;&quot;</span>
&nbsp;
      all<span style="color: #66cc66;">:</span>
        files<span style="color: #66cc66;">:</span> <span style="color: black;">&#91;</span>
          src<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= cssDir %&gt;/app.less&quot;</span>
          dest<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= outputDir %&gt;/css/app.css&quot;</span>
        <span style="color: black;">&#93;</span>
&nbsp;
&nbsp;
    <span style="color: #808080; font-style: italic;"># Copy static files</span>
    copy<span style="color: #66cc66;">:</span>
      html<span style="color: #66cc66;">:</span>
        files<span style="color: #66cc66;">:</span> <span style="color: black;">&#91;</span>
          expand<span style="color: #66cc66;">:</span> <span style="color: #0000cd;">true</span>
          cwd<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= contentDir %&gt;/html&quot;</span>
          src<span style="color: #66cc66;">:</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;**/*.html&quot;</span><span style="color: black;">&#93;</span>
          dest<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= outputDir %&gt;&quot;</span>
        <span style="color: black;">&#93;</span>
&nbsp;
      images<span style="color: #66cc66;">:</span>
        files<span style="color: #66cc66;">:</span> <span style="color: black;">&#91;</span>
          expand<span style="color: #66cc66;">:</span> <span style="color: #0000cd;">true</span>
          cwd<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= contentDir %&gt;/images&quot;</span>
          src<span style="color: #66cc66;">:</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;**/*&quot;</span><span style="color: black;">&#93;</span>
          dest<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= outputDir %&gt;/images&quot;</span>
        <span style="color: black;">&#93;</span></pre></td></tr></table></div><p>Here we define some tasks to compile our less stylesheets and copy our static assets like images into our output directory.</p><div
class="wp_syntax"><table><tr><td
class="code"><pre class="coffeescript" style="font-family:monospace;">&nbsp;
    <span style="color: #808080; font-style: italic;"># Set up file monitors to rebuild project on changes</span>
    regarde<span style="color: #66cc66;">:</span>
      coffee<span style="color: #66cc66;">:</span>
        files<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= srcDir %&gt;/**/*.coffee&quot;</span>
        tasks<span style="color: #66cc66;">:</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;coffee:changed&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;concat:js&quot;</span><span style="color: black;">&#93;</span>
&nbsp;
      templates<span style="color: #66cc66;">:</span>
        files<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= srcDir %&gt;/**/*.jade&quot;</span>
        tasks<span style="color: #66cc66;">:</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;jade:changed&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;concat:js&quot;</span><span style="color: black;">&#93;</span>
&nbsp;
      vendor<span style="color: #66cc66;">:</span>
        files<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= vendorDir %&gt;/**/*.js&quot;</span>
        tasks<span style="color: #66cc66;">:</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;concat:js&quot;</span><span style="color: black;">&#93;</span>
&nbsp;
      less<span style="color: #66cc66;">:</span>
        files<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= cssDir %&gt;/**/*.less&quot;</span>
        tasks<span style="color: #66cc66;">:</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;spawn_less&quot;</span><span style="color: black;">&#93;</span>
&nbsp;
      html<span style="color: #66cc66;">:</span>
        files<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= contentDir %&gt;/html/**/*.html&quot;</span>
        tasks<span style="color: #66cc66;">:</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;copy:html&quot;</span><span style="color: black;">&#93;</span>
&nbsp;
      images<span style="color: #66cc66;">:</span>
        files<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= contentDir %&gt;/images/**/*&quot;</span>
        tasks<span style="color: #66cc66;">:</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;copy:images&quot;</span><span style="color: black;">&#93;</span></pre></td></tr></table></div><p>The <code>regarde</code> task defined here watches for changes to our source files and executes the specified task(s) whenever a watched file is changed. This saves us from manually rebuilding every time we make a change. Notice that for CoffeeScript and jade files, it calls the <code>changed</code> subtask, which only recompiles the files that were actually changed. This drastically cuts down our compilation times when there are a lot of source files, and only one was changed.</p><div
class="wp_syntax"><table><tr><td
class="code"><pre class="coffeescript" style="font-family:monospace;">&nbsp;
    <span style="color: #808080; font-style: italic;"># Set up a static file server</span>
    connect<span style="color: #66cc66;">:</span>
      server<span style="color: #66cc66;">:</span>
        options<span style="color: #66cc66;">:</span>
          hostname<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;0.0.0.0&quot;</span>
          port<span style="color: #66cc66;">:</span> <span style="color: #ff4500;">9292</span>
          base<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= outputDir %&gt;&quot;</span>
          keepalive<span style="color: #66cc66;">:</span> <span style="color: #0000cd;">true</span>
&nbsp;
&nbsp;
&nbsp;
    <span style="color: #808080; font-style: italic;"># Clean up artifacts</span>
    clean<span style="color: #66cc66;">:</span>
      build<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= buildDir %&gt;&quot;</span>
      output<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= outputDir %&gt;&quot;</span>
&nbsp;
&nbsp;
&nbsp;
    <span style="color: #808080; font-style: italic;"># Execute server script</span>
    exec<span style="color: #66cc66;">:</span>
      server<span style="color: #66cc66;">:</span>
        cmd<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;./server.js&quot;</span></pre></td></tr></table></div><p>The above are miscellaneous tasks:</p><ul><li><code>connect</code> serves our output directory on our local machine so that we can open our newly generated site in a browser</li><li><code>clean</code> simply erases the build and output directories when invoked</li><li><code>exec</code> task lets us execute arbitrary shell programs (in this case, a custom server script that I&#8217;ll show in a moment)</li></ul><div
class="wp_syntax"><table><tr><td
class="code"><pre class="coffeescript" style="font-family:monospace;">&nbsp;
    <span style="color: #808080; font-style: italic;"># Karma conf</span>
    karma<span style="color: #66cc66;">:</span>
      unit<span style="color: #66cc66;">:</span>
        configFile<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= testDir %&gt;/unit_conf.js&quot;</span>
      e2e<span style="color: #66cc66;">:</span>
        configFile<span style="color: #66cc66;">:</span> <span style="color: #483d8b;">&quot;&lt;%= testDir %&gt;/e2e_conf.js&quot;</span>
&nbsp;
&nbsp;
    <span style="color: #808080; font-style: italic;"># The contrib-less task has an outstanding bug that will kill a running grunt</span>
    <span style="color: #808080; font-style: italic;"># process (like a watch process) when it fails.</span>
    grunt.<span style="color: black;">registerTask</span> <span style="color: #483d8b;">'spawn_less'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'Run Less in a subprocess'</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">-&gt;</span>
      done = <span style="color: #dc143c;">this</span>.<span style="color: black;">async</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
      grunt.<span style="color: black;">util</span>.<span style="color: black;">spawn</span> grunt<span style="color: #66cc66;">:</span> <span style="color: #0000cd;">true</span><span style="color: #66cc66;">,</span> args<span style="color: #66cc66;">:</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">'less'</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#40;</span>err<span style="color: black;">&#41;</span> <span style="color: #66cc66;">-&gt;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> err
          grunt.<span style="color: black;">log</span>.<span style="color: black;">writeln</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;&gt;&gt; Error compiling LESS file!&quot;</span><span style="color: black;">&#41;</span>
        done<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    grunt.<span style="color: black;">registerTask</span> <span style="color: #483d8b;">&quot;js&quot;</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;coffee:all&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;jade:all&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;concat:js&quot;</span><span style="color: black;">&#93;</span>
    grunt.<span style="color: black;">registerTask</span> <span style="color: #483d8b;">&quot;build&quot;</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;clean&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;js&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;less&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;copy&quot;</span><span style="color: black;">&#93;</span>
    grunt.<span style="color: black;">registerTask</span> <span style="color: #483d8b;">&quot;server&quot;</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;exec:server&quot;</span><span style="color: black;">&#93;</span>
    grunt.<span style="color: black;">registerTask</span> <span style="color: #483d8b;">&quot;unit&quot;</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;build&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;karma:unit&quot;</span><span style="color: black;">&#93;</span>
    grunt.<span style="color: black;">registerTask</span> <span style="color: #483d8b;">&quot;e2e&quot;</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;build&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;karma:e2e&quot;</span><span style="color: black;">&#93;</span>
    grunt.<span style="color: black;">registerTask</span> <span style="color: #483d8b;">&quot;ci&quot;</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;build&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;karma&quot;</span><span style="color: black;">&#93;</span>
&nbsp;
&nbsp;
    grunt.<span style="color: black;">loadNpmTasks</span> <span style="color: #483d8b;">&quot;grunt-contrib-coffee&quot;</span>
    grunt.<span style="color: black;">loadNpmTasks</span> <span style="color: #483d8b;">&quot;grunt-contrib-jade&quot;</span>
    grunt.<span style="color: black;">loadNpmTasks</span> <span style="color: #483d8b;">&quot;grunt-contrib-concat&quot;</span>
    grunt.<span style="color: black;">loadNpmTasks</span> <span style="color: #483d8b;">&quot;grunt-contrib-less&quot;</span>
    grunt.<span style="color: black;">loadNpmTasks</span> <span style="color: #483d8b;">&quot;grunt-contrib-copy&quot;</span>
    grunt.<span style="color: black;">loadNpmTasks</span> <span style="color: #483d8b;">&quot;grunt-regarde&quot;</span>
    grunt.<span style="color: black;">loadNpmTasks</span> <span style="color: #483d8b;">&quot;grunt-contrib-connect&quot;</span>
    grunt.<span style="color: black;">loadNpmTasks</span> <span style="color: #483d8b;">&quot;grunt-contrib-clean&quot;</span>
    grunt.<span style="color: black;">loadNpmTasks</span> <span style="color: #483d8b;">&quot;grunt-exec&quot;</span>
    grunt.<span style="color: black;">loadNpmTasks</span> <span style="color: #483d8b;">&quot;grunt-karma&quot;</span></pre></td></tr></table></div><p>The last part of the Gruntfile defines a task to load and run our tests via the karma test runner, registers some aliases for groups of tasks, and loads our tasks from our node modules.</p><p>The associated package.json file looks about like you would expect:</p><h3>package.json</h3><div
class="wp_syntax"><table><tr><td
class="code"><pre class="javascript" style="font-family:monospace;">&nbsp;
<span style="color: #006600; font-style: italic;">// package.json</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #3366CC;">&quot;name&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;rcr-frontend&quot;</span><span style="color: #339933;">,</span>
  <span style="color: #3366CC;">&quot;version&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;0.1.0&quot;</span><span style="color: #339933;">,</span>
  <span style="color: #3366CC;">&quot;dependencies&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">&quot;grunt&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;latest&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;grunt-contrib-coffee&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;latest&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;grunt-contrib-jade&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;latest&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;grunt-contrib-less&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;latest&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;grunt-contrib-copy&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;latest&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;grunt-contrib-connect&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;latest&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;grunt-contrib-concat&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;latest&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;grunt-regarde&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;latest&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;grunt-notify&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;latest&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;grunt-contrib-clean&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;latest&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;grunt-karma&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;latest&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;grunt-exec&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;latest&quot;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div><p>And as promised, the <code>server.js</code> file referenced in our <code>exec</code> task. This script allows us to run both our webserver and file watcher service in the same terminal by just running the command <code>grunt server</code>.</p><h3>server.js</h3><div
class="wp_syntax"><table><tr><td
class="code"><pre class="javascript" style="font-family:monospace;">&nbsp;
#<span style="color: #339933;">!/</span>usr<span style="color: #339933;">/</span>bin<span style="color: #339933;">/</span>env node
&nbsp;
<span style="color: #000066; font-weight: bold;">var</span> spawn <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;child_process&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">spawn</span><span style="color: #339933;">,</span>
    watcher <span style="color: #339933;">=</span> spawn<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;grunt&quot;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;regarde&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;--force&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    server <span style="color: #339933;">=</span> spawn<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;grunt&quot;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;build&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;connect:server&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
watcher.<span style="color: #660066;">stdout</span>.<span style="color: #660066;">on</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;data&quot;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">var</span> importantOutput <span style="color: #339933;">=</span> data.<span style="color: #660066;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">split</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;<span style="color: #000099; font-weight: bold;">\r</span>?<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">filter</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>str<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009966; font-style: italic;">/&gt;&gt;|Done|Warning|Running/</span>.<span style="color: #660066;">test</span><span style="color: #009900;">&#40;</span>str<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  process.<span style="color: #660066;">stdout</span>.<span style="color: #660066;">write</span><span style="color: #009900;">&#40;</span>importantOutput.<span style="color: #660066;">join</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #006600; font-style: italic;">// process.stdout.write(data);</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
server.<span style="color: #660066;">stdout</span>.<span style="color: #660066;">on</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;data&quot;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  process.<span style="color: #660066;">stdout</span>.<span style="color: #660066;">write</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
watcher.<span style="color: #660066;">on</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;exit&quot;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>code<span style="color: #339933;">,</span> signal<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  server.<span style="color: #660066;">kill</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  process.<span style="color: #660066;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
server.<span style="color: #660066;">on</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;exit&quot;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>code<span style="color: #339933;">,</span> signal<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  watcher.<span style="color: #660066;">kill</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  process.<span style="color: #660066;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
process.<span style="color: #660066;">on</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;exit&quot;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  watcher.<span style="color: #660066;">kill</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  server.<span style="color: #660066;">kill</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div><p>There you have it, a relatively straightforward build configuration for a complicated static JavaScript site, made easy with Grunt.
<br
/> &nbsp;</p><p>The post <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~spin.atomicobject.com/2013/05/13/javascript-front-end-grunt/">Build a Rich JavaScript Front End with Grunt</a> appeared first on <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~spin.atomicobject.com">Atomic Spin</a>.</p><Img align="left" border="0" height="1" width="1" style="border:0;float:left;margin:0;padding:0" hspace="0" src="http://feeds.feedblitz.com/~/i/41103689/0/atomicspin">
</div>]]>
&lt;div style=&quot;clear:both;padding-top:0.2em;&quot;&gt;&lt;a title=&quot;Add to Any&quot; href=&quot;http://feeds.feedblitz.com/_/26/41103689/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/addtoany20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to FaceBook&quot; href=&quot;http://feeds.feedblitz.com/_/2/41103689/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/fbshare20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Share on Google+&quot; href=&quot;http://feeds.feedblitz.com/_/30/41103689/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/googleplus20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to LinkedIn&quot; href=&quot;http://feeds.feedblitz.com/_/16/41103689/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/linkedin20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Tweet This&quot; href=&quot;http://feeds.feedblitz.com/_/24/41103689/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/twitter20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by email&quot; href=&quot;http://feeds.feedblitz.com/_/19/41103689/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/email20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by RSS&quot; href=&quot;http://feeds.feedblitz.com/_/20/41103689/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/rss20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;&lt;h3 style=&quot;clear:left;padding-top:10px&quot;&gt;Related Stories&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/12/dynamic-ember-js-binding-observers/&quot;&gt;Dynamic Binding in Ember.js Using Observers&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/08/pair-programming-teleport/&quot;&gt;Effortless Pair Programming with Teleport&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/05/ruby-chipmunk-gem-6130/&quot;&gt;Chipmunk Gem, version 6.1.3.0.rc1&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;/div&gt;</content:encoded> <wfw:commentRss>http://feeds.feedblitz.com/~/41103689/0/atomicspin~Build-a-Rich-JavaScript-Front-End-with-Grunt/feed/</wfw:commentRss> <slash:comments>2</slash:comments></item>
<item>
<feedburner:origLink>http://spin.atomicobject.com/2013/05/12/dynamic-ember-js-binding-observers/</feedburner:origLink><title>Dynamic Binding in Ember.js Using Observers</title><link>http://feeds.feedblitz.com/~/41072935/0/atomicspin~Dynamic-Binding-in-Emberjs-Using-Observers/</link> <comments>http://feeds.feedblitz.com/~/41072935/0/atomicspin~Dynamic-Binding-in-Emberjs-Using-Observers/#comments</comments> <pubDate>Sun, 12 May 2013 15:00:42 +0000</pubDate> <dc:creator>Jason Porritt</dc:creator> <category><![CDATA[Tools]]></category> <category><![CDATA[binding]]></category> <category><![CDATA[emberjs]]></category> <category><![CDATA[json]]></category> <guid
isPermaLink="false">http://spin.atomicobject.com/?p=96586</guid> <description><![CDATA[<p><p><img
src="http://d37rcl8t6g8sj5.cloudfront.net/wp-content/uploads/knot_binding.png" alt="knot_binding" width="600" height="278" class="aligncenter size-full wp-image-96898" /></p><p>I&#8217;m currently working on an Ember.js web application that is a basic <span
class="caps">CRUD</span> app with a twist — we don&#8217;t know all of the form fields or model attributes ahead of time, but rely on a <span
class="caps">JSON</span> document to specify the names and types of attributes for which we need to render form controls. This presents some interesting challenges, the most significant being that our input elements don&#8217;t know what to bind their value to until they are instantiated.</p><p><a
href="http://feeds.feedblitz.com/~/41072935/0/atomicspin~Dynamic-Binding-in-Emberjs-Using-Observers/" class="more-link">Read more on Dynamic Binding in Ember.js Using Observers <span
class="meta-nav">&#187;</span></a></p></p><p>The post <a
href="http://feeds.feedblitz.com/~/41072935/0/atomicspin~Dynamic-Binding-in-Emberjs-Using-Observers/">Dynamic Binding in Ember.js Using Observers</a> appeared first on <a
href="http://spin.atomicobject.com">Atomic Spin</a>.</p>]]>
&lt;div style=&quot;clear:both;padding-top:0.2em;&quot;&gt;&lt;a title=&quot;Add to Any&quot; href=&quot;http://feeds.feedblitz.com/_/26/41072935/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/addtoany20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to FaceBook&quot; href=&quot;http://feeds.feedblitz.com/_/2/41072935/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/fbshare20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Share on Google+&quot; href=&quot;http://feeds.feedblitz.com/_/30/41072935/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/googleplus20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to LinkedIn&quot; href=&quot;http://feeds.feedblitz.com/_/16/41072935/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/linkedin20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Tweet This&quot; href=&quot;http://feeds.feedblitz.com/_/24/41072935/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/twitter20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by email&quot; href=&quot;http://feeds.feedblitz.com/_/19/41072935/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/email20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by RSS&quot; href=&quot;http://feeds.feedblitz.com/_/20/41072935/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/rss20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;&lt;h3 style=&quot;clear:left;padding-top:10px&quot;&gt;Related Stories&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/15/html5-date-input-ember-js/&quot;&gt;HTML5 Date Inputs and Ember.js&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/13/javascript-front-end-grunt/&quot;&gt;Build a Rich JavaScript Front End with Grunt&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/08/pair-programming-teleport/&quot;&gt;Effortless Pair Programming with Teleport&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;/div&gt;</description> <content:encoded><![CDATA[<div style="clear:left"><p><img
src="http://d37rcl8t6g8sj5.cloudfront.net/wp-content/uploads/knot_binding.png" alt="knot_binding" width="600" height="278" class="aligncenter size-full wp-image-96898" /></p><p>I&#8217;m currently working on an Ember.js web application that is a basic <span
class="caps">CRUD</span> app with a twist — we don&#8217;t know all of the form fields or model attributes ahead of time, but rely on a <span
class="caps">JSON</span> document to specify the names and types of attributes for which we need to render form controls. This presents some interesting challenges, the most significant being that our input elements don&#8217;t know what to bind their value to until they are instantiated.</p><p>After trying a few different approaches, we settled on using a pair of observers to accomplish what a more direct binding could not in this scenario. One observer watches the input&#8217;s <code>value</code> property and updates the remote property value, and the other observer watches the remote property and updates the input&#8217;s <code>value</code>.</p><h2>Our Solution</h2><p>Cut to the chase and <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~jsbin.com/ebusip/3/edit">check out the jsbin example</a>, or read on for a few more details.</p><p>(This example uses Ember.js 1.0.0-RC.1, and we are using the same general solution in 1.0.0-RC.3.)</p><p><span
id="more-96586"></span></p><p>Say we have the following definition for a set of fields:</p><p> <script src="https://gist.github.com/5473393.js"></script><noscript><pre><code class="language-json json">{&quot;fields&quot;:  [
  { &quot;name&quot;: &quot;First Name&quot;, &quot;key&quot;: &quot;first_name&quot; },
  { &quot;name&quot;: &quot;Last Name&quot;, &quot;key&quot;: &quot;last_name&quot; },
  { &quot;name&quot;: &quot;Email&quot;, &quot;key&quot;: &quot;email&quot; }
]}</code></pre></noscript></p><p>We want to display a text field for each element in the array and bind its value to a property on our model defined by the <code>key</code>. This example uses a <code>CollectionView</code> to render a subclass of <code>Ember.TextField</code> for each element. The <code>DynamicBoundTextField</code> here has the pair of observers.</p><p> <script src="https://gist.github.com/5473506.js"></script><noscript><pre><code class="language-coffeescript coffeescript">App.DynamicBoundTextField = Ember.TextField.extend
  placeholderBinding: 'content.name'
  # Update the remote property's value when the value of
  # our text field changes
  _setRemoteValue:(-&gt;
    val = @get('value')
    @set(&quot;controller.data.#{@get('content.key')}&quot;, val) if val?
  ).observes('value')
  # Since we don't know the name of the property to
  # observe ahead of time, create the observer when
  # inserted into the DOM (we'll have the key then).
  didInsertElement: -&gt;
    updateCurrentValue = =&gt;
      currentValue = @get(&quot;controller.data.#{@get('content.key')}&quot;)
      console.log currentValue
      @set('value', currentValue) if currentValue?
    updateCurrentValue()
    @addObserver &quot;controller.data.#{@get('content.key')}&quot;, updateCurrentValue</code></pre></noscript></p><p>Our implementation uses an intermediate object to perform the observation because it requires specialized knowledge about the context that the binding is being performed in, and we felt it was odd having that information on the input itself. But it works the same way.</p><p>Try it out in this JS Bin: <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~jsbin.com/ebusip/3/edit">Runtime binding using observers JS Bin</a>.</p><h2>Things that Didn&#8217;t Work</h2><h3>TextField with a valueBinding</h3><p>The primary constraint we&#8217;re dealing with is not knowing what the TextField should bind to until it&#8217;s created. This means we can&#8217;t simply place a <code>valueBinding</code> on our text input in our class definition like most Ember examples show. It needs another level of indirection to work.</p><h3>TextField and an Intermediate Object with Bindings</h3><p>So we tried creating a <code>valueBinding</code> to a known property, <code>inputValue</code>, of an intermediate view. The intermediate view then bound its <code>inputValue</code> to the target property in <code>init</code>. This caused interesting but unwanted behavior, like the target property getting set to undefined instead of the input&#8217;s value getting set to the existing value of the target property. It just didn&#8217;t work out very well.</p><p>Our current, working implementation does have an intermediate object, but it uses the observer pair pattern instead of a binding to the target property to avoid the bad behavior described above.
<br
/> &nbsp;</p><p>The post <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~spin.atomicobject.com/2013/05/12/dynamic-ember-js-binding-observers/">Dynamic Binding in Ember.js Using Observers</a> appeared first on <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~spin.atomicobject.com">Atomic Spin</a>.</p><Img align="left" border="0" height="1" width="1" style="border:0;float:left;margin:0;padding:0" hspace="0" src="http://feeds.feedblitz.com/~/i/41072935/0/atomicspin">
</div>]]>
&lt;div style=&quot;clear:both;padding-top:0.2em;&quot;&gt;&lt;a title=&quot;Add to Any&quot; href=&quot;http://feeds.feedblitz.com/_/26/41072935/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/addtoany20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to FaceBook&quot; href=&quot;http://feeds.feedblitz.com/_/2/41072935/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/fbshare20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Share on Google+&quot; href=&quot;http://feeds.feedblitz.com/_/30/41072935/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/googleplus20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to LinkedIn&quot; href=&quot;http://feeds.feedblitz.com/_/16/41072935/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/linkedin20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Tweet This&quot; href=&quot;http://feeds.feedblitz.com/_/24/41072935/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/twitter20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by email&quot; href=&quot;http://feeds.feedblitz.com/_/19/41072935/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/email20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by RSS&quot; href=&quot;http://feeds.feedblitz.com/_/20/41072935/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/rss20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;&lt;h3 style=&quot;clear:left;padding-top:10px&quot;&gt;Related Stories&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/15/html5-date-input-ember-js/&quot;&gt;HTML5 Date Inputs and Ember.js&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/13/javascript-front-end-grunt/&quot;&gt;Build a Rich JavaScript Front End with Grunt&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/08/pair-programming-teleport/&quot;&gt;Effortless Pair Programming with Teleport&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;/div&gt;</content:encoded> <wfw:commentRss>http://feeds.feedblitz.com/~/41072935/0/atomicspin~Dynamic-Binding-in-Emberjs-Using-Observers/feed/</wfw:commentRss> <slash:comments>4</slash:comments></item>
<item>
<feedburner:origLink>http://spin.atomicobject.com/2013/05/11/makerbot-replicator-2-issues/</feedburner:origLink><title>Replicator 2 Teething Issues</title><link>http://feeds.feedblitz.com/~/41042228/0/atomicspin~Replicator-Teething-Issues/</link> <comments>http://feeds.feedblitz.com/~/41042228/0/atomicspin~Replicator-Teething-Issues/#comments</comments> <pubDate>Sat, 11 May 2013 15:00:30 +0000</pubDate> <dc:creator>Mitchell Johnson</dc:creator> <category><![CDATA[Miscellaneous]]></category> <category><![CDATA[makerbot]]></category> <guid
isPermaLink="false">http://spin.atomicobject.com/?p=96613</guid> <description><![CDATA[<p><p><img
src="http://d37rcl8t6g8sj5.cloudfront.net/wp-content/uploads/makerbot-replicator-2-b.jpg" alt="MakerBot Replicator 2" width="640" height="427" class="alignnone size-full wp-image-96856" /></p><p>Recently, a group of people at AO <a
href="http://spin.atomicobject.com/2013/03/22/3d-printer-atomic-object/">collectively bought a MakerBot Replicator 2</a>. The printer has been going pretty steadily, but not without the teething problems expected in an early-adopter technology.</p><p><a
href="http://feeds.feedblitz.com/~/41042228/0/atomicspin~Replicator-Teething-Issues/" class="more-link">Read more on Replicator 2 Teething Issues <span
class="meta-nav">&#187;</span></a></p></p><p>The post <a
href="http://feeds.feedblitz.com/~/41042228/0/atomicspin~Replicator-Teething-Issues/">Replicator 2 Teething Issues</a> appeared first on <a
href="http://spin.atomicobject.com">Atomic Spin</a>.</p>]]>
&lt;div style=&quot;clear:both;padding-top:0.2em;&quot;&gt;&lt;a title=&quot;Add to Any&quot; href=&quot;http://feeds.feedblitz.com/_/26/41042228/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/addtoany20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to FaceBook&quot; href=&quot;http://feeds.feedblitz.com/_/2/41042228/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/fbshare20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Share on Google+&quot; href=&quot;http://feeds.feedblitz.com/_/30/41042228/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/googleplus20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to LinkedIn&quot; href=&quot;http://feeds.feedblitz.com/_/16/41042228/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/linkedin20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Tweet This&quot; href=&quot;http://feeds.feedblitz.com/_/24/41042228/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/twitter20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by email&quot; href=&quot;http://feeds.feedblitz.com/_/19/41042228/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/email20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by RSS&quot; href=&quot;http://feeds.feedblitz.com/_/20/41042228/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/rss20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;&lt;h3 style=&quot;clear:left;padding-top:10px&quot;&gt;Related Stories&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/14/managing-email-good-habits/&quot;&gt;Kick Your Bad Email Habits&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/07/career-advice-for-success/&quot;&gt;Getting the Best Career Advice at Any Age/Stage&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/03/technology-mundane-amazing/&quot;&gt;Technology Has Become Mundane, and that&amp;#8217;s Amazing&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;/div&gt;</description> <content:encoded><![CDATA[<div style="clear:left"><p><img
src="http://d37rcl8t6g8sj5.cloudfront.net/wp-content/uploads/makerbot-replicator-2-b.jpg" alt="MakerBot Replicator 2" width="640" height="427" class="alignnone size-full wp-image-96856" /></p><p>Recently, a group of people at AO <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~spin.atomicobject.com/2013/03/22/3d-printer-atomic-object/">collectively bought a MakerBot Replicator 2</a>. The printer has been going pretty steadily, but not without the teething problems expected in an early-adopter technology.</p><h2>Poor Extruder Block Design</h2><p>Makerbot&#8217;s stock extruder for the Replicator 2 uses a round delrin plunger mounted on the end of a screw to pinch the filment against the stepper motor&#8217;s hobbed wheel to push filament. Delrin has a low enough coefficient of friction that this works great so long as your filament is a constant diameter. In our printing, we&#8217;ve found that our extruder occasionaly still skips steps, leaving gaps in the extruded filament.</p><p><span
id="more-96613"></span>This delrin plunger is <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~www.makerbot.com/support/replicator2/documentation/maintenance/">adjustable</a>, but only after removing the print-cooling fan, which is attached with self-tapping screws. It takes quite some time to remove the fan, and the self-tapping screws give you a limited number of removal and replacement cycles.</p><p>Thankfully, Makerbot has recently <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~store.makerbot.com/drive-block-hardware-kit.html">put released</a> a <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~www.thingiverse.com/thing:42250">commmunity-derived</a> pinch roller design which is theoretically much more tolerant to filament thickness deviations. They even sent us the upgrade kit at no cost when we contacted them. It was installed earlier this week and is working pretty well so far.</p><p><img
src="http://d37rcl8t6g8sj5.cloudfront.net/wp-content/uploads/makerbot-replicator-2-a.jpg" alt="MakerBot Replicator 2" width="640" height="427" class="alignnone size-full wp-image-96857" /></p><h2>Belt Tension Issues</h2><p>An issue kept appearing in various prints where infill would sometimes not reach the edges of the print in the positive y direction. After running prints through several independent software chains (<a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~www.makerbot.com/makerware/">Makerware</a> with <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~makerbot.github.io/Miracle-Grue/">MiracleGrue</a> and <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~www.makerbot.com/support/replicatorg/documentation/skeinforge/">Skeinforge</a>, <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~replicat.org/">ReplicatorG</a> with Skeinforge and <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~slic3r.org/">Slic3r</a>) and seeing the same issue, I determined it *must* be either a firmware or a hardware issue.</p><p>To try and narrow down the issue, I printed out a 20mm diameter, 20mm height cylinder. The thought was that any axis slope would be very apparent with a pair of digital calipers. When the printed part was measured, I found a minimum diameter of 19.7mm and a maximum of 20.4mm. 0.7mm is way more variance than I was expecting.</p><p>Some previous experience with an Ultimaker suggested that this could be a belt tension issue. I went through the belts in the machine and found that the belt connecting the y-axis stepper motor to the gantry system was quite loose. Once I found a 5.5mm socket and extension with which to loosen the two mounting nuts and repositioned the stepper motor, the print improved much more to a .3mm difference.</p><h2>Still an Early Technology</h2><p>Makerbot has come a very, very long way in their efforts to bring 3d printing to the masses.  When comparing the amount of effort needed to get good prints out of a Cupcake CNC or even a Thing-o-Matic to that required on the Replicator 2, the ease of use is astonishing. The question I ask myself when wondering whether something is ready for the mass market is &#8220;Would I be willing to shoulder the technical support load if I gave this to my grandmother?&#8221; For the Replicator 2, the answer is a definitive no.</p><p>The <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~groups.google.com/group/makerbot">Makerbot Operators Group</a> is a great place to go for help with issues like these.  Have you encountered any odd issues or assembly inconsistencies with your Replicators?
<br
/> &nbsp;</p><p>The post <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~spin.atomicobject.com/2013/05/11/makerbot-replicator-2-issues/">Replicator 2 Teething Issues</a> appeared first on <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~spin.atomicobject.com">Atomic Spin</a>.</p><Img align="left" border="0" height="1" width="1" style="border:0;float:left;margin:0;padding:0" hspace="0" src="http://feeds.feedblitz.com/~/i/41042228/0/atomicspin">
</div>]]>
&lt;div style=&quot;clear:both;padding-top:0.2em;&quot;&gt;&lt;a title=&quot;Add to Any&quot; href=&quot;http://feeds.feedblitz.com/_/26/41042228/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/addtoany20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to FaceBook&quot; href=&quot;http://feeds.feedblitz.com/_/2/41042228/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/fbshare20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Share on Google+&quot; href=&quot;http://feeds.feedblitz.com/_/30/41042228/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/googleplus20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to LinkedIn&quot; href=&quot;http://feeds.feedblitz.com/_/16/41042228/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/linkedin20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Tweet This&quot; href=&quot;http://feeds.feedblitz.com/_/24/41042228/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/twitter20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by email&quot; href=&quot;http://feeds.feedblitz.com/_/19/41042228/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/email20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by RSS&quot; href=&quot;http://feeds.feedblitz.com/_/20/41042228/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/rss20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;&lt;h3 style=&quot;clear:left;padding-top:10px&quot;&gt;Related Stories&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/14/managing-email-good-habits/&quot;&gt;Kick Your Bad Email Habits&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/07/career-advice-for-success/&quot;&gt;Getting the Best Career Advice at Any Age/Stage&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/03/technology-mundane-amazing/&quot;&gt;Technology Has Become Mundane, and that&amp;#8217;s Amazing&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;/div&gt;</content:encoded> <wfw:commentRss>http://feeds.feedblitz.com/~/41042228/0/atomicspin~Replicator-Teething-Issues/feed/</wfw:commentRss> <slash:comments>0</slash:comments></item>
<item>
<feedburner:origLink>http://spin.atomicobject.com/2013/05/10/haskell-logic-library/</feedburner:origLink><title>Towards a Haskell Logic Library</title><link>http://feeds.feedblitz.com/~/41004251/0/atomicspin~Towards-a-Haskell-Logic-Library/</link> <comments>http://feeds.feedblitz.com/~/41004251/0/atomicspin~Towards-a-Haskell-Logic-Library/#comments</comments> <pubDate>Fri, 10 May 2013 12:00:38 +0000</pubDate> <dc:creator>Job Vranish</dc:creator> <category><![CDATA[Languages]]></category> <category><![CDATA[haskell]]></category> <guid
isPermaLink="false">http://spin.atomicobject.com/?p=96514</guid> <description><![CDATA[<p><p>In one of my previous posts, I described an implementation of <a
href="http://spin.atomicobject.com/2012/12/08/minikanren-in-haskell/">miniKanren in Haskell</a>. I have since been improving the implementation.</p><p>I am currently working on the third iteration of my logic library. The first one was described by my previous post. The second is in <a
href="https://github.com/jvranish/MiniKanrenT/tree/rework">a GitHub repository</a>. I have yet to settle on a design that I really like, but I thought I&#8217;d post something about what I&#8217;ve been working on.</p><p><a
href="http://feeds.feedblitz.com/~/41004251/0/atomicspin~Towards-a-Haskell-Logic-Library/" class="more-link">Read more on Towards a Haskell Logic Library <span
class="meta-nav">&#187;</span></a></p></p><p>The post <a
href="http://feeds.feedblitz.com/~/41004251/0/atomicspin~Towards-a-Haskell-Logic-Library/">Towards a Haskell Logic Library</a> appeared first on <a
href="http://spin.atomicobject.com">Atomic Spin</a>.</p>]]>
&lt;div style=&quot;clear:both;padding-top:0.2em;&quot;&gt;&lt;a title=&quot;Add to Any&quot; href=&quot;http://feeds.feedblitz.com/_/26/41004251/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/addtoany20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to FaceBook&quot; href=&quot;http://feeds.feedblitz.com/_/2/41004251/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/fbshare20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Share on Google+&quot; href=&quot;http://feeds.feedblitz.com/_/30/41004251/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/googleplus20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to LinkedIn&quot; href=&quot;http://feeds.feedblitz.com/_/16/41004251/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/linkedin20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Tweet This&quot; href=&quot;http://feeds.feedblitz.com/_/24/41004251/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/twitter20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by email&quot; href=&quot;http://feeds.feedblitz.com/_/19/41004251/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/email20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by RSS&quot; href=&quot;http://feeds.feedblitz.com/_/20/41004251/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/rss20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;&lt;h3 style=&quot;clear:left;padding-top:10px&quot;&gt;Related Stories&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/06/k-nearest-neighbor-racket/&quot;&gt;Basic Machine Learning with KNN and Racket&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/02/chicken-scheme-part-1/&quot;&gt;Behind the Scenes with CHICKEN Scheme (Part 1)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/04/28/reactivecocoa/&quot;&gt;ReactiveCocoa: The Future of Cocoa Programming&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;/div&gt;</description> <content:encoded><![CDATA[<div style="clear:left"><p>In one of my previous posts, I described an implementation of <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~spin.atomicobject.com/2012/12/08/minikanren-in-haskell/">miniKanren in Haskell</a>. I have since been improving the implementation.</p><p>I am currently working on the third iteration of my logic library. The first one was described by my previous post. The second is in <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~https://github.com/jvranish/MiniKanrenT/tree/rework">a GitHub repository</a>. I have yet to settle on a design that I really like, but I thought I&#8217;d post something about what I&#8217;ve been working on.</p><h2>Improvements</h2></p><p>The key improvements in the second iteration were the ability to easily add custom data types and the addition of a <code>match</code> function. The custom data type addition was pretty straightforward. <span
id="more-96514"></span></p><p>The <code>match</code> function was an attempt to replicated the functionality of the <code>match</code> function in <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~https://scholarworks.iu.edu/dspace/bitstream/handle/2022/8777/Byrd_indiana_0093A_10344.pdf">William Byrd&#8217;s thesis</a>. I <em>think</em> what I have does the same thing; if not, it still gave me the idea.</p><p>The type of my <code>match</code> function is as follows:</p><div
class="wp_syntax"><table><tr><td
class="code"><pre class="haskell" style="font-family:monospace;">match <span style="color: #339933; font-weight: bold;">::</span> <span style="color: green;">&#40;</span>MonadKanren m<span style="color: #339933; font-weight: bold;">,</span> Matchable a<span style="color: #339933; font-weight: bold;">,</span> Unifiable b<span style="color: green;">&#41;</span>
      <span style="color: #339933; font-weight: bold;">=&gt;</span> <span style="color: green;">&#40;</span>a <span style="color: #339933; font-weight: bold;">-&gt;</span> m <span style="color: green;">&#40;</span>LVar b<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> m <span style="color: green;">&#40;</span>LVar a<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> m <span style="color: green;">&#40;</span>LVar b<span style="color: green;">&#41;</span></pre></td></tr></table></div><p>Think of the type <code>m (LVar a)</code> as a relational monadic computation that returns a logic variable.</p><p><code>match</code> turns code that looks like this:</p><div
class="wp_syntax"><table><tr><td
class="code"><pre class="haskell" style="font-family:monospace;">logic<span style="color: #339933; font-weight: bold;">_</span>append a b ab <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span>
   conde <span style="color: green;">&#91;</span> <span style="color: #06c; font-weight: bold;">do</span>
      <span style="color: green;">&#40;</span>h<span style="color: #339933; font-weight: bold;">,</span> t<span style="color: #339933; font-weight: bold;">,</span> res<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">&lt;-</span> fresh
      Cons h t <span style="color: #339933; font-weight: bold;">===</span> a
      Cons h res <span style="color: #339933; font-weight: bold;">===</span> ab
      ab <span style="color: #339933; font-weight: bold;">===</span> logic<span style="color: #339933; font-weight: bold;">_</span>append t b res
   <span style="color: #339933; font-weight: bold;">,</span> <span style="color: #06c; font-weight: bold;">do</span>
      Nil <span style="color: #339933; font-weight: bold;">===</span> a
      b <span style="color: #339933; font-weight: bold;">===</span> ab
   <span style="color: green;">&#93;</span></pre></td></tr></table></div><p>into this:</p><div
class="wp_syntax"><table><tr><td
class="code"><pre class="haskell" style="font-family:monospace;">logic<span style="color: #339933; font-weight: bold;">_</span>append a b <span style="color: #339933; font-weight: bold;">=</span> match <span style="color: green;">&#40;</span>logic<span style="color: #339933; font-weight: bold;">_</span>append<span style="color: #339933; font-weight: bold;">_</span>match b<span style="color: green;">&#41;</span> a
      <span style="color: #06c; font-weight: bold;">where</span>
        <span style="color: #5d478b; font-style: italic;">-- Note that the order of the arguments was swapped</span>
        logic<span style="color: #339933; font-weight: bold;">_</span>append<span style="color: #339933; font-weight: bold;">_</span>match b Nil <span style="color: #339933; font-weight: bold;">=</span> b
        logic<span style="color: #339933; font-weight: bold;">_</span>append<span style="color: #339933; font-weight: bold;">_</span>match b <span style="color: green;">&#40;</span>Cons x xs<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> conso x <span style="color: green;">&#40;</span>logic<span style="color: #339933; font-weight: bold;">_</span>append xs b<span style="color: green;">&#41;</span></pre></td></tr></table></div><p>It lets me take some advatage of Haskell&#8217;s built-in pattern matching and cleans things up quite a bit.</p><h2>Hey look! I found a Monad!</h2><p>One of the <em>really</em> interesting things about <code>match</code> that I didn&#8217;t notice at first is that
<br
/> it, has a <em>very</em> similar type signature to the monad bind operator: <code>=&lt;&lt;</code></p><div
class="wp_syntax"><table><tr><td
class="code"><pre class="haskell" style="font-family:monospace;">match <span style="color: #339933; font-weight: bold;">::</span> <span style="color: green;">&#40;</span>a <span style="color: #339933; font-weight: bold;">-&gt;</span> m <span style="color: green;">&#40;</span>LVar b<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> m <span style="color: green;">&#40;</span>LVar a<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> m <span style="color: green;">&#40;</span>LVar b<span style="color: green;">&#41;</span>
<span style="color: #339933; font-weight: bold;">=&lt;&lt;</span>   <span style="color: #339933; font-weight: bold;">::</span> <span style="color: green;">&#40;</span>a <span style="color: #339933; font-weight: bold;">-&gt;</span> m       b<span style="color: green;">&#41;</span>  <span style="color: #339933; font-weight: bold;">-&gt;</span> m       a  <span style="color: #339933; font-weight: bold;">-&gt;</span> m       b</pre></td></tr></table></div><p>Is it possible to build a monad around match? It turns out: yes! This is the core idea behind my <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~https://github.com/jvranish/MiniKanrenT/tree/relational">third iteration</a>, which is starting to look a lot less like miniKanren.</p><p>In this implementation, <code>match</code> is implicit in monadic bind <code>&gt;&gt;=</code>. The main interesting consequence of this is that logic variable are abstracted away. A given piece of code in the resulting monad cannot tell the difference between a logic variable and a plain old
<br
/> regular value. And in fact, if it could, that would mess up everything.</p><p>I&#8217;m still working on fleshing out the implications of this. I honestly don&#8217;t know if this is a really cool idea or a really dumb idea. Perhaps both?</p><p>The most obvious implication is that it saves a lot of wrapping and unwrapping to convert between logic variables and computations that produce logic variable. Though at first glance it doesn&#8217;t look like it grants much more than just some extra syntactic sugar for the &#8216;match&#8217; function. But&#8230;</p><h2>Laziness</h2><p>One thing that appears to be a more significant implication is laziness.</p><p>In my previous iterations, when I defined customs datatypes to be used by the logic library, I put the logic variables right in the datatype like so:</p><div
class="wp_syntax"><table><tr><td
class="code"><pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">data</span> List a <span style="color: #339933; font-weight: bold;">=</span> Cons <span style="color: green;">&#40;</span>LVar a<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>LVar <span style="color: green;">&#40;</span>List a<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
    <span style="color: #339933; font-weight: bold;">|</span> Nil</pre></td></tr></table></div><p>Which worked fine, but it meant that I had to run all the computations that would produce those logic variables before I constructed an instance of my datatype.</p><p>In the new system, the list type looks like this:</p><div
class="wp_syntax"><table><tr><td
class="code"><pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">data</span> List f m <span style="color: #339933; font-weight: bold;">=</span> Cons <span style="color: green;">&#40;</span>m <span style="color: green;">&#40;</span>f m<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>m <span style="color: green;">&#40;</span>List f m<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
    <span style="color: #339933; font-weight: bold;">|</span> Nil</pre></td></tr></table></div><p>Which, first of all looks <em>terrible</em> (and I&#8217;ll talk more about that later), but secondly it lets me construct my list with just the <em>computation</em> that will produce the logic variable (or maybe just a value) rather than the logic variable itself. The computation is only run when the value is needed.</p><h2>Going Forward</h2><p>I&#8217;m still not sure if all this is a really cool idea or just a really dumb idea, but I&#8217;m learning a ton about relational/logic programming in the process.</p><p>My goal for my next iteration is to clean up the super ugly datastructures. Currently a custom datatype in the new system must be a higher-kinded type with higher-kinded parameters, which is not just ugly, but also a real pain. Defining your own datastructures and converting back a forth between the logic and regular variants of a datastructure is currently the biggest pain point in the new system. Fortunately, I think I can fix it.
<br
/> &nbsp;</p><p>The post <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~spin.atomicobject.com/2013/05/10/haskell-logic-library/">Towards a Haskell Logic Library</a> appeared first on <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~spin.atomicobject.com">Atomic Spin</a>.</p><Img align="left" border="0" height="1" width="1" style="border:0;float:left;margin:0;padding:0" hspace="0" src="http://feeds.feedblitz.com/~/i/41004251/0/atomicspin">
</div>]]>
&lt;div style=&quot;clear:both;padding-top:0.2em;&quot;&gt;&lt;a title=&quot;Add to Any&quot; href=&quot;http://feeds.feedblitz.com/_/26/41004251/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/addtoany20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to FaceBook&quot; href=&quot;http://feeds.feedblitz.com/_/2/41004251/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/fbshare20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Share on Google+&quot; href=&quot;http://feeds.feedblitz.com/_/30/41004251/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/googleplus20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to LinkedIn&quot; href=&quot;http://feeds.feedblitz.com/_/16/41004251/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/linkedin20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Tweet This&quot; href=&quot;http://feeds.feedblitz.com/_/24/41004251/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/twitter20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by email&quot; href=&quot;http://feeds.feedblitz.com/_/19/41004251/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/email20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by RSS&quot; href=&quot;http://feeds.feedblitz.com/_/20/41004251/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/rss20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;&lt;h3 style=&quot;clear:left;padding-top:10px&quot;&gt;Related Stories&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/06/k-nearest-neighbor-racket/&quot;&gt;Basic Machine Learning with KNN and Racket&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/05/02/chicken-scheme-part-1/&quot;&gt;Behind the Scenes with CHICKEN Scheme (Part 1)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/04/28/reactivecocoa/&quot;&gt;ReactiveCocoa: The Future of Cocoa Programming&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;/div&gt;</content:encoded> <wfw:commentRss>http://feeds.feedblitz.com/~/41004251/0/atomicspin~Towards-a-Haskell-Logic-Library/feed/</wfw:commentRss> <slash:comments>0</slash:comments></item>
<item>
<feedburner:origLink>http://spin.atomicobject.com/2013/05/09/budget-extensions-are-a-smell/</feedburner:origLink><title>Budget Extensions Are a &#8220;Smell&#8221;</title><link>http://feeds.feedblitz.com/~/40961069/0/atomicspin~Budget-Extensions-Are-a-Smell/</link> <comments>http://feeds.feedblitz.com/~/40961069/0/atomicspin~Budget-Extensions-Are-a-Smell/#comments</comments> <pubDate>Thu, 09 May 2013 12:00:48 +0000</pubDate> <dc:creator>Mike Swieton</dc:creator> <category><![CDATA[Project Management]]></category> <category><![CDATA[Project Planning]]></category> <guid
isPermaLink="false">http://spin.atomicobject.com/?p=96271</guid> <description><![CDATA[<p><p>I recently came off a project where it is clear, in retrospect, that we operated in a rush throughout much of the last half of the project. The budget got extended more than once so that we could &#8220;just get it out the door.&#8221; It was a small project: a month or two initially, then another month part time working on &#8220;that last detail&#8221; and helping to transition it to the customer&#8217;s internal team.</p><p><a
href="http://feeds.feedblitz.com/~/40961069/0/atomicspin~Budget-Extensions-Are-a-Smell/" class="more-link">Read more on Budget Extensions Are a &#8220;Smell&#8221; <span
class="meta-nav">&#187;</span></a></p></p><p>The post <a
href="http://feeds.feedblitz.com/~/40961069/0/atomicspin~Budget-Extensions-Are-a-Smell/">Budget Extensions Are a &#8220;Smell&#8221;</a> appeared first on <a
href="http://spin.atomicobject.com">Atomic Spin</a>.</p>]]>
&lt;div style=&quot;clear:both;padding-top:0.2em;&quot;&gt;&lt;a title=&quot;Add to Any&quot; href=&quot;http://feeds.feedblitz.com/_/26/40961069/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/addtoany20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to FaceBook&quot; href=&quot;http://feeds.feedblitz.com/_/2/40961069/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/fbshare20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Share on Google+&quot; href=&quot;http://feeds.feedblitz.com/_/30/40961069/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/googleplus20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to LinkedIn&quot; href=&quot;http://feeds.feedblitz.com/_/16/40961069/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/linkedin20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Tweet This&quot; href=&quot;http://feeds.feedblitz.com/_/24/40961069/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/twitter20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by email&quot; href=&quot;http://feeds.feedblitz.com/_/19/40961069/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/email20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by RSS&quot; href=&quot;http://feeds.feedblitz.com/_/20/40961069/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/rss20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;&lt;h3 style=&quot;clear:left;padding-top:10px&quot;&gt;Related Stories&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/04/12/agile-team-epic/&quot;&gt;Tear Down the Walls! (part duex): Reorganizing Teams Around Epics&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/03/28/three-layers-management/&quot;&gt;The Three Layers of Management&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/03/11/software-team-management/&quot;&gt;5 Techniques to Get the Most Out of Your Software Team&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;/div&gt;</description> <content:encoded><![CDATA[<div style="clear:left"><p>I recently came off a project where it is clear, in retrospect, that we operated in a rush throughout much of the last half of the project. The budget got extended more than once so that we could &#8220;just get it out the door.&#8221; It was a small project: a month or two initially, then another month part time working on &#8220;that last detail&#8221; and helping to transition it to the customer&#8217;s internal team.</p><p>This has led me to the conclusion that, when coming to the end of a budget, deciding under pressure to extend the work for &#8220;just another week&#8221; is a very bad idea. The technical decisions driven by a project size of six months are probably not the same decisions that you&#8217;d make on a one year project. <b>When you find that your schedule is slipping, it&#8217;s important to make an honest review as soon as possible.</b></p><p><span
id="more-96271"></span></p><p>The overall size of a project is the best constraint you have for driving decisions and tradeoffs: &#8220;We have six months to work on this and will have time to build features X and Y for return on investment of $Z.&#8221; That information can inform decisions throughout the project. The problem is that when you make decisions based on the wrong constraint, you end up making the wrong decisions. For example, you might choose a technology you&#8217;re not familiar with if you have time for training. I&#8217;ve written about this before from the other side, <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~spin.atomicobject.com/2012/03/20/an-unlimited-budget-is-almost-as-bad-as-no-budget/">describing why having too large a budget makes it difficult to know how much to refine features</a>.</p><h2>Where Things Went Wrong</h2><p>Because so much of my recent project was based on a short timeline, we made a few decisions that I think I&#8217;d do differently in retrospect:</p><h3>&#8220;Silo-ing&#8221; Information</h3><p>I worked on one feature and allowed my colleague to work on another. We finished quickly, each of us not having to stop to teach the other about what we&#8217;d built. Then later, when it was just me, I was not equipped to debug it as effectively as I could.</p><p>This problem showed up on my customer&#8217;s side too — like me, they had too much to do, so we didn&#8217;t talk to each other nearly enough. Now — having a complex system with multiple interacting components — debugging is a more difficult proposition than it ought to be.</p><h3>Not Taking the Customer&#8217;s Capabilities into Account</h3><p>When I started, the customer did not have any full-time developers on staff, so I wasn&#8217;t driven towards choosing a tech stack their developers were expert in. Instead, I chose technology that I know well so there were no ramp-up costs. Because we had such a short target, we built a heterogenous system.</p><p>Now, they&#8217;ve hired a developer that is only expert in some parts of the technology stack. I think if I&#8217;d planned for the timeline we ended up with (after more than one &#8220;just one more feature&#8221;), I&#8217;d have chosen something more homogenous that fits their team better. On a short project, the time for me to ramp in to their tech might be a substantial proportion of the project, but on our final timeline, it would not have been nearly as significant.</p><h2>Lessons Learned</h2><p>A project&#8217;s schedule and budget are always necessarily estimates, and they are not always going to be correct. When you realize that your plan is not accurate, it&#8217;s important to adjust the plan. The problem with only extending the budget (instead of extending the budget <i>and</i> reviewing the plan) is that you&#8217;re still making decisions based on a plan you just proved was wrong.</p><p>Every decision I made was sensible at the time, but in aggregate I think things could have gone better. You should make sure to stick your head up regularly and take stock of the big picture. Frederick Brooks&#8217; famous quote about from <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~en.wikipedia.org/wiki/The_Mythical_Man-Month#Progress_tracking">The Mythical Man-Month</a> was appropriate in 1975, and it hasn&#8217;t stopped being true:</p><blockquote><p>Question: How does a large software project get to be one year late?
<br
/> Answer: One day at a time!</p></blockquote><p>Problems accumulate a bit at a time. When you see a second or third 10% budget extension for &#8220;just one more thing,&#8221; you should ask &#8220;what has really changed?&#8221;
<br
/> &nbsp;</p><p>The post <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~spin.atomicobject.com/2013/05/09/budget-extensions-are-a-smell/">Budget Extensions Are a &#8220;Smell&#8221;</a> appeared first on <a
href="http://feeds.feedblitz.com/~/t/0/0/atomicspin/~spin.atomicobject.com">Atomic Spin</a>.</p><Img align="left" border="0" height="1" width="1" style="border:0;float:left;margin:0;padding:0" hspace="0" src="http://feeds.feedblitz.com/~/i/40961069/0/atomicspin">
</div>]]>
&lt;div style=&quot;clear:both;padding-top:0.2em;&quot;&gt;&lt;a title=&quot;Add to Any&quot; href=&quot;http://feeds.feedblitz.com/_/26/40961069/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/addtoany20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to FaceBook&quot; href=&quot;http://feeds.feedblitz.com/_/2/40961069/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/fbshare20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Share on Google+&quot; href=&quot;http://feeds.feedblitz.com/_/30/40961069/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/googleplus20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Add to LinkedIn&quot; href=&quot;http://feeds.feedblitz.com/_/16/40961069/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/linkedin20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Tweet This&quot; href=&quot;http://feeds.feedblitz.com/_/24/40961069/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/twitter20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by email&quot; href=&quot;http://feeds.feedblitz.com/_/19/40961069/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/email20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;  &lt;a title=&quot;Subscribe by RSS&quot; href=&quot;http://feeds.feedblitz.com/_/20/40961069/atomicspin&quot;&gt;&lt;img height=&quot;20&quot; src=&quot;http://assets.feedblitz.com/i/rss20.png&quot; style=&quot;border:0;float:left;margin:0px 3px 0px;padding:0&quot;&gt;&lt;/a&gt;&lt;h3 style=&quot;clear:left;padding-top:10px&quot;&gt;Related Stories&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/04/12/agile-team-epic/&quot;&gt;Tear Down the Walls! (part duex): Reorganizing Teams Around Epics&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/03/28/three-layers-management/&quot;&gt;The Three Layers of Management&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://spin.atomicobject.com/2013/03/11/software-team-management/&quot;&gt;5 Techniques to Get the Most Out of Your Software Team&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;/div&gt;</content:encoded> <wfw:commentRss>http://feeds.feedblitz.com/~/40961069/0/atomicspin~Budget-Extensions-Are-a-Smell/feed/</wfw:commentRss> <slash:comments>0</slash:comments></item>
</channel></rss>

