tag:blogger.com,1999:blog-53785269536059213622024-02-19T05:16:48.345-05:00On Being A Journeyman Software DeveloperCorey Haineshttp://www.blogger.com/profile/06863615802688642075noreply@blogger.comBlogger121125tag:blogger.com,1999:blog-5378526953605921362.post-59664398888949262092013-02-28T16:51:00.002-05:002013-03-01T09:48:32.165-05:00Emulation March<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjx-HUQLTdf45ABBrIDModQwj-J13Aua9RBKFjAtTmLQKGGZ48ixBR-MWFZWX1qNR39TvSAV1B8GPdHTygnO703ZIrVL5gA0ABIJc-oGtmJ5ePm3tFJhAta3rkt314XC0IJgAVfijHP3KI/s1600/emu2.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="304" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjx-HUQLTdf45ABBrIDModQwj-J13Aua9RBKFjAtTmLQKGGZ48ixBR-MWFZWX1qNR39TvSAV1B8GPdHTygnO703ZIrVL5gA0ABIJc-oGtmJ5ePm3tFJhAta3rkt314XC0IJgAVfijHP3KI/s320/emu2.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">An Emu, get it?</td></tr>
</tbody></table>
Programming communities are full of inspirational people. People who do great things. Not only great things, but specific things that inspire us. Whether it is blogging, working on open source projects or mentoring, I often look out and say to myself, "wow, I should do more of X." But, it can seem a bit overwhelming. After all, I don't have unlimited time. Add to that the seeming enormous task to start doing all those things.<br />
<h3>
Change is hard</h3>
Change starts with small steps, though. It is rare to be successful by making a huge shift in your life, not to mention developing it all into a habit. So, rather than looking at all the inspiring actions around our community and wishing that I was doing them more, I decided that I would pick just one. Thus was born "Emulation March."<br />
<br />
The goal is simple: find someone that inspires you through a concrete action; make a vow to do that action with some regularity during the month of March; change your twitter bio (or other indication somewhere) to their name and the hashtag <a href="https://twitter.com/search?q=%23emumarch&src=typd" target="_blank">#emumarch</a>. Simple as pie (<i>note: simplicity also available as cake in certain areas</i>).<br />
<br />
You don't even have to be public about it. If you don't want to change your title or bio or whatever, that's cool. The month is about choosing an activity you want to pick up and doing it in a reasonable fashion. I find that being public often is a motivating factor to keep going. You might not. That's okay. But, if you want to be public, then blog about it, tweet about it (hashtag <a href="https://twitter.com/search?q=%23emumarch&src=typd" target="_blank">#emumarch</a>), facebookize about it, google+-ercize about it, shout from the building tops.<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBH1dJzPQcV9Q-mRmNb2E1BfQ2W_biqpEJVy3-ESxNfqfJHarbe_t38-RH8TSmWTiYXvrcqgaE1G-hB-4nhI898TcHVD_YUt4ObB_Pot-CP2Odk9C270A7V8C82FYJV-qxxXZ0sPNUA1s/s1600/fullheadmullet.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBH1dJzPQcV9Q-mRmNb2E1BfQ2W_biqpEJVy3-ESxNfqfJHarbe_t38-RH8TSmWTiYXvrcqgaE1G-hB-4nhI898TcHVD_YUt4ObB_Pot-CP2Odk9C270A7V8C82FYJV-qxxXZ0sPNUA1s/s200/fullheadmullet.jpg" width="160" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Not Aaron, but WHAT HAIR!</td></tr>
</tbody></table>
<h3>
My Emulation March Person</h3>
I admire people who contribute a lot to open source projects. I have contributed here and there, mostly through pairing with people, but I'd like to do it more deliberately.<br />
<br />
<br />
A person I admire for contributing to open source (and lots of other things) is <a href="http://twitter.com/tenderlove" target="_blank">Aaron Patterson</a>, our precious tenderlove of the ruby community. Not only does Aaron contribute to open source which makes our lives more productive, but he also brings us wonderful projects like <a href="https://github.com/tenderlove/enterprise" target="_blank">Enterprise</a> and <a href="https://github.com/tenderlove/phuby" target="_blank">Phuby</a> that really enrich our lives. I think this is important, reminding us that coding should be like a full-head mullet: Party AND Business ALL AROUND!<br />
<h4>
So, I've chosen Aaron Patterson as my emulation march title.</h4>
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg18xB52roo8pewyUUHTH0qdqWbbmr2NNI5hlfAh_Vv0B6h3rBP6L2UDMcW92q4z3OqObzOIVxUIO-h1XfSqHT8iAMuaFTfKH2NveMUNiU183g2uTzavZj5Y3_lkKCmOeqXAX27gYRcm_w/s1600/2013-02-23+11.00.18.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg18xB52roo8pewyUUHTH0qdqWbbmr2NNI5hlfAh_Vv0B6h3rBP6L2UDMcW92q4z3OqObzOIVxUIO-h1XfSqHT8iAMuaFTfKH2NveMUNiU183g2uTzavZj5Y3_lkKCmOeqXAX27gYRcm_w/s320/2013-02-23+11.00.18.jpg" width="240" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Fierce Red Carpet Action</td></tr>
</tbody></table>
<h3>
My Emulation March Activity</h3>
I vow to contribute to an open source project at least twice a week through the month of March.<br />
<br />
I hope to build up a habit that will last longer than that, but Emulation March isn't about setting up expectations. I've even chosen my first open source contribution, which I'll push up in a couple days.<br />
<br />
<h4>
Who's your <a href="https://twitter.com/search?q=%23emumarch&src=typd" target="_blank">#emumarch</a> inspiration?</h4>
[<b>Update:</b> My first contribution came in early by a day. Here is my gem based on Aaron's minitest-emoji. Mine adds RSpec support: <a href="https://github.com/coreyhaines/emoji-test-love" target="_blank">Emoji-Test-Love</a>)<br />
<br />
<br />
<br />
<br />Corey Haineshttp://www.blogger.com/profile/06863615802688642075noreply@blogger.comtag:blogger.com,1999:blog-5378526953605921362.post-71468581164479606022013-01-23T23:07:00.000-05:002013-01-23T23:16:34.809-05:00I'm sorry<br />
Yesterday <a href="http://harthur.wordpress.com/2013/01/24/771/" target="_blank">I made a mistake</a>. Without thinking, I put up a mean tweet about some code that Heather Arthur wrote. And I want to apologize.<br />
<br />
I value being supportive. And I value being nice. I have thoughts around code, but they are all trumped by my strong belief that we should be working to bring each other up. Yesterday I went against all of those things, and I am ashamed. There are constructive ways to talk about code, but I did not use them. I will be thinking more strongly about these ways and how to use them in the future.<br />
<br />
It is easy to forget that people write code. But it is important that we don't forget that. Writing code is easy, putting it out in front of the world isn't.<br />
<br />
So, I'm sorry, Heather. There is no excuse for what I wrote.<br />
<br />
(note: I won't be publishing comments on this post)<br />
<br />Corey Haineshttp://www.blogger.com/profile/06863615802688642075noreply@blogger.comtag:blogger.com,1999:blog-5378526953605921362.post-49931480293521709492012-12-27T16:16:00.001-05:002014-11-17T12:14:04.387-05:00Why I Don't Use ActiveSupport::Concern<h3>
or, why I actively replace ActiveSupport::Concern with Ruby in codebases I work on</h3>
<br />
<h3>
tl;dr</h3>
I don't use ActiveSupport::Concern.<br />
<ul>
<li>Unlike other Rails-based bastardization of concepts and names, ActiveSupport::Concern has very little to do with common connotations of "concern."</li>
<li>It tightly couples a useful design concept to a single, possibly-least-optimal implementation of the idea (mixins).</li>
<li>Its implementation is actual hiding a dependency management system. This hides design issues that are highlighted when you are more explicit.</li>
</ul>
<b>However, if you want to use it, the world isn't going to end.</b><br />
<br />
<h4>
Background on why I noticed this</h4>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXmDfgrbJFDIM5IbHqotRfvoMItfEJXMIwkLRefg3iA2U0VnYVLdUU_LVs3NPk_6P2n4_4sH4xhMm8njaU4cHEm6yybQa3l026qKdGEzbvGsHVMZHsekv6PLTHPKpRGXVFxhScQrAyE0I/s1600/Photo+on+12-19-12+at+1.57+PM.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXmDfgrbJFDIM5IbHqotRfvoMItfEJXMIwkLRefg3iA2U0VnYVLdUU_LVs3NPk_6P2n4_4sH4xhMm8njaU4cHEm6yybQa3l026qKdGEzbvGsHVMZHsekv6PLTHPKpRGXVFxhScQrAyE0I/s320/Photo+on+12-19-12+at+1.57+PM.jpg" height="213" width="320" /></a></div>
This summer, I spent some time at a local startup here in Chicago doing some work. I was brought in to build some features, look at their architecture, work on improving their test suite, etc. The system was young-ish (between 1- and 2-years old) and wasn't in bad shape. Features were still being added fairly readily (although starting to slow), and it wasn't TOO hard to find where things were. But the original developers had made some poor decisions, and you could see that if the same idioms were followed much more, the system would start to follow what is a common Rails progression, calcifying as heavy coupling starts to make it more and more difficult to make small changes without negatively influencing other parts.<br />
<br />
Also, as their system grew, the lack of a good testing practice and structure slowed down their test time, both for the suite and (more importantly) the unit level. Heavy use of FactoryGirl-style integrated tests were making their test startup time less and less useful for the minute-to-minute development process. When running a single tests takes a long time, it is less likely that you'll run them frequently, so you lose one of the major benefits that a good test-driven process provides: design feedback as you flesh out your components, behaviors and interactions.<br />
<br />
Again, their system wasn't in a horrible shape. I wasn't brought in to fix an already horrible situation. I was actually there to help keep them from going over the "super fast at first, then slows down tremendously" development cliff that haunts many of the Rails developers that I've talked to and spent time coding with.<br />
<br />
They also had at least one missing domain concept in their system, as the original developers had waited a bit too long to focus on extracting the necessary design elements. This is a common problem I've seen: people (rightfully) wait to extract domain concepts until they present themselves, then miss the point in time when they can be easily extracted. So, it was a little bit past where reifying this fundamental concept was going to be a bit more work than they were comfortable taking. Since then, we've worked through a baby-step process to slowly bring the concept to life as a central figure in the design.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDNffym25vzgv1cUzSQ9ZxG8YdqjX5Go_zrnGUdqrI05X3lw2QRoPirynvUQ9JnHN1PibR7w8knOogfeCMKpEMprTFkPYAZQ3P8NAryRCHHmwj7s2Lx0cD22wjCO499PO-P05lcdVfaTI/s1600/Photo+on+12-25-12+at+7.26+PM.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDNffym25vzgv1cUzSQ9ZxG8YdqjX5Go_zrnGUdqrI05X3lw2QRoPirynvUQ9JnHN1PibR7w8knOogfeCMKpEMprTFkPYAZQ3P8NAryRCHHmwj7s2Lx0cD22wjCO499PO-P05lcdVfaTI/s320/Photo+on+12-25-12+at+7.26+PM.jpg" height="213" width="320" /></a></div>
They were following a fairly idiomatic Rails design, focusing on putting business logic into their models. They tried to keep their controllers focused on the interaction between the user and the models. Of course, as many people who have worked with Rails know, this often leads to very large models. It also has a tendency to create complex interactions between your models. This results in large dependency graphs between objects, instead of a more streamlined tree-looking dependency diagram (also can be considered an acyclic graph). So, you have Model A depending on services from Model B, which depend on both Model A and Model C, which can lead to very complicated relationships and paths through your codebase.<br />
<br />
The codebase had a combination of very large ActiveRecord model class files, as well as a hefty dose of extracted module code that was then added to the model via an include. The modules all used ActiveSupport::Concern to manage their inclusion, which is where this blog post comes from.<br />
<h4>
What is a concern?</h4>
One of the first steps I do when trying to pull apart large AR models is to group the methods into actual conceptual "concerns." By moving these groups into modules and mixing them into the AR class, I can also get a good sense of the dependency graph between them. In general, I like these concerns to be orthogonal to each other. If I find that they are dependent on each other, it is usually an indication that there is a helper object of some sort waiting to be extracted.<br />
<h4>
Orthogonality of concerns</h4>
<div class="separator" style="clear: both; text-align: center;">
</div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAHEZhLurYlgiUsIIfmlHD38BBpEfHfFu4cHtzrxSOKeji0dXO6KAzr9OEg6gxzHuB65bp6blSRHptjOy8UR5tUDZvoQDtllVi1NB_QbHaVVyV5uFfy5EpGe8lnXUlPcuxbz7eU60L9UA/s1600/2012-12-15+16.28.41.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAHEZhLurYlgiUsIIfmlHD38BBpEfHfFu4cHtzrxSOKeji0dXO6KAzr9OEg6gxzHuB65bp6blSRHptjOy8UR5tUDZvoQDtllVi1NB_QbHaVVyV5uFfy5EpGe8lnXUlPcuxbz7eU60L9UA/s320/2012-12-15+16.28.41.jpg" height="240" width="320" /></a><br />
Although there are times when it can be the simplest, or at least an interim, solution, allowing a module to depend on another module should be treated as a design smell. This smell often flags a missing, but needed, service object. Unfortunately, idiomatic Rails design seems to shy away from more service-focused objects, relying on the "everything is in the AR model" design.<br />
<br />
A good way to make sure that these concern modules are truly orthogonal is to mix them into your AR module without loading the other modules. This allows you to test just their code. If you find that you can't load them independently, then they have dependencies on each other and are perhaps hiding another concern. Loading modules in isolation is fairly easy to do, just create an empty version of the undesired modules before you require your AR module. Doing this allows you to run isolated tests of specific concern modules when doing development, but also allows you to have the same tests run in the context of loading all concern modules when running your whole suite. It works great, and I use this technique extensively.<br />
<br />
<i>NOTE:</i> this requires an isolation-focus for testing your AR models. That is, you shouldn't need to load up your entire application just to test your AR models. You can see <a href="https://gist.github.com/2068977" target="_blank">the way I do it here</a>.<br />
<h4>
Isn't ActiveSupport::Concern just an alternate syntax for include/extend?</h4>
However, when I tried doing this on this specific codebase, the full suite wasn't working. The real versions of some of the modules weren't loading. Something was changing the way that Ruby's include was working. After some investigation, I narrowed it down to the modules that were relying on ActiveSupport::Concern, rather than just using Ruby's built-in include functionality. This shocked me, as I assumed that ActiveSupport::Concern was just an alternate syntax for Ruby's include/extend functionality. I was working with a pre-existing codebase, so I was just going by what I had read in blog posts, which emphasized the syntax. Now, personally, I dislike the syntax and find it to be one of the more unnecessary "syntactic sugar" pieces in an otherwise useful set of helpers provided with Rails.<br />
<h4>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPA2zDeq_i5RwbTfe5Aob4VX3x-ntAumJ1JGmOvrNWjDnxcyiWyC8NA6SfHZHSHTYApKij4Z2zwWiwXJKWcheQ7TFExav9P8xT1zezko7VXYdvbQ-iuaqKP3VX6DHh2RjN_wGG5F5GFvc/s1600/Photo+on+11-30-12+at+1.01+PM+%232.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPA2zDeq_i5RwbTfe5Aob4VX3x-ntAumJ1JGmOvrNWjDnxcyiWyC8NA6SfHZHSHTYApKij4Z2zwWiwXJKWcheQ7TFExav9P8xT1zezko7VXYdvbQ-iuaqKP3VX6DHh2RjN_wGG5F5GFvc/s320/Photo+on+11-30-12+at+1.01+PM+%232.jpg" height="213" width="320" /></a>Whoa! Dependency Management?</h4>
So, I went looking at the code for ActiveSupport::Concern. <a href="https://github.com/rails/rails/blob/2ff888181d8d3425864f58141881e36b5f12e8c3/activesupport/lib/active_support/concern.rb#L100-L126" target="_blank">Go look at it, yourself, as well</a>. ActiveSupport::Concern is focused on mucking around with the loading of modules in the case that you've allowed one module to depend on another. Having modules depending on other modules is a design smell, but, as with all design discussions, there are always some edge cases where this is needed and potentially the simplest solution. What caught me off guard, though, was that a component that was focused on managing a specific design was wrapped in a name that has nothing to do with that, namely "Concern."<br />
<div>
<h4>
Rails history of naming problems</h4>
<div>
<a href="http://gilesbowkett.blogspot.com/" target="_blank">Giles Bowkett</a> has been writing some great stuff lately about Rails, OO and design. His book, <a href="http://railsoopbook.com/" target="_blank">Rails As She Is Spoke</a> (yes, you should get it), has a good section on the problem with ActiveRecord as a name for the implementation in Rails. I won't go into too much detail, but it revolves around the misrepresentation of ActiveRecord, the ORM, and active record, the design pattern. Along with MVC, Controllers, Models, and pretty much the entirety of the "testing" names, Rails has had a history of bastardizing and confusing the meaning of already established terms.</div>
<div>
<br /></div>
<div>
It is common for Rails to be the first point of contact for developers with these terms. Many of the people who come to Rails either are beginners or come from programming cultures with less emphasis on software design and the history of where these terms come from. The result is that they now have a skewed view of these terms from the larger software industry as a whole. As an example, talk to a testing professional and use the terms that Rails uses for the different types of tests. You'll get some interesting looks.</div>
</div>
<div>
<h4>
Let's do the time-warp again</h4>
<div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNXivrz7bMB0rUS5BwPKf-SrfwUlW6USIikV_2sScY4-ZomUeXdGEdPGtkwtaXT82A2uRiPHfS4cC0elnfgbCjrdvbwZ6FJu2Hsn9knCcTE_yazgEcWUu5uQHY9-OwsTX5Zg_QzOqnFDg/s1600/2012-12-13+13.39.15.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNXivrz7bMB0rUS5BwPKf-SrfwUlW6USIikV_2sScY4-ZomUeXdGEdPGtkwtaXT82A2uRiPHfS4cC0elnfgbCjrdvbwZ6FJu2Hsn9knCcTE_yazgEcWUu5uQHY9-OwsTX5Zg_QzOqnFDg/s320/2012-12-13+13.39.15.jpg" height="320" width="240" /></a>And now we have the term "concern" being bandied about. DHH recently wrote a reasonable blog post about <a href="http://37signals.com/svn/posts/3372-put-chubby-models-on-a-diet-with-concerns" target="_blank">separating out the different concerns of your AR models into modules</a>. Unfortunately, he consistently confuses ActiveSupport::Concern (dependency management for module inclusion) with concern (orthogonal, possibly reusable modules containing conceptually related groups of functionality). By doing this, Rails once again is co-opting a term that is commonly used and has a well-established mechanism in Ruby (include/extend) and replacing it with a capitalized extra dependency. By presenting ActiveSupport::Concern as the same as "concern" the naming is again confused. And, unlike the other parts of Rails, this one has no added benefit related to even the most vague definition of concerns. In fact, it adds complexity to your system that wasn't there before when relying on include/extend.</div>
<div>
<br /></div>
<div>
It also tightly ties the idea of a "concern" to a concrete implementation in ActiveSupport. I use the idea of concerns a lot to guide me as I build the design for my systems. Sometimes the idea leads me to a module mixin, sometimes to a wrapper-type class, and sometimes to a helper class that I delegate requests to.</div>
<div>
<h4>
Do I need this dependency management functionality?</h4>
<div>
With the complexity (both inherent in the problem and caused by the choice of design) in Rails, I can see a need for a component that does what ActiveSupport::Concern does, managing module-to-module dependencies. But, why not have this as a separate, well-named component? On the surface, Rails purports to have a focus on usability, and it succeeds in a lot of areas, but historically it has messed up when it comes to names. While the other names at least have a passing similarity to their common connotation, though, ActiveSupport::Concern doesn't seem to have any actual link to anything but the vaguest of definitions of concern.</div>
<div>
<br /></div>
<div>
However, being explicit about this allows us to get necessary feedback from our design when we start creating strange dependency chains.</div>
</div>
</div>
<div>
<h4>
Adding complexity to Ruby's mixins</h4>
<div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs_cSUY6Q0J0jNr4HU6UHQdYPWh4PHgSRPPH3PSxd5k8rOX6N6S1wkVX4fNEzQ9_o7C_MPJHzpnkUZFo9zwMZkmjHfqgthqH2i52R0NRmv_yhu4DYh3sN9t1lALBS0H0XT-c__X1naqgc/s1600/2012-11-23+12.10.27.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs_cSUY6Q0J0jNr4HU6UHQdYPWh4PHgSRPPH3PSxd5k8rOX6N6S1wkVX4fNEzQ9_o7C_MPJHzpnkUZFo9zwMZkmjHfqgthqH2i52R0NRmv_yhu4DYh3sN9t1lALBS0H0XT-c__X1naqgc/s320/2012-11-23+12.10.27.jpg" height="240" width="320" /></a><br />
Because of the built-in dependency management overriding that this contains, you now have to jump through hoops to test ActiveSupport::Concern mixins in isolation of other mix-ins.</div>
<div>
<br /></div>
<div>
As an example, suppose you have the idea of authorization for certain behaviors. It could be argued (I've heard it, in fact) that authorization is a cross-cutting concern across models. So, why not implement this as a Concern? This is a reasonable idea, because you can then test that the authorization code is working, then declaratively lay it down on the rest of your system. However, this causes another small issue. In order to test the behavior of your component, you have to provide some form of setup around the authorization stuff. That adds unrelated complexity to your testing, masking the reason behind the test. Do this with enough "concerns" and you'll have a tremendous amount of cruft in your tests. Now, change one of them and all your tests break. Sound familiar? This is a common situation where the fragility of tests is a direct pointer to an implementation problem in your underlying design.</div>
<div>
<br /></div>
<div>
The current implementation of ActiveSupport::Concerns doesn't allow you to simply swap out the Authorization concern with a dummy implementation, due to its real nature as a dependency-management component.</div>
<div>
<br /></div>
<div>
And this is in place of Ruby's built-in mixin support with include/extend. Josh Cheek has a good blog post where he talks about <a href="http://blog.8thlight.com/josh-cheek/2012/02/03/modules-called-they-want-their-integrity-back.html" target="_blank">include vs extend and some ways to use them</a>. Yes, you should go read it.</div>
<div>
<h4>
What it actually does</h4>
<div>
So, ActiveSupport::Concern appears to have 2 functions: an alternate syntax ("sugar" is a matter of opinion, I personally think it is less useful than Ruby's) for specifying how a module gets included into a class; and, a complex dependency management system (which has absolutely nothing to do with the concept of concerns).</div>
<h4>
But I like concerns</h4>
<div>
I love the idea of concerns. I use the concept all the time to guide my design decisions. In fact, I agree with DHH on a high level. If you replaced all references to ActiveSupport::Concern with just simple concern/include/extend in DHH's post about them, I think that his points are valid. In Rails, this is the place where you should be focused on separation of concerns. However, based on my experiences, mixins shouldn't be the primary mechanism for doing this in your system (I think wrappers or helpers are better way of eliminating duplication of knowledge/behavior), but it does fit with idiomatic "everything is in your model" Rails designs.</div>
<div>
<h4>
What should it be called?</h4>
<div>
ActiveSupport has a whole slew of useful additions to built in Ruby classes. Why not just have this be an augmentation of Module, focused on the dependency management?</div>
<h4>
Ultimate Question: should you use it?</h4>
<div>
I don't use them. I find that they add complexity to my system without providing any value. Adding dependencies and hiding complexity is a choice that you should make according to your desires and experience.</div>
<div>
<br /></div>
<div>
But, this blog post isn't about convincing you not to use them; it is about explaining the reasons why I don't use them. I prefer using Ruby's built-in, more flexible include/extend syntax. Your mileage may vary depending on your choice.</div>
<div>
<br /></div>
<div>
And, most importantly, the world won't end if you do. I would just ask yourself if it actually provides value. Rails has some awesome parts that make it very useful, but you should think before blindly using it for more than what it really is: a set of reusable helpers to route from a url to a method and a passably useful ORM. That part in-between those: that's your application, it is worth putting thought and care there.<br />
<h4>
Update: Other Options</h4>
People mentioned two alternatives to include/extend that don't have the naming- and dependency-management-craziness in them. Plus, the code is a bit more clear IMNSHO.<br />
<a href="https://github.com/ahoward/shared" target="_blank">Shared</a> by <a href="https://twitter.com/drawohara/" target="_blank">Ara Howard</a> - The more complex of the two, supporting deferred execution of the code. Very interesting.<br />
<a href="https://github.com/henrik/augmentations" target="_blank">Augmentations</a> by <a href="https://twitter.com/henrik" target="_blank">Henrik Nyh</a> - Incredibly simple and focused.<br />
Check them out, and especially check out the code! I'm not saying you should use them, but I definitely have a better feel about them than ActiveSupport::Concern.<br />
<br />
And finally, here's a picture of Zak the Cat </div>
<div>
You just read a long blog post. You deserve to smile.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAJ4m5Dx7hgj1M1vxmUBt5UVm56IjarIZZi9ErP7NWuCK1xa9SG2lwZWviY-knRxVlLwSLbzlxRjfcrtnfNSjKX6QX9VszyYhygvmVtO_g8vuuMIuEuXTdGIKoOQQoS_dwEWULnRiKFNw/s1600/2012-12-12+13.09.40.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAJ4m5Dx7hgj1M1vxmUBt5UVm56IjarIZZi9ErP7NWuCK1xa9SG2lwZWviY-knRxVlLwSLbzlxRjfcrtnfNSjKX6QX9VszyYhygvmVtO_g8vuuMIuEuXTdGIKoOQQoS_dwEWULnRiKFNw/s640/2012-12-12+13.09.40.jpg" height="480" width="640" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
</div>
</div>
</div>
<br />
Thanks to <a href="http://twitter.com/fablednet" target="_blank">Sarah Gray</a>, <a href="http://twitter.com/gilesgoatboy" target="_blank">Giles Bowkett</a> and <a href="https://twitter.com/enebo" target="_blank">Thorsten B<span style="background-color: white; color: black; font-family: sans-serif; font-size: 12.800000190734863px; line-height: 19.200000762939453px;">ö</span>ttger</a> for reviewing this.<br />
<div>
<br /></div>
<br />
<div>
<br /></div>
<br />
<br />Corey Haineshttp://www.blogger.com/profile/06863615802688642075noreply@blogger.comtag:blogger.com,1999:blog-5378526953605921362.post-53192536250270728582012-12-17T15:02:00.001-05:002014-11-17T12:15:10.035-05:00Roman Numerals Kata with CommentaryI recently participated in an awesome Kata Battle at <a href="http://www.8thlight.com/">8th Light</a> against the worthy adversary, <a href="http://twitter.com/demmer12">Craig Demyanovitch</a>. The kata was the wonderful <a href="http://codingdojo.org/cgi-bin/wiki.pl?KataRomanNumerals">Roman Numerals Kata</a>, converting arabic numbers to their roman numeral equivalent.<br />
<br />
While practicing the kata, I noticed a lot of interesting things around the decisions I made in the solution. So, I thought I would record a katacast and lay over some voice commentary around it.<br />
<br />
I'm putting two videos here, with and without commentary.<br />
<br />
Here is the kata WITH commentary. It runs about 16 minutes and 40 seconds, so it isn't too bad to watch. I'd love to hear any constructive feedback in the comments. Version with no commentary is at the bottom of this post. I'd highly recommend watching it full-screen, so you can actually see it.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/vX-Yym7166Y?feature=player_embedded' frameborder='0'></iframe></div>
<br />
<br />
Resources:<br />
<br />
<ul>
<li><a href="http://cleancoder.posterous.com/the-transformation-priority-premise">Transformation Priority Premise</a></li>
<li><a href="http://c2.com/cgi/wiki?XpSimplicityRules">4 Rules of Simple Design</a></li>
<li><a href="http://codingdojo.org/cgi-bin/wiki.pl?KataRomanNumerals">Roman Numeral Kata</a></li>
</ul>
<br />
Here it is with no commentary, if you just want to see me run through it at a reasonable speed.<br />
<div>
<div class="separator" style="clear: both; text-align: left;">
<object class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="http://i.ytimg.com/vi/500_wECxSKE/0.jpg" height="266" width="320"><param name="movie" value="http://www.youtube.com/v/500_wECxSKE?version=3&f=user_uploads&c=google-webdrive-0&app=youtube_gdata&rel=0" /><param name="bgcolor" value="#FFFFFF" /><param name="allowFullScreen" value="true" /><embed width="320" height="266" src="http://www.youtube.com/v/500_wECxSKE?version=3&f=user_uploads&c=google-webdrive-0&app=youtube_gdata" type="application/x-shockwave-flash" allowfullscreen="true"></embed></object></div>
<br />
<br />
<br />
<br /></div>
Corey Haineshttp://www.blogger.com/profile/06863615802688642075noreply@blogger.comtag:blogger.com,1999:blog-5378526953605921362.post-69583650474068808072011-08-07T19:15:00.002-04:002011-08-07T19:30:16.106-04:00Being honest vs Making excusesThe other day, I was involved in a conversation with a group of developers. Several of them work at a large company whose product is built on Ruby on Rails. We were talking about the development environment there, specifically the test suite. The codebase is quite a few years old and has a very slow test suite in part due to some design issues in the codebase. I asked what their test suite was currently running at, and I don't remember the exact figure, but it definitely had a lower bound at 30 minutes (I think it might have been an hour). I then asked about just the unit test suite, the one you should be running frequently while developing. The speed for that was on the order of many minutes. Someone else then asked how it was to run a single set of examples, the type that's focused on whatever part of the codebase you're actively working on, the type that should be run almost constantly while writing code. This was 'better,' being on the order of 30-45 seconds. I remarked that this was still horrible, especially when working on a piece of the system that didn't need specific features of Rails*. One person remarked that this was inevitable with a large codebase. I disagreed. That is, I disagreed with the statement that the size of the codebase was the cause. Slow unit test suites and the inability to quickly run focused subsets are an indication of a design problem with the codebase, not the size. As we talked more, I started to notice something that I've seen before but had a hard time placing: extreme rationalization of bad situations.<br />
<br />
This got me thinking. Often times, we choose to be in certain situations and then, rather than admitting that the situation is bad and dysfunctional, then convince ourselves -- and justify to others -- that this is the only way it can be. While we are free to choose trade-offs for whatever situation we place ourselves in, it is important to be honest with ourselves about the causes of the situation. For example, the above company has interesting computer-science-types of problems which makes up for the bad situation regarding the actual development process.<br />
<br />
If we are not honest about the causes of a bad situation, we pose a significant danger to those who are either less-experienced or uncertain about their own situation. Take a slow test suite, for example. Having a test suite that actively hinders a developer from running portions of it while developing is a deterent even to run the suite at all. As the run time climbs into minutes, the test suite becomes an antagonist, rather than the helper and guide that it should be. Instead of rationalizing, say you have some serious design flaws in your system. Or, say you have a large codebase and a huge team consisting of people with varying desires to write automated tests. When we mask the real causes of a problem, it has the potential to confuse less-experienced developers who look to us for guidance. For example, thinking a slow test suite is inevitable could stop someone from asking for help optimizing their own codebase while there is still time. If you are talking to a less-experienced developer and you mask the fundamental problems, what message are you conveying to them?<br />
<br />
The point of this post is not to point out how people are wrong or that you have to fix, or are able to fix, a bad situation. I just want to raise a reminder that there is a difference between rationalization and being honest with the reasons for something. By rationalizing, we are fooling ourselves and those who learn from us into thinking that you can't do better and it isn't worth trying. By being honest with the reasons, we have the opportunity to both learn from our mistakes, and teach others what pitfalls might await given certain decisions.<br />
<br />
So, the next time you find yourself talking with someone and describing a less-than-optimal situation, ask yourself whether you are being honest about the causes. It doesn't mean you have the power or inclination to fix the problem, but talking about the causes can lead to valuable conversations about how we can do things better in the future.<br />
<br />
also... can we stop using the terms 'ivory tower' or 'real world' when rationalizing our situations? As DHH said, "The real world isn’t a place, it’s an excuse. It’s a justification for not trying." (<a href="http://katelynfriedson.com/post/6679488974/40-inspiring-quotes-for-entrepreneurs-on-what-it-takes-t">other inspirational quotes</a>)<br />
<br />
*In fact, I will put forward you can't do an effective test-driven development cycle with a feedback loop that long.<br />
<br />
As always, thoughtful comments are happily accepted.Corey Haineshttp://www.blogger.com/profile/06863615802688642075noreply@blogger.comtag:blogger.com,1999:blog-5378526953605921362.post-53538100878940122432011-03-23T15:14:00.000-04:002011-03-23T15:14:31.785-04:00My talk from SCNA2010I was honored to be asked to give the closing talk at the Software Craftsmanship North America conference (SCNA) last year. It was a fantastic event filled will great thought, exciting conversations and wonderful people. This was the talk I gave introducing the idea of <a href="http://programmingtour.blogspot.com/2010/11/positivember.html">positivember</a>.<br />
<br />
Dates have been announced for this year's version of SCNA, November 18-19, 2011, so make sure to go <a href="http://scna.softwarecraftsmanship.org/">check it out</a>.<br />
<br />
The video from my talk has been put up, so I wanted to share it. You can watch it on this page, full screen or <a href="http://vimeo.com/21197926">click over to vimeo to watch it</a>.<br />
<br />
<iframe src="http://player.vimeo.com/video/21197926?portrait=0" width="400" height="300" frameborder="0"></iframe><p><a href="http://vimeo.com/21197926">SCNA 2010 / Corey Haines</a> from <a href="http://vimeo.com/user6329244">Brian Pratt</a> on <a href="http://vimeo.com">Vimeo</a>.</p>Corey Haineshttp://www.blogger.com/profile/06863615802688642075noreply@blogger.comtag:blogger.com,1999:blog-5378526953605921362.post-46090303256448339762011-03-02T08:32:00.006-05:002011-03-02T08:37:47.549-05:00Turbulence, measuring the turbulent nature of your codeRecently, <a href="http://twitter.com/#!/mfeathers">Michael Feathers</a> has been investigating the idea of mining all the data in our source code repositories to start finding information about our codebase and system design. He wrote an article about possibly using a churn v complexity chart to look for areas that could use some refactoring love called "<a href="http://www.stickyminds.com/s.asp?F=S16679_COL_2">Getting Empirical about Refactoring</a>".<br />
Since he has joined Obtiva as Chief Scientist, he is here in Chicago fairly frequently. I had the pleasure of spending a morning with him, and we naturally talked about his ideas. I was inspired to build a short bash script that generated a churn graph for my own codebase on <a href="https://www.mercuryapp.com/">MercuryApp</a>. <a href="http://twitter.com/#!/chadfowler">Chad Fowler</a> took my short script and merged it with a script he wrote to run Flog over the codebase. While Michael, Chad and I were in Boulder, CO, for a <a href="http://coderetreat.com/how-it-works.html">coderetreat</a> this past weekend, we put together a project called <a href="https://github.com/chad/turbulence">Turbulence</a>.<br />
<br />
Turbulence is a gem that you install and run in the directory of your code. It does a churn report, combines it with Flog data, and generates a nice scatter plot view. You can find instructions on <a href="https://github.com/chad/turbulence">the Turbulence project page</a>. Although it currently only support Ruby code, we have plans for expanding the project to support other languages.<br />
<br />
One goal is to have people take a screenshot of their graph and post it to twitter with the hashtag #codeturb. This will allow us to view <a href="http://hashalbum.com/codeturb">the graphs on hashalbum</a> and see what we can see.<br />
<br />
Another goal is to have people send us their data, so we can do some analysis on different contexts. If you'd like to take part in this project, please <a href="http://www.coreyhaines.com/">email me</a>. We are working on finishing up an anonymizer function that will mask the filenames, in case you might worry about directory structures/file names giving away your codebase's dirty secrets.<br />
<br />
We are also proposing a series of talks at conferences outlining both results, recommendations and tools for helping analyzing your design based on the shape of your metrics. Keep watch for those.<br />
<br />
I've uploaded <a href="http://twitpic.com/44s66m">my current graph</a> for <a href="https://www.mercuryapp.com/">MercuryApp</a>, you can see it in all its glory by clicking on the picture below.<br />
<a href="http://twitpic.com/44s66m" title="#codeturb on Twitpic"><img alt="#codeturb on Twitpic" height="150" src="http://twitpic.com/show/thumb/44s66m.jpg" width="150" /></a>Corey Haineshttp://www.blogger.com/profile/06863615802688642075noreply@blogger.comtag:blogger.com,1999:blog-5378526953605921362.post-13371750021451580042011-01-20T10:39:00.021-05:002018-02-27T12:16:31.470-05:00On the goals of CoderetreatLast Sunday, I facilitated a <a href="http://www.coderetreat.com/">coderetreat</a> in Cleveland, Ohio, at the <a href="http://www.leandog.com/">Leandog Software boat</a>. It was a great time, filled with writing code, practicing technique and learning both obvious and subtle lessons. I'm always excited to see people's reactions about the event (for example, <a href="http://csanyk.com/rants/2011/01/things-i-learned-at-coderetreat/">here</a> and <a href="http://agile-thanou.com/?p=155">here</a>), as they gain more insights into their journey. Over the past two years, I've found my own role as facilitator transform into a guide, poking a bit here and there at the code.<br />
The full benefits of coderetreat come clear through the course of a whole day, starting with a session, or two, of understanding the problem domain, then the rest of the day is spent pushing our limits, accepting that our 'normal' way of coding isn't enough, that we should be striving towards an ideal. The format of the day is structured very specifically to allow for this experimentation. This is a reason we start early and I don't support having people 'drop by': we want time to get over the 'hacking away to finish' mentality that normally accompanies time pressure and brings with it the necessary corner-cutting. Focusing on improving our skills over 'getting it done' is one of the primary aspects that sets us apart from just being another hackfest: we are practicing to get better at the fundamentals. For example, we aren't there as a way to primarily practice or sell TDD, we aren't there to work on design patterns, we aren't there to finish the problem. We are there to work on learning better software design skills through exploration of the <a href="http://agileinaflash.blogspot.com/2009/02/simple-design.html">4 rules of simple design</a>. This is done through experimentation and exploration.<br />
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
Corey Haineshttp://www.blogger.com/profile/06863615802688642075noreply@blogger.comtag:blogger.com,1999:blog-5378526953605921362.post-5022246964360772612010-12-09T02:49:00.002-05:002010-12-09T16:38:36.923-05:00'Taking it too far' v 'Taking too much time'<a href="http://www.coderetreat.com/how-it-works.html">Coderetreat</a> is about spending the day writing perfect code. During our day-to-day programming tasks, whether they are for pay or our side-projects, we always have the end goal of getting something done. This inevitably causes us to cut corners, writing less-than-perfect code. Why do we do this? For one, it is because writing the code that we 'know we should write' will take too long. We have to weigh the value of merciless refactoring and ultimate clean code with the reality of the benefit we get from delivering something. At coderetreat, though, the pressure to finish goes away, deleting the code makes it so that you can't finish the problem. This allows us the freedom to act as though we have an infinite amount of time.<br />
<br />
As I've traveled around and had the opportunity to work with people of widely varying experience and skill level, I've noticed that the big difference is which corners get cut. For people with less experience, say 1-5 years, the 'get it done' code is significantly different, less clean, than the code written by those with a lot more experience, say 15-20 years, yet written in the same amount of time. This makes sense and isn't a knock against beginners, it is just a good indication that there is always more to learn. The gap between what we actually write and what we think we would write given enough time is always there, just at a different level. As we gain more experience, that gap simply moves upward, so the code is cleaner given the same constraints.<br />
<br />
I've facilitated a lot of coderetreats. I've watched people of widely varying skill levels work on the same problem. Some will write very readable code, others will write less readable code. My role as a facilitator is to ask the questions about the code, questioning the refactoring decisions, and, more often, helping people understand why they stopped refactoring.<br />
<br />
Suppose you have this method, a very common one used to figure out whether a living cell will die in <a href="http://en.wikipedia.org/wiki/Conway's_game_of_life">Conway's Game of Life</a>:<br />
<br />
<script src="https://gist.github.com/734455.js?file=too_far_pre.rb">
</script><br />
<br />
Commonly a team arrives at this and moves to the next test. I'll ask if they aren't skimping a bit on the refactoring and get a response similar to "well, we don't want to go too far" or "this is very readable." I'll generally add a little code:<br />
<br />
<script src="https://gist.github.com/734455.js?file=too_far_extracted.rb">
</script><br />
<br />
That is clearly more readable; most teams that see this small change agree. My question is "why did you stop?" The readability also exposes a few other problems, mostly around the method names, but that is a topic for a different blog post. So, the question remains "why is the first form 'good enough'?" After all, the extracted version is more readable, captures the domain better (underpopulated vs a cryptic number comparison) and is not much more work to extract, especially with basic refactoring support.<br />
<br />
[Just a note here that this is not the absolute end state of the system, but an intermediate step along the way of evolving the design. If teams get that far, this usually ends up being extracted into another object that resolves some of the design issues inherent in it.]<br />
<br />
One hypothesis is that we often mix up the idea of "going to far" with "taking too much time." After all, I would be surprised if someone would say that the extracted version truly is taking it too far. However, I do believe that some people would argue that it might take them too much time to do this all the time. I've worked with people who didn't have a good understanding of their toolsets, so this sort of extraction would take more time: manually extracting it doesn't take a lot of time, but it is definitely non-zero. So, creating code like this is time-consuming on a larger scale, so we don't do it. This, though, is really about "taking too much time."<br />
<br />
Another hypothesis is that we aren't comfortable with more abstractions. For various reasons, most of us don't have a great familiarity and comfort with abstractions. One difference I've noticed between people with varying experience levels is a view on abstractions and how they handle them. I like to say that programming is based a lot on just being adept at abstraction wrangling, and my experiences with people has shown me that this has more than a hint of truth to it. As we encounter the creation and manipulation of abstractions, we get a better sense of where they are hiding in the system and how to be effective in drawing them out into the open. A common argument against heavy abstraction is that you then have to jump around the system to see what is 'really' going on. For people who are truly comfortable with it, though, you either don't need to see what is 'really' going on, relying on the names to truly reveal their intent. And, when you do need to see what a specific part of the system is doing, navigation can be a trivial act, due to a clear signpost guiding you to your destination.<br />
<br />
<br />
These are just musings of mine. I don't have the answers; these thoughts are based on my experiences pairing with different people and watching people of various levels writing the same problem over and over at coderetreats. I'd love to hear any ideas that others have either in comments or as blog posts. I think this is an important topic that can help us understand ourselves better both as a means of accurate self-assessment and developing more effective training mechanisms.Corey Haineshttp://www.blogger.com/profile/06863615802688642075noreply@blogger.comtag:blogger.com,1999:blog-5378526953605921362.post-38095316852988243532010-11-01T06:34:00.005-04:002011-11-01T10:26:59.765-04:00PositivemberAt the 2010 Software Craftsmanship North America conference (<a href="http://scna.softwarecraftsmanship.org/">SCNA</a>), I was given the honor of giving the closing talk, titled "The Long Road Ahead." (<a href="http://vimeo.com/21197926">watch here</a>) My goal was to focus on where we had come and where we are going as a movement, not only looking into the previous year's activity, but also what might stand in our way of spreading the ideas of craftsmanship to the general programming communities.<br />
<br />
As I was preparing, several conference talks influenced my thoughts and the focus of my presentation.<br />
<br />
At <a href="http://jrubyconf.com/">jRubyConf</a>, <a href="http://twitter.com/#!/objo">Joe O'Brien</a> gave a wonderful talk about how the people around us are not stupid and not worthy of the scorn often laid upon them. Instead, we should consider them experts in their domain helping us better build the software we are hired to make. At the same conference, <a href="http://twitter.com/#!/glv">Glen Vanderberg</a> provided a informed view of the problems with the term "software engineering," and what we might do to establish ourselves as a true engineering discipline, all the while capturing and celebrating the artistic, creative bent on which we pride ourselves.<br />
<br />
At SCNA, <a href="http://twitter.com/#!/dougbradbury">Doug Bradbury</a> gave a great talk on our inclination to build, to make; we need to get back to our roots, back to our core qualities as makers. Deep down, we are all creators; we start with nothing but a blank screen, and we put our hearts and souls into the creation of something real, something that acts and solves problems. We write new creation myths every day, except ours reach up out of myth and into reality. <a href="http://twitter.com/#!/chadfowler">Chad Fowler</a> gave an inspiring talk on readdressing what we thought of as quality, putting forth the challenge to merge the realms of art and utility. Often, we hear the argument that the craftsmanship principles are unrealistic and potentially harmful to production; Chad's talk was a refreshing counter to these, showing that we can support both.<br />
<br />
While there is no 'craftsmanship canon,' these talks, for me, cut to the core of the craftsmanship manifesto, highlighting the fundamentals of what we do and care about. They were wonderful examples of how the fundamentals have crystallized over the past two years. Looking forward, the question of spreading the ideas is moving into the spotlight. The ideals are sound, so what could stand in the way?<br />
<br />
Considering the topic of what might hold us back, I watched the mailing lists, I read blog posts, and I paid attention to the twitter stream. I thought about what would set us apart as a movement, and, on a larger scale, what were some hurdles that the software industry as a whole faced. There were a lot of thoughts, but one thing really stood out: we are an overwhelmingly negative group. We complain about our hours, we complain about our jobs, we complain about our coworkers, we complain our toolsets. If we are going to become better, we need to change this.<br />
<br />
I believe that a significant factor impeding us in the goal of selling to those around us the care and professionalism espoused by the craftsmanship movement is the negativity we propogate. So, in my SCNA talk, I challenged the audience to take part in what I am calling "positivember." That is, one month, just one month, where we guard ourselves from the trap of negativity, during which we filter ourselves from taking part in the easy trap of those little comments that we put on twitter, the offhand remarks that we make on our blogs, the complains we focus on when we spend time in person. One month where we put forward an air of positivity in all of our dealings. What would happen if we all did this? What would be the result if we took a minute before we complained, a moment to reflect on whether our dissatisfaction is because of our own choices, those decisions we have made about our tools, our coworkers, our entire work environment?<br />
<br />
So, I ask each and every one of you to take part in this grand experiment: spend a single month portraying only positivity and happiness in what we do. After all, we have one of the greatest jobs there is. We get paid to do that which we gladly do for fun, for a hobby. I spent my teen years programming, relishing the thrill of creation, the thrill of making. Now, more than 20 years later, I get paid to do this. We all do.<br />
<br />
Join with me this November to celebrate the beauty and happiness in what we do. Try to take a moment to filter every outward expression of yourself and look for the joy in what we do. We all get frustrated at times; the world isn't perfect. But, if we can take a second to reflect and focus on the positive, maybe that will actually have an effect on our industry, and on our world.<br />
<br />
The hashtag for this is <a href="http://twitter.com/#!/search/positivember">#positivember</a>. This word captures the essence of the movement: 'positiv' stands for looking forward, appreciating the life of creation that we have built for ourselves, being proud of what we are doing; 'ember' is hungarian for 'person,' the simple link that this is about us as individuals. So, I ask you to help spread the word: tweet about it; blog about it; talk about it. Most of all, present yourself as a happy, positive person who cares about what they do. As people see that those of us who care are happy, they will want to know why. When they ask, we can proudly say, "I love what I do. I'm happy doing what I love."<br />
<br />
And, in the end, I believe this to be the only way we can convince others to follow along. Will you join us?<br />
<br />
<b>Help support <a href="http://twitter.com/#!/search/positivember">#positivember</a></b><br />
<br />
<ul><li>Please <a href="http://digg.com/news/technology/positivember">vote for this on Digg</a>, so we can get more people taking part.</li>
<li>Do you have a podcast? Please give us a shoutout. I'm also available for short interviews about the motivation behind it.</li>
</ul>Corey Haineshttp://www.blogger.com/profile/06863615802688642075noreply@blogger.comtag:blogger.com,1999:blog-5378526953605921362.post-51704188858806431712010-07-19T10:33:00.003-04:002010-07-19T13:19:02.788-04:00Learn To Type Week - Recap<div>(interested in what all the fuss is about? Read the <a href="http://programmingtour.blogspot.com/2010/07/learn-to-type-week.html">original post</a>)</div><div><br /></div><div>Wow! It has been a great week of typing practices. <a href="http://twitter.com/#search?q=learn2typewk">Lots of people took up the challenge</a> and began practicing home-row touch-typing. There were people who were starting from scratch, unlearning years of existing techniques, and some who took the opportunity for further refinement, perhaps getting those pesky numbers and symbols under control (something most people have trouble with). A bunch of people frequented <a href="http://typeracer.com/">typeracer.com</a> for incredibly fun car-racing action. At Eden Labs, they even did a video of <a href="http://vimeo.com/13332121">two employees racing</a> (<a href="http://twitter.com/sermoa">Aimee Daniells</a> and <a href="http://twitter.com/t_crayford">Tom Crayford</a>). Watch and see what it looks like when someone types 100+ wpm.</div><div><br /></div><div>Rather than write a teary-eyed, looking-back account of the journey through the week, I'll end with a challenge: Keep It Up! This week was an intense series of 30-minute sessions every day, but it was just a start. If you continue to practice frequently, either while writing blog posts, coding or just doing focused transcription practices, you'll find your speed increasing and your errors decreasing. Transcription is an important way to learn and practice the techniques, but the real stuff comes when you are producing content. Write a blog post with a paper over your hands. How did it feel? When you get back to coding, are you looking at your hands when you hit the funky symbols, like ( or { or [? If so, why not do some practices to get those under control.</div><div><br /></div><div>And remember, typing is a fundamental skill, not just in coding, but these days, in life. Is it the only skill you need as a developer? Not by a long shot. However, chipping away at impediments to getting your ideas out there is an important step towards improving your competency. Having a strong and fluid command of your keyboard is a valuable first step towards the goal of mastering your toolset.</div><div><br /></div>Corey Haineshttp://www.blogger.com/profile/06863615802688642075noreply@blogger.comtag:blogger.com,1999:blog-5378526953605921362.post-23312871810993511512010-07-15T08:33:00.003-04:002010-07-15T08:38:32.513-04:00Learn To Type Week - Day 4<div>(interested in what all the fuss is about? Read the <a href="http://programmingtour.blogspot.com/2010/07/learn-to-type-week.html">original post</a>)</div><div><br /></div><div>So, <b><span class="Apple-style-span" style="font-size:large;">Day 4</span></b>! How quickly time flies when you are typing, eh?</div><div><br /></div><div>This week has been amazing. I've talked to people who are taking the time to unlearning years-learned techniques in the effort to improve their typing skills. Others already type from home row, but they realized they don't have a good feel for the number/symbol row. More people are discovering "Learn To Type Week" and starting at the beginning. And, of course, there is the <a href="http://www.typeracer.com/">typeracer.com racing</a>. It is a blast to sit and let my fingers fly around the keyboard, totally balls-out.</div><div><br /></div><div>Speaking of typeracer.com, Eden Development realized a video of two of their people, <a href="http://vimeo.com/13332121">Tom Crayford and Aimee Daniells racing</a>. (<a href="http://twitter.com/t_crayford">@t_crayford</a> and <a href="http://twitter.com/sermoa">@sermoa</a>) Hilarious! Go watch what 90-100+ wpm fingers look like.</div><div><br /></div><div>So, my advice for today is about the same: continue the path you've started. Watch the <a href="http://twitter.com/#search?q=learn2typewk">#learn2typewk search on twitter</a>, so you can keep up with the others who are doing it. As a community, we can keep ourselves motivated in our practice. A great way you could practice what you've learned so far is to write a halfway-mark blog post about your experiences. In our day-to-day lives, we rarely do transcription, instead we are typing while producing. Writing a blog post will allow you the opportunity to apply what you've done these past days to a more real-world situation. And, as a bonus, it will spread the word.</div><div><br /></div><div>See you on the <a href="http://vurl.me/TEL">#learn2typewk racetrack</a>! If you want to send the racetrack link to others, you can use the shortened url: <a href="http://vurl.me/TEL">http://vurl.me/TEL</a>.</div><div><br /></div>Corey Haineshttp://www.blogger.com/profile/06863615802688642075noreply@blogger.comtag:blogger.com,1999:blog-5378526953605921362.post-45594754598910031322010-07-14T00:42:00.001-04:002010-07-14T00:44:51.791-04:00Learn To Type Week - Day 3<div>(interested in what all the fuss is about? Read the <a href="http://programmingtour.blogspot.com/2010/07/learn-to-type-week.html">original post</a>)</div><div><br /></div><div>Wow! Another day has gone by in "Learn To Type" week. I've had a great time watching people mark their progress on twitter (hashtag: <a href="http://twitter.com/#search?q=learn2typewk">#learn2typewk</a>): everything from home row stats to switching to dvorak. I'd highly recommend putting a persistent search into your twitter client for #learn2typewk, so you can see all the people who are working with you. Tomorrow is <b>Day 3</b>! Almost halfway done, so don't despair, we're almost there!</div><div><br /></div><div>There are a lot of people putting their speeds and accuracy counts up; it is really neat to see the improvement. Now that 2 days have gone by, try to set a realistic goal for the end of the week. Speed isn't what it is about, though, perhaps you want to consistently type effectively for all the rows without looking.</div><div><br /></div><div>What to do today?</div><div><br /></div><div>As always, I recommend starting with a baseline: <a href="http://www.freetypinggame.net/free-typing-test.asp">freetypinggame.net's 1-, 3- or 5-minute tests</a>. Then, continue the practicing you started.</div><div><br /></div><div>I've noticed that when I'm doing practices, I find it easy to stay on a single one until I've 'mastered' it. So, I might be practicing the home row keys and find that I have them down, but maybe I could do them faster. Don't worry about the speed, just move on to the next exercise. Remember, speed comes once the techniques are in place. </div><div><br /></div><div>As always, don't forget to intersperse your practice with fun! <a href="http://typeracer.com/">Typeracer.com</a> is a great way to reap the benefits of all that practice. I'm keeping the racetrack open at <a href="http://vurl.me/TEL">http://vurl.me/TEL</a>, so feel free to post a challenge on twitter with the hashtag #learn2typewk. If you are registered on the site, you can create your own track too and put out a private challenge.</div><div><br /></div><div>Just think, no matter what, if you participate, you will win! Huzzah! That's more than can be said for a lot of things.</div><div><br /></div>Corey Haineshttp://www.blogger.com/profile/06863615802688642075noreply@blogger.comtag:blogger.com,1999:blog-5378526953605921362.post-36045634348414154312010-07-13T10:15:00.004-04:002010-07-13T10:23:39.804-04:00Learn To Type Week - Day 2<div>(interested in what all the fuss is about? Read the <a href="http://programmingtour.blogspot.com/2010/07/learn-to-type-week.html">original post</a>)</div><div><br /></div><div>Good morning, everyone! I meant to have this up last night, but I misjudged my timing. Sorry to the people in Europe, already being long into the afternoon and all.</div><div><br /></div><div><b><span class="Apple-style-span" style="font-size:large;">Day 2!</span></b> I've been excited to see how much the response and participation from people for "Learn To Type" week. There are people who are trying to learn to touch-type for the first time, people working hard to overcome years of bad technique, people who are moving from QWERTY to Dvorak, and loads and loads of racing on <a href="http://typeracer.com/">typeracer.com</a>. But remember it isn't about your speed, it is about your technique. Speed will come, but technique and form is what we are practicing. Of course, everyone needs fun, so we meet on <a href="http://typeracer.com/">typeracer</a> for some balls-out typing competition.</div><div><br /></div><div>What to do today?</div><div><br /></div><div>I would recommend starting with a baseline on <a href="http://www.freetypinggame.net/free-typing-test.asp">freetypinggame.net's 1-, 3- or 5-minute tests</a>. Then, continue with the lessons you started yesterday.</div><div><br /></div><div>If you have started some lessons, continue them. How are you feeling on the home row? Move on to the lessons that include other parts of the keyboard. I would recommend you keep on the path you started yesterday, as those lessons are built for incremental learning.</div><div><br /></div><div>If you already touch-type, but are working on your form, then I highly recommend doing a few 5-minute tests on <a href="http://www.freetypinggame.net/">freetypinggame.net</a>; I like the <a href="http://www.freetypinggame.net/free-typing-test.asp">fairy tales</a>. My goal this week is to make it all the way through #26: the cobbler and the elves (not to be confused with the keebler elves).</div><div><br /></div><div>Don't forget to intersperse it with some fun. If you want to take a break, then head on over to <a href="http://typeracer.com/">typeracer.com</a>. I'll be keeping the <a href="http://vurl.me/TEL">coreyhaines track open</a>, so you should be able to use that as a primary meeting point if you want to race other "Learn To Type Week" participants. If you want to call some people into a game, you can post the shortened url http://vurl.me/TEL on twitter with the hashtag #learn2typewk; people might be up for a race. Otherwise, go on the open tracks and race away.</div><div><br /></div><div>And remember, it isn't about where you are today (no cries of 'I Suck!'), but about where you will be soon (only cries of 'I'm getting better!').</div><div><br /></div><div>Keep it up today!</div><div><br /></div>Corey Haineshttp://www.blogger.com/profile/06863615802688642075noreply@blogger.comtag:blogger.com,1999:blog-5378526953605921362.post-86839792126871709582010-07-11T21:26:00.003-04:002010-07-12T09:44:27.750-04:00Learn To Type Week - Day 1<div>As I wrote in my <a href="http://programmingtour.blogspot.com/2010/07/learn-to-type-week.html">last blog post</a>, tomorrow starts "Learn To Type Week." What does this mean? I encourage you to read that post to understand the motivation. For now, though, let's talk about this week. We had a lot of fun over the past couple days with typeracer.com, and I hope to keep having fun with it, but now starts the work for the week.</div><div><br /></div><div>I will be writing a blog post every night with some ideas and encouragement to keep you going through this week, spending 30 minutes a day working on your touch-typing. Are you already touch-typing? Maybe you want to spend the time improving your speed. Or, work on the top row (numbers/symbols).</div><div><br /></div><div>On Day 1, first thing, here's my recommendation: <a href="http://www.freetypinggame.net/free-typing-test.asp">go here</a> and do either a 1-, 3- or 5-minute test. If you are just starting to touch-type, then do the 1-minute test; if you are an experienced touch-typist, do the 5-miute. But here's the catch: do it with a piece of paper over your hands: no peeking! The key for this is not to do it quickly, but to do it with 0 mistakes. This is your real touch-typing speed. So, do it a couple times, if you want, until you are satisfied. This is what you are going to measure yourself against over the course of the week. After you do that, mark it down. Why not put it on twitter or your blog? Let's do this together, and we will be more likely to keep it up and encourage each other.</div><div><br /></div><div>Now, choose your typing lessons (I have some links on the original blog post, and you can always google for them) and start. Are you just learning to touch-type with home row? Then start going through the step-by-step tutorials. Are you an experienced home-row touch-typist wanting to get better? Maybe do the 5-minute typing test a couple times, interspersing a few trips to <a href="http://typeracer.com/">typeracer.com</a>. Go to <a href="http://www.freetypinggame.net/play.asp">this site and play some games</a>: what's your best score at <a href="http://www.freetypinggame.net/play15.asp">Keyboard Revolution</a>? Gotta Love The Duck!</div><div><br /></div><div>Tomorrow, we'll reconvene and do some more.</div><div><br /></div><div>And remember, this isn't about where you are now (no cries of 'I Suck!' only cries of 'I'm Getting Better!'), but where you are going to be, where you'll be in a week. So, try to make positive comments about your status. Believe me, it will help.</div><div><br /></div><div>Hashtag: #learn2typewk</div><div><br /></div>Corey Haineshttp://www.blogger.com/profile/06863615802688642075noreply@blogger.comtag:blogger.com,1999:blog-5378526953605921362.post-24750523531381282572010-07-07T17:53:00.011-04:002010-07-19T13:18:41.059-04:00Learn To Type Week!<div>(posts for the week:</div><div><a href="http://programmingtour.blogspot.com/2010/07/learn-to-type-week-day-1.html">Day 1</a></div><div><a href="http://programmingtour.blogspot.com/2010/07/learn-to-type-week-day-2.html">Day 2</a></div><div><a href="http://programmingtour.blogspot.com/2010/07/learn-to-type-week-day-3.html">Day 3</a></div><div><a href="http://programmingtour.blogspot.com/2010/07/learn-to-type-week-day-4.html">Day 4</a></div><div><a href="http://programmingtour.blogspot.com/2010/07/learn-to-type-week-recap.html">Recap</a></div><div>)</div><div><br /></div><div>As I've traveled around and programmed with a lot of different people, I've noticed a really frightening thing: in general, programmers don't type correctly. I'm not sure why this is, but it makes me sad. Most of the people I meet that don't touch type still can bang away a lot of words a minute, but if you watch their heads, it is like a bobbing robin, constantly looking down to see where their hands are. What a waste of motion and context switching.</div><div><br /></div><div>Typing is a fundamental skill for programmers. We spend our days manipulating text, so it makes sense that you should have it mastered. In a way, it would be like hiring a carpenter and seeing them flailing around with the screwdriver, missing the screw sometimes, maybe poking their finger. What would you think? That's how it looks when you are hunt-and-pecking. Embarrassing!</div><div><br /></div><div>So, I thought I would put a challenge out there: Learn To Touch Type! For the most part, you know where the keys are, it is just a matter of quieting your hands down and learning the home row position. I wager that, for most people, it would take about a week of daily 30-minute practices. A Pomodoro! That's all.</div><div><br /></div><div>In fact, why not do it next week, <i><b>July 12th - July 18th</b></i>. I declare next week to be "<i><b>Learn To Type Correctly</b></i>" week (hashtag: #learn2typewk)! If we do it as a community, supporting each other, then it is more likely that we'll shed the baggage of bad typing skills. Come on, you can do it! Blog about it, twitter about it, get the word out. Everyone will feel better, and imagine your pride when you sit down at a keyboard and don't ever have to look at your hands.</div><div><br /></div><div><i>But, Corey, </i>you say,<i> I thought typing wasn't the bottleneck.</i> No, it isn't, but ineffective typing can be. Having to look down at your hands disrupts your flow. When you can just let the words come out without thinking, you will be much more effective.</div><div><br /></div><div>There are plenty of online typing courses that you can use. Here's a couple I checked out:</div><div><br /></div><div><a href="http://www.powertyping.com/qwerty/lessonsq.html">http://www.powertyping.com/qwerty/lessonsq.html</a></div><div>This one is very structured, using extreme repetition to push the positions into your head. Try it out.</div><div><br /></div><div><br /></div><div><a href="http://www.freetypinggame.net/default.asp">http://www.freetypinggame.net/default.asp</a></div><div>This is one of my favorites. I'm not sure about the actual lessons, but the games are a lot of fun (I like Keyboard Revolution).</div><div><br /></div><div><br /></div><div><a href="http://www.goodtyping.com/default.htm">http://www.goodtyping.com/default.htm</a></div><div>This is a step-by-step lesson plan. You have to register, but it keeps rankings and lets you print out certificates.</div><div><br /></div><div><a href="http://www.typeracer.com/">http://www.typeracer.com</a></div><div>This is a fantastic site where you get into 'car races' against other online opponents. Think of the old horse-racing games at the carnival with the balls that you throw into holes to make your horse go. Now, instead of horses, think cars, instead of balls, think your keystrokes. (BTW: I'm Corey Haines or coreyhaines or coreyhaines@gmail.com on typeracer.com, if you want to friend me)</div><div><br /></div><div>This is just a short list. If you don't like them, feel free to use another.</div><div><br /></div>Corey Haineshttp://www.blogger.com/profile/06863615802688642075noreply@blogger.comtag:blogger.com,1999:blog-5378526953605921362.post-43784876060513640472010-04-02T11:16:00.009-04:002010-10-28T08:32:45.872-04:00Interview with J.B. Rainsberger and me<div>When we were in Romania, teaching a TDD class and facilitating a coderetreat, Maria and Alex sat down and asked us some questions. The first part includes some of <a href="http://vimeo.com/10372086">our thoughts on education and software craftsmanship</a>.<br />
<br />
[Update: The second part continues our discussion]<br />
[Update: The third part rounds out our discussion]</div><div><br />
</div><div>My favorite phrase: "Every 20-person software development team is a 6-person team trying to get out."</div><div><br />
</div><div>Note: Okay, okay, perhaps 'scourge of the industry' was a rough turn of phrase that I used. :)</div><div><br />
If you would like to get in touch with J.B., you can contact him from <a href="http://www.jbrains.ca/">J.B. Rainsberger</a>.</div><div>Enjoy!</div><div><br />
</div><div>Part I<br />
<br />
<object height="265" width="400"><param name="allowfullscreen" value="true"><param name="allowscriptaccess" value="always"><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=10372086&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=&fullscreen=1"><embed src="http://vimeo.com/moogaloop.swf?clip_id=10372086&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=&fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" height="265" width="400"></embed></object><br />
<a href="http://vimeo.com/10372086">Exclusive Interview in Bucharest with J.B. Rainsberger and Corey Haines - Part I</a> from <a href="http://vimeo.com/user3233384">Maria Diaconu</a> on <a href="http://vimeo.com/">Vimeo</a>.<br />
Part II</div><div><br />
</div><div><object height="265" width="400"><param name="allowfullscreen" value="true"><param name="allowscriptaccess" value="always"><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=10899877&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=00ADEF&fullscreen=1"><embed src="http://vimeo.com/moogaloop.swf?clip_id=10899877&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=00ADEF&fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" height="265" width="400"></embed></object><br />
<a href="http://vimeo.com/10899877">Exclusive Interview in Bucharest with J.B. Rainsberger and Corey Haines - Part II</a> from <a href="http://vimeo.com/user3233384">Maria Diaconu</a> on <a href="http://vimeo.com/">Vimeo</a>.</div><div>Part III<br />
<br />
</div><div><object height="265" width="400"><param name="allowfullscreen" value="true"><param name="allowscriptaccess" value="always"><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=10904638&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=&fullscreen=1"><embed src="http://vimeo.com/moogaloop.swf?clip_id=10904638&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=&fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="265"></embed></object><br />
<a href="http://vimeo.com/10904638">Exclusive Interview in Bucharest with J.B. Rainsberger and Corey Haines - Part III</a> from <a href="http://vimeo.com/user3233384">Maria Diaconu</a> on <a href="http://vimeo.com/">Vimeo</a>.<br />
<br />
</div>Corey Haineshttp://www.blogger.com/profile/06863615802688642075noreply@blogger.comtag:blogger.com,1999:blog-5378526953605921362.post-72083410504815164792010-03-24T11:11:00.010-04:002010-10-28T08:37:47.847-04:00J.B. Rainsberger - On CoderetreatSince these videos with <a href="http://www.jbrains.ca/">J.B. Rainsberger</a> were taken after facilitating the Bucharest coderetreat, I thought it appropriate that we spend some time talking about coderetreat. J.B. was a participant in the very first retreat in January of 2009 in Ann Arbor. Since then, we've both been at many of them, both participating and facilitating.<br />
<div><br />
</div><div>J.B. and I talk about the goals of <a href="http://www.coderetreat.com/">coderetreat</a>, how they've changed, what the future holds and what the benefits of them are. This is a great conversation about what is a fundamental technique for practicing basic software development principles.<br />
<br />
</div><div>If you would like to get in touch with J.B., you can contact him from <a href="http://www.jbrains.ca/">his website</a>.</div><br />
<div>Enjoy! And, as always, thoughtful comments are appreciated, blog posts are better! :)</div><div><br />
</div><div><span class="Apple-style-span" style="color: #645f5e; font-family: verdana, sans-serif; font-size: 10px; white-space: pre-wrap;"><object height="300" width="400"><param name="allowfullscreen" value="true"><param name="allowscriptaccess" value="always"><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=10405547&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=00ADEF&fullscreen=1"><embed src="http://vimeo.com/moogaloop.swf?clip_id=10405547&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=00ADEF&fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="300"></embed></object></span><br />
<span class="Apple-style-span" style="color: #645f5e; font-family: verdana, sans-serif; font-size: 10px; white-space: pre-wrap;"><a href="http://vimeo.com/10405547">CRT - JB Rainsberger - CodeRetreat</a> from <a href="http://vimeo.com/coreyhaines">Corey Haines</a> on <a href="http://vimeo.com/">Vimeo</a>.</span></div>Corey Haineshttp://www.blogger.com/profile/06863615802688642075noreply@blogger.comtag:blogger.com,1999:blog-5378526953605921362.post-46081711818983370382010-03-20T17:32:00.005-04:002010-03-20T17:38:01.629-04:00How to be a software craftsmanWhile in London, I gave a talk to the London Ruby Users Group (LRUG). This was a shortened version of the talk I did earlier in the day at QCon. It is about one of the essences of software craftsmanship: being a better developer and how that relates to the terms 'apprentice' and 'journeyman.' LRUG is hosted at Skills Matter, and they put the video of <a href="http://skillsmatter.com/podcast/ajax-ria/corey-haines-software-craftsmanship-terminology">my talk online</a>.<div><br /></div><div>Plus, bonus: definitive answer to the question of how to be a software craftsman!</div><div><br /></div><div>I had a great time talking to them, and it was very encouraging to see the number of hands that were raised when I asked how many people practiced test-driven development. Thanks to various influences, test-first and test-driven development are pretty common when you talk to people active in the ruby community.</div><div><br /></div><div>After the talk, we went to a bar. Thanks to everyone for the great conversations and ideas.</div>Corey Haineshttp://www.blogger.com/profile/06863615802688642075noreply@blogger.comtag:blogger.com,1999:blog-5378526953605921362.post-4703045396870440802010-03-20T10:04:00.013-04:002010-03-20T14:04:51.375-04:00Blaming your tools<p></p><p>This blog post "<a href="http://wisdomofhands.blogspot.com/2010/03/human-tool-intellectual-partnership.html">Human-tool intellectual partnership</a>" made me think on our own field. Here's some thoughts of mine.</p><p>As long as I've been around, I've heard people bring up the phrase "a poor craftsman blames his tools." With the rise in the software craftsmanship movement and the associated (oft-misrepresented/misunderstood/misapplied) terminology, this happens even more often.</p><p>When someone talks about how you are more productive with Rails than with some other frameworks, out comes the 'a poor craftsman blames his tools.'</p><p>When you talk about how using a dynamic language offers affordances and design possibilities that a static language, such as C# or Java, doesn't you can hear the cries of 'a poor craftsman blames his tools.'</p><p>How often would you see a professional, custom-furniture maker use a saw to pound in a nail, or use an awl to attach a screw. Could they pound in a nail with a saw? Sure, I bet they could. But they don't. They choose the right tool for the job. And therein lies the rub, I think: 'the right tool for the job.' Everyone has their favorite tool, but, for everyday work, I'm sure the furniture maker tries to keep their general toolset up-to-date, replacing older, less-effective versions of a tool with more productive ones. Having a manual screw-driver is great and very important for certain situations, but having an electric one can help tremendously when trying to be productive. A professional tends to have a whole slew of tools, used effectively at the right time.</p><p>Why do we, as programmers, have a tendency to defend our possibly old, less-effective tools. Personally, in the past, I've fallen into the trap where I made judgements about a new tool before giving it a real shot, assuming I understand it before I've given myself a chance to become familiar with at least the rudimentary subtleties. Perhaps I held to the belief that 'all tools are equal, it is just a matter of how you use them.' Over time, with experience in different realms, it becomes abundantly clear that this is patently false. Can you do most anything with any tool? Sure. Should you? No.</p><p></p><p>Does this mean that there is only ever one 'best tool for the job?' No, I'm not saying that. But, there are certainly a whole slew of tools/languages that are average-at-best with their appropriateness. Here's a statement: the more 'general-purpose' a language is, the worse it is for the majority of the tasks we use it for. This is why you see an significant increase in productivity in languages built on top of Ruby, such as Rails. They are fine-tuned to be effective and productive in a constrained set of tasks. This is why you often see people writing the solution to a problem in the language they wish they had, then implementing it in their underlying, general-purpose language.</p><p></p><p><b>Snarky comment</b>: ever notice how, in general, the people who like to chime in with 'a poor craftsman blames his tools' tend to be the ones who use crappy tools. :)</p><p>As always, thoughtful comments are appreciated. Blog posts are even better.</p><p></p>Corey Haineshttp://www.blogger.com/profile/06863615802688642075noreply@blogger.comtag:blogger.com,1999:blog-5378526953605921362.post-34139962167168484962010-03-16T20:16:00.004-04:002010-10-28T08:41:19.173-04:00J.B. Rainsberger - Value ObjectsAs part 2 (part 1 was <a href="http://programmingtour.blogspot.com/2010/03/jb-rainsberger-primitive-obsession.html">primitive obsession</a>) in the 3-part series of interviews that I had the opportunity to do with J.B. Rainsberger recently in Romania, we talk about the idea of value objects and identity.<br />
<br />
If you'd like to get in touch with J.B., you can contact him through <a href="http://www.jbrains.ca/">his website</a>.<br />
<br />
Enjoy! And, as always, comments are welcome, but blog post responses are welcome even more!<br />
<br />
<object height="300" width="400"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=9919802&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=00ADEF&fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=9919802&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=00ADEF&fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="300"></embed></object><br />
<a href="http://vimeo.com/9919802">JB Rainsberger - Value Objects</a> from <a href="http://vimeo.com/coreyhaines">Corey Haines</a> on <a href="http://vimeo.com/">Vimeo</a>.Corey Haineshttp://www.blogger.com/profile/06863615802688642075noreply@blogger.comtag:blogger.com,1999:blog-5378526953605921362.post-41119010499127082252010-03-09T07:33:00.005-05:002010-03-09T08:01:28.126-05:00Conversation with Gary Bernhardt<a href="http://twitter.com/garybernhardt">Gary Bernhardt</a> has a unique perspective, having spent significant time in both python and ruby development, as well as taking part in both communities. He spends a lot of time talking and writing about testing and design and their intersection on his blog, <a href="http://blog.extracheese.org/">Extra Cheese</a>.<br /><br />Gary did an i<a href="http://blog.extracheese.org/2009/11/refactoring_a_cyclomatic_complexity_script.html">ncredible refactoring screecast</a>, as well as his much-talked-about presentation at Northwest Python Day, called <a href="http://blog.extracheese.org/2010/02/python-vs-ruby-a-battle-to-the-death.html">Python vs Ruby: A Battle to the Death</a>.<br /><br />Gary organized the Seattle stop on my coderetreat tour 2010, and I made sure to get a chance to sit down and record a conversation with him. In this video, we meander a little bit, but focus primarily on some of the differences between the ruby and python communities, especially as it relates to testing habits and ideas.<br /><br />Enjoy! And please leave comments if you are so inclined. Blog post reactions on your own blog are also highly encouraged.<br /><br /><object width="400" height="300"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=9938700&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=00ADEF&fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=9938700&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=00ADEF&fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="300"></embed></object><p><a href="http://vimeo.com/9938700">Gary Bernhardt</a> from <a href="http://vimeo.com/coreyhaines">Corey Haines</a> on <a href="http://vimeo.com">Vimeo</a>.</p>Corey Haineshttp://www.blogger.com/profile/06863615802688642075noreply@blogger.comtag:blogger.com,1999:blog-5378526953605921362.post-23159243341260917402010-03-02T21:10:00.008-05:002010-03-02T21:27:49.911-05:00J.B. Rainsberger - Primitive ObsessionNote: I am in the process of working with the 5by5 network to begin a regular video and audio podcast. This podcast will contain the bulk of the interviews and videos that I'll be doing while I travel around on the <a href="http://www.coderetreat.com/">coreyhaines coderetreat tour 2010</a>. Until the details have been sorted out, I will be posting them on this blog, similar to how I did last year. fI you are new to the interviews, please check the archives of this blog to see other great content.<br /><br />While in Romania, facilitating the <a href="http://www.coderetreat.com/">Bucharest Coderetreat</a>, I had the opportunity to teach a Test-Driven Development class with <a href="http://www.twitter.com/jbrains">J.B. Rainsberger</a>. We've talked about teaching together for many years, and I'm honored to have finally had the opportunity. If you have watched the videos that I did last summer with J.B., you'll know that he has an amazing amount of experience and insight into the development process. He has an ongoing blog called '<a href="http://blog.thecodewhisperer.com/">The Code Whisperer</a>,' which has consistently thought-provoking content on design, testing and other coding techniques. If you haven't watched them, I urge you to look through the archives for them, as his thoughts on test-driven development are enlightening.<br /><br />Whenever I have time with J.B., I do my best to get some videos recorded with him covering whatever might be of interest to us at the time. This past opportunity was a goldmine, as, not only did I get 3 videos, but we also used ustream to live-stream the interviews. While I was copying onto my computer, J.B. was kind enough to do impromptu Q&A sessions with the people viewing.<br /><br />This is the first of those video interviews, focusing on the often-mentioned, more-often-misunderstood topic of 'Primitive Obsession' in design.<br /><br />Enjoy! As always, constructive feedback is welcomed in the comments. If you are so inclined, please write a blog post with your thoughts.<br /><br />Coming next week: <a href="http://www.twitter.com/garybernhardt">Gary Bernhardt</a> discusses some of the differences between the ruby and python cultures.<br /><br /><object width="400" height="300"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=9870277&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=00ADEF&fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=9870277&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=00ADEF&fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="300"></embed></object><p><a href="http://vimeo.com/9870277">JB Rainsberger - Primitive Obsession</a> from <a href="http://vimeo.com/coreyhaines">Corey Haines</a> on <a href="http://vimeo.com">Vimeo</a>.</p>Corey Haineshttp://www.blogger.com/profile/06863615802688642075noreply@blogger.comtag:blogger.com,1999:blog-5378526953605921362.post-49444166903306636142010-02-15T11:51:00.009-05:002010-02-15T15:26:36.462-05:00Please Help - CodeRetreat Tour Videos<div><span class="Apple-style-span" style="font-size: x-large;">THANKS:</span></div><div><span class="Apple-style-span" style="font-size: x-large;"></span><a href="http://twitter.com/danbenjamin">Dan Benjamin</a> of <a href="http://5by5.tv/">5by5.tv</a> is going to help me out. Thanks to everyone who has contacted me to see if they can help. It is really flattering when the community out there is interested in helping.</div><div><br /></div><div>I'll let everyone know how it goes, and I'll be writing up a guide when I'm finished.</div><div><br /></div><div><br /></div><br /><hr /><br /><div><br /></div>As I'm traveling around this year on the coreyhaines coderetreat tour 2010, I'll be doing video interviews with people I meet. These will be very similar to the videos that I did during the 2008/2009 pair-programming tour. Already, I have an interview with Gary Bernhardt about the testing cultures in Ruby and Python, as well as several videos with J.B. Rainsberger, talking about such topics as primitive obsession, why inheritance is bad, value types and other random things. And these are just during the first two code retreats!<div><br /></div><div>During the previous tour, I simply put the videos up here on the blog, embedded via vimeo. Throughout the year, people were always asking for a podcast format, providing both an audio and a video component, so people could listen in the car, working out, while knitting, etc. I agree this is a great idea, but I haven't taken the time to really figure out how to do it. People tell me it is easy these days, but I'm currently at the ignorant end of 'everything is easy once you have someone show you how to do it.' As an example, the current 15-minute video that I'm trying to upload rendered out at 835M! That takes hours to upload. I don't know what compression I'm not setting that causes this. I'm a sad panda. </div><div><br /></div><div>I'm putting out a request for help. I know there are a lot of people out there who have successful podcasts with audio and video parts. I'm hoping that someone will be willing to take a few hours over the next week, or so, to help me set up my environment to do this effectively. My video editing needs are small, as I intentionally leave the videos with little editing, focusing more on the impromptu, conversational aspects of the interview.</div><div><br /></div><div>Here are the main things I don't know how to do effectively or at all:</div><div><ul><li>Render a video (with iMovie or Quicktime) that is good quality and small enough to upload without taking what feels like a million hours;</li><li>Effectively strip out the audio from the movie;</li><li>Set up a podcast for the audio version;</li><li>Set up a podcast for the video version;</li><li>Get podcasts into iTunes;</li><li>Create a process for effectively updating the podcasts;</li><li>Anything else I should know how to do.</li></ul></div><div>Wow, I sure don't ask for a lot.</div><div><br /></div><div>I am looking for someone who would volunteer their time to help me do all this. Once I know how to do all these steps, I can do them going forward; I would rather have someone teach me how to do this, rather than continue to stumble around.</div><div><br /></div><div>As a way to say thank you, I will do two things:</div><div><ul><li>Credit you as a the person who helped me figure all this out;</li><li>Write a guide / do a screencast on how we did it, so others can have the step-by-step instructions.</li></ul></div><div>Note: I'm on a mac, so experience on that platform/toolset would be necessary. I currently have iMovie, Quicktime Pro and Camtasia.</div><div><br /></div><div>If you can help me, please email me at coreyhaines@gmail.com. I'd like to get all this done over the next week, so I can start pushing these videos up.</div><div><br /></div><div>Thanks in advance.</div><div> </div><div> </div>Corey Haineshttp://www.blogger.com/profile/06863615802688642075noreply@blogger.comtag:blogger.com,1999:blog-5378526953605921362.post-62789614304369968952010-02-11T04:12:00.003-05:002010-02-11T04:14:42.952-05:00Just a reminder<div style="text-align: center;"><span class="Apple-style-span" style="font-size: x-large; ">Remember!</span></div><div><br /></div><div style="text-align: left;"><table style="width:auto;"><tr><td><a href="http://picasaweb.google.com/lh/photo/TAodTbsr9hAP6i7-1RSUKA?feat=embedwebsite"><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9KcwL-ul8H6d58gFd1E7ciiT-hpoStA6F-mGw8KYXqDFMW_IN_uhJ0j8zn3tJuXhWFRAt5IJC4dGhqsO_BaG5cczGO1nfelc4bCv4rlfAIoziuxw3EIOJmRmieoZtFflafCU9z7BpyrY/s400/motivatord340904b0496385ae59593063d970e091b838a6c.jpg" /></a></td></tr><tr><td style="font-family:arial,sans-serif; font-size:11px; text-align:right">From <a href="http://picasaweb.google.com/coreyhaines/Miscellaneous?feat=embedwebsite">Miscellaneous</a></td></tr></table></div>Corey Haineshttp://www.blogger.com/profile/06863615802688642075noreply@blogger.com