<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Object Mentor Blog: Category Schuchert's Scattered Synapses </title>
    <link>http://blog.objectmentor.com/articles/category/schuchert%27s-scattered-synapses</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description></description>
    <item>
      <title>Working on C++ Book Again</title>
      <description>&lt;p&gt;Picked up working on a book on C++. It&amp;#8217;s freely available (as I work on it) and a &lt;span class="caps"&gt;PDF&lt;/span&gt; is available &lt;a href="http://schuchert.wikispaces.com/cpptraining.CppAndOodTheLeastYouNeedToKnow"&gt;here&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Wed, 03 Aug 2011 18:56:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:5e8ace45-ffaa-449f-9813-73061ed1e77c</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2011/08/03/working-on-c-book-again</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>cpp</category>
      <category>TDD</category>
      <category>ood</category>
    </item>
    <item>
      <title>Bamboo reminds me of a time when...</title>
      <description>&lt;p&gt;I needed to do some yard work. It&#8217;s nearly always windy in Oklahoma where I live, so when I got up Friday morning I noticed a distinct lack of wind and thought it would be a good idea to get started on the yard work. I was tired of getting dust, dirt and other unmentionable things in my eyes and ears and nose.&lt;/p&gt;


	&lt;p&gt;Things started as normal, but since I got started so early I took the time to clean up the west side of the house. Then I managed to rake and clean up a bit more. I pulled some weeds. Much of the work I did was not visible most of the time but it bothered me just a little. Then I got to the part of the job that was visible. I took a little extra time raking, sweeping, mowing, etc. I was &#8220;done&#8221; earlier than I had expected and then I made a crucial decision, it was time to take care of the bamboo.&lt;/p&gt;


	&lt;p&gt;3 years ago I planted an 8 foot by 2 foot plot of bamboo. When I did that I dug down 2 feet into the ground. Not knowing how to dig like a professional, it took me a long time &amp;#8211; total planting time was 13 hours. 32 cubic feed of dirt and clay takes a lot of work to remove. I needed to dig so deep to put a protective lining around the bamboo. There are two kinds of bamboo you might plant. One kind stays in clumps and doesn&#8217;t invade everything. That&#8217;s not the kind I planted. I plated the kind that takes over. Thus, I needed to dig 2 feet into the ground and surround the bed with a thick plastic lining. I did all the prep work but then I decided I would let it move into my yard but not into the neighbor&#8217;s yard. So I left the front of the bed open.&lt;/p&gt;


	&lt;p&gt;Fast forward 3 years and notice that the bamboo moved more quickly than I imagined. I&#8217;ve been meaning to get to this outside job, but I&#8217;ve managed to put it off. I decided to dig a 2-foot deep trench in the front of the bed and add in the missing plastic lining. It took me about 6 hours. Here it is two days later and my hands and forearms are still quite sore. Much of the digging at the top was easy, but as I got deeper, the digging got more difficult. Then I hit clay. That was even worse. I really didn&#8217;t have the right tool for the job. I needed a trench digger, but I had a regular shovel, a gardening shovel and a standard spade. These were ok at the top but not as I worked deeper into the ground.&lt;/p&gt;


	&lt;p&gt;Finally, needing a break, I went to buy more lawn supplies including: pete moss, top soil, steaks, fencing, grass seed, lime, oh, and a 4 inch trench digger.&lt;/p&gt;


	&lt;p&gt;I was about 20 inches into the ground. The last inch had cost me plenty. The 2 inch bruise on the palm of my right hand (yes, I wore gloves) is one example. That last inch took me maybe an hour. 4 more inches would take me longer than another 4 hours. The trench digger, however, made it more like 15 minutes.&lt;/p&gt;


	&lt;p&gt;When I started digging I knew I needed to start wider at the top because the trench would naturally get narrower as I worked my way into the ground. This might not be the case if either a: I knew what I was doing, or b: I had the right tools for the job. So I started much wider than &#8220;necessary&#8221; to give me a little slack later.&lt;/p&gt;


	&lt;p&gt;That decision was key. Even though I eventually bought the right tool for the job, a 4 inch trench digger, if the trench was too narrow to use it, then I still would have been out of luck. So this decision made it possible for me to use the right tool later.&lt;/p&gt;


	&lt;p&gt;I managed to finish the trench, line the bed, replace the soil and then get about 100 square feet of yard reseeded.&lt;/p&gt;


	&lt;p&gt;Other than sore muscles, bruises and the satisfaction of getting something off my well-aged to-do list, what other take aways do I have from this experience?&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Adoption of best practices&lt;/li&gt;
		&lt;li&gt;Leave a little slack&lt;/li&gt;
		&lt;li&gt;Right tool for the job&lt;/li&gt;
	&lt;/ul&gt;


&lt;h2&gt;Adoption of Best Practices&lt;/h2&gt;

	&lt;p&gt;(There&#8217;s a great story of a manager of a Coca-cola plant who&#8217;s numbers were far better than his peers. When asked what his &#8220;secret&#8221; was, he said simply that rather than take a best practice and modify it to meet what the plant did, he instead modified the plant to match the best practice. His secret was not trying to be too clever.&lt;/p&gt;


	&lt;p&gt;I knew that I should have lined the bed three years ago. I knew that bamboo can spread. There was a well-established best practice on planting bamboo. It was easy to follow. I had everything I needed to follow the practice. I had a 2 foot deep hole just begging to be fully lined. I thought I was more clever (not build here syndrome anybody?) and decided to just line the back of the bed. So 3 years later I managed to spend 6 hours doing something that would have been an additional 5 minutes. If I had just followed the best practice recommended by people who were experts, I would have avoided most of the work I did and all of the bruises, scratches, etc. But I was far too smart to follow the recommendation of someone with real experience.&lt;/p&gt;


	&lt;p&gt;The best practice when adoption best practices is to adopt the best practice. If you decide to modify a best practice to your local conditions before having direct experience with the practice, the very problems that lead you to consider adopting the practice may be the same thing that will mange to remove all the teeth out of the best practice.&lt;/p&gt;


	&lt;p&gt;Does this mean you don&#8217;t adapt the practice? No. It just means you need to fully understand the practice and more importantly what are its intentions before you start to modify it. When you have direct experience with it, that, coupled with the knowledge of your current challenges, might give you a better chance of coming up with something that works even better. Or, you might just keep with the practice as is.&lt;/p&gt;


	&lt;p&gt;I had another recent experience with this regarding Uncle Bob&#8217;s &lt;span class="caps"&gt;TPP&lt;/span&gt; (http://cleancoder.posterous.com/the-transformation-priority-premise). From my reading of his example, he also practiced &lt;span class="caps"&gt;TDD&lt;/span&gt; as if you mean it (http://gojko.net/2009/08/02/tdd-as-if-you-meant-it-revisited/). I talked to him about this and sure enough he confirmed it. I was working on a &#8220;known&#8221; problem, a kata. I resisted doing what he had done because it wasn&#8217;t what I had done in the past. I even recognized this and mentioned it to him. I decided to just see what happens. Well I ate crow that evening because when I did it, the kata moved quite smoothly for me. In fact, better than it had in the past. It didn&#8217;t require as much planning ahead.&lt;/p&gt;


	&lt;p&gt;What can you do about this? If you can figure out how you tend to resist change, and then notice when you are doing so, you might be able to just work through it. In my case I could tell I was resisting change rather than rejecting the idea &amp;#8211; if I slow down a bit and just pay attention I can make that determination, something I learned from practicing Yoga. As for how you can start to learn this, here&#8217;s one exercise you could try (http://schuchert.wikispaces.com/AlternatingHandGripExercise). Another idea is to try Yoga. Or, try pausing whenever you find yourself resisting something and ask yourself the question: am I resisting the idea or change. If you&#8217;re not sure, then give it a try (and assume you&#8217;re resisting the change).&lt;/p&gt;


&lt;h2&gt;Leave a Little Slack&lt;/h2&gt;

	&lt;p&gt;I stared digging by marking a line where I wanted to put the new edge. I then dug a shallow trench about a foot wide. The extra width was to give me enough room to work. While it might seem like more work at first, in fact it gave me enough rom to move around, attack the dirt at different angles and I used the &#8220;extra&#8221; dirt to fill a hole dug by my dogs in the bamboo (I hope it recovers).&lt;/p&gt;


	&lt;p&gt;As I got deeper, I used different kinds of shovels, and the trench became narrower because of the angle I was using to dig, which was related to the tools I used. When I finally hit clay, the larger shovels were too hard to work with both because of the angle but also because of the density of the clay and the amount I was trying to move. I started using a hand-shovel for gardening.&lt;/p&gt;


	&lt;p&gt;When I bought the right tool it was possible to use because there was enough room for it. Unlike the other shovels that are 10 inches wide or wider, this one was 4 inches wide. It worked perfectly. I was able to take out about 1 &amp;#8211; 2 inches laterally and 3 &amp;#8211; 4 inches deep at a time. While it might seem like slow going, it was blazing fast compared to my previous attempts.&lt;/p&gt;


&lt;h2&gt;Right Tools&lt;/h2&gt;

	&lt;p&gt;Growing up on a farm in Iowa, my dad often reminded me of the idea of using the right tool for a job. You might be able to use another tool, but if you use the right tool for the job, it will just go smoother.&lt;/p&gt;


	&lt;p&gt;My wife bough a few pruning tools last fall. One in particular was much nicer than I might have bought. In the past I would just use the shovel to try and break the roots. This, as you might imagine, is hard work. It will eventually work, but as the roots get bigger, the work grows at least by the square of the diameter (the difficulty felt NP hard (grin) but that&#8217;s because I don&#8217;t do this work on a regular basis). When I started the trench this time, I used that tool instead of the shovel. To be sure, it required a touch more work. I had to find it in the garage (it was where I though it would be), I had to carry it to the back yard. When I finished the job I had to put it away.&lt;/p&gt;


	&lt;p&gt;However, it was exactly the right thing to cut the roots that I came across. Trying to use a shovel to cut those roots in the past versus using a proper pruning tool is a great way to have a kinesthetic experience on the use of the right tool for the job.&lt;/p&gt;


	&lt;p&gt;As I used the pruning tool, I was reminded of this &#8220;right tool for the job.&#8221; When I took a break to buy more stuff to do more work on the yard, I looked for and found the trench digger. It was a bit expensive. I&#8217;ll probably use it for this one job and never again. Even so, within 2 minutes of using it, I did not regret the money spent versus the time saved. This initial impression was confirmed when I moved so much more quickly than I had been moving in more difficult situations. If I never use that tool again it was still the right thing for me to do. If I ever need to dig a trench again, I&#8217;m ready for it.&lt;/p&gt;


	&lt;p&gt;The danger is that you buy a tool for the problem you think you have but while it solves the apparent problem, the actual problem is something else. Case in point, scripting tools for ui-based checking.&lt;/p&gt;


	&lt;p&gt;I am not against using scripting tools, far from it. However, the secret of checking the UI is to design the code so that most of the logic is unit checkable (http://schuchert.wikispaces.com/tdd.Refactoring.UiExample). The scripting tool seems to be solving the problem of manual checking but that&#8217;s a surface problem. A well-design system makes it possible to easily look at it in ways that let you know if it works as expected. We&#8217;re used to thinking about headless checking, but what about body-less checking?&lt;/p&gt;


&lt;h2&gt;Conclusion&lt;/h2&gt;

	&lt;p&gt;Everything is related to everything else, right? Old habits die hard. Insert your favorite cliche here. In a sense, that&#8217;s all I&#8217;m really saying.&lt;/p&gt;


	&lt;p&gt;I wonder if working with software allows me to figure these things out more quickly &amp;#8211; or at least with less physical pain &amp;#8211; or if in fact doing so makes me take longer? I became test infected in 1997. Before that I wrote code to test my code, but I did not keep it around as a living artifact. On the surface it appears to take more time and effort, but in practice doing so pays dividends.&lt;/p&gt;


	&lt;p&gt;Moving to practicing &lt;span class="caps"&gt;TDD&lt;/span&gt; came later. When I started trying out &lt;span class="caps"&gt;TDD&lt;/span&gt;, I though it was a bit silly. When I originally read an article about Inversion of Control (http://martinfowler.com/articles/injection.html), I though &#8220;meh.&#8221; When I was originally shown Mozilla 0.8, I though &#8220;hyper cards over gopher net, meh.&#8221; In fact, I can almost predict the viability of a technological idea as the inverse of my initial impression to it.&lt;/p&gt;


	&lt;p&gt;The cost of being wrong isn&#8217;t too bad if, as I often do, change my mind with evidence. In the case of physical labor &amp;#8211; planing bamboo &amp;#8211; the real physical pain of doing it poorly has a much more real feeling consequence and maybe works better for me as a way to reinforce things I already know.&lt;/p&gt;


	&lt;p&gt;When you work do you leave a little slack? Do practices like &lt;span class="caps"&gt;TDD&lt;/span&gt; give you a little slack? When you follow those practices, do you try to get a &#8220;pure&#8221; experience before adapting or do you adapt from the beginning? Are you using effective tools to solve your actual problems or do you notice tools that solve an apparent problem but simply introduce worse problems than the one they were originally meant to solve?&lt;/p&gt;</description>
      <pubDate>Tue, 24 May 2011 10:53:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:3b4bd450-c568-4119-8d22-a4df3d374039</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2011/05/24/bamboo-reminds-me-of-a-time-when</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>best</category>
      <category>practices</category>
      <category>adopting</category>
      <category>tools</category>
      <category>TDD</category>
    </item>
    <item>
      <title>A Gradle Example</title>
      <description>&lt;p&gt;Gradle is a build tool. Even though it is younger than Maven, I really like it and it shows decent maturity. Here&amp;#8217;s one example of getting started using it: &lt;a href="http://schuchert.wikispaces.com/gradle.GettingStarted"&gt;http://schuchert.wikispaces.com/gradle.GettingStarted&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Tue, 24 May 2011 10:31:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:cd93dee4-aa1b-4a3c-8b68-e9cda39a6c26</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2011/05/24/a-gradle-example</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>build</category>
      <category>gradle</category>
    </item>
    <item>
      <title>New century, old mistakes</title>
      <description>&lt;p&gt;In the early 90&#8217;s, I taught classes in Object-Oriented Analysis and Design, as well as just Object Oriented Design and Programming in C++ and Smalltalk (Java didn&#8217;t exist yet). I got burnt out teaching both kinds of classes for different reasons.&lt;/p&gt;


	&lt;p&gt;The language classes were tough &#8211; more C++ than Smalltalk, because there was so much detail and I wanted to cover too much &#8211; notice the classic error that the instructor&#8217;s opinion is relevant to learning. Both classes were hard, though, because getting the ideas of Object Orientation across in addition to learning a language and an environment (in the case of Smalltalk) was a lot. That, coupled with a lack of discipline in not using some kind of unit testing framework was tough. (This last observation is based on my current observations of teaching similar language classes versus what I used to do last century.)&lt;/p&gt;


	&lt;p&gt;I have fewer problems with that these days: First, I don&#8217;t try to cover it all. I just try to cover some of language highlights. More importantly, using a unit test framework makes it easy to experiment.&lt;/p&gt;


	&lt;p&gt;On the &lt;span class="caps"&gt;OOAD&lt;/span&gt; front, the problem I used to have was trying to &#8220;help&#8221; the students by pointing out mistakes ahead of time, so they wouldn&#8217;t suffer the same mistakes I&#8217;ve made. That was fundamentally wrong on my part, well intended, but just flat-out wrong.&lt;/p&gt;


	&lt;p&gt;People need to see mistakes and even make mistakes to move forward. I&#8217;ve personally learned probably most of what I know based on either making mistakes or observing other mistakes &#8211; ones I would have committed myself if my customers had not already done so themselves &amp;#8211; thank you for that.&lt;/p&gt;


	&lt;p&gt;I&#8217;ve recently discovered myself making this same mistake again. In this case it has to do with enforcing code coverage to get people to write tests. I used to think this was a bad idea, and maybe it is, but even bad ideas can have utility &amp;#8211; context, context, context.&lt;/p&gt;


	&lt;p&gt;How can this possibly be a bad idea? Well when this happens, developers tend to write tests with few checks that are heavily implementation-oriented. If the production code is written first, which is more common, it often has high path (cyclomatic) complexity. What ends up happening is developers write complex production code for many &#8220;just in case&#8221; scenarios, the code has many paths, they are told to get 80% coverage and so they write tests to verify that all the paths of their code have been executed.&lt;/p&gt;


	&lt;p&gt;Of course, how many of those paths are essential versus incidental isn&#8217;t typically considered. Since the tests are written to drive coverage, and the underlying code is probably overly complex, the tests tend to be heavily implementation-oriented rather than intention oriented (or scenario-based). The tests are hard to write, harder to read and even worse to maintain.&lt;/p&gt;


	&lt;p&gt;So up to a few months ago, my advice was to not enforce coverage. But a great theory is often destroyed by data. I&#8217;ve had 2 customers recently enforce code coverage on new development. Both of them experienced something like what I expect would happen. They implemented coverage standards, implementation-oriented tests got written and developers were having problems with writing unit tests. However, something else more important happened. Even though the tests were hard to maintain, many of the developers started to get test infected. That is, they started to be convinced that writing unit tests was valuable and now they needed to know how to do that more effectively; rather than this being the destination, it was a step in an ongoing journey. (Another example of a mistake I make, confusing a process for one of its events.)&lt;/p&gt;


	&lt;p&gt;To me, someone who is writing tests, thinks they are useful and is now ready to learn how to write them more effectively is easier to work with than someone who has not written tests, don&#8217;t think they add value and certainly are not their responsibility.&lt;/p&gt;


	&lt;p&gt;So it appears this &#8220;bad practice&#8221; has merit as an intermediate step in a longer learning arc.; one possible path through the murky testing waters. Did I make these kinds of mistakes? I&#8217;ve never been in a situation where I was told to have some % coverage, so not exactly. However, have I written implementation-oriented tests? Yes. Have I written tests with few or no checks? Yes. I still do sometimes, but much less so than in the past. Just now I do so consciously rather than out of a lack of options.&lt;/p&gt;


	&lt;p&gt;As I see it, I committed several mistakes I&#8217;ve made in the past. First, trying to &#8220;help&#8221; people by giving advice which would allow them to avoid mistakes I&#8217;ve made in the past. Maybe those mistakes are a necessary rite of passage for some people. Another mistake I made was thinking of the learning experience as an event rather than a process. Finally, while I might be tangentially involved, ultimately someone else&#8217;s learning is their learning, not mine. They need to do what they need to do. I need to be available if necessary, but otherwise keep my agenda out of it!&lt;/p&gt;


	&lt;p&gt;Take in the context of a class, learning really doesn&#8217;t stop after a &lt;span class="caps"&gt;TDD&lt;/span&gt; class, or coaching. Some might argue that learning doesn&#8217;t start &lt;span class="caps"&gt;UNTIL&lt;/span&gt; the &lt;span class="caps"&gt;TDD&lt;/span&gt; class is over &#8211; I could make that argument myself. In any case, I was looking at my involvement as &#8220;the learning event&#8221;. As I write this, I realize just how insane that really is. I wasn&#8217;t aware of my mental model until recently; now that I am hopefully I can fundamentally change how I approach this situation going forward.&lt;/p&gt;


	&lt;p&gt;What are some other &#8220;don&#8217;t do&#8217;s&#8221; you&#8217;re aware of that make sense in the context of a process, but not as an end or goal?&lt;/p&gt;</description>
      <pubDate>Wed, 19 Jan 2011 15:13:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:cfe434ea-24c9-4d80-a708-2952ddace567</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2011/01/19/new-century-old-mistakes</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>TDD</category>
      <category>training</category>
      <category>learning</category>
      <category>education</category>
      <category>event</category>
      <category>process</category>
    </item>
    <item>
      <title>Tdd for the iPhone: Continued</title>
      <description>&lt;p&gt;After a week in Israel and the UK, I got back to this series. I&amp;#8217;ve switched to using XCode 4, but as it is not officially released, the videos I recorded using it were a bad idea to upload.&lt;/p&gt;


	&lt;p&gt;Back to XCode 3: &lt;a href="http://www.vimeo.com/album/1472322"&gt;http://www.vimeo.com/album/1472322&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Mon, 22 Nov 2010 00:45:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:4aab9cfc-47ab-484a-a981-990347659e29</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/11/22/tdd-for-the-iphone-continued</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>TDD</category>
      <category>iphone</category>
      <category>xcode</category>
      <category>refactoring</category>
    </item>
    <item>
      <title>iPhone and Tdd: The Video Series Begins</title>
      <description>&lt;p&gt;&lt;a href="http://www.vimeo.com/album/1472322"&gt;http://www.vimeo.com/album/1472322&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Title says it all. Well, I&amp;#8217;ll add that this was take #20 (or so). It&amp;#8217;s rough getting back in to video recording mode. I will do more in this series.&lt;/p&gt;


	&lt;p&gt;And I barely know Objective-C, so as the series progresses, I&amp;#8217;ll expect some help on better practices.&lt;/p&gt;</description>
      <pubDate>Thu, 11 Nov 2010 02:03:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:db408603-c72d-4977-a3ed-46803ef9c829</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/11/11/iphone-and-tdd-the-video-series-begins</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>TDD</category>
      <category>objectivec</category>
      <category>xcode</category>
      <category>getting</category>
      <category>started</category>
      <category>video</category>
    </item>
    <item>
      <title>Info Please: Tdd and Pair Programming</title>
      <description>&lt;p&gt;I often get asked to provide background materials on &lt;span class="caps"&gt;TDD&lt;/span&gt; and Pair Programming.&lt;/p&gt;


	&lt;p&gt;Here are a few I often cite, but can you point me to some more? Are there any that you particularly like/dislike?&lt;/p&gt;


	&lt;p&gt;I would like both for and against. I prefer research or experience rather than rants, though if the rant is funny&amp;#8230;&lt;/p&gt;


	&lt;p&gt;Thanks!&lt;/p&gt;


	&lt;p&gt;&lt;del&gt;&amp;#8212;&lt;/del&gt;&lt;p/&gt;
(This is taken from a recent email I sent.)&lt;/p&gt;


&lt;h2&gt;Start Here&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Pair_programming"&gt;http://en.wikipedia.org/wiki/Pair_programming&lt;/a&gt;&lt;/ul&gt;&lt;/li&gt;

	&lt;p&gt;Good overview and sites studies.&lt;/p&gt;


&lt;h2&gt;Then here&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://accu.org/index.php/journals/1395"&gt;http://accu.org/index.php/journals/1395&lt;/a&gt;&lt;/ul&gt;&lt;/li&gt;

Here&amp;#8217;s a good Snippet from that site:
&lt;blockquote&gt;
&lt;span class="caps"&gt;A 1975&lt;/span&gt; study of &amp;#8220;two-person programming teams&amp;#8221; reported a 127% gain in productivity and an error rate that was three orders of magnitude less than normal for the organization under study. [Crosstalk]
&lt;/blockquote&gt;

&lt;h2&gt;Pairing in Education&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.89.6834&amp;#38;rep=rep1&amp;#38;type=pdf"&gt;http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.89.6834&amp;#38;rep=rep1&amp;#38;type=pdf&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;h2&gt;Other Articles&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.stsc.hill.af.mil/crosstalk/2003/03/jensen.html"&gt;http://www.stsc.hill.af.mil/crosstalk/2003/03/jensen.html&lt;/a&gt;&lt;/ul&gt;&lt;/li&gt;</description>
      <pubDate>Tue, 09 Nov 2010 08:58:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:bcc270bf-5c58-4c7e-af9d-074346d38282</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/11/09/info-please-tdd-and-pair-programming</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>request</category>
      <category>for</category>
      <category>information</category>
      <category>TDD</category>
      <category>pairing</category>
      <category>pair</category>
      <category>programming</category>
    </item>
    <item>
      <title>iPhone Development with Unit Testing</title>
      <description>&lt;p&gt;I&amp;#8217;m finally getting back to iPhone development. The environment is taking some getting used to and it took me some time to get to a reasonable working environment.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;m starting to document that. I plan to have both written and video tutorials. For now, I&amp;#8217;ve got some rough notes put together. Have a look and feedback is appreciated:
&lt;a href="http://schuchert.wikispaces.com/iPhone.SettingUpTheEnvionment"&gt;http://schuchert.wikispaces.com/iPhone.SettingUpTheEnvionment&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Tue, 09 Nov 2010 03:08:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:23073f38-8101-423a-a2b5-be8dc73b9fe0</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/11/09/iphone-development-with-unit-testing</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>TDD</category>
      <category>objectivec</category>
      <category>xcode</category>
      <category>getting</category>
      <category>started</category>
    </item>
    <item>
      <title>CPP And OOD: The Least You Need To Know</title>
      <description>&lt;p&gt;I&amp;#8217;ve put what I&amp;#8217;ve been writing up, available for free. Not sure if I&amp;#8217;ll ever try to get it published dead-tree form.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://schuchert.wikispaces.com/cpptraining.CppAndOodTheLeastYouNeedToKnow"&gt;http://schuchert.wikispaces.com/cpptraining.CppAndOodTheLeastYouNeedToKnow&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Feedback appreciated.&lt;/p&gt;


	&lt;p&gt;Have a great weekend.&lt;/p&gt;</description>
      <pubDate>Fri, 08 Oct 2010 16:34:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:269b7430-05c9-47b5-b652-57187d67dd59</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/10/08/cpp-and-ood-the-least-you-need-to-know</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>cpp</category>
      <category>c</category>
      <category>ood</category>
    </item>
    <item>
      <title>Quick Intro To BDD Style Table Syntax</title>
      <description>&lt;p&gt;Here it is a over a year after I wrote several FitNesse tutorials. Several months back Bob added some new ways to write scenarios using a placeholder syntax and an alternative way to render script tables. What you end up with is something just a little less table-like.&lt;/p&gt;


	&lt;p&gt;This is a very quick and dirty writeup I&amp;#8217;ve been meaning to put together for nearly half a year. So while it&amp;#8217;s not pretty, it works, shows the basics and may make you aware of something you didn&amp;#8217;t know was there &amp;#8211; unless you&amp;#8217;ve been reading the release notes.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://tinyurl.com/2wfyxyb"&gt;Alternative Script Table Syntax&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Comments and requests welcome.&lt;/p&gt;


	&lt;p&gt;Brett&lt;/p&gt;</description>
      <pubDate>Tue, 21 Sep 2010 23:54:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:01018108-8559-40bc-a148-792a6ad26482</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/09/21/quick-intro-to-bdd-style-table-syntax</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>script</category>
      <category>Tables</category>
      <category>alternative</category>
      <category>syntax</category>
      <category>FitNesse</category>
      <category>bdd</category>
      <category>slim</category>
    </item>
    <item>
      <title>Selection of tools for otherwise free content, Your Opinion</title>
      <description>&lt;h1&gt;The Question&lt;/h1&gt;
Should I be concerned that free content I release on my wiki, or the videos I release, use paid-for tools?&lt;p/&gt;

	&lt;p&gt;I expect people will also answer a secondary question: which tool I should use for Ruby. I&amp;#8217;m interested in that as well, however my primary question is the general one of whether I should stick to free tools for the free content I release.&lt;/p&gt;


&lt;h1&gt;The Background&lt;/h1&gt;
I&amp;#8217;m planning on recording a few &lt;span class="caps"&gt;BDD&lt;/span&gt; videos for Ruby and I&amp;#8217;ve hit a bit of a roadblock.
&lt;ul&gt;
&lt;li&gt;Eclipse Helios doesn&amp;#8217;t cut it for running RSpec out of the box&lt;/li&gt;
&lt;li&gt;I understand that The Aptana plugin might support RSpec, however in the past when I&amp;#8217;ve used that plugin, it felt like kudzu&lt;/li&gt;
&lt;li&gt;IntelliJ 9.0.3 doesn&amp;#8217;t seem to work out of the box either&lt;/li&gt;
&lt;li&gt;RubyMine works out of the box, but it&amp;#8217;s not free&lt;/li&gt;
&lt;li&gt;RubyMine Early Access Program is free, but neither stable (less of a concern) nor long-lasting (I assume the license to use it expires)&lt;/li&gt;
&lt;li&gt;I&amp;#8217;m not familiar with another cross-platform option for tools other that vi/emacs(I&amp;#8217;m a vi user)&lt;/li&gt;
&lt;/ul&gt;
Here&amp;#8217;s the thing, everything on my wiki is released under &lt;a href="http://www.creativecommons.org/licenses/by-sa/2.5"&gt;Creative Commons Attribution Share-Alike 2.5 License&lt;/a&gt;. The &lt;a href="http://vimeo.com/user3159463/videos"&gt;videos I&amp;#8217;ve released&lt;/a&gt; are also freely available. So it seems strange to me to release something free that uses tools someone has to pay for to use for non-commercial use.&lt;p/&gt;

	&lt;p&gt;At least for the stuff I typically release that is. If it were just some video I expected people to watch and not replicate, then I&amp;#8217;d be less concerned about the toolset. However, I hope people will use what I&amp;#8217;ve released by attempting to replicate it. I don&amp;#8217;t want people to have to buy tools to replicate free material. The one exception I can think of is using ReSharper for .Net-baed languages. Since people are already paying big $$ for the &lt;span class="caps"&gt;IDE&lt;/span&gt; in that case (mono developers probably excluded), adding ReSharper doesn&amp;#8217;t seem like a big deal.&lt;p/&gt;&lt;/p&gt;


	&lt;p&gt;Since I&amp;#8217;d like people to have the option of &amp;#8220;repeating the experiment&amp;#8221;, the tool selection adds another dimension of importance to me. Should it be? If I were working on a product, I&amp;#8217;d consider tool cost a wash. If something will make me more productive and I&amp;#8217;m going to be working on it for more than a few weeks, that justifies a tool purchase. I&amp;#8217;ve personally spent $$ to make myself more efficient when I could not get my company/customer to pay for a particular tool. But this seems different. It seems like a barrier to entry.&lt;p/&gt;&lt;/p&gt;


&lt;h1&gt;Question Repeated&lt;/h1&gt;
So what&amp;#8217;s your opinion? If I&amp;#8217;m releasing something for free, should I strive to find a decent toolset that&amp;#8217;s free?&lt;p/&gt;

	&lt;p&gt;And I&amp;#8217;m also interested in the implied question: What toolset should I use? Can you recommend a toolset that will work on &lt;span class="caps"&gt;OS X&lt;/span&gt;, Linux, and Windows XP/7? I&amp;#8217;ve got the command line already and vim. If you can recommend free tools to make that better, I&amp;#8217;d like to hear it. If you can recommend something that works for either Eclipse or the community edition of IntelliJ, that&amp;#8217;s fine as well. Should I give Aptana another try? Does is RadRails plugin not take over Eclipse?&lt;/p&gt;</description>
      <pubDate>Sun, 12 Sep 2010 10:04:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:eb3005fc-7ebe-4267-963c-ec7e12d72ca5</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/09/12/selection-of-tools-for-otherwise-free-content-your-opinion</link>
      <category>Schuchert's Scattered Synapses </category>
    </item>
    <item>
      <title>The 4-contact points of software development</title>
      <description>The three laws of &lt;span class="caps"&gt;TDD&lt;/span&gt; are:
	&lt;ul&gt;
	&lt;li&gt;Write no production code without a failing test&lt;/li&gt;
		&lt;li&gt;Write just enough of a test to fail&lt;/li&gt;
		&lt;li&gt;Write just enough production code to get the test to pass&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;This list doesn&amp;#8217;t include refactoring, which is typically an assumed activity. In fact, some people refer to these rules as &amp;#8220;red, green, refactor&amp;#8221;. An even older version of this, from the Smalltalk community, is Red, Green, Blue. (Why Blue for refactor? I think someone was thinking &lt;span class="caps"&gt;RBG&lt;/span&gt; for a color space, luckily they didn&amp;#8217;t try to use &lt;span class="caps"&gt;CMYK&lt;/span&gt; or &lt;span class="caps"&gt;LAB&lt;/span&gt;!)&lt;/p&gt;


	&lt;p&gt;In this simple model, there two kinds of code: test &amp;#38; production. There are two kinds of activity: writing &amp;#38; refactoring. Interestingly, at one level it is all code. The thing that distinguishes both sets is intent.&lt;/p&gt;


	&lt;p&gt;The intent of a test is to demonstrate or maybe specify behavior. The intent of production code is to implement (hopefully) business-relevant functionality.&lt;/p&gt;


	&lt;p&gt;The intent of writing code is creation. The intent of refactoring code is to change (hopefully improve) its structure without changing its behavior (this is oversimplified but essentially correct).&lt;/p&gt;


If you mix those combinations you have the&lt;i&gt; &lt;b&gt;4-limbs of development&lt;/b&gt;&lt;/i&gt;:
	&lt;ul&gt;
	&lt;li&gt;Writing a test&lt;/li&gt;
		&lt;li&gt;Writing production code&lt;/li&gt;
		&lt;li&gt;Refactoring a test&lt;/li&gt;
		&lt;li&gt;Refactoring production code&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;An important behavior to practice is doing only one of these at a time. That is, when you are writing tests, don&amp;#8217;t also write production code. Sure, you might use tools to stub out missing methods and classes, but the heart of what you are doing is writing a test. Finish that train of thought before focusing on writing production code.&lt;/p&gt;


	&lt;p&gt;On the other hand, if you are refactoring production code, do just that. Don&amp;#8217;t change tests at the same time, try to only do one refactoring at a time, etc.&lt;/p&gt;


	&lt;p&gt;&lt;span class="caps"&gt;WHY&lt;/span&gt;?&lt;/p&gt;


	&lt;p&gt;First an analogy that almost always misses since most developers don&amp;#8217;t additionally rock climb.&lt;/p&gt;


	&lt;p&gt;When rock climbing, a good general bit of advice is to only move one contact point at a time. For this discussion, consider your two hands and two feet as your four contact points. Sure, you can use your face or knee, but neither are much fun. So just considering two hands and two feet, that suggests that if, for example, you move your right hand, then leave your left hand and both feet in place.&lt;/p&gt;


	&lt;p&gt;This gives you stability, a chance to easily recover by simply moving the most recent appendage back in place and, when the inevitable happens, another appendage slips, you have a better chance of not eating rock face. If you move more than one thing at a time, you are in more danger because you&amp;#8217;ve taken a risky action and reduced the number of points of contact, or stability.&lt;/p&gt;


	&lt;p&gt;Will you sometimes move multiple appendages? Sure. But not as a habit. Sometimes you need to take risks. The rock face may not always offer up movement patterns that make applying this recommendation possible. Since you know the environment will occasionally work against you, you need to maintain some slack for the inevitable.&lt;/p&gt;


	&lt;p&gt;Practicing Test Driven Development is similar. If you change production code and tests at the same time, what happens if a test fails? What is wrong? The production code, the test, both, neither? An even more subtle problem is that tests pass but the test is fragile or heavily implementation-dependent. While not necessarily an immediate threat, it represents design debt that will eventually cause problems. (This also happens frequently when tests are written after the production code as it&amp;#8217;s seductively easy to write tests that exercise code, expressing the production&amp;#8217;s code implementation but fundamentally hiding the intent.)&lt;/p&gt;


	&lt;p&gt;Notice, if you had only refactored code, then you know the problem is in one place. When you change both, the problem space actually goes from 1 to 3 (4 if you allow for neither). Furthermore, if you are changing both production and test code at the same time and you get to a point where you&amp;#8217;ve entered a bottomless pit, you&amp;#8217;ll end up throwing away more work if you choose to restore from the repository.&lt;/p&gt;


	&lt;p&gt;Are there going to be times when you change both? Sure. Sometimes you may not see a clear path that gives you the option to do only one thing at a given time. Sometimes the tests and code will work against you. Often, you&amp;#8217;ll be working in a legacy code base where there are no tests. Given that the environment will occasionally (or frequently) work against you, you need to maintain some slack.&lt;/p&gt;


	&lt;p&gt;Essentially, be focused on a single goal at any given time: write a test. then get it to pass. clean up production code &amp;#38; keep the tests first unchanging and then passing.&lt;/p&gt;


	&lt;p&gt;I find that this is a hard thing both to learn and to apply. I frequently jump ahead of myself. Unfortunately I&amp;#8217;m &amp;#8220;lucky&amp;#8221; enough when I do jump ahead that when I fail, I thoroughly fall flat on my face.&lt;/p&gt;


	&lt;p&gt;This approach is contextual (aren&amp;#8217;t they all?). Every time you start working on code, you&amp;#8217;ll be faced with these four possibilities. Each time you are, you need to figure out what is the most important thing in the moment, and do that one thing. Once you&amp;#8217;ve taken care of the most important thing, you may have just promoted the second most important thing to first place. Even so, reassess. What is the most important thing now? Do that.&lt;/p&gt;


	&lt;p&gt;Good luck trying to apply this idea to your development work. I&amp;#8217;m interesting in hearing about it.&lt;/p&gt;</description>
      <pubDate>Thu, 19 Aug 2010 22:59:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:a43fda5f-eaf6-4d2d-bb76-34f395bebda2</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/08/19/the-4-contact-points-of-software-development</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>TDD</category>
      <category>refactoring</category>
      <category>4</category>
      <category>contact</category>
      <category>points</category>
    </item>
    <item>
      <title>Is it worth killing trees over another C&amp;amp;#43;&amp;amp;#43; Book?</title>
      <description>&lt;p&gt;I&amp;#8217;ve taught a few C&amp;#43;&amp;#43; courses recently to people primarily moving from C to C&amp;#43;&amp;#43;. I know C&amp;#43;&amp;#43; has been around for years and it&amp;#8217;s not in vogue like it was 15 years ago. I stopped using it full time in 1997. Even so, there&amp;#8217;s been quite a bit of work on the library and language standard. And there are still a lot of places developing new systems with C&amp;#43;&amp;#43;. I know some people are still be learning C&amp;#43;&amp;#43; in school.&lt;/p&gt;


	&lt;p&gt;In my most recent classes, I&amp;#8217;ve been teaching students who have recently taken a class on &lt;span class="caps"&gt;OO A&lt;/span&gt; &amp;#38; D based on the work of Craig Larman. The C&amp;#43;&amp;#43; class attempts to follow that class by dovetailing into what it covers. Because of this, I did not use ObjectMentors&amp;#8217; standard C&amp;#43;&amp;#43; and &lt;span class="caps"&gt;OOD&lt;/span&gt; class. Good as it is, it has different starting assumptions. I instead wrote a class, using two problems as the entire basis of all the material I cover. I know, &amp;#8220;not build here syndrom.&amp;#8221; It pained me to do this, I did my research and I considered retro-fitting the OM course. The discrepancy was too large to consider reuse. And refactoring the existing class to accomodate changes, which I also considered, wasn&amp;#8217;t practical. Looking back I made the right decision.&lt;/p&gt;


So this course has a few key design elements:
	&lt;ul&gt;
	&lt;li&gt;Problem focused&lt;/li&gt;
		&lt;li&gt;Test oriented (sometimes test-first, other times test-driven, occasionally refactor-oriented)&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;The problem-focus limits the topic coverage. If something about the language doesn&amp;#8217;t come up somewhat naturally (not contrived) in the two projects I use, I don&amp;#8217;t cover the material. For example, I don&amp;#8217;t mention placement new, I only cover Multiple Inheritance if asked about it. I also try to focus on classes in the standard library. For example, std::array, std::vector, std::map, std::shared_ptr.&lt;/p&gt;


	&lt;p&gt;Additionally, there&amp;#8217;s an early focus on testing. That&amp;#8217;s another thing that&amp;#8217;s different from how I taught C&amp;#43;&amp;#43; say before 1995 &amp;#8211; I really didn&amp;#8217;t teach it from 1995 &amp;#8211; 2007, so no comments on what I might have done differently in that span of years.&lt;/p&gt;


	&lt;p&gt;To give you an idea of how early the focus is on test, I only show cout if asked. The first main() calls CommandLineTestRunner::RunAllTests and everything after that runs within a unit test. the last time I taught the class, I demonstrated tests executing with cslim, but still, a test focus.&lt;/p&gt;


	&lt;p&gt;I have them use unit tests as a way to experiment with the language. In one example, I have them write tests that force a method to become virtual that was not virtual before. In another case, I do the same thing with a virtual destructor. I have them test from raw pointers into shared_ptr and then update their code accordingly.&lt;/p&gt;


Because of the test focus, I make certain recommendations that impact overall class design. That means learning C&amp;#43;&amp;#43; with designs supporting testability early on. In C&amp;#43;&amp;#43; this means (among other things):
	&lt;ul&gt;
	&lt;li&gt;Dependency Injection (OK, this is not just C&amp;#43;&amp;#43;)&lt;/li&gt;
		&lt;li&gt;Virtual functions and by corollary a virtual destructor&lt;/li&gt;
		&lt;li&gt;Storing pointers because 1. calling methods through an auto object are not virtually dispatched, and 2. you cannot put references in the standard collections&lt;/li&gt;
		&lt;li&gt;Use std::shared_ptr to avoid memory leaks, which are detected by the unit testing tool I have them use.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;I take the class to a certain level, but I make it clear I&amp;#8217;m just scratching the surface. I believe it&amp;#8217;s not really possible to learn C&amp;#43;&amp;#43; in a 1-week class. You can get the beginnings of proficiency and be in a good position to continue learning &amp;#8211; that&amp;#8217;s an assumption I state up front after the students have had their first exercise &amp;#8211; about 5 minutes into the start of the class. I try to only go into detail as the students ask questions, but at times I just want to really open up the beast and get into what&amp;#8217;s really happening.&lt;/p&gt;


	&lt;p&gt;To address this, I&amp;#8217;ve started novelizing the class I&amp;#8217;ve been teaching. I&amp;#8217;m following the same outline as the class, but I dive under the surface and at times get to quite a bit of detail that I would not typically get into in a 4.5 day class.&lt;/p&gt;


I know this material will augment the class. This will give my students three sources of information:
	&lt;ul&gt;
	&lt;li&gt;The class itself, which is exercise-driven&lt;/li&gt;
		&lt;li&gt;Online videos&lt;/li&gt;
		&lt;li&gt;A novelization of the class, going into much more detail&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;The thing I&amp;#8217;m wondering is, would the book be worth making more generally available? I&amp;#8217;m writing it so that it can stand on its own. There&amp;#8217;s a certain advantage to knowing my students have taken the previous &lt;span class="caps"&gt;OO A&lt;/span&gt; &amp;#38; D class I mentioned because it uses a problem that I&amp;#8217;ve used on and off since 1992. This allows me to give examples from a problem they have looked at in the past and then at the current problem. I&amp;#8217;ve not yet made references to that problem in the book I&amp;#8217;m writing. I could, I just have not done so yet &amp;#8211; it&amp;#8217;s more natural in the second problem and I&amp;#8217;m still working on the first problem (and therefor the first half of the book). I&amp;#8217;m certain I can make those references without the previous class experience. (It&amp;#8217;s the Monopoly problem.)&lt;/p&gt;


In any case, I need to do some research. If I do start the publishing process, a key step involves competitive research. Can you recommend any books published for the first time this century (really in the past 7 years) that have any of these characteristics:
	&lt;ul&gt;
	&lt;li&gt;Cover a minimal set of C&amp;#43;&amp;#43;, enough for decent OO solutions&lt;/li&gt;
		&lt;li&gt;Have any kind of emphasis on test &amp;#8211; at least half the book?&lt;/li&gt;
		&lt;li&gt;Cover the language strictly through a problem-based approach rather than from a language perspective?&lt;/li&gt;
		&lt;li&gt;Involve deliberately making mistakes and observing those mistakes to learn how the language works?&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Additionally, can you recommend any great C&amp;#38;#43&amp;#38;#43 books? I can list many of the ones I&amp;#8217;ve read and enjoyed, but the last time I bought a book for myself on the topic, Amazon did not exist as an online company.&lt;/p&gt;


	&lt;p&gt;Independent of whether I deal with trying to get this thing published as a printed book, I&amp;#8217;m going to finish it because I think it will be useful to my students. I suspect I&amp;#8217;ll be teaching this class in the future, so I will find it useful in the future as well. If I don&amp;#8217;t attempt publishing it through a major publisher, I&amp;#8217;ll put it on my wiki at the very least. Though it&amp;#8217;s going to be quite a bit more effort than my typical wiki articles.&lt;/p&gt;


	&lt;p&gt;But the question I keep coming back to, is this: Is there really a need for this book dead tree version,  or it is primarily useful as supplemental material for a class I teach?&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;d like to hear your opinions.&lt;/p&gt;</description>
      <pubDate>Tue, 17 Aug 2010 00:17:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:66306ecb-5578-4490-9b17-69cd5da4547f</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/08/17/is-it-worth-killing-trees-over-another-c-43-43-book</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>c</category>
      <category>43</category>
      <category>ood</category>
      <category>automated</category>
      <category>test</category>
    </item>
    <item>
      <title>Nearly 22 years ago</title>
      <description>&lt;p&gt;Moved the article and the file. Reduced resolution from 300 dpi to 75 dpi (using a quartz filter on &lt;span class="caps"&gt;OS X&lt;/span&gt; from &lt;a href="http://discussions.apple.com/profile.jspa?userID=57524"&gt;Jerome Colas&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s the story with the updated location: &lt;a href="http://schuchert.wikispaces.com/IntorductionToMicrocomputersAndDataProcessing"&gt;The Moved Blog&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Wed, 11 Aug 2010 22:23:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:6ce78f16-6696-4c53-a7d9-6151d4b81bd9</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/08/11/nearly-22-years-ago</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>old</category>
      <category>computer</category>
      <category>book</category>
      <category>FIRST</category>
      <category>the</category>
      <category>80</category>
      <category>s</category>
    </item>
    <item>
      <title>Getting Started With cslim in Visual Studio 2010 Using the Command Line Tools</title>
      <description>&lt;p&gt;Some of you asked for it. Here&amp;#8217;s something to get you started: &lt;blockquote&gt;&lt;a href="http://schuchert.wikispaces.com/cpptraining.UsingCSlimWithVisualStudio2010"&gt;http://schuchert.wikispaces.com/cpptraining.UsingCSlimWithVisualStudio2010&lt;/a&gt;&lt;/blockquote&gt;&lt;/p&gt;


	&lt;p&gt;These instructions are a work in progress and alpha. However, they do get the basics working.&lt;/p&gt;


	&lt;p&gt;If you are so inclined, have a look at the NMakefile (you&amp;#8217;ll come across it in the instructions) and give me a better way to build it.&lt;/p&gt;


	&lt;p&gt;I spent probably 8 hours getting a working environment (much yak shaving including a faulty mac book pro &lt;span class="caps"&gt;DVD&lt;/span&gt; drive). I then spent another 8 &amp;#8211; 10 hours getting this working. I worked through it about 5 times to minimize the amount of changes I needed to make to the original library source.&lt;/p&gt;


	&lt;p&gt;I ended up using some link and pre-processor seams to get most of this built. However, most of my time was spent trying to figure out the command line tools and their options.&lt;/p&gt;


	&lt;p&gt;If you can give me some guidance on improving this, I&amp;#8217;d like to hear it. However, this is now a low-burning thread, so some assembly required!&lt;/p&gt;


	&lt;p&gt;Enjoy,&lt;/p&gt;</description>
      <pubDate>Sun, 08 Aug 2010 22:08:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:b9ed3dc1-bb3c-4c54-beb5-9f6785ea21c6</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/08/08/getting-started-with-cslim-in-visual-studio-2010-using-the-command-line-tools</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>c</category>
      <category>cpp</category>
      <category>cslim</category>
      <category>visual</category>
      <category>studio</category>
      <category>2010</category>
    </item>
    <item>
      <title>Rough Notes on using FitNesse with C++</title>
      <description>&lt;p&gt;I&amp;#8217;ve been working with FitNesse.slim, using the cslim implementation to execute C++ code. I have some rough notes online. These should be enough to get started, though you&amp;#8217;ll need to be using G++ 4.4 or later.&lt;/p&gt;


	&lt;p&gt;In any case, have a look. Give me some feedback if you&amp;#8217;d like. I&amp;#8217;ll be working on these over the next month or so:
&lt;a href="http://schuchert.wikispaces.com/cpptraining.ExecutingBinaryOperators"&gt;http://schuchert.wikispaces.com/cpptraining.ExecutingBinaryOperators&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Fri, 30 Jul 2010 22:09:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:155f5034-8a3b-48d9-aa7c-d68584e51670</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/07/30/rough-notes-on-using-fitnesse-with-c</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>c</category>
      <category>FitNesse</category>
      <category>cslim</category>
    </item>
    <item>
      <title>Preprocessor seams and assignment of responsibility</title>
      <description>In my &lt;a href="http://tinyurl.com/2fljzng"&gt;previous blog&lt;/a&gt; I mentioned adding a single method to the cslim library:
&lt;blockquote&gt;
&lt;b&gt;cslim/include/CSlim/SlimListSerializer.h:&lt;/b&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;void SlimList_Release(char *serializedResults);&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;b&gt;cslim/src/CSlim/SlimListSerializer.c:&lt;/b&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;void SlimList_Release(char *serializedResults)
{
  if(serializedResults)
    free(serializedResults);
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/blockquote&gt;

Now I&amp;#8217;m going to explain how I came across this need, what it took to figure it out and then why I picked this solution.
&lt;h2&gt;Background&lt;/h2&gt;
In FitNesse, Query Table Results are a list of list of list:

	&lt;ul&gt;
	&lt;li&gt;The outer-most list represents &amp;#8220;rows&amp;#8221;. It collects all objects found. It has zero or more entries.&lt;/li&gt;
		&lt;li&gt;The inner-most list represents a single field. It is a key value pair. It is a list of size 2. The first entry is the name of the field (column to FitNesse). The second field is the value. Both are strings.&lt;/li&gt;
		&lt;li&gt;The middle list represents a single object. It is a collection of fields. It has zero or more entires.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;I understand the need for this representation and it takes a little bit to get it built correctly. So much so, I built a &lt;a href="http://github.com/schuchert/queryresultbuilder"&gt;simple tool to do it in java&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;C&amp;#43;&amp;#43; is no different. In fact, the authors of cslim though the same thing and they created a C Abstract Data Type to help out (and an add-on method to create the correct final form):&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;SlimList&lt;/li&gt;
		&lt;li&gt;SlimList_Serializer&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;They use C because it can be used by both C and C&amp;#43;&amp;#43;. I&amp;#8217;m using C&amp;#43;&amp;#43; and I wanted to make building query results even easier, so I built a QueryResultAccumulator. The most recent source is in the &lt;a href="http://tinyurl.com/2fljzng"&gt;previous blog&lt;/a&gt; and I&amp;#8217;ll be putting it on github after I&amp;#8217;ve had some more time to work on it.&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s the progression to my QueryResultAccumulator class:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Wrote a Query-Table based fixture and followed the example provided with cslim (thank you for that!)&lt;/li&gt;
		&lt;li&gt;Moved the code from functions into methods on a class&lt;/li&gt;
		&lt;li&gt;Extracted a class, called SlimListWrapper, which made the fixture code easier to follow.&lt;/li&gt;
		&lt;li&gt;Went to get takeout and realized that I had named the class incorrectly and that it was really accumulating query results (thus the name). The SlimList was a mechanism, not an intent.&lt;/li&gt;
		&lt;li&gt;Refactored the class into QueryResultAccumulator (I left the original alone, created a new class, copied code from one to the other and changed it around a bit.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Now it might sound like I didn&amp;#8217;t have any tests. In fact, I did. I had my original Acceptance Test in FitNesse. I kept running that, so in a sense I was practicing &lt;span class="caps"&gt;ATDD&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;I was not happy with that, because I was not sure that I had properly handled memory allocation correctly. In fact, I had not. The final result is dynamically allocated and I was not releasing that. So I &amp;#8220;fixed&amp;#8221; it. (It needs to be released &lt;b&gt;after&lt;/b&gt; the return from slim back to FitNesse, so the typical pattern is to lazily delete it, or release it in a &amp;#8220;destroy&amp;#8221; method called after the execution of a single table.)&lt;/p&gt;


&lt;h2&gt;I have a memory leak?!&lt;/h2&gt;
I am simplifying this story a bit. So I&amp;#8217;m skipping some intermediate results. Ultimately I wrote the following test to check that you could use a single query result accumulator for multiple results correctly:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;TEST(QueryResultAccumulator, CanProduceFinalResultsMultipleTimes) {
    QueryResultAccumulator accumulator;
    accumulator.produceFinalResults();
    accumulator.produceFinalResults();
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;This caused a memory leak of 60 bytes. It was at this point I was up too late and banging my head against a wall. About 3 hours later I figured that out and went to bed. I fixed the problem and sent a patch to authors of cslim in maybe 45 minutes. So I should have gotten more sleep.&lt;/p&gt;


&lt;h2&gt;Where is that damn thing&lt;/h2&gt;
In any case, I visually checked the code. I debugged it. I did everything I could initially think of, and I was convinced that my code was correct. (As we&amp;#8217;ll see it both was and was not due to a preprocessor seam in cslim.) I got to the point where I even tried different versions of gcc. (I found a parsing error in g&amp;#43;&amp;#43; 4.5 when handling templates, so in desperation and late at night I wasted 5 minutes switching my compiler.)

I had the following code in my class:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;  if(result)
    free(result);&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;This was the correct thing, but it was in the wrong location. Again, this was related to a preprocessor seam in cslim.&lt;/p&gt;


&lt;h2&gt; Eureka!&lt;/h2&gt;
I looked at the cslim code and confirmed it was doing basic C stuff, nothing surprising. It was at that point that I remembered something important:
&lt;blockquote&gt;
cslim depends on CppUTest and uses a different malloc/free
&lt;/blockquote&gt;

	&lt;p&gt;Ah ha! That&amp;#8217;s it. So I tired to recompile my C&amp;#43;&amp;#43; code to use the same thing. However, I was not able to do that. CppUTest&amp;#8217;s memory tracking implementation does not work with many of the C&amp;#43;&amp;#43; standard classes like &amp;lt;string&amp;gt; and &amp;lt;vector&amp;gt;. So I could not compile my code using the same approach.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;m glad this happened becuase it made me realize that it was the wrong place anyway. Here&amp;#8217;s the logic:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;CSlim has a preprocessor seam, comile with or without -Dfree=cpputest_free, -Dmalloc=cpputest_malloc&lt;/li&gt;
		&lt;li&gt;I&amp;#8217;m using a class in cslim to do the allocation, where the policy of allocation is stored&lt;/li&gt;
		&lt;li&gt;I should &lt;b&gt;not&lt;/b&gt; release the memory but instead allow the cslim library to release the memory becaue it has the allocation policy, and therefore the release policy.&lt;/li&gt;
	&lt;/ul&gt;


About 2 minutes later, I had added a single function to the library:
&lt;blockquote&gt;
&lt;b&gt;cslim/include/CSlim/SlimListSerializer.h:&lt;/b&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;void SlimList_Release(char *serializedResults);&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;b&gt;cslim/src/CSlim/SlimListSerializer.c:&lt;/b&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;void SlimList_Release(char *serializedResults)
{
  if(serializedResults)
    free(serializedResults);
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/blockquote&gt;

	&lt;p&gt;I updated my QueryResultAccumulator to use SlimList_Release and my false positive disappeared.&lt;/p&gt;


	&lt;p&gt;It also turns out that this improved symmetry in the library. To allocate and release entries in an SlimList you use the following functions:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;SlimList* SlimList_Create() &lt;/li&gt;
		&lt;li&gt;void SlimList_Destroy(SlimList*);&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Now to serlalize a list and release the memory later you use:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;SlimList_Serialize&lt;/li&gt;
		&lt;li&gt;SlimList_Release&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;As I write this, I think there&amp;#8217;s a better name. I&amp;#8217;ll let the authors give it a better name (like SlimList_Release_Serialization_Results). But in any case, if you use a function in the cslim library that allocates something, you use another method in the cslim library to release it.&lt;/p&gt;


	&lt;p&gt;Since the libray has a preprocessor seam, that symmetry removes a false-positive memory leak.&lt;/p&gt;


&lt;h2&gt;What took so long?&lt;/h2&gt;
I had an interesting time with this. Originally I had not released that memory in the class but rather in the unit test. I was working too late and not thinking clearly. I realized that my class needed to manage that.

	&lt;p&gt;When I called free in the unit test, it was calling the correct version of free, cpputest_free, becasue it was a unit test using CppUTest. When I moved the code into the class, which has no knowledge of CppUTest (nor can it), the flow of the code was correct, but the compilation (preprocessor symbols) were different and it caused a false positive.&lt;/p&gt;


	&lt;p&gt;Since I changed the code, I assumed it was a problem with how I changed the code. To me more clear, I though it was a code-flow problem, not a preprocessor seam problem. So I spent a lot of time verifyig my code. Once I determined it was correct, I then moved into debugger mode.&lt;/p&gt;


	&lt;p&gt;It was not long after that when I finally figured out what was going on.&lt;/p&gt;


&lt;h2&gt;Conslusions&lt;/h2&gt;
As with many things in life, this is intuitive once you understand it!-)

	&lt;p&gt;That cslim depends on CppUTest might be questionable. However, if I treat cslim as a (mostly) black box, and I don&amp;#8217;t know its allocation policy, I should not assume a deallocation policy.&lt;/p&gt;


	&lt;p&gt;By putting the responsiblity in the correct library level, it fixed the problem and added symmetry to the overall solution.&lt;/p&gt;


	&lt;p&gt;I also really enjoyed this (after it was done). I&amp;#8217;ve come across memory leaks using CppUTest in the past. Often they were my fault. Sometimes they were not. This was interesting because it both was and was not my fault. I originally had written the code incorrectly. When I put he correct steps in my code, I still had wrong code because I put the responsibility in the wrong place. It really was only correct after I moved the actual implementation into the library and then called it from my code that I had finally written it correctly.&lt;/p&gt;</description>
      <pubDate>Thu, 22 Jul 2010 10:32:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:dfbd2b43-7d99-443b-8325-bfa1b93ed842</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/07/22/preprocessor-seams-and-assignment-of-responsibility</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>c</category>
      <category>FitNesse</category>
      <category>cslim</category>
      <category>assignment</category>
      <category>of</category>
      <category>responsibility</category>
      <category>malloc</category>
      <category>free</category>
      <category>preprocessor</category>
      <category>seam</category>
    </item>
    <item>
      <title>Some C++ Fixtures for FitNesse.slim</title>
      <description>&lt;p&gt;I continue working on these. I was stuck in the airport for 5 hours. Between that and the actual flight, I managed to create three different test examples against a C++ RpnCalculator. Each example uses a different kind of fixture. I had a request from @lrojas to publish some results on the blog. So this is that, however these are in progress and rough.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;m still trying different forms to figure out what I like the best.&lt;/p&gt;


	&lt;p&gt;By the way, that lastValue stuff in the fixtures has to do with the fact that all of the hook methods return a char* but I&amp;#8217;m responsible for cleaning up after myself.&lt;/p&gt;


&lt;h2&gt;A Decision Table&lt;/h2&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;!|ExecuteBinaryOperator    |
|lhs|rhs|operator|expected?|
|3  |4  |-       |-1       |
|5  |6  |*       |30       |&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;And Its Fixture Code&lt;/h2&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string&amp;gt;
#include &amp;quot;RpnCalculator.h&amp;quot;
#include &amp;quot;OperationFactory.h&amp;quot;
#include &amp;quot;Fixtures.h&amp;quot;
#include &amp;quot;SlimUtils.h&amp;quot;

struct ExecuteBinaryOperator {
    ExecuteBinaryOperator() {
        lastValue[0] = 0;
    }

    int execute() {
        RpnCalculator calculator(factory);
        calculator.enterNumber(lhs);
        calculator.enterNumber(rhs);
        calculator.executeOperator(op);
        return calculator.getX();
    }

    static ExecuteBinaryOperator* From(void *fixtureStorage) {
        return reinterpret_cast&amp;lt;ExecuteBinaryOperator*&amp;gt;(fixtureStorage);
    }

    OperationFactory factory;
    int lhs;
    int rhs;
    std::string op;
    char lastValue[32];
};

extern &amp;quot;C&amp;quot; {
void* ExecuteBinaryOperator_Create(StatementExecutor* errorHandler, SlimList* args) {
    return new ExecuteBinaryOperator;
}

void ExecuteBinaryOperator_Destroy(void* self) {
    delete ExecuteBinaryOperator::From(self);
}

static char* setLhs(void* fixture, SlimList* args) {
    ExecuteBinaryOperator *self = ExecuteBinaryOperator::From(fixture);
    self-&amp;gt;lhs = getFirstInt(args);
    return self-&amp;gt;lastValue;
}

static char* setRhs(void* fixture, SlimList* args) {
    ExecuteBinaryOperator *self = ExecuteBinaryOperator::From(fixture);
    self-&amp;gt;rhs = getFirstInt(args);
    return self-&amp;gt;lastValue;
}

static char* setOperator(void *fixture, SlimList* args) {
    ExecuteBinaryOperator *self = ExecuteBinaryOperator::From(fixture);
    self-&amp;gt;op = getFirstString(args);
    return self-&amp;gt;lastValue;
}
static char* expected(void* fixture, SlimList* args) {
    ExecuteBinaryOperator *self = ExecuteBinaryOperator::From(fixture);
    int result = self-&amp;gt;execute();
    snprintf(self-&amp;gt;lastValue, sizeof(self-&amp;gt;lastValue), &amp;quot;%d&amp;quot;, result);
    return self-&amp;gt;lastValue;
}

SLIM_CREATE_FIXTURE(ExecuteBinaryOperator)
    SLIM_FUNCTION(setLhs)
    SLIM_FUNCTION(setRhs)
    SLIM_FUNCTION(setOperator)
    SLIM_FUNCTION(expected)
SLIM_END

}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
There&amp;#8217;s a bit of duplication. I&amp;#8217;ve been experimenting with pointers to member functions and template functions to make it better. I really should be using lambdas, but I&amp;#8217;m not there yet. I have them available in some form since I&amp;#8217;m using gcc 4.5. I simply compile with the option -sdd=c++0x. Even so, I&amp;#8217;m not quite ready to do that.

&lt;h2&gt;A Script Table&lt;/h2&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;!|script           |ProgramTheCalculator                   |
|startProgramCalled|primeFactorsOfSum                      |
|addOperation      |sum                                    |
|addOperation      |primeFactors                           |
|saveProgram                                               |
|enter             |4                                      |
|enter             |13                                     |
|enter             |7                                      |
|execute           |primeFactorsOfSum                      |
|check             |stackHas|3|then|2|then|2|then|2|is|true|&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;And Its Fixture Code&lt;/h2&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string&amp;gt;
#include &amp;quot;RpnCalculator.h&amp;quot;
#include &amp;quot;OperationFactory.h&amp;quot;
#include &amp;quot;SlimUtils.h&amp;quot;
#include &amp;quot;SlimList.h&amp;quot;
#include &amp;quot;Fixtures.h&amp;quot;

struct ProgramTheCalculator {
    ProgramTheCalculator() : calculator(factory) {
    }

    static ProgramTheCalculator* From(void *fixtureStorage) {
        return reinterpret_cast&amp;lt;ProgramTheCalculator*&amp;gt;(fixtureStorage);
    }

    OperationFactory factory;
    RpnCalculator calculator;
};

extern &amp;quot;C&amp;quot; {

void* ProgramTheCalculator_Create(StatementExecutor* errorHandler, SlimList* args) {
    return new ProgramTheCalculator;
}

void ProgramTheCalculator_Destroy(void *fixture) {
    delete ProgramTheCalculator::From(fixture);
}

static char* startProgramCalled(void *fixture, SlimList *args) {
    auto *self = ProgramTheCalculator::From(fixture);
    self-&amp;gt;calculator.createProgramNamed(getFirstString(args));
    return remove_const(&amp;quot;&amp;quot;);
}

static char* addOperation(void *fixture, SlimList *args) {
    auto *self = ProgramTheCalculator::From(fixture);
    self-&amp;gt;calculator.addOperation(getFirstString(args));
    return remove_const(&amp;quot;&amp;quot;);
}

static char* saveProgram(void *fixture, SlimList *args) {
    auto *self = ProgramTheCalculator::From(fixture);
    self-&amp;gt;calculator.saveProgram();
    return remove_const(&amp;quot;&amp;quot;);
}

static char* enter(void *fixture, SlimList *args) {
    auto *self = ProgramTheCalculator::From(fixture);
    self-&amp;gt;calculator.enterNumber(getFirstInt(args));
    return remove_const(&amp;quot;&amp;quot;);
}

static char* execute(void *fixture, SlimList *args) {
    auto *self = ProgramTheCalculator::From(fixture);
    self-&amp;gt;calculator.executeOperator(getFirstString(args));
    return remove_const(&amp;quot;&amp;quot;);
}

static char* stackHasThenThenThenIs(void *fixture, SlimList *args) {
    auto *self = ProgramTheCalculator::From(fixture);
    for(int i = 0; i &amp;lt; 4; ++i) {
            if(self-&amp;gt;calculator.getX() != getIntAt(args, i))
                return remove_const(&amp;quot;false&amp;quot;);
            self-&amp;gt;calculator.executeOperator(&amp;quot;drop&amp;quot;);
    }

      return remove_const(&amp;quot;true&amp;quot;);
}

SLIM_CREATE_FIXTURE(ProgramTheCalculator)
    SLIM_FUNCTION(startProgramCalled)
    SLIM_FUNCTION(addOperation)
    SLIM_FUNCTION(saveProgram)
    SLIM_FUNCTION(enter)
    SLIM_FUNCTION(execute)
    SLIM_FUNCTION(stackHasThenThenThenIs)
SLIM_END

}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
This one is a bit more regular. I am using the updated auto keyword in this code. The fixture is just holding the calculator and its OperationFactory (not my preferred name, but that&amp;#8217;s what students wanted to call things like +, -, etc, operations not operators).

&lt;h2&gt;The Dreaded Query Table&lt;/h2&gt;
It&amp;#8217;s a bit of a pain to produce query results. So much so, I wrote a simple library in Java to make it easier. I can create a well-formed query result from a single object or a list of objects and even do basic transforms (in names and in paths to data). I started using the jakarta bean utils, but my use was so simple (2 methods), I ripped out that library and just hand-wrote the methods I needed. It was not a case of &amp;#8220;not invented here syndrom.&amp;#8221; I started by using the library, and I had tests. I didn&amp;#8217;t like the size of the library relative to how much I was using it, so I just got rid of it.

	&lt;p&gt;Well here I am working C++ and I felt compelled to make it easier work with query results in C++.&lt;/p&gt;


First the FitNesse table, then the fixture and finally the support  class. I have tests for it as well, I&amp;#8217;m not going to show those, however.
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;!|Query: SingleCharacterNameOperators|
|op                                  |
|+                                   |
|*                                   |
|/                                   |
|!                                   |
|-                                   |&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;And Its Fixture Code&lt;/h2&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;string&amp;gt;
#include &amp;lt;memory&amp;gt;
#include &amp;quot;RpnCalculator.h&amp;quot;
#include &amp;quot;OperationFactory.h&amp;quot;
#include &amp;quot;Fixtures.h&amp;quot;
#include &amp;quot;SlimUtils.h&amp;quot;
#include &amp;quot;QueryResultAccumulator.h&amp;quot;

struct SingleCharacterNameOperators {
    OperationFactory factory;
    RpnCalculator calculator;

    SingleCharacterNameOperators() :
        calculator(factory), result(0) {
    }

    ~SingleCharacterNameOperators() {
        delete result;
    }
    static SingleCharacterNameOperators* From(void *fixtureStorage) {
        return reinterpret_cast&amp;lt;SingleCharacterNameOperators*&amp;gt; (fixtureStorage);
    }

    void resetResult(char *newResult) {
        delete result;
        result = newResult;
    }

    void conditionallyAddOperatorNamed(const std::string &amp;amp;name) {
        if (name.size() == 1) {
            accumulator.addFieldNamedWithValue(&amp;quot;op&amp;quot;, name);
            accumulator.finishCurrentObject();
        }
    }

    void buildResult() {
        v_string names = calculator.allOperatorNames();
        buildResult(names);
    }

    void buildResult(v_string &amp;amp;names) {
        for (v_string::iterator iter = names.begin(); iter != names.end(); ++iter)
            conditionallyAddOperatorNamed(*iter);

        resetResult(accumulator.produceFinalResults());
    }

    QueryResultAccumulator accumulator;
    char *result;
};

extern &amp;quot;C&amp;quot; {
void* SingleCharacterNameOperators_Create(StatementExecutor* errorHandler,
        SlimList* args) {
    return new SingleCharacterNameOperators;
}

void SingleCharacterNameOperators_Destroy(void *fixture) {
    delete SingleCharacterNameOperators::From(fixture);
}

static char* query(void *fixture, SlimList *args) {
    auto *self = SingleCharacterNameOperators::From(fixture);
    self-&amp;gt;buildResult();
    return self-&amp;gt;result;
}

SLIM_CREATE_FIXTURE(SingleCharacterNameOperators)
    SLIM_FUNCTION(query)SLIM_END
SLIM_END&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;And the Helper Class&lt;/h2&gt;
&lt;b&gt;QueryResultAccumulator.h&lt;/b&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;#pragma once
#ifndef QUERYRESULTACCUMULATOR_H_
#define QUERYRESULTACCUMULATOR_H_

class SlimList;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;string&amp;gt;
class QueryResultAccumulator {
public:
    typedef std::vector&amp;lt;SlimList*&amp;gt; v_SlimList;
    typedef v_SlimList::iterator iterator;

    QueryResultAccumulator();
    virtual ~QueryResultAccumulator();

    void finishCurrentObject();
    void addFieldNamedWithValue(const std::string &amp;amp;name, const std::string &amp;amp;value);
    char *produceFinalResults();

private:
    SlimList* allocate();
    void releaseAll();
    void setInitialConditions();

private:
    v_SlimList created;
    SlimList *list;
    SlimList *currentObject;
    int lastFieldCount;
    int currentFieldCount;
    char *result;

private:
    QueryResultAccumulator(const QueryResultAccumulator&amp;amp;);
    QueryResultAccumulator&amp;amp; operator=(const QueryResultAccumulator&amp;amp;);
};

#endif
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;I know there are too many fields. The counts help with validating correct usage. I also wrote it so one instance could be re-used and I tried to make sure it was in a &amp;#8220;ready to receive fields&amp;#8221; state when necessary. In any case, this error checking helped find a defect I introduced while refactoring.&lt;/p&gt;


&lt;b&gt;QueryResultAccumulator.cpp&lt;/b&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;#include &amp;quot;QueryResultAccumulator.h&amp;quot;
#include &amp;quot;DifferentFieldCountsInObjects.h&amp;quot;
#include &amp;quot;InvalidStateException.h&amp;quot;

extern &amp;quot;C&amp;quot; {
#include &amp;quot;SlimList.h&amp;quot;
#include &amp;quot;SlimListSerializer.h&amp;quot;
}

QueryResultAccumulator::QueryResultAccumulator() : result(0) {
    setInitialConditions();
}

QueryResultAccumulator::~QueryResultAccumulator() {
    releaseAll();
    SlimList_Release(result);
}

void QueryResultAccumulator::setInitialConditions() {
    releaseAll();
    list = allocate();
    currentObject = allocate();
    lastFieldCount = -1;
    currentFieldCount = -1;
}

SlimList* QueryResultAccumulator::allocate() {
    SlimList *list = SlimList_Create();
    created.push_back(list);
    return list;
}

void QueryResultAccumulator::releaseAll() {
    for (iterator i = created.begin(); i != created.end(); ++i)
        SlimList_Destroy(*i);
    created.clear();
}

void QueryResultAccumulator::finishCurrentObject() {
    if(lastFieldCount &amp;gt;= 0 &amp;amp;&amp;amp; lastFieldCount != currentFieldCount)
        throw DifferentFieldCountsInObjects(lastFieldCount, currentFieldCount);

    SlimList_AddList(list, currentObject);
    currentObject = allocate();

    lastFieldCount = currentFieldCount;
    currentFieldCount = -1;
}

void QueryResultAccumulator::addFieldNamedWithValue(const std::string &amp;amp;name, const std::string &amp;amp;value) {
    SlimList *fieldList = allocate();
    SlimList_AddString(fieldList, name.c_str());
    SlimList_AddString(fieldList, value.c_str());
    SlimList_AddList(currentObject, fieldList);
    ++currentFieldCount;
}

char* QueryResultAccumulator::produceFinalResults() {
    if(currentFieldCount != -1)
        throw InvalidStateException(&amp;quot;Current object not written&amp;quot;);

    SlimList_Release(result);
    result = SlimList_Serialize(list);
    setInitialConditions();
    return result;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

Note, this code uses a method I added to the cslim library:
&lt;b&gt;SlimListSerializer.h &amp;#8211; in include/CSlim&lt;/b&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;void SlimList_Release(char *serializedResults);&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;b&gt;SlimListSerializer.c &amp;#8211; in src/CSlim&lt;/b&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;void SlimList_Release(char *serializedResults)
{
  if(serializedResults)
    free(serializedResults);
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;I needed to add these methods due to a false-positive memory leak indicated when using CppUTest to test this code. That&amp;#8217;s another blog.&lt;/p&gt;</description>
      <pubDate>Thu, 22 Jul 2010 00:32:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:63a89994-cb84-4422-b3c8-5ac5e7f53331</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/07/22/some-c-fixtures-for-fitnesse-slim</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>c</category>
      <category>FitNesse</category>
      <category>cslim</category>
    </item>
    <item>
      <title>FitNesse, C++ and cslim, step-by-step instructions</title>
      <description>&lt;p&gt;Title says it all:
&lt;a href="http://schuchert.wikispaces.com/cpptraining.GettingStartedWithFitNesseInCpp"&gt;http://schuchert.wikispaces.com/cpptraining.GettingStartedWithFitNesseInCpp&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;First draft. If you have problems, please let me know.&lt;/p&gt;</description>
      <pubDate>Mon, 19 Jul 2010 23:26:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:d1463d08-3298-4a46-bb72-4208f313a52a</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/07/19/fitnesse-c-and-cslim-step-by-step-instructions</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>c</category>
      <category>FitNesse</category>
      <category>cslim</category>
    </item>
    <item>
      <title>A Few C plus plus TDD videos</title>
      <description>&lt;p&gt;Using CppUTest, gcc 4.4 and the Eclipse &lt;span class="caps"&gt;CDT&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;Rough, as usual.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://www.vimeo.com/album/254486"&gt;The Video Album&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Might redo first one with increased font size. Considering redoing whole series at 800&amp;#215;600.&lt;/p&gt;</description>
      <pubDate>Mon, 12 Jul 2010 06:30:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:a05f9c5f-4b90-46ab-9eaf-72750d3ae303</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/07/12/a-few-c-plus-plus-tdd-videos</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>TDD</category>
      <category>c</category>
      <category>plus</category>
      <category>std</category>
      <category>tr1</category>
      <category>accumulate</category>
      <category>for_each</category>
      <category>bind</category>
      <category>_1</category>
      <category>refactoring</category>
      <category>array</category>
      <category>vector</category>
      <category>random</category>
    </item>
    <item>
      <title>C++ Algorithms, Boost and function currying</title>
      <description>&lt;p&gt;I&amp;#8217;ve been experimenting with C++ using the Eclipse &lt;span class="caps"&gt;CDT&lt;/span&gt; and gcc 4.4. Since I&amp;#8217;m a fan of boost, I&amp;#8217;ve been using that as well. I finally got into I realistic use of boost::bind.&lt;/p&gt;


I converted this:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;int Dice::total() const {
  int total = 0;

  for(const_iterator current = dice.begin();
      current != dice.end();
      ++current)
    total += (*current)-&amp;gt;faceValue();

  return total;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
Into this:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;int Dice::total() const {
  return std::accumulate(
      dice.begin(),
      dice.end(),
      0,
      bind(std::plus&amp;lt;int&amp;gt;(), _1, bind(&amp;amp;Die::faceValue, _2))
  );
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;To see how to go from the first version to the final version with lots of steps in between: &lt;a href="http://schuchert.wikispaces.com/cpptraining.SummingAVector"&gt;http://schuchert.wikispaces.com/cpptraining.SummingAVector&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;This is a first draft. I&amp;#8217;ll be cleaning it up over the next few days. If you see typos, or if anything is not clear from the code, please let me know where. Also, if my interpretation of what boost is doing under the covers (there&amp;#8217;s not much of that) is wrong, please correct me.&lt;/p&gt;


	&lt;p&gt;Thanks!&lt;/p&gt;</description>
      <pubDate>Sat, 12 Jun 2010 23:41:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:549aae6e-42fc-4ae7-ad78-126667918e8d</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/06/12/c-algorithms-boost-and-function-currying</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>c</category>
      <category>cpp</category>
      <category>boost</category>
      <category>function</category>
      <category>currying</category>
      <category>std</category>
      <category>for_each</category>
      <category>vector</category>
      <category>shared_ptr</category>
      <category>accumulate</category>
    </item>
    <item>
      <title>Hello World Revisited</title>
      <description>&lt;p&gt;Surprising revelations while taking a &lt;span class="caps"&gt;TDD&lt;/span&gt; approach to writing hello world.&lt;/p&gt;


	&lt;p&gt;Here it nearly 21 years since I started writing in C++ (and more for C+) and I realize I&amp;#8217;ve been blindly writing main functions to actually do something.&lt;/p&gt;


	&lt;p&gt;This insanity must stop!&lt;/p&gt;


	&lt;p&gt;What am I talking about? &lt;a href="http://schuchert.wikispaces.com/Tdd.HelloWorld.Cpp"&gt;Read it here.&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Thu, 20 May 2010 10:12:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:d09424a6-eb8f-4d9a-8025-35839675f928</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/05/20/hello-world-revisited</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>TDD</category>
      <category>seam</category>
      <category>link</category>
    </item>
    <item>
      <title>TDD is wasting time if...</title>
      <description>&lt;p&gt;You have no design sense.&lt;/p&gt;


	&lt;p&gt;OK, discuss.&lt;/p&gt;</description>
      <pubDate>Sat, 08 May 2010 10:36:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:f6a0d637-2639-493f-ba51-4535409bd137</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/05/08/tdd-is-wasting-time-if</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>TDD</category>
      <category>design</category>
    </item>
    <item>
      <title>Parts 5 and 6 of the 4-part series</title>
      <description>&lt;p&gt;The title says it all. I was bothered by a few things in the Shunting Yard Algorithm (actually many more things), but I felt compelled to fix two of those things.&lt;/p&gt;


So if you have a &lt;a href="http://vimeo.com/album/210446"&gt;look at the album&lt;/a&gt;, you&amp;#8217;ll notice 2 more videos:
	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://vimeo.com/10979675"&gt;Video 5 of 4&lt;/a&gt;: Remove the need for spaces between tokens.&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://vimeo.com/10994492"&gt;Video 6 of 4&lt;/a&gt;: Remove duplication of operators in algorithm and tokenizer.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Hope these are interesting or at least entertaining.&lt;/p&gt;</description>
      <pubDate>Fri, 16 Apr 2010 20:57:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:e2b52b26-ffe1-4953-8749-9f6987cb224a</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/04/16/parts-5-and-6-of-the-4-part-series</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>c</category>
      <category>TDD</category>
      <category>visual</category>
      <category>studio</category>
      <category>resharper</category>
      <category>shunting</category>
      <category>yard</category>
      <category>algorithm</category>
      <category>dry</category>
      <category>SRP</category>
      <category>don</category>
      <category>t</category>
      <category>repeat</category>
      <category>yourself</category>
      <category>single</category>
      <category>responsibility</category>
      <category>Principle</category>
      <category>refactoring</category>
    </item>
    <item>
      <title>C# TDD Videos - You asked for them</title>
      <description>&lt;p&gt;Several people asked for them, so here is a series of 4 videos. The first series on the &lt;span class="caps"&gt;RPN&lt;/span&gt; calculator in Java was a bit rough, these are even rougher.&lt;/p&gt;


	&lt;p&gt;Even so, hope you find them valuable.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://vimeo.com/album/210446"&gt;Shunting Yard Algorithm in C# Video Album&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Comments and feedback welcome.&lt;/p&gt;</description>
      <pubDate>Wed, 14 Apr 2010 23:29:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:1cbbb31c-687f-4789-97f7-496168f5d0e4</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/04/14/c-tdd-videos-you-asked-for-them</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>c</category>
      <category>TDD</category>
      <category>visual</category>
      <category>studio</category>
      <category>resharper</category>
      <category>shunting</category>
      <category>yard</category>
      <category>algorithm</category>
    </item>
    <item>
      <title>Open Spaces at conferences, what's your take?</title>
      <description>&lt;p&gt;I&amp;#8217;m the host for an open space this year at &lt;a href="http://www.agiletestingdays.com/"&gt;Agile Testing Days 2010, Berlin&lt;/a&gt; (October 4th &amp;#8211; 7th, the open space being the 7th). I&amp;#8217;ve attended a few open spaces and I have some ideas on what the role of host might entail.&lt;/p&gt;


	&lt;p&gt;But, I know I&amp;#8217;m better at collecting requirements than sourcing them, so what have you experienced that worked. What has not worked. Any advice you want to give me?&lt;/p&gt;


	&lt;p&gt;Please help me better understand what I can do to facilitate a successful open space.&lt;/p&gt;


	&lt;p&gt;What questions should I be asking?&lt;/p&gt;


	&lt;p&gt;Do you think having a few things scheduled up front in one room, and several unscheduled rooms left to be determined October 4th &amp;#8211; 6th, through a a mix if you will, is an OK thing to do, or should what happens be left completely open?&lt;/p&gt;


	&lt;p&gt;Or, leave everything completely open until the 7th, then start with the &amp;#8220;traditional&amp;#8221; introductions and let the agenda form then an there?&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;m aware of a few models of open spaces. What I really want to know is, what works for&lt;i&gt;  &lt;b&gt;you&lt;/i&gt;&lt;/b&gt;.&lt;/p&gt;</description>
      <pubDate>Wed, 07 Apr 2010 10:39:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:135e7271-d989-42a8-b37c-632b0b6ddc96</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/04/07/open-spaces-at-conferences-whats-your-take</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>open</category>
      <category>space</category>
      <category>agile</category>
      <category>testing</category>
      <category>days</category>
    </item>
    <item>
      <title>First Pass Completed: Rough Draft TDD Demonstration Videos</title>
      <description>&lt;p&gt;As promised, I&amp;#8217;ve made a complete sweep through a series of videos. You can find all of them: &lt;a href="http://www.vimeo.com/album/205252"&gt;here&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;These videos include several warts and false starts. Depending on the interest and feedback, I&amp;#8217;ll redo these at some point in the future.&lt;/p&gt;


	&lt;p&gt;Question: Should I repeat this series in C#, or some other language? Some people have expressed interest in this. It&amp;#8217;s probably 15 hours of work in C#, so I&amp;#8217;d need to know it was worth the effort. What&amp;#8217;s your opinion on that?&lt;/p&gt;


The videos are meant to be watched in order. The link above is to an album that is in the correct order. Here are the direct links (also in the intended order):
	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://vimeo.com/10569751"&gt;Getting Started&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://vimeo.com/10570537"&gt;Adding Basic Operators&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://vimeo.com/10597511"&gt;Removing Duplication&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://vimeo.com/10597797"&gt;Extracting to Strategy&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://vimeo.com/10639853"&gt;Removing Duplication via Refactoring&lt;/a&gt; or &lt;a href="http://vimeo.com/10647496"&gt;Removing Duplication via Tdd using Mockito&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://vimeo.com/10647851"&gt;Introducing an Abstract Factory&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://vimeo.com/10679730"&gt;Adding a Sum operator&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://vimeo.com/10681803"&gt;Adding Prime Factors Operator&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://vimeo.com/10685388"&gt;Composing Operators and Programming the Calculator&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://vimeo.com/10686005"&gt;Using FitNesse to Program the Calculator&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;I&amp;#8217;ve already received several comments both here on the blog as well as with the videos. I&amp;#8217;ll keep track of those comments and incorporate the ones that fit for me.&lt;/p&gt;


Each video has a link on its page to download it. However, to download a video, you will have to create an account and log in. So here are the links, these won&amp;#8217;t work without first creating an account (I&amp;#8217;ll update original blog with these as well):
	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://vimeo.com/download/video:18304530?v=2&amp;#38;e=1270570714&amp;#38;h=b96f13f4196fb68985933c1c21fb5806&amp;#38;uh=336ace2a37cb6bd8e82e9fac1c0b7f02"&gt;Getting Started Download&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://vimeo.com/download/video:18306776?v=2&amp;#38;e=1270570773&amp;#38;h=c38f8df6121e8df77af35fcd36e419bf&amp;#38;uh=336ace2a37cb6bd8e82e9fac1c0b7f02"&gt;Adding Basic Ops Download&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://vimeo.com/download/video:18366822?v=2&amp;#38;e=1270570794&amp;#38;h=407bf072c5fca10490bcf35d77ccf220&amp;#38;uh=336ace2a37cb6bd8e82e9fac1c0b7f02"&gt;Removing Duplication Download&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://vimeo.com/download/video:18367523?v=2&amp;#38;e=1270570821&amp;#38;h=318f20bb72e306d89fe8970ab7005ab0&amp;#38;uh=336ace2a37cb6bd8e82e9fac1c0b7f02"&gt;Extracting to Strategy&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://vimeo.com/download/video:18461046?v=2&amp;#38;e=1270570837&amp;#38;h=a77d9a69d45406e22265ab01b899c9f3&amp;#38;uh=336ace2a37cb6bd8e82e9fac1c0b7f02"&gt;Removing Dups/Refactoring Download&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://vimeo.com/download/video:18514764?v=2&amp;#38;e=1270570854&amp;#38;h=44c7be60020a70b78731eae5e5d9eb45&amp;#38;uh=336ace2a37cb6bd8e82e9fac1c0b7f02"&gt;Removing Dups/Tdd Download&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://vimeo.com/download/video:18507614?v=2&amp;#38;e=1270570871&amp;#38;h=1d52c79bdec4ab10c5201eb58b1024c7&amp;#38;uh=336ace2a37cb6bd8e82e9fac1c0b7f02"&gt;Abstract Factory Download&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://vimeo.com/download/video:18549114?v=2&amp;#38;e=1270570893&amp;#38;h=70bb69d0d935a26baf4048ec173bb6ae&amp;#38;uh=336ace2a37cb6bd8e82e9fac1c0b7f02"&gt;Sum Operator Download&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://vimeo.com/download/video:18553519?v=2&amp;#38;e=1270570907&amp;#38;h=e6147f1020074049b8047a38623940e7&amp;#38;uh=336ace2a37cb6bd8e82e9fac1c0b7f02"&gt;Prime Factors Download&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://vimeo.com/download/video:18561716?v=2&amp;#38;e=1270570924&amp;#38;h=5ef2bec871f87e2c694c7baaddab20b2&amp;#38;uh=336ace2a37cb6bd8e82e9fac1c0b7f02"&gt;Composing Math Operators Download&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://vimeo.com/download/video:18563340?v=2&amp;#38;e=1270570944&amp;#38;h=cfe26669faf53b7521f6ef9b992311ec&amp;#38;uh=336ace2a37cb6bd8e82e9fac1c0b7f02"&gt;Using FitNesse Download&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;</description>
      <pubDate>Mon, 05 Apr 2010 01:15:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:6b7e69d3-afbb-42a9-9d56-0319292ef786</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/04/05/first-pass-completed-rough-draft-tdd-demonstration-videos</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>TDD</category>
      <category>mockito</category>
      <category>FitNesse</category>
      <category>video</category>
      <category>Eclipse</category>
      <category>Java</category>
    </item>
    <item>
      <title>Some Rough Draft TDD Demonstration Videos</title>
      <description>&lt;p&gt;I&amp;#8217;m doing a series of videos on &lt;span class="caps"&gt;TDD&lt;/span&gt;. The ultimate result will be a much more polished version with embedded slides, and such. But as a part of the development process, I&amp;#8217;m creating scratch videos.&lt;/p&gt;


	&lt;p&gt;Much of what you see in these videos will be in the final versions, but those are far in the future relative to this work.&lt;/p&gt;


	&lt;p&gt;Hope you find them interesting.&lt;/p&gt;


	&lt;p&gt;Comments welcome.&lt;/p&gt;


Here is what is already available:
	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://vimeo.com/10569751"&gt;Getting started&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://vimeo.com/10570537"&gt;Adding Operators&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


Next up:
	&lt;ul&gt;
	&lt;li&gt;Removing violation of Open/Closed principle&lt;/li&gt;
		&lt;li&gt;Removing duplication in operations with a combination of the Strategy pattern and the Template Method pattern&lt;/li&gt;
		&lt;li&gt;Adding new operators after the removal of duplication.&lt;/li&gt;
		&lt;li&gt;Reducing coupling by using the Abstract Factory pattern, Dependency Inversion and Dependency Injection&lt;/li&gt;
		&lt;li&gt;Adding a few more operations&lt;/li&gt;
		&lt;li&gt;Allowing the creation of complex &amp;#8220;programs&amp;#8221; or &amp;#8220;macros&amp;#8221; by using the Composite pattern &amp;#8211; and avoiding Liskov Substitution Principle inherent in the GoF version of the pattern&lt;/li&gt;
		&lt;li&gt;Driving the calculator via FitNesse + Slim&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Anyway, that&amp;#8217;s the plan. I&amp;#8217;ll try to add each of these videos over the next few weeks.&lt;/p&gt;</description>
      <pubDate>Tue, 30 Mar 2010 21:01:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:f9144f21-6bbf-4e5d-b525-9e526c000fe8</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/03/30/some-rough-draft-tdd-demonstration-videos</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>TDD</category>
      <category>bdd</category>
      <category>video</category>
      <category>demonstration</category>
      <category>design</category>
      <category>patterns</category>
      <category>SRP</category>
      <category>LSP</category>
      <category>OCP</category>
      <category>DIP</category>
    </item>
    <item>
      <title>Injecting Those Dependencies</title>
      <description>&lt;p&gt;Last week I was teaching a class with a good group of C++ developers in Chicago. They were up on C++, current standardization efforts, virtual machines, performance analysis and tuning. At one point I mentioned a metric for virtual method dispatch on the &lt;span class="caps"&gt;JVM&lt;/span&gt; and one of the students used my numbers to work backwards to determine the number of instructions on different processors.&lt;/p&gt;


	&lt;p&gt;I was teaching our Working Effectively with Legacy Code class. Michael Feathers usually teaches this class, but he was busy (probably working with legacy code somewhere, which, ironically, is why he wrote the book &amp;#8211; to solve the problem once and for all and to stop working with legacy code).&lt;/p&gt;


In an early project we have some problem code (the class was in Java, but we discussed C++ quite a bit):
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;    public void addEvent(Event event) {
        event.added();
        events.add(event);
        mailService.sendMail(&amp;quot;jacques@spg1.com&amp;quot;, &amp;quot;Event Notification&amp;quot;, event
                .toString());
        display.showEvent(event);
    }&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

The problem with this code, however, comes from what happens in the constructor:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;    public Scheduler(String owner, SchedulerDisplay display) {
        this.owner = owner;

        mailService = MailService.getInstance();
        this.display = new SchedulerDisplay();
    }&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;The display object is associated with a real device (OK, not in our simulation, but you get the point). We need to fix that dependency.&lt;/p&gt;


So we traditionally talk about a few ways to address that:
	&lt;ol&gt;
	&lt;li&gt;Create an interface and then have a concrete and test-double implementation&lt;/li&gt;
		&lt;li&gt;Create a test subclass&lt;/li&gt;
	&lt;/ol&gt;


Those are a few typical ways to handle this problem, but given that the students also worked in C++ and were very concerned with performance (and dynamic binding), so we discussed more alternatives:
1. Link seam &amp;#8211; build the system using the original SchedulerDispaly header file but link in a different version of the class. 2. Template parameter (compiler seam) &amp;#8211; introduce a template parameter and compile in the dependency rather than link it in.
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;#pragma once

template&amp;lt;class D&amp;gt; class Scheduler
{
public:
  Scheduler(D &amp;amp;display);
  ~Scheduler();
  void handleEvent();

private:
  D &amp;amp;display;
};&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

So here are 4 ways to remove the dependency (working bottom up in a sense):
	&lt;ol&gt;
	&lt;li&gt;Link seam: link in a different version of SchedulerDisplay&lt;/li&gt;
		&lt;li&gt;Compiler seam: use a template parameter&lt;/li&gt;
		&lt;li&gt;Dynamic seam: create a test subclass that removes external dependency&lt;/li&gt;
		&lt;li&gt;Dynamic seam: extract an interface from existing concrete class, and make Scheduler depend on the new interface.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;For C++, the first option might be a good option if it allows a very quick build/test cycle. Imagine using a class that brings in several unwanted dependencies. By making a test version replacement and linking to it, you might be able to get up and running quickly. On the other hand, you have to have a custom build target, which is really outside of the language.&lt;/p&gt;


The second option is good for C++ and maybe C#, but not Java. Java&amp;#8217;s implementation of generics is so bad, that it requires an interface for this particular case, so you end up with the final option anyway. Using templates puts the seam into the language rather than the build system. It will affect clients because either:
	&lt;ol&gt;
	&lt;li&gt;They will have to provide a template parameter&lt;/li&gt;
		&lt;li&gt;Or, by providing a default value for the template parameter, clients will be aware of a class they were not previously aware of. Still, a viable option, but it will increase build time at least a little.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;The third option may not work in any language without changing the original problem code. Imagine a no argument constructor that performs some static initialization. Without changing the constructor, you cannot guarantee that this approach will work. In any case, the problem as presented requires a change since the constructor was doing the initialization of the display; it did not allow for dependency injection.&lt;/p&gt;


	&lt;p&gt;The final option requires a bit more change, but is pretty flexible if you can afford the virtual method overhead. In Java this isn&amp;#8217;t much of an issue (for a number of reasons, mostly related to effective &lt;span class="caps"&gt;JIT&lt;/span&gt; optimization). The cost is a bit more of a problem in C++ because introducing a first virtual method is a big deal. Personally, I don&amp;#8217;t work on embedded systems, so I can generally ignore that problem. But this is not something to simply ignore, context does matter.&lt;/p&gt;


	&lt;p&gt;So which option is the best?&lt;/p&gt;


	&lt;p&gt;None of the above.&lt;/p&gt;


	&lt;p&gt;As a developer, you should probably be aware of all of these options (or maybe not the template option of you&amp;#8217;re strictly a Java developer). Then, when you are faced with a legacy coding problem, you&amp;#8217;ll have more tools from which to choose.&lt;/p&gt;</description>
      <pubDate>Mon, 22 Mar 2010 16:00:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:079869bc-e7ef-4708-9a69-7b24541bd190</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/03/22/injecting-those-dependencies</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>welc</category>
      <category>refactoring</category>
      <category>dependency</category>
      <category>injection</category>
    </item>
    <item>
      <title>One way to configure FitNesse for team Development</title>
      <description>&lt;p&gt;Here are some notes (and instructions) on a way to configure FitNesse for use in a team environment: &lt;a href="http://schuchert.wikispaces.com/FitNesse.PageHierarchyForTeamDevelopment"&gt;Page Hierarchy For Team Development&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Comments and suggestions welcome.&lt;/p&gt;</description>
      <pubDate>Fri, 19 Feb 2010 14:12:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:35d8f8e2-f3c5-4b68-a893-9d8e457c67ed</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/02/19/one-way-to-configure-fitnesse-for-team-develomment</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>FitNesse</category>
      <category>team</category>
      <category>development</category>
      <category>server</category>
      <category>configuration</category>
    </item>
    <item>
      <title>Updated ConTest Instructions</title>
      <description>&lt;p&gt;Just updated the instructions for using ConTest &amp;#8211; a tool to assist in testing concurrent applications for Java. Check them out here: &lt;a href="http://tinyurl.com/ydq83rn"&gt;ConTest Instructions&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Thu, 18 Feb 2010 12:12:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:fb2adb07-9afb-44d4-9f18-f8efe67dd563</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/02/18/updated-contest-instructions</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>concurrent</category>
      <category>testing</category>
    </item>
    <item>
      <title>Getting Started in Objective-C with XCode</title>
      <description>&lt;p&gt;As I mentioned in a previous &lt;a href="http://blog.objectmentor.com/articles/2010/02/08/rudimentary-tdd-with-xcode-and-objective-c"&gt;previous blog&lt;/a&gt;, I wrote up some notes on getting started practicing &lt;span class="caps"&gt;TDD&lt;/span&gt; using XCode and Objective-C. I&amp;#8217;m intending to write a bit more, so the top level of the overall tutorial path starts here: &lt;a href="http://schuchert.wikispaces.com/tdd.objectivec.AFirstProject"&gt;A First Objective-C Project&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;If you just want to see the details of getting started: &lt;a href="http://schuchert.wikispaces.com/tdd.objectivec.XCodeProjectSetup"&gt;XCodeProjectSetup&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;The biggest change from the previous blog is an embedded video demonstration. If you&amp;#8217;re just interested in the video: &lt;a href="http://vimeo.com/9394596"&gt;Getting started&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Want to seem more? Something in particular? Let me know.&lt;/p&gt;


	&lt;p&gt;Comments welcome.&lt;/p&gt;</description>
      <pubDate>Thu, 11 Feb 2010 23:07:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:24a88145-37df-44a3-94f7-e91671b790af</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/02/11/getting-started-in-objective-c-with-xcode</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>TDD</category>
      <category>objective</category>
      <category>c</category>
      <category>getting</category>
      <category>started</category>
    </item>
    <item>
      <title>Is TDD Language Neutral?</title>
      <description>On another blog, a commenter wrote (I&amp;#8217;m leaving names out, though you can see the original blog if you look):
&lt;blockquote&gt;
    I don&#8217;t think that it makes sense to say &#8220;teach a &lt;span class="caps"&gt;TDD&lt;/span&gt; class in several languages simultaneously&#8221;. &lt;span class="caps"&gt;TDD&lt;/span&gt; is a language-independent technique. 
&lt;/blockquote&gt;

	&lt;p&gt;What follows is a slightly changed version of my response. What I&amp;#8217;m wondering is this: Do you think the practice of &lt;span class="caps"&gt;TDD&lt;/span&gt; is fundamentally impacted by your programming language?&lt;/p&gt;


	&lt;p&gt;Read on for my response. You might want to add a comment before reading my response to avoid &amp;#8220;group think.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;Based on the original comment, I started with: It seems to me that you&#8217;ve not written professionally in many different languages. Or if you have, you&#8217;ve not effectively used those different programming languages.&lt;/p&gt;


	&lt;p&gt;Now let me be a bit more clear. Java and C++ are different languages, to be sure. However, they are both class-based, statically typed languages without lambdas (well C++ and Java will both be getting them, but they don&#8217;t have them now).&lt;/p&gt;


	&lt;p&gt;Contrast Java and C++ with Smaltalk and Self. Smalltalk is class based and supports inheritance but it is dynamically typed. Self is object-oriented, but it does not have classes. In fact, it technically does not have inheritance, but it fully supports &lt;span class="caps"&gt;OOP&lt;/span&gt;. How? Delegation. JavaScript is closer to Self than it is to Smalltalk. But JavaScript, Self and Smalltalk are all closer than C++, Java, C# and Objective-C.&lt;/p&gt;


	&lt;p&gt;How about the Open/Closed principle? How I interpret that design principle depends on the context (language) in which work. In raw Java, what I think needs to be closed is different than say raw Ruby. If I add Aspect Oriented Programming into the mix (yes, I&#8217;ve actually written and deployed systems that used Aspect J &#8211; in a limited fashion), then that opens things up a bit, but still not as much as in Ruby.&lt;/p&gt;


	&lt;p&gt;In Smalltalk, the closest analog to static methods are class methods. However, a class method in Smalltalk is actually an instance method on a class object, which is a subclass of the Class class. (Yes, that&#8217;s what I meant.)&lt;/p&gt;


	&lt;p&gt;Why is this important? When I&#8217;m working with legacy code in C++/Java/C#/VB.Net &#8211; languages where static methods are never dynamically bound, I avoid using static methods and, in fact, I redesign using what Michel Feathers calls &#8220;Introducing an Instance Delegator&#8221;.&lt;/p&gt;


	&lt;p&gt;In Smalltalk, this technique is irrelevant and unnecessary.&lt;/p&gt;


	&lt;p&gt;In languages like JavaScript, Self, Smaltalk, Ruby, etc., interfaces are not really necessary. Sure you can use them, but they are more for documentation.&lt;/p&gt;


	&lt;p&gt;Consider templates in C++ versus generics in Java. In Java, generics experience type erasure so you often need to use interfaces with generics &#8211; or at least tell the compiler a type it can assume will always be used with a generic. In C++, the most you really need to do is let the complier know that a template parameter is a typename as opposed to a primitive. When the code is compiled, any implied requirements of the type parameter will either be satisfied or not. (Woe be it to you if they are not!)&lt;/p&gt;


	&lt;p&gt;Why? In Java, generics are syntactic sugar. C++ generates a unique class for each template occurrence. C# is much closer to C++ than Java in this respect. Java got it wrong (in my opinion) &#8211; though what they did add did improve the language a bit.&lt;/p&gt;


	&lt;p&gt;How about moving away from OO languages? Scala is a mixed language, as is F#. Haskel is not. Lisp as well. How you break a problem into parts is (or at least should be) different in these languages. I don&#8217;t mean different in syntax, to be sure it will be. I mean how you break a problem into its parts is fundamentally different in pure functional languages than OO languages.&lt;/p&gt;


	&lt;p&gt;Or consider &lt;span class="caps"&gt;COBOL&lt;/span&gt;. I&#8217;ve programmed in it. I can thank &lt;span class="caps"&gt;COBOL&lt;/span&gt; for my touch-typing skills. &lt;span class="caps"&gt;COBOL&lt;/span&gt; is yet a different kind of language. Yes, syntactically, but that&#8217;s not the interesting difference. &lt;span class="caps"&gt;COBOL&lt;/span&gt; is a record-oriented processing language. It is well suited to batch processing. &lt;span class="caps"&gt;AWK&lt;/span&gt; is similar in this respect as is &lt;span class="caps"&gt;SNOBOL&lt;/span&gt;. (I&#8217;ve used &lt;span class="caps"&gt;AWK&lt;/span&gt; quite a bit, and I&#8217;ve used a variant of &lt;span class="caps"&gt;SNOBOL&lt;/span&gt; called &lt;span class="caps"&gt;SPITBOL&lt;/span&gt; as well.)&lt;/p&gt;


	&lt;p&gt;Let&#8217;s continue with a building analogy. If all I have to build is bamboo then I have available to me certain techniques for building a house. If I have steel, I have different alternatives. The design of my house will be directly impacted by the media (language) available.&lt;/p&gt;


	&lt;p&gt;Additionally, if I&#8217;m building on clay versus bedrock, I will also make fundamentally different design issues. When I lived in Texas I had a floating slab foundation, which were common for several reasons: cost, temperature zone, available building materials. Texas was the first place I lived that did not in general have basements. The other option, pier and beam, was no longer practiced in general due to cost.&lt;/p&gt;


	&lt;p&gt;I&#8217;m originally from the Mid-West (Iowa). In Iowa, buildings are built such that their foundation is below the frost line. The frost line was something like 30&#8221; (I&#8217;m remembering something from 20 &#8211; 30 years ago). So all the houses had basements. Or if not basements, half-basements.&lt;/p&gt;


	&lt;p&gt;The same kinds of things can be said about programming languages as well as their ecosystems as well as the political environment. I&#8217;ve already made the language point above. But what about the political environment?&lt;/p&gt;


	&lt;p&gt;I have worked at places where open source was forbidden. So this rules out Hibernate and Spring. Taking away these tools does not stop me from building a system, but it does have an impact on gross assignment of responsibility, which is an important component of software architecture.&lt;/p&gt;


	&lt;p&gt;Now, back down to a &lt;span class="caps"&gt;TDD&lt;/span&gt; class. When I teach &lt;span class="caps"&gt;TDD&lt;/span&gt;, I am not teaching just &lt;span class="caps"&gt;TDD&lt;/span&gt;. Furthermore, I am not just talking about &lt;span class="caps"&gt;TDD&lt;/span&gt;. I want students to apply the practice.
So I start with a problem &#8211; a requirements statement. That does not initially vary with the language. In practice it eventually does for several reasons:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;How far the class can get with the problem is impacted by by their skills as well as the programming language. C++ and vi are slower to work in that Java and Eclipse.&lt;/li&gt;
		&lt;li&gt;What you can reasonably do is impacted by both the language as its environment. For example, it is easy to look at a &lt;span class="caps"&gt;DLL&lt;/span&gt; and dynamically find all concrete implementations of an interface in any .Net language. It&#8217;s harder to do that in Java, though possible. In C++ it is platform specific.&lt;/li&gt;
		&lt;li&gt;There are more&#8230;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;The students do need to learn the mechanics:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;How to write a test using a particular unit testing framework&lt;/li&gt;
		&lt;li&gt;How to write production code&lt;/li&gt;
		&lt;li&gt;The shortcut keys of the environment&lt;/li&gt;
		&lt;li&gt;The refactoring support in the &lt;span class="caps"&gt;IDE&lt;/span&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;But what are the students testing? Units? Sure, let&#8217;s go there.&lt;/p&gt;


	&lt;p&gt;Language affects the units. You are testing units. Different kinds of units, different kinds of responsibilities. Different kinds of responsibilities to be verified, different unit tests.&lt;/p&gt;


	&lt;p&gt;Things are not so cleanly separated as you would like to imagine.&lt;/p&gt;


	&lt;p&gt;This very idea can be seen in natural languages. Different languages are better/worse at expressing things. The language you use directly affects how you interpret the world. This actually impacts the physical wiring in the brain. Really, it does.&lt;/p&gt;


	&lt;p&gt;So I do not agree.&lt;/p&gt;


	&lt;p&gt;And I challenge you to write the same problem in two fundamentally different languages (e.g. Java and Lisp) using &lt;span class="caps"&gt;TDD&lt;/span&gt;. Then have those two different solutions reviewed by experts in each of those languages.&lt;/p&gt;


	&lt;p&gt;I claim that if you&#8217;ve done an effective job of using those languages, your solutions will be different &lt;span class="caps"&gt;AND&lt;/span&gt; the unit tests you created to get to those solutions will be fundamentally different (not just mechanically different).&lt;/p&gt;


	&lt;p&gt;If, on the other hands, the unit tests are the same (other than the mechanics), then at least one group of people will say your solution is a bad use of their particular language. You&#8217;ll either be programming Java in Lisp or Lisp in Java.&lt;/p&gt;</description>
      <pubDate>Tue, 09 Feb 2010 09:38:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:99b04a35-41dd-4abc-9cc7-feeb9d67c715</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/02/09/is-tdd-language-neutral</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>language</category>
      <category>impact</category>
      <category>TDD</category>
    </item>
    <item>
      <title>Rudimentary TDD with XCode and Objective-C</title>
      <description>We have a potential client that would like us to teach a &lt;span class="caps"&gt;TDD&lt;/span&gt; class in several languages simultaneously:
	&lt;ul&gt;
	&lt;li&gt;Java&lt;/li&gt;
		&lt;li&gt;JavaScript&lt;/li&gt;
		&lt;li&gt;C++&lt;/li&gt;
		&lt;li&gt;Objective-C&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;In turns out that for what we teach in our &lt;span class="caps"&gt;TDD&lt;/span&gt; class, Java, C++ and Objective-C can be taught at the same time fairly easily. JavaScript, however, not so much. It is a very different (great, but different) beast.&lt;/p&gt;


	&lt;p&gt;In fact I could add C# to the mix as well, but I&amp;#8217;d have to leave out &lt;span class="caps"&gt;LINQ&lt;/span&gt; and Lambdas.&lt;/p&gt;


	&lt;p&gt;In any case, to teach a class like that, I prefer to have the students do a bit of preliminary work so that they know how to set up their environments. When there&amp;#8217;s just one language, I do this on the fly. But when there&amp;#8217;s 3, I don&amp;#8217;t want 2/3rds of the class waiting while 1/3rd learns how to create a basic project supporting &lt;span class="caps"&gt;TDD&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;The last time I used Objective-C was in 1991, so I needed to figure out how to do this in the environment it is most likely to be used. This turned out to be a bit more work than I expected. I found it all using the good old google-machine, but in pieces. Since there really wasn&amp;#8217;t a great (in my opinion) one-stop place that clearly laid out all of the steps, &lt;a href="http://schuchert.wikispaces.com/tdd.objectivec.XCodeProjectSetup"&gt;I created one&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;This is in a early state. If you have comments, I&amp;#8217;d appreciate them. I&amp;#8217;ll probably add more. (If you&amp;#8217;d like to see more, let me know that as well.) At this point, the basics are pretty much there, so I don&amp;#8217;t actually need to do anything else. However, I have taken this just a bit further: &lt;a href=http://schuchert.wikispaces.com/tdd.objectivec.AFirstProject"&gt;This is the top-level of the tutorial&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Again, comments and suggestions welcome.&lt;/p&gt;</description>
      <pubDate>Mon, 08 Feb 2010 18:24:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:76caf33c-893e-4e12-9803-e4f2992165ba</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/02/08/rudimentary-tdd-with-xcode-and-objective-c</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>TDD</category>
      <category>objective</category>
      <category>c</category>
      <category>xcode</category>
      <category>ocunit</category>
    </item>
    <item>
      <title>CppUTest Recent Experiences</title>
      <description>&lt;h2&gt;Background&lt;/h2&gt;
Mid last year I ported several exercises from Java to C++. At that time, I used CppUTest 1.x and Boost 1.38. Finally, half a year later, it was time to actually brush the dust off those examples and make sure they still work.&lt;p/&gt;

	&lt;p&gt;They didn&amp;#8217;t. Bit rot. Or user error. Not sure which.&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;Bit rot&lt;/b&gt;: bits decay to the point where things start failing. Compiled programs&lt;i&gt; &lt;b&gt;do&lt;/b&gt;&lt;/i&gt; have a half-life.&lt;p/&gt;
&lt;b&gt;User Error&lt;/b&gt;: maybe things were not checked in as clean as I remember. Though I suspect they were, I don&amp;#8217;t really have any evidence to prove it, so I have to leave that option available.&lt;/p&gt;


	&lt;p&gt;To add to the mix, I decided to upgrade to CppUTest 2.x and to the latest version of the Boost library (1.41). I think that broke many several things. But the fixes were simple, once I figured out what I needed to do.&lt;/p&gt;


&lt;h2&gt;The Fixes&lt;/h2&gt;
What follows are the three things I needed to do to get CppUTest 2.0, Boost and those exercises playing nicely together.&lt;p/&gt;

&lt;h3&gt;Header File Include Order&lt;/h3&gt;
First, I used to have the header file for the CppUTest Test Harness, &lt;CppUTest/TestHarness.h&gt; included first. It seems logical, but it caused all sorts of problems with CppUTest 2. That header file, includes a file, that ultimately includes something that uses macros to redefine new and delete. This is done so the testing framework can do simple memory tracking, which lets you know if your unit tests contains memory leaks.&lt;p/&gt;

	&lt;p&gt;I like this feature. Sure, it&amp;#8217;s simple and light-weight, but it coves a lot of ground for a little hassle. The hassle? Include that header file last, instead of first. Problem Solved. Well at least the code compiles without hundreds of errors.&lt;p/&gt;&lt;/p&gt;


&lt;h3&gt;Boost Shared Pointer&lt;/h3&gt;
Rather than hold pointers directly, I used the boost shared pointer class for a light-weight way to manage memory allocation. This is something I would do on a real project as well.&lt;p/&gt;

	&lt;p&gt;Somehow, the updated memory tracking in CppUTest 2.0 found something I had missed when using CppUTest 1.0.&lt;/p&gt;


	&lt;p&gt;I need to be able to control the date, so I have a simple date factory. By default, the date factory, when asked for the current date, returns the current date. Several unit tests want to simulate different dates. E.g., check out a book on one day, return it 14 days later. To do that, I manipulate the date factory (a form of dependency injection). This works fine, but by default the date factory is allocated using new.&lt;p/&gt;&lt;/p&gt;


When I replaced the existing date factory, I was not resetting it after the test. It turns out that this did not break anything because I was &amp;#8220;lucky&amp;#8221;. (Actually unlucky, I like things to&lt;i&gt; &lt;b&gt;fail fast&lt;/b&gt;&lt;/i&gt;.) CppUTest caught this in the form of not deallocating memory correctly:
	&lt;ul&gt;
	&lt;li&gt;I want to replace behavior&lt;/li&gt;
		&lt;li&gt;To do so I used polymorphism&lt;/li&gt;
		&lt;li&gt;Polymorphism in C++ requires virtual methods (please don&amp;#8217;t correct me by suggesting that overloading is polymorphism, that is an opinion with which I strongly disagree)&lt;/li&gt;
		&lt;li&gt;Methods are only virtually dispatched via references or pointers&lt;/li&gt;
		&lt;li&gt;References cannot be changed, so I must use a pointer if I want a substitutable factory, which I wanted&lt;/li&gt;
		&lt;li&gt;Pointers suggest dynamic memory allocation&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;To fix this, I updated the setup method to store the original date factory in an attribute and then I updated the teardown method to restore the original date factory from that attribute. That I missed this suggests that my test suite is not adequate. I did not fix this problem for no good reason other than I was porting existing tests, so I left it as is. For the context it will not cause a problem. Pragmatic or lazy? You decide.&lt;p/&gt;&lt;/p&gt;


&lt;h3&gt;One Time Allocation&lt;/h3&gt;
Here is a simple utility that uses Boost dates and regex:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_cpp "&gt;ptime DateUtil::dateFromString(const string &amp;amp;dateString) {
  boost::regex e(&amp;quot;^(\\d{1,2})/(\\d{1,2})/(\\d{4})$&amp;quot;);
  string replace(&amp;quot;\\3/\\1/\\2&amp;quot;);
  string isoDate = boost::regex_replace(dateString, e, replace, boost::match_default | boost::format_sed);
  return ptime(date(from_string(isoDate)));
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Now this is somewhat simplistic code. So be it, it serves the purposes of the exercise. I can think of ways to fix this, but there&amp;#8217;s an underling issue that exists if you use the regex library from Boost.&lt;p/&gt;&lt;/p&gt;


	&lt;p&gt;When you use the library, it allocates (in this example) 10 blocks of memory. If you read the documentation (I did), it&amp;#8217;s making space for its internal state machine for regex evaluation. This is done once and then kept around.&lt;p/&gt;&lt;/p&gt;


So what&amp;#8217;s the problem? Well, when I run my tests, the first test that happens to exercise this block of code reports some memory allocation issues:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;c:\projects\cppppp\dependencyinversionprinciple\dependencyinversionprinciple\pat
rongatewaytest.cpp:34: error: Failure in TEST(PatronGateway, AddAFew)
        Memory leak(s) found.
Leak size: 1120 Allocated at: &amp;lt;unknown&amp;gt; and line: 0. Type: &amp;quot;new&amp;quot; Content: &amp;quot;
?&amp;quot;
Leak size: 16 Allocated at: &amp;lt;unknown&amp;gt; and line: 0. Type: &amp;quot;new&amp;quot; Content: ?a&amp;quot;
Leak size: 20 Allocated at: &amp;lt;unknown&amp;gt; and line: 0. Type: &amp;quot;new&amp;quot; Content: &amp;quot;&#234;&#224;4&amp;quot;
Leak size: 52 Allocated at: &amp;lt;unknown&amp;gt; and line: 0. Type: &amp;quot;new&amp;quot; Content: &#228;4&amp;quot;
Leak size: 4096 Allocated at: &amp;lt;unknown&amp;gt; and line: 0. Type: &amp;quot;new&amp;quot; Content: &amp;quot;&amp;quot;
Leak size: 52 Allocated at: &amp;lt;unknown&amp;gt; and line: 0. Type: &amp;quot;new&amp;quot; Content: &amp;quot;&#234;&#226;4&amp;quot;
Leak size: 20 Allocated at: &amp;lt;unknown&amp;gt; and line: 0. Type: &amp;quot;new&amp;quot; Content: ~4&amp;quot;
Leak size: 32 Allocated at: &amp;lt;unknown&amp;gt; and line: 0. Type: &amp;quot;new&amp;quot; Content: &amp;quot;?&#224;4&amp;quot;
Leak size: 32 Allocated at: &amp;lt;unknown&amp;gt; and line: 0. Type: &amp;quot;new&amp;quot; Content: &amp;quot;h~4&amp;quot;
Leak size: 80 Allocated at: &amp;lt;unknown&amp;gt; and line: 0. Type: &amp;quot;new&amp;quot; Content: &amp;quot;&#234;&#228;4&amp;quot;
Total number of leaks:  10&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;This is a false positive. This is a one-time allocation and a side-effect of C++ memory allocation and static initialization.&lt;p/&gt;&lt;/p&gt;


	&lt;p&gt;There is a way to &amp;#8220;fix&amp;#8221; this. You use a command line option, -r, to tell the command line test runner to run the tests twice. If the allocation problem happens the first time but not the second time, then the tests are &amp;#8220;OK&amp;#8221;.&lt;p/&gt;&lt;/p&gt;


I didn&amp;#8217;t want to do this. 
	&lt;ul&gt;
	&lt;li&gt;The tests do take some time to run (30 seconds maybe, but still that doubles the time)&lt;/li&gt;
		&lt;li&gt;The output is ugly&lt;/li&gt;
		&lt;li&gt;It&amp;#8217;s off topic for what the exercise is trying to accomplish&lt;/li&gt;
	&lt;/ul&gt;


I tried a few different options but ultimately I went with simply calling that method before using the command line test runner. So I changed my main from:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_cpp "&gt;#include &amp;lt;CppUTest/CommandLineTestRunner.h&amp;gt;

int main(int argc, char **argv) {
  return CommandLineTestRunner::RunAllTests(argc, argv);
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

To this:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_cpp "&gt;#include &amp;quot;DateUtil.h&amp;quot;
#include &amp;lt;CppUTest/CommandLineTestRunner.h&amp;gt;

/** ************************************************************
    The boost regex library allocates several blocks of memory
    for its internal state machine. That memory is listed as a 
    memory leak in the first test that happens to use code that
    uses the boost regext library. To avoid having to run the
    tests twice using the -r option, we instead simply force
    this one-time allocation before starting test execution.
    *********************************************************** **/

void forceBoostRegexOneTimeAllocation() {
  DateUtil::dateFromString(&amp;quot;1/1/1980&amp;quot;);
}

int main(int argc, char **argv) {
  forceBoostRegexOneTimeAllocation();
  return CommandLineTestRunner::RunAllTests(argc, argv);
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Since this one-time allocation happens before any of the tests run, it is no longer reported as a problem by CppUTest.&lt;/p&gt;


	&lt;p&gt;Before I introduced this &amp;#8220;fix&amp;#8221;, I spent quite a bit of time to verify that each of the 10 allocations were done by one of the three lines dealing with regex code in my DateUtil class. I used a conditional breakpoint and looked at the stack trace. (I know, using the debugger is considered a code smell, but not all smells are bad.)&lt;/p&gt;


&lt;h3&gt;Conclusion&lt;/h3&gt;
I still like CppUTest. I&amp;#8217;ve used a few C++ unit testing tools but there are several I have not tried. I don&amp;#8217;t have enough face-time with C++ for this to be an issue. I am not terribly comfortable with the order of includes sensitivity. I&amp;#8217;m not sure if that would scale.&lt;p/&gt;

	&lt;p&gt;I do appreciate the assistance with memory checking, though dealing with false positives can be a bit of a hassle. There was another technique, that of expressing the number of allocations. But in this case, that simply deferred the reporting of memory leaks to after test execution. In any case, I do like this. I&amp;#8217;m not sure how well it would scale so it leaves me a bit uneasy.&lt;p/&gt;&lt;/p&gt;


	&lt;p&gt;If you happen to be using these tools, hope this helps. If not, and you are using C++, what can you say about your experiences with using this or other unit testing tools?&lt;/p&gt;</description>
      <pubDate>Thu, 04 Feb 2010 13:42:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:3b1ab465-7276-4c72-9361-9103092a7ca5</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/02/04/cpputest-recent-experiences</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>TDD</category>
      <category>c</category>
      <category>boost</category>
      <category>memory</category>
      <category>allocation</category>
    </item>
    <item>
      <title>Makefiles, what are you doing with them?</title>
      <description>&lt;p&gt;Half a year ago, I took some exercises written in Java and ported them to C++. At that time I punted on writing makefiles and decided to reply on an &lt;span class="caps"&gt;IDE&lt;/span&gt; (Visual Studio). That worked fine but recently we almost had a customer that was going to take this class and, bless their heart, use the command line.&lt;/p&gt;


	&lt;p&gt;Turns out they are going to use visual studio, so I can shelve this, but I figured I&amp;#8217;d get feedback on what I have created for a makefile. Since I have not written a makefile for 12ish years, I figured things have changed. They have, but I suspect they have even more.&lt;/p&gt;


	&lt;p&gt;What follows are my environment assumptions and the makefile. I&amp;#8217;d appreciate any suggestions.&lt;/p&gt;


	&lt;p&gt;&lt;span class="caps"&gt;FWIW&lt;/span&gt;, I wrote this makefile because it turns out fully building all files takes longer than just building what has changed. I know this seems obvious, but it is not always the case with small projects like this. There is some point where the project becomes big enough to warrant dependency-based building. The exercise meets that criteria. Sometimes the time taken to evaluate build changes is enough overhead that it can be safely removed in lieu of a full build. This is a consideration when creating custom build files for legacy-based refactoring efforts.&lt;/p&gt;


&lt;b&gt;Environment&lt;/b&gt;
	&lt;ul&gt;
	&lt;li&gt;Generic Unix&lt;/li&gt;
		&lt;li&gt;zsh &amp;#8211; though any shell will do really &lt;/li&gt;
		&lt;li&gt;g++&lt;/li&gt;
		&lt;li&gt;gnu make&lt;/li&gt;
		&lt;li&gt;This source base will still be used in Visual Studio but not this makefile&lt;/li&gt;
		&lt;li&gt;CppUTest used for unit testing tool&lt;/li&gt;
		&lt;li&gt;Provide default location for CppUTest, which can be overridden by environment variable&lt;/li&gt;
		&lt;li&gt;Boost library installed in /usr/local/include and /usr/local/lib (reasonable assumption or should I go ahead and allow this to be configured easily in the makefile &amp;#8211; what&amp;#8217;s your opinion?)&lt;/li&gt;
		&lt;li&gt;Project is small enough that all headers and source files are in the same directory (should I build the .o&amp;#8217;s and put them in another directory to hide them?)&lt;/li&gt;
	&lt;/ul&gt;


&lt;b&gt;Current Makefile&lt;/b&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;ifdef CPP_U_TEST
    CppUTest_base = $(CPP_U_TEST)
else
    CppUTest_base = $(wildcard ~/src/cpputest)
endif

LIB_DIRS = -L$(CppUTest_base)/lib
INC_DIRS = -I$(CppUTest_base)/include
LIBS = -lCppUTest -lboost_date_time -lboost_regex -lboost_thread
CFLAGS = -g $(INC_DIRS) 
LDFLAGS = $(LIB_DIRS) $(LIBS)
CC = g++
SRCS := $(wildcard *.cpp)
OBJS = $(SRCS:.cpp=.o)
OUT = run_all_tests
DEP_DIR = dependencies

all: $(OBJS)
    $(CC) $(CFLAGS) $(LDFLAGS) -o $(OUT) $(OBJS)

clean:
    @rm -rf $(DEP_DIR) $(OBJS) $(OUT)

-include $(SRCS:.cpp=$(dep_dir)/.d)

.cpp.o:
    @if [ ! -d $(DEP_DIR) ] ; then mkdir $(DEP_DIR) ; fi
    $(CC) -c $(CFLAGS) -o $@ $&amp;lt; 
    @$(CC) -MM $(CFLAGS) $*.cpp &amp;gt; $(DEP_DIR)/$*.d&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
      <pubDate>Wed, 27 Jan 2010 09:02:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:2e89212d-2630-4f8c-ac26-b1c8091cd19c</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/01/27/makefiles-what-are-you-doing-with-them</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>c</category>
      <category>makefile</category>
      <category>gnu</category>
      <category>build</category>
    </item>
    <item>
      <title>Name that refactoring: 2 - Version 2</title>
      <description>&lt;p&gt;A few updates applied to the second name that refactoring. Note that I&amp;#8217;m using a star to represent a problem dependency. It is the &amp;#8220;star&amp;#8221; of the refactoring. I&amp;#8217;m looking for a better image. I could go with a database icon, but the principle is more general than that. The cloud was confusing. So if you have an idea, please let me know what it is!&lt;/p&gt;


	&lt;p&gt;Again, thanks for taking a look and giving me the feedback.&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;&lt;i&gt;Step 0: Problematic Dependency&lt;/i&gt;&lt;/b&gt;&lt;p/&gt;
&lt;img src="http://schuchert.wikispaces.com/file/view/NameThatRefactoring_2-0.png/109818239/NameThatRefactoring_2-0.png"/&gt;&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;&lt;i&gt;Step 1: Capture dependency in a single class&lt;/i&gt;&lt;/b&gt;&lt;p/&gt;
&lt;img src="http://schuchert.wikispaces.com/file/view/NameThatRefactoring_2-1.png/109818237/NameThatRefactoring_2-1.png"/&gt;&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;&lt;i&gt;Step 2: Raise the abstraction to a domain-level interface&lt;/i&gt;&lt;/b&gt;&lt;p/&gt;
&lt;img src="http://schuchert.wikispaces.com/file/view/NameThatRefactoring_2-2.png/109818235/NameThatRefactoring_2-2.png" /&gt;&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;&lt;i&gt;Step 3: Introduce test doubles as needed&lt;/i&gt;&lt;/b&gt;&lt;p/&gt;
&lt;img src="http://schuchert.wikispaces.com/file/view/NameThatRefactoring_2-3.png/109818233/NameThatRefactoring_2-3.png" /&gt;&lt;/p&gt;</description>
      <pubDate>Wed, 16 Dec 2009 02:14:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:8a78598f-7598-49e9-85c3-415b4afb89f3</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2009/12/16/name-that-refactoring-2-version-2</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>refactoring</category>
      <category>TDD</category>
      <category>picture</category>
      <category>writing</category>
    </item>
    <item>
      <title>Name that refactoring: 1 - Version 2</title>
      <description>&lt;p&gt;Here is an update to the first name that refactoring based on feedback. How about this?&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;&lt;i&gt;Step 0: Method with embedded dependency&lt;/b&gt;&lt;/i&gt;&lt;p/&gt;
&lt;img src="http://schuchert.wikispaces.com/file/view/NameThatRefactoring_1-1.png/109816073/NameThatRefactoring_1-1.png"/&gt;&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;&lt;i&gt;Step 1:Extract method to move dependency to another method&lt;/b&gt;&lt;/i&gt;&lt;p/&gt;
&lt;img src="http://schuchert.wikispaces.com/file/view/NameThatRefactoring_1-2.png/109816629/NameThatRefactoring_1-2.png"/&gt;&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;&lt;i&gt;Step 2: Subclass and override method with new code that does not have original dependency&lt;/b&gt;&lt;/i&gt;&lt;p/&gt;
&lt;img src="http://schuchert.wikispaces.com/file/view/NameThatRefactoring_1-3.png/109816627/NameThatRefactoring_1-3.png"/&gt;&lt;/p&gt;


	&lt;p&gt;So what do you think? Better or worse?&lt;/p&gt;


	&lt;p&gt;What about using the star in other image? In general, the star could represent the dependency we&amp;#8217;re trying to get rid of.&lt;/p&gt;</description>
      <pubDate>Wed, 16 Dec 2009 01:43:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:f54168c7-20d6-4c62-ba6f-7de62ec2295d</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2009/12/16/name-that-refactoring-1-version-2</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>refactoring</category>
      <category>TDD</category>
      <category>picture</category>
      <category>writing</category>
    </item>
    <item>
      <title>Name that refactoring: 2</title>
      <description>&lt;p&gt;Ok, so I&amp;#8217;m getting good feedback on the first picture. Now for a series of pictures.&lt;/p&gt;


	&lt;p&gt;How do you interpret this series?&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;&lt;i&gt;Step 0&lt;/b&gt;&lt;/i&gt;&lt;p/&gt;
&lt;img src="http://schuchert.wikispaces.com/file/view/NameThatRefactoring_2-1.png/109310773/NameThatRefactoring_2-1.png"/&gt;&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;&lt;i&gt;Step 1&lt;/b&gt;&lt;/i&gt;&lt;p/&gt;
&lt;img src="http://schuchert.wikispaces.com/file/view/NameThatRefactoring_2-2.png/109310771/NameThatRefactoring_2-2.png"/&gt;&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;&lt;i&gt;Step 2&lt;/b&gt;&lt;/i&gt;&lt;p/&gt;
&lt;img src="http://schuchert.wikispaces.com/file/view/NameThatRefactoring_2-3.png/109310769/NameThatRefactoring_2-3.png"/&gt;&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;&lt;i&gt;Step 3&lt;/b&gt;&lt;/i&gt;&lt;p/&gt;
&lt;img src="http://schuchert.wikispaces.com/file/view/NameThatRefactoring_2-4.png/109310767/NameThatRefactoring_2-4.png"/&gt;&lt;/p&gt;</description>
      <pubDate>Sun, 13 Dec 2009 22:51:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:f612878a-68b6-427b-bca5-78783f70c884</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2009/12/13/name-that-refactoring-2</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>refactoring</category>
      <category>TDD</category>
      <category>picture</category>
      <category>writing</category>
    </item>
    <item>
      <title>Name that refactoring: 1</title>
      <description>&lt;p&gt;I&amp;#8217;m working on writing up a few handouts I can use in a &lt;span class="caps"&gt;TDD&lt;/span&gt; class (and a few other places). There are a few drawings I keep doing and I&amp;#8217;m trying to replicate them so I can refer to something.&lt;/p&gt;


Problem is, with many such drawings, the observation of the creation is as important as the end product. I&amp;#8217;d like your feedback/recommendations (or links to better pictures). I&amp;#8217;m curious about at least two things.
	&lt;ul&gt;
	&lt;li&gt;What does this picture suggest to you or what can you draw from it, if anything?&lt;/li&gt;
		&lt;li&gt;Do you think this would be better served as a series of pictures showing the build-up?&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;&lt;img src=http://schuchert.wikispaces.com/file/view/NameThatRefactoring_1.png/109280805/NameThatRefactoring_1.png"&gt;&lt;/p&gt;


	&lt;p&gt;Thanks for your feedback.&lt;/p&gt;</description>
      <pubDate>Sun, 13 Dec 2009 19:35:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:55886ea2-c35a-4ab2-a166-7e2dd425404b</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2009/12/13/name-that-refactoring-1</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>refactoring</category>
      <category>TDD</category>
      <category>picture</category>
      <category>writing</category>
    </item>
    <item>
      <title>the Importance of Observers</title>
      <description>&lt;p&gt;This week I spent 2 days with my friend &lt;a href="http://www.enthiosys.com/"&gt;Luke Hohmann&lt;/a&gt; getting trained in the use of &lt;a href="http://www.amazon.com/Innovation-Games-Creating-Breakthrough-Collaborative/dp/0321437292/ref=sr_1_1?ie=UTF8&amp;#38;s=books&amp;#38;qid=1259949907&amp;#38;sr=8-1"&gt;Innovation Games&amp;#174;&lt;/a&gt;. &lt;a href="http://www.amazon.com/Innovation-Games-Creating-Breakthrough-Collaborative/dp/0321437292/ref=sr_1_1?ie=UTF8&amp;#38;s=books&amp;#38;qid=1259949907&amp;#38;sr=8-1"&gt;Innovation Games&amp;#174;&lt;/a&gt; are a class of so-called serious games that use metaphor and experiential learning situations with an end-result-goal of developing actionable information. (This is my current way of describing them anyway.)&lt;/p&gt;


	&lt;p&gt;During one of these games I played the role of a facilitator. There were 2 of us facilitating, three &amp;#8220;customers&amp;#8221; being interviewed and 4 observers.&lt;/p&gt;


	&lt;p&gt;In my typical consulting role, I am often playing the role of facilitator, but I also have set myself up as an observer at the same time. In the past, this has seemed to make sense given I was the only consultant in the room. This recent experience, however, has really changed how I think about those situations.&lt;/p&gt;


In the design of &lt;a href="http://www.amazon.com/Innovation-Games-Creating-Breakthrough-Collaborative/dp/0321437292/ref=sr_1_1?ie=UTF8&amp;#38;s=books&amp;#38;qid=1259949907&amp;#38;sr=8-1"&gt;Innovation Games&amp;#174;&lt;/a&gt;, the facilitator will typically have a number (1/2 &amp;#8211; 1/3) of the participants serve as observers. This has several advantages.
	&lt;ul&gt;
	&lt;li&gt;The facilitator can focus on one thing (think single responsibility principle).&lt;/li&gt;
		&lt;li&gt;Different observers, different filters (we all have filters all of the time), resulting in more perspectives captured, giving better overall information.&lt;/li&gt;
		&lt;li&gt;Given enough observers, you can have individual observers focus on specific things.&lt;/li&gt;
		&lt;li&gt;Since the observers are typically from the team (not the consulting company), it reinforces the notion of ownership. The facilitator does not own the results, nor does s/he produce the results.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Why so many observers? &lt;a href="http://www.amazon.com/Innovation-Games-Creating-Breakthrough-Collaborative/dp/0321437292/ref=sr_1_1?ie=UTF8&amp;#38;s=books&amp;#38;qid=1259949907&amp;#38;sr=8-1"&gt;Innovation Games&amp;#174;&lt;/a&gt; are designed to get access to the things you don&amp;#8217;t know you don&amp;#8217;t know.&lt;/p&gt;


Jerry Weinberg has a simple model of leadership. The &lt;span class="caps"&gt;MOIJ&lt;/span&gt; model.
	&lt;ul&gt;
	&lt;li&gt;M is for Motivation&lt;/li&gt;
		&lt;li&gt;O is for Organization&lt;/li&gt;
		&lt;li&gt;I is for Innovation&lt;/li&gt;
		&lt;li&gt;J is for Jiggle&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;In any situation, take a read. Do you have too much Motivation or too little? Too much? People are frantic and running around like kids just after getting back from a successful night of trick-or-treating. Too little? Everybody is exhausted from yet another all nighter getting ready for a demo because too much focus was placed on adding stuff rather than adding stuff well.&lt;/p&gt;


	&lt;p&gt;The same idea applies to Organization and Innovation. It is possible to have to much or too little organization and too many or too few ideas.&lt;/p&gt;


	&lt;p&gt;What happens when none of those first three seem to fit? That&amp;#8217;s the Jiggle. You introduce some random element to see if you can get access to something you don&amp;#8217;t know you don&amp;#8217;t know.&lt;/p&gt;


	&lt;p&gt;With many observers (e.g. 8-10 in a group of 20), you have the flexibility to have someone look at hand gestures, someone to look at eye contact, someone to listen to change in vocal pitch, etc. That is, you have &amp;#8220;typical&amp;#8221; observers listening for &amp;#8220;important&amp;#8221; information and &amp;#8220;jiggiling&amp;#8221; observers searching form something else. Since you don&amp;#8217;t know what you don&amp;#8217;t know, doing things with specific kinds of observations might jiggle out information that otherwise you would have missed. It may not, that&amp;#8217;s part of the problem of trying to work in the space of you don&amp;#8217;t know you don&amp;#8217;t know.&lt;/p&gt;


	&lt;p&gt;In any case, to me this is now one of those &amp;#8220;intuitive once you know it&amp;#8221; things. In the past, I have worked within my self-perceived constraints of being a single person with 2 roles needing to be filled. Maybe on an intellectual level I understood the value of having observers separate from the facilitator but I did not really grok it.&lt;/p&gt;


	&lt;p&gt;Now I think I do.&lt;/p&gt;


	&lt;p&gt;Will I always separate those roles? I don&amp;#8217;t believe in context-free best practices, so no. However, will I make this my default preference? I&amp;#8217;ll certainly work on it.&lt;/p&gt;


	&lt;p&gt;More specifically, how am I going to use this new knowledge?&lt;/p&gt;


	&lt;p&gt;In 2 weeks, Michael Feathers and I are co-teaching an Agile/XP Immersion in Seattle. I&amp;#8217;ve already planned to use a few of the &lt;a href="http://www.amazon.com/Innovation-Games-Creating-Breakthrough-Collaborative/dp/0321437292/ref=sr_1_1?ie=UTF8&amp;#38;s=books&amp;#38;qid=1259949907&amp;#38;sr=8-1"&gt;Innovation Games&amp;#174;&lt;/a&gt; during the class. The big difference, however, is that I&amp;#8217;m going to encourage a number of the students to play the role of an observer (listening, recording, saying nothing) to give the customer a chance to own what&amp;#8217;s going on rather than being the recipient of a technique.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;m sure it will take me some time to embody this new approach as my default rather than falling back on the (up until now) current way I&amp;#8217;ve been doing things. I&amp;#8217;m sure I&amp;#8217;ll stumble along the way. But as long as I keep making new mistakes and not repeating the old ones over and over, I&amp;#8217;ll be moving in a good direction.&lt;/p&gt;</description>
      <pubDate>Fri, 04 Dec 2009 11:51:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:39dbbe5e-7638-422c-9828-d3146b3cb7c2</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2009/12/04/the-importance-of-observers</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>innovation</category>
      <category>games</category>
      <category>r</category>
      <category>observation</category>
    </item>
    <item>
      <title>Oh you poor, poor customer</title>
      <description>&lt;p&gt;I just got back from my third time at the &lt;a href="http://www.ayeconference.com/"&gt;&lt;span class="caps"&gt;AYE&lt;/span&gt;&lt;/a&gt; conference and it was another great time. I had a real eye-opening experience on Wednesday and it had to do with how I interact with customers, QA and even developers. Pretty much anybody taking a class or starting a project where I am involved.&lt;/p&gt;


I participated in a simulation of a project, playing the role of customer.
	&lt;ul&gt;
	&lt;li&gt;There were two of us playing customers &amp;#8211; we did not understand the problem and we did not necessarily agree or understand where we had different interpretations&lt;/li&gt;
		&lt;li&gt;We were freshly assigned the role and did not quite understand the details of the problem, our actual responsibility or how to interact with the team (a deficit of tacit knowledge)&lt;/li&gt;
		&lt;li&gt;Time was (perceived to be) at a premium&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;The session/simulation was run with great expertise by &lt;a href="http://www.donaldegray.com/tiki-index.php"&gt;Don Gray&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;My first really strong observation was during the first meeting with the development group &amp;#8211; about 5 minutes in. My co-customer and I had spent a few minutes (literally) reading the requirements and coming to some partial understanding. We met with the &amp;#8220;simulated&amp;#8221; development team and all hell broke loose (at least in my head).&lt;/p&gt;


The development team did some things well.
	&lt;ul&gt;
	&lt;li&gt;They tried to think of something small they could do in a time-box.&lt;/li&gt;
		&lt;li&gt;They presented us (the customers) with concrete examples of things they could do as first examples.&lt;/li&gt;
		&lt;li&gt;They asked concrete questions about the requirements.&lt;/li&gt;
		&lt;li&gt;The presented some preliminary examples of possible interpretations.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;These are all good things; things I would and have recommend in the past &amp;#8211; and will contine to do in the future. And these things&lt;i&gt; &lt;b&gt;did not work for me&lt;/b&gt;&lt;/i&gt;.&lt;/p&gt;


&amp;#8220;Playing&amp;#8221; the role of customer, when I came to that initial meeting there were many things in flux.
	&lt;ul&gt;
	&lt;li&gt;I did not really have much of an idea of a time-box.&lt;/li&gt;
		&lt;li&gt;I had looked at the problem in a very different way than the development team, so many of their questions simply did not make any sense to me.&lt;/li&gt;
		&lt;li&gt;I felt bombarded by many voices, with many different kinds and levels of content.&lt;/li&gt;
	&lt;/ul&gt;


I took away quite a bit away from that experience that I&amp;#8217;d do well to incorporate in my future interactions.
	&lt;ul&gt;
	&lt;li&gt;I am a big-time &lt;a href="http://en.wikipedia.org/wiki/Extraversion_and_introversion"&gt;extravert&lt;/a&gt; (Jung&amp;#8217;s definition) and I&amp;#8217;ve been the source of this kind of bombardment.&lt;/li&gt;
		&lt;li&gt;I need to catch myself jumping right in on what I think is important and instead&lt;i&gt; &lt;b&gt;ask what is important&lt;/b&gt;&lt;/i&gt; to the customer (or BA or QA or developer for that matter).&lt;/li&gt;
		&lt;li&gt;I probably have overly high expectations of what can be accomplished before the team has started to form, much of that initial interaction lacks the tacit knowledge of actual roles and requirements, such that many things are in flux.&lt;/li&gt;
		&lt;li&gt;Or, given a team that has been together, I need to get a grasp on its structure before making change recommendations.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;At one point, someone mentioned (in essence) that the &amp;#8220;actual&amp;#8221; requirements were coming from Don, not me, and essentially wrote me off. That was quite a powerful experience as I felt completely devalued as the customer. I can imagine a business person or QA person feeling the same thing.&lt;/p&gt;


	&lt;p&gt;I think the biggest one-word summary of the experience for me is empathy.&lt;/p&gt;


	&lt;p&gt;&amp;#8220;After&amp;#8221; the simulation (I still had not fully decompressed I think), one person expressed concern over how the customers (me) had not followed &amp;#8220;the process&amp;#8221;. Wow is all I can say to my experience during that simple, loaded phrase.&lt;/p&gt;


	&lt;p&gt;In my world of the simulation, there was no process &amp;#8211; explicit or implicit. If there was one used by the team, it was tacit and I certainly was not aware of it (in fact, I don&amp;#8217;t think there was one &amp;#8220;the process&amp;#8221; as far as I could tell because I was able to both participate and observe). But regardless of whether there was or was not an explicit or implicit process, it does not matter. Can you imagine someone who is not fully available (a customer), being treated as if they were &amp;#8220;not following the process?&amp;#8221;, which I inferred to mean &amp;#8220;I was being difficult.&amp;#8221;&lt;/p&gt;


When I&amp;#8217;ve thought that, consciously or even subconsciously, I&amp;#8217;m certain that belief clouded my interactions with other people and it probably has come across as aggressive/offensive/inconsiderate. Maybe a good mantra to repeat to myself is something like:
&lt;blockquote&gt;
&lt;b&gt;&lt;i&gt;No matter how it might look, people are trying to be helpful to the best of their ability.&lt;/b&gt;&lt;/i&gt;
&lt;/blockquote&gt;

I know for certain my intentions during that simulation were good. I was trying to give information to the best of my abilities. I just wasn&amp;#8217;t yet aware of the requirements and I did not know how the development team was working. To be treated as if I was sabotaging &amp;#8220;the process&amp;#8221; was in fact quite offensive to me. I am certain I&amp;#8217;ve done that over the years. &amp;#8220;The process&amp;#8221;, regardless of which process it is, is a&lt;i&gt; &lt;b&gt;model&lt;/b&gt;&lt;/i&gt; of how to do things. And something I overheard really speaks about this:
&lt;blockquote&gt;
&lt;b&gt;&lt;i&gt;All models are wrong; some are useful.&lt;/b&gt;&lt;/i&gt;
&lt;/blockquote&gt;

	&lt;p&gt;(Notice how that applies to things like &lt;span class="caps"&gt;TDD&lt;/span&gt;, BDD, Scrum, XP, ...?-)&lt;/p&gt;


	&lt;p&gt;If you have a chance to attend &lt;span class="caps"&gt;AYE&lt;/span&gt; next year (or &lt;span class="caps"&gt;PSL&lt;/span&gt; in May), I&amp;#8217;d encourage you to do so. But be prepared to be overwhelmed with personal observations.&lt;/p&gt;</description>
      <pubDate>Fri, 13 Nov 2009 13:12:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:1d89322b-a60b-4c2c-b420-ac6fb43338e4</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2009/11/13/oh-you-poor-poor-customer</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>Extroversion</category>
      <category>aye</category>
      <category>tacit</category>
      <category>process</category>
      <category>people</category>
    </item>
    <item>
      <title>C++ Bowling Kata Result</title>
      <description>&lt;p&gt;I&amp;#8217;m teaching a &lt;span class="caps"&gt;TDD&lt;/span&gt; and Refactoring class this week using C&amp;#43;&amp;#43;. Since I had not recently wrote the bowling kata in C&amp;#43;&amp;#43;, I figured it was about time to do it again.&lt;/p&gt;


	&lt;p&gt;Unlike the previous Scala version, this one only addresses the happy-path. I do not consider throwing too many balls or scoring too many pins in any frame. However, having just written this in Scala, I&amp;#8217;m sure I could do something similar in C&amp;#43;&amp;#43;.&lt;/p&gt;


	&lt;p&gt;I just switched to &lt;a href="http://sourceforge.net/projects/cpputest/"&gt;CppUTest 2.0&lt;/a&gt; and something I noticed is that if you use &amp;lt;vector&amp;gt; or other std-based classes, you need to make sure to include those first before including &amp;lt;CppUTest/TestHarness.h&amp;gt;. This is because CppUTest overloads new and delete, which causes havoc with the std-based classes. No big deal, I just made sure to include that file as the last header (rather than the first, which is what I used to do).&lt;/p&gt;


Here are the various files:
&lt;p/&gt;&lt;b&gt;&lt;i&gt;RunAllTests.cpp&lt;/b&gt;&lt;/i&gt;
&lt;div class="typocode"&gt;&lt;table class="typocode_linenumber"&gt;&lt;tr&gt;&lt;td class="lineno"&gt;
&lt;pre&gt;
1
2
3
4
5
&lt;/pre&gt;
&lt;/td&gt;&lt;td width="100%"&gt;&lt;pre&gt;&lt;code class="typocode_cpp "&gt;#include &amp;lt;CppUTest/CommandLineTestRunner.h&amp;gt;

int main(int argc, char** argv) {
  CommandLineTestRunner::RunAllTests(argc, argv);
}&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p/&gt;&lt;b&gt;&lt;i&gt;BowlingScoreCardTest.cpp&lt;/b&gt;&lt;/i&gt;
&lt;div class="typocode"&gt;&lt;table class="typocode_linenumber"&gt;&lt;tr&gt;&lt;td class="lineno"&gt;
&lt;pre&gt;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
&lt;/pre&gt;
&lt;/td&gt;&lt;td width="100%"&gt;&lt;pre&gt;&lt;code class="typocode_cpp "&gt;#include &amp;quot;BowlingScoreCard.h&amp;quot;

#include &amp;lt;CppUTest/TestHarness.h&amp;gt;

TEST_GROUP(BowlingScoreCard) {
  BowlingScoreCard* card;

  TEST_SETUP() {
    card = new BowlingScoreCard;
  }

  TEST_TEARDOWN() {
    delete card;
  }

  void throwOne(int value) {
      card-&amp;gt;recordThrow(value);
  }

  void throwMany(int rolls, int value) {
    for(int i = 0; i &amp;lt; rolls; ++i)
      throwOne(value);
  }

  void confirmScoreIs(int expected) {
    LONGS_EQUAL(expected, card-&amp;gt;score());
  }
};

TEST(BowlingScoreCard, noRollsGame) {
  confirmScoreIs(0);
}

TEST(BowlingScoreCard, throwAll0s) {
  throwMany(20, 0);
  confirmScoreIs(0);
}

TEST(BowlingScoreCard, throwAll1s) {
  throwMany(20, 1);
  confirmScoreIs(20);
}

TEST(BowlingScoreCard, throwOneSpare) {
  throwOne(7);
  throwOne(3);
  throwOne(6);
  throwMany(17, 0);
  confirmScoreIs(22);
}

TEST(BowlingScoreCard, all5sthrown) {
  throwMany(21, 5);
  confirmScoreIs(150);
}

TEST(BowlingScoreCard, throwOneStrike) {
  throwOne(10);
  throwOne(4);
  throwOne(3);
  confirmScoreIs(24);
}

TEST(BowlingScoreCard, perfectGame) {
  throwMany(12, 10);
  confirmScoreIs(300);
}

TEST(BowlingScoreCard, dutch200StrikeSpare) {
  for(int i = 0; i &amp;lt; 10; ++i) {
    throwOne(10);
    throwMany(2, 5);
  }
  throwOne(10);
  confirmScoreIs(200);
}

TEST(BowlingScoreCard, dutch200SpareStrike) {
  for(int i = 0; i &amp;lt; 10; ++i) {
    throwMany(2, 5);
    throwOne(10);
  }
  throwMany(2, 5);
  confirmScoreIs(200);
}&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p/&gt;&lt;b&gt;&lt;i&gt;BowlingScoreCard.h&lt;/b&gt;&lt;/i&gt;
&lt;div class="typocode"&gt;&lt;table class="typocode_linenumber"&gt;&lt;tr&gt;&lt;td class="lineno"&gt;
&lt;pre&gt;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
&lt;/pre&gt;
&lt;/td&gt;&lt;td width="100%"&gt;&lt;pre&gt;&lt;code class="typocode_cpp "&gt;#pragma once

#ifndef BOWLING_SCORE_CARD_H
#define BOWLING_SCORE_CARD_H

#include &amp;lt;vector&amp;gt;
using namespace std;

class BowlingScoreCard
{
public:
  enum { Frames = 10, Mark = 10 };

  BowlingScoreCard();
  virtual ~BowlingScoreCard();
  int score();
  void recordThrow(int roll);

private:
  typedef vector&amp;lt;int&amp;gt; v_int;
  typedef v_int::size_type size_type;

  int scoreFrameAt(size_type index);
  int nextTwoRollsSummed(size_type index);
  int scoreAt(size_type index);
  int frameSizeAt(size_type index);
  bool isStrikeAt(size_type index);
  bool isSpareAt(size_type index);
  int scoreStrikeAt(size_type index);
  int scoreSpareAt(size_type index);

  v_int rolls;
};

#endif&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p/&gt;&lt;b&gt;&lt;i&gt;BowlingScoreCard.cpp&lt;/b&gt;&lt;/i&gt;
&lt;div class="typocode"&gt;&lt;table class="typocode_linenumber"&gt;&lt;tr&gt;&lt;td class="lineno"&gt;
&lt;pre&gt;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
&lt;/pre&gt;
&lt;/td&gt;&lt;td width="100%"&gt;&lt;pre&gt;&lt;code class="typocode_cpp "&gt;#include &amp;quot;BowlingScoreCard.h&amp;quot;

BowlingScoreCard::BowlingScoreCard() {
}

BowlingScoreCard::~BowlingScoreCard() {
}

int BowlingScoreCard::score() {
  int score = 0;

  for(int index = 0, frame = 0; frame &amp;lt; Frames; ++frame) {
    score += scoreFrameAt(index);
    index += frameSizeAt(index);
  }

  return score;
}

int BowlingScoreCard::scoreFrameAt(size_type index) {
  if(isStrikeAt(index))
    return scoreStrikeAt(index);
  else if(isSpareAt(index))
    return scoreSpareAt(index);

  return nextTwoRollsSummed(index);
}

bool BowlingScoreCard::isStrikeAt(size_type index) {
  return scoreAt(index) == Mark;
}

bool BowlingScoreCard::isSpareAt(size_type index) {
  return !isStrikeAt(index) &amp;amp;&amp;amp; nextTwoRollsSummed(index) == Mark;
}

int BowlingScoreCard::scoreStrikeAt(size_type index) {
  return Mark + nextTwoRollsSummed(index + 1);
}

int BowlingScoreCard::scoreSpareAt(size_type index) {
  return Mark + scoreAt(index + 2);
}

int BowlingScoreCard::frameSizeAt(size_type index) {
  if(scoreAt(index) == Mark)
    return 1;
  return 2;
}

int BowlingScoreCard::nextTwoRollsSummed(size_type index) {
  return scoreAt(index) + scoreAt(index + 1);
}

int BowlingScoreCard::scoreAt(size_type index) {
  return index &amp;lt; rolls.size() ? rolls[index] : 0;
}

void BowlingScoreCard::recordThrow(int roll) {
  rolls.push_back(roll);
}&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

	&lt;p&gt;I sure do miss refactoring tools!-)&lt;/p&gt;</description>
      <pubDate>Tue, 27 Oct 2009 15:37:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:21e94a12-259b-4c2d-968b-7b8cea58c877</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2009/10/27/c-bowling-kata-result</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>c</category>
      <category>kata</category>
      <category>bowling</category>
      <category>TDD</category>
    </item>
    <item>
      <title>Scala Bowling Kata - still in the middle I suppose</title>
      <description>I had a 3.5 hour flight today. I realized I was missing some of the validation from the Ruby version related to how many rolls a valid game should allow:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_scala "&gt;  &amp;quot;One more roll on a game with 20 rolls and an open 10th frame&amp;quot; should {
    20 times { roll(1) }
    roll(1) must throwA[IllegalArgumentException]
  }

  &amp;quot;Two more rolls a game with 10 spares&amp;quot; should {
    10 times { spare }
    roll(1)
    roll(1) must throwA[IllegalArgumentException]
  }

  &amp;quot;Two marks in the 10th frame should&amp;quot; should {
    18 times { roll(1) }
    strike
    spare
    roll(1) must throwA[IllegalArgumentException]
  }&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;On my flight from &lt;span class="caps"&gt;DFW&lt;/span&gt; to &lt;span class="caps"&gt;SNA&lt;/span&gt;, I got these behaviors implemented. The code was pretty ugly!&lt;/p&gt;


	&lt;p&gt;However, ugly code in hand, passing examples, a slight understanding of some of the problems with my code and a desire to make the BowlingScorer immutable was all I needed to make progress.&lt;/p&gt;


I removed the index instance field by rewriting the score method and injecting a tuple into foldLeft (written here using the short-hand notation /:):
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_scala "&gt;  def scoreAt(frame:Int) = 
    ((0,0) /: (1 to frame)) { (t, _) =&amp;gt;  
      (t._1 + scoreAtIndex(t._2), t._2 + incrementAt(t._2))
    }._1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

I had a mini state machine to track whether the first ball had been thrown yet or not. I replaced that by walking the list of scores:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;  def onFirstThrow = {
    var index = 0
    while(index &amp;lt; rolls.length)
      if(isStrike(index)) index += 1 else index += 2
    index == rolls.length
  }&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;While I am happy I was able to remove the index variable, which was really a parameter being passed around in a field (ugly), I am not happy with this method.&lt;/p&gt;


I changed the roll method to return a new instance of a BowlingScorer, making the bowling scorer immutable:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_scala "&gt;  def roll(roll:Int) = {
    validate(roll)
    new BowlingScorer(rolls ++ Array(roll))
  }&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;So I think I&amp;#8217;m still somewhere in the middle of working through this code. Again, I&amp;#8217;m still learning Scala. I have a lot to learn. I really only barely understand functional programming and, frankly, the Eclipse &lt;span class="caps"&gt;IDE&lt;/span&gt;, while functional, is getting in the way quite a bit. So for a toy example it is OK. Given the choice of this environment or vi and the command line, I&amp;#8217;d not pick the former. (I might give the other &lt;span class="caps"&gt;IDE&lt;/span&gt;&amp;#8217;s a go, but that&amp;#8217;s not really what I&amp;#8217;m interested in learning right now.)&lt;/p&gt;


	&lt;p&gt;So here&amp;#8217;s the next version. I plan to work through all of the comments I&amp;#8217;ve yet to process from the previous blog posting over the next few days. If you can recommend a better implementation of onFirstThrow, I&amp;#8217;d appreciate it.&lt;/p&gt;


	&lt;p&gt;Other general comments also welcome.&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;&lt;i&gt;BowlingScorerExampleGroup.scala&lt;/b&gt;&lt;/i&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_scala "&gt;package com.om.example

import org.specs._

object BowlingScorerExampleGroup extends SpecificationWithJUnit {
  var scorer = new BowlingScorer(Nil);

  def roll(value:Int) =
    scorer = scorer.roll(value) 

  def haveAScoreOf(expected:Int) =
    scorer.score must_== expected

  def strike =
    roll(10)

  def spare {
    roll(5)
    roll(5)
  }

  implicit def intToDo(count: Int) = {
    new {
      def times(f: =&amp;gt; Unit) = {
        1 to count foreach { _ =&amp;gt; f }
      }
    }
  }

  &amp;quot;A Newly Created Bowling Scorer&amp;quot; should {
    haveAScoreOf(0)
  }

  &amp;quot;A game with all 0's&amp;quot; should {
    20 times { roll(0) }
    haveAScoreOf(0)
  }

  &amp;quot;A game with all 1's&amp;quot; should {
    20 times { roll(1) }
    haveAScoreOf(20)
  }

  &amp;quot;A game with a single spare followed by a 5&amp;quot; should {
    spare
    roll(5)
    haveAScoreOf(20)
  }

  &amp;quot;A game with all 5's&amp;quot; should {
    10 times { spare }
    roll(5)
    haveAScoreOf(150)
  }

  &amp;quot;A game with a single strike followed by a 4&amp;quot; should {
    strike
    roll(4)
    haveAScoreOf(18)
  }

  &amp;quot;A game with a strike, spare then an open frame with two 3's&amp;quot; should {
    strike
    spare
    2 times { roll(3) }
    haveAScoreOf(39)
  }

  &amp;quot;A game with strike, spare then an open frame with two 3's&amp;quot; should {
    spare
    strike
    2 times { roll(3) }
    haveAScoreOf(42)
  }

  &amp;quot;A Dutch 200 game, Spare-Strike&amp;quot; should {
    5 times {
      spare 
      strike
    }
    spare
    haveAScoreOf(200)
  }

  &amp;quot;A Dutch 200 game, Strike-Spare&amp;quot; should {
    5 times {
      strike
      spare 
    }
    strike
    haveAScoreOf(200)
  } 

  &amp;quot;A Perfect game&amp;quot; should {
    12 times { strike }
    haveAScoreOf(300)
  }

  &amp;quot;The score for each frame of a Perfect game, each frame&amp;quot; should {
    12 times { strike }
    1 to 10 foreach { frame =&amp;gt; scorer.scoreAt(frame) must_== 30 * frame }
  }

  &amp;quot;An individaul roll of &amp;gt; 10&amp;quot; should {
    roll(11) must throwA[IllegalArgumentException]
  }

  &amp;quot;An iniviaul roll of &amp;lt; 0&amp;quot; should {
    roll(-1) must throwA[IllegalArgumentException]
  }

  &amp;quot;A frame trying to contain more than 10 pins&amp;quot; should {
    roll(8)
    roll(3) must throwA[IllegalArgumentException]
  }

  &amp;quot;One more roll on a game with 20 rolls and an open 10th frame&amp;quot; should {
    20 times { roll(1) }
    roll(1) must throwA[IllegalArgumentException]
  }

  &amp;quot;Two more rolls a game with 10 spares&amp;quot; should {
    10 times { spare }
    roll(1)
    roll(1) must throwA[IllegalArgumentException]
  }

  &amp;quot;Two marks in the 10th frame should&amp;quot; should {
    18 times { roll(1) }
    strike
    spare
    roll(1) must throwA[IllegalArgumentException]
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;&lt;i&gt;BowlingScorer.scala&lt;/b&gt;&lt;/i&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_scala "&gt;package com.om.example

class BowlingScorer(rollsSoFar:List[Int]){
   val rolls:List[Int] = rollsSoFar

  def roll(roll:Int) = {
    validate(roll)
    new BowlingScorer(rolls ++ Array(roll))
  }

  def validate(roll:Int) {
    if(invalidRoll(roll))
      throw new IllegalArgumentException(&amp;quot;Individaul rolls must be from 0 .. 10&amp;quot;)

    if(frameRollTooHigh(roll))
      throw new IllegalArgumentException(&amp;quot;Total of rolls for frame must not exceed 10&amp;quot;);

    if(willBeTooManyRolls)
      throw new IllegalArgumentException(&amp;quot;Game over, no more rolls allowed&amp;quot;)
  }

  def invalidRoll(roll:Int) = 
    (0 to 10 contains(roll)) == false  

  def frameRollTooHigh(roll:Int) =
    openScoreAt(indexToValidate) + roll &amp;gt; 10

  def willBeTooManyRolls = 
    tenthRolled(indexOf10thFrame) &amp;amp;&amp;amp; nextRollTooMany(indexOf10thFrame)

  def tenthRolled(tenthIndex:Int) = 
    tenthIndex &amp;lt; rolls.length

  def nextRollTooMany(tenthIndex: Int) = 
    allowedTenthFrameRolls(tenthIndex) &amp;lt; rollsInTenthFrame(tenthIndex) + 1

  def indexOf10thFrame = 
    (0 /: (1 until 10)) {(c, _) =&amp;gt; c + incrementAt(c)}

  def allowedTenthFrameRolls(index:Int) =
    if(isMark(index)) 3 else 2

  def rollsInTenthFrame(index: Int) =
    rolls.length - index

  def indexToValidate =
    if(onFirstThrow) rolls.length else rolls.length - 1

  def onFirstThrow = {
    var index = 0
    while(index &amp;lt; rolls.length)
      if(isStrike(index)) index += 1 else index += 2
    index == rolls.length
  }

  def scoreAt(frame:Int) = 
    ((0,0) /: (1 to frame)) { (t, _) =&amp;gt;  
      (t._1 + scoreAtIndex(t._2), t._2 + incrementAt(t._2))
    }._1

  def score = scoreAt(10)

  def scoreAtIndex(index:Int) =
    if(isMark(index)) markScoreAt(index) else openScoreAt(index)

  def incrementAt(index:Int) =
    if(isStrike(index)) 1 else 2

  def isMark(index:Int) =
    isStrike(index) || isSpare(index)

  def isStrike(index:Int) =
    valueAt(index) == 10

  def markScoreAt(index:Int) =
    sumNext(index, 3)

  def isSpare(index:Int) =
    openScoreAt(index) == 10 &amp;amp;&amp;amp; valueAt(index) != 10

  def openScoreAt(index:Int) =
    sumNext(index, 2)

  def sumNext(index:Int, count:Int) =
    (0 /: (index until index+count))(_ + valueAt(_))

  def valueAt(index:Int) = 
    if(rolls.length &amp;gt; index) rolls(index) else 0
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;</description>
      <pubDate>Wed, 07 Oct 2009 00:51:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:92053ad6-01f8-4086-abbe-55dd0e6088d9</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2009/10/07/scala-bowling-kata-still-in-the-middle-i-suppose</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>Scala</category>
      <category>bdd</category>
      <category>specs</category>
      <category>bowling</category>
      <category>kata</category>
    </item>
    <item>
      <title>Scala Bowling Kata - somewhere in the middle...</title>
      <description>I need to do some work with Scala to update our Concurrency in Java class. We want to demonstrate some other approaches to concurrency, e.g., Scala Actors (among others). I began by shaving yaks:
	&lt;ul&gt;
	&lt;li&gt;Installed the &lt;a href="http://www.scala-lang.org/node/94"&gt;Eclipse Scala Plugin&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;Installed Scala using Mac Ports&lt;/li&gt;
		&lt;li&gt;Figured out how to get those things playing nice (the plugin page pretty much did that, but in a nutshell, add a few jar files to the classpath)&lt;/li&gt;
	&lt;/ul&gt;


Next, I wanted to use some &lt;span class="caps"&gt;BDD&lt;/span&gt; tool. I&amp;#8217;m going to try and stop using the term &lt;span class="caps"&gt;TDD&lt;/span&gt; simply because the T, which stands for Test in &lt;span class="caps"&gt;TDD&lt;/span&gt;, really means &amp;#8220;desired behavior&amp;#8221;. I considered calling it Trait Driven Development, but:
	&lt;ul&gt;
	&lt;li&gt;We don&amp;#8217;t need &lt;span class="caps"&gt;YADT&lt;/span&gt; &amp;#8211; Yet another damn term&lt;/li&gt;
		&lt;li&gt;Trait is a heavily overloaded word&lt;/li&gt;
		&lt;li&gt;I like the term &lt;span class="caps"&gt;BDD&lt;/span&gt; better and it fits.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Anyway, one such choice was &lt;a href="http://code.google.com/p/specs/"&gt;Specs&lt;/a&gt;, which is what I decided to use.&lt;/p&gt;


So back to yak shaving:
	&lt;ul&gt;
	&lt;li&gt;I added another jar to my classpath in Eclipse&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://code.google.com/p/specs/wiki/RunningSpecs#Run_your_specification_with_JUnit4_in_Eclipse"&gt;Then read how to get it running in Eclipse&lt;/a&gt;. Not too bad, I suppose.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;So now I need to learn Scala. Sure, I&amp;#8217;ve used it, but far less than Ruby. So it took me several hours to get specs running along with writing some Scala code to score a game &amp;#8211; I&amp;#8217;m glad I know the domain at least.&lt;/p&gt;


	&lt;p&gt;I wanted to make similar behaviors to the ones I wrote for the &lt;a href="http://blog.objectmentor.com/articles/2009/10/01/bowling-game-kata-in-ruby"&gt;Ruby version&lt;/a&gt;, which I did.&lt;/p&gt;


However, unlike the Ruby version, I was curious what would happen if I:
	&lt;ul&gt;
	&lt;li&gt;Took an approach similar to Uncle Bob &amp;#8211; strikes take one slot in an array&lt;/li&gt;
		&lt;li&gt;Added input validation&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;On the one hand, there are some interesting things I managed to create. On the other hand, I&amp;#8217;ve got a bit of a mess. I have a stateful object to avoid passing parameters so that I can write some of the code cleanly. I know I need to add in an intermediate computational object, and I&amp;#8217;m going to get to that. However, I wanted to get feedback on what I&amp;#8217;ve put out there so far.&lt;/p&gt;


Specifically, 
	&lt;ul&gt;
	&lt;li&gt;What do you think of the (bdd-style) examples from specc?&lt;/li&gt;
		&lt;li&gt;What is the correct way to write the Times(20).Do( ...) thing I came up with, there&lt;i&gt; &lt;b&gt;has&lt;/b&gt;&lt;/i&gt; be a better way? &lt;/li&gt;
		&lt;li&gt;For the part of the bowling scoring code that is not stateful (read this as, does not violate the &lt;span class="caps"&gt;SRP&lt;/span&gt;), what do you think of it?&lt;/li&gt;
		&lt;li&gt;How would you remove most/all of the state (other than the individual rolls) out of the Bowling scorer class? (Or would you choose to have the roll() method return a new instance of BowlingScorer with the new score recorded?)&lt;/li&gt;
		&lt;li&gt;Notice that the class maintains a mini state machine in the form of tracking whether the first ball of he current frame (not tracked) has or has not been thrown. That&amp;#8217;s only there to be able to perform input validation. I considered:
	&lt;ul&gt;
	&lt;li&gt;Walking the array&lt;/li&gt;
		&lt;li&gt;Going to 2 slots for every frame (making it easy to find the frame)&lt;/li&gt;
		&lt;li&gt;Storing a frame object (ok, I didn&amp;#8217;t really consider it, but I did think about it)&lt;/li&gt;
		&lt;li&gt;The mini state machine&lt;/li&gt;
	&lt;/ul&gt;
	&lt;/li&gt;
		&lt;li&gt;nextFrameScore uses the index instance variable, and changes it. This both violates command-query separation and demonstrates a violation of the &lt;span class="caps"&gt;SRP&lt;/span&gt;, but it made the scoreAt method look nice.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;An interesting side effect is that scoring marks (strikes and spares) uses the same approach, sum up three rolls total.&lt;/p&gt;


	&lt;p&gt;I know this needs work. What I&amp;#8217;ve got works according to its current specification (its examples), so in a sense, that&amp;#8217;s a good thing because I&amp;#8217;ve already stared experimenting with trying out different solutions. However, I am painfully aware of how unaware I am of Scala at the moment, so your (hopefully gentle) feedback will tell me what I need to learn next.&lt;/p&gt;


	&lt;p&gt;Looking forward to the virtual beating &amp;#8230;&lt;/p&gt;


	&lt;p&gt;Brett&lt;/p&gt;


Here are the two files I&amp;#8217;ve created so far (and to be clear, all of the examples pass):
&lt;p&gt;&lt;/p&gt;
&lt;b&gt;&lt;i&gt;BowlingScorerExampleGroup.scala&lt;/b&gt;&lt;/i&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_scala "&gt;package com.om.example

import org.specs._

object BowlingScorerExampleGroup extends SpecificationWithJUnit {
  var scorer = new BowlingScorer();

  def roll(value:Int) {
    scorer.roll(value) 
  }

  def rollMany(rolls:Int, value:Int) {
    0.until(rolls).foreach { arg =&amp;gt; scorer.roll(value) }
  }

  def haveAScoreOf(expected:Int) {
    scorer.score must_== expected
  }

  def strike {
    roll(10)
  }

  def spare {
    rollMany(2, 5) 
  }

  abstract class IDo {
    def Do(block: =&amp;gt; Unit) 
  }

  def Times(count:Int): IDo = {
    return new IDo {
      def Do(block: =&amp;gt; Unit) {
        1.to(count).foreach( arg =&amp;gt; block )
      }
    }
  }

  &amp;quot;A Newly Created Bowling Scorer&amp;quot; should {
    haveAScoreOf(0)
  }

  &amp;quot;A game with all 0's&amp;quot; should {
    Times(20).Do( roll(0) )
    haveAScoreOf(0)
  }

  &amp;quot;A game with all 1's&amp;quot; should {
    Times(20).Do { roll(1) }
    haveAScoreOf(20)
  }

  &amp;quot;A game with a single spare followed by a 5&amp;quot; should {
    spare
    roll(5)
    haveAScoreOf(20)
  }

  &amp;quot;A game with all 5's&amp;quot; should {
    Times(10).Do( spare ) 
    roll(5)
    haveAScoreOf(150)
  }

  &amp;quot;A game with a single strike followed by a 4&amp;quot; should {
    strike
    roll(4)
    haveAScoreOf(18)
  }

  &amp;quot;A game with a strike, spare then an open frame with two 3's&amp;quot; should {
    strike
    spare
    Times(2).Do( roll(3) )
    haveAScoreOf(39)
  }

  &amp;quot;A game with strike, spare then an open frame with two 3's&amp;quot; should {
    spare
    strike
    Times(2).Do( roll(3) )
    haveAScoreOf(42)
  }

  &amp;quot;A Dutch 200 game, Spare-Strike&amp;quot; should {
    Times(5).Do { 
      spare 
      strike
    }
    spare
    haveAScoreOf(200)
  }

  &amp;quot;A Dutch 200 game, Strike-Spare&amp;quot; should {
    Times(5).Do { 
      strike
      spare 
    }
    strike
    haveAScoreOf(200)
  } 

  &amp;quot;A Perfect game&amp;quot; should {
    Times(12).Do( strike ) 
    haveAScoreOf(300)
  }

  &amp;quot;The score for each frame of a Perfect game, each frame&amp;quot; should {
    Times(12).Do( strike ) 
    1.to(10).foreach{ frame =&amp;gt; scorer.scoreAt(frame) must_== 30 * frame }
  }

  &amp;quot;An individaul roll of &amp;gt; 10&amp;quot; should {
    roll(11) must throwA[IllegalArgumentException]
  }

  &amp;quot;An iniviaul roll of &amp;lt; 0&amp;quot; should {
    roll(-1) must throwA[IllegalArgumentException]
  }

  &amp;quot;A frame trying to contain more than 10 pins&amp;quot; should {
    roll(8)
    roll(3) must throwA[IllegalArgumentException]
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;&lt;b&gt;&lt;i&gt;BowlingScorer.scala&lt;/b&gt;&lt;/i&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_scala "&gt;package com.om.example

class BowlingScorer {
  var rolls:Array[Int] = Array()
  var index:Int = 0
  var firstBallInFrameThrown: Boolean = false;

  def roll(roll:Int) = {
    validate(roll)
    record(roll)
  }

  def validate(roll:Int) {
    if((0).to(10).contains(roll) == false)
      throw new IllegalArgumentException(&amp;quot;Individaul rolls must be from 0 .. 10&amp;quot;)

    if(openScoreAt(indexToValidate) + roll &amp;gt; 10)
      throw new IllegalArgumentException(&amp;quot;Total of rolls for frame must not exceed 10&amp;quot;);
  }

  def record(roll: Int) {
    rolls = rolls ++ Array(roll)
    firstBallInFrameThrown = firstBallInFrameThrown == false &amp;amp;&amp;amp; roll != 10
  }

  def indexToValidate = {
    if(firstBallInFrameThrown) rolls.length - 1 else rolls.length
  }

  def scoreAt(frame:Int) = {
    1.to(frame).foldLeft(0) { (total, frame) =&amp;gt;  total + nextFrameScore  }
  }

  def score = {
    scoreAt(10)
  }

  def nextFrameScore = {
    var result = 0;
    if(isStrike(index)) {
      result += markScoreAt(index)
      index += 1
    } else if(isSpare(index)) {
      result += markScoreAt(index);
      index += 2
    } else {
      result += openScoreAt(index);
      index += 2
    }
    result
  }

  def isStrike(index:Int) = {
    valueAt(index) == 10
  }

  def markScoreAt(index:Int) = {
    sumNext(index, 3)
  }

  def isSpare(index:Int) = {
    openScoreAt(index) == 10
  }

  def openScoreAt(index:Int) = {
    sumNext(index, 2)
  }

  def sumNext(index:Int, count:Int) = {
    index.until(index+count).foldLeft(0)(_ + valueAt(_))
  }

  def valueAt(index:Int) = {
    if(rolls.length &amp;gt; index) rolls.apply(index) else 0
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;</description>
      <pubDate>Mon, 05 Oct 2009 23:33:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:23cd72fc-e4b5-4dbd-b219-e4bb2e4b92c7</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2009/10/05/scala-bowling-kata-somewhere-in-the-middle</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>Scala</category>
      <category>bdd</category>
      <category>specs</category>
      <category>bowling</category>
      <category>kata</category>
    </item>
    <item>
      <title>Bowling Game Kata in Ruby</title>
      <description>&lt;p&gt;I have not really used Ruby much. I&amp;#8217;ve written a few tutorials, messed around with RSpec and Test::Unit and even Rails a bit, but I really don&amp;#8217;t know Ruby that well. I get Ruby (the &lt;span class="caps"&gt;MOP&lt;/span&gt;, instances, blocks, open classes, ...) but there&amp;#8217;s a difference between understanding that stuff and using it day-to-day.&lt;/p&gt;


	&lt;p&gt;Last night we had a Dojo in Oklahoma City and I wanted to get refreshed with RSpec, so I decided to jump in and do the bowling game kata. I did not follow uncle bob&amp;#8217;s lead exactly. For one, I went ahead and stored two throws for each frame. While what he ends up with is a bit shorter, it bothers me a little bit. I&amp;#8217;ve also seen people surprised by how bob stores his scores, so in a sense it violates the law of least astonishment.&lt;/p&gt;


	&lt;p&gt;That&amp;#8217;s neither here nor there, I got it working just fine &amp;#8211; though handling strikes was a bit more difficult because I decided to store two rolls instead of one (so clearly, there&amp;#8217;s no best answer, just ones that suck for different reasons).&lt;/p&gt;


	&lt;p&gt;After my first go around, I had a single spec with examples all under a single describe (what&amp;#8217;s that term they&amp;#8217;d use for what the describe expression creates?). I added several examples for partial scores, to make sure I was handling incomplete games correctly. I restructured those a bit and tried to make the names a bit more clear, not sure if I was successful.&lt;/p&gt;


	&lt;p&gt;In my original version I started with a frame in the score method as a local variable, but it quickly got converted to an index, and the index was mostly passed around after that. The approach was very c-esque. I didn&amp;#8217;t like that index all over the place, so I tried to remove it by refactoring. It took several false starts before I bit the bullet and simply duplicated each of the methods, one at a time, using parallel development. The old version using an index, the new one use a 1-based frame number. After I got that working with frames, I removed most of the methods using an index, except for a few.&lt;/p&gt;


	&lt;p&gt;What follows is the spec file and the ruby class. If you read the names of some of the examples, you might think I used to bowl in league, I did. My average was a paltry 158, my best game ever a 248. Best split I ever picked up? 4, 6, 7, 10.&lt;/p&gt;


	&lt;p&gt;Comments welcome.&lt;/p&gt;


	&lt;p&gt;&lt;i&gt;&lt;b&gt;bowling_score_card_spec.rb&lt;/i&gt;&lt;/b&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;bowling_score_card&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

&lt;span class="ident"&gt;describe&lt;/span&gt; &lt;span class="constant"&gt;BowlingScoreCard&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
    &lt;span class="ident"&gt;before&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:each&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
        &lt;span class="attribute"&gt;@bowling_game_scorer&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;BowlingScoreCard&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;roll&lt;/span&gt; &lt;span class="ident"&gt;value&lt;/span&gt;
        &lt;span class="attribute"&gt;@bowling_game_scorer&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="ident"&gt;value&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;roll_many&lt;/span&gt; &lt;span class="ident"&gt;count&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;value&lt;/span&gt;
        &lt;span class="ident"&gt;count&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;times&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="ident"&gt;value&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;score_should_be&lt;/span&gt; &lt;span class="ident"&gt;value&lt;/span&gt;
        &lt;span class="attribute"&gt;@bowling_game_scorer&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;score&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;should&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="ident"&gt;value&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score 0&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
        &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="ident"&gt;describe&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Scores for Complete Games&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score 0 for an all gutter game&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll_many&lt;/span&gt; &lt;span class="number"&gt;20&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should show 20 for an all 1 game&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll_many&lt;/span&gt; &lt;span class="number"&gt;20&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;20&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score game with single spare correctly&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll_many&lt;/span&gt; &lt;span class="number"&gt;3&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;5&lt;/span&gt;
            &lt;span class="ident"&gt;roll_many&lt;/span&gt; &lt;span class="number"&gt;17&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;20&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score game with single strike correctly&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;5&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;2&lt;/span&gt;
            &lt;span class="ident"&gt;roll_many&lt;/span&gt; &lt;span class="number"&gt;17&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;24&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score a dutch-200, spare-strike, correclty&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="number"&gt;10&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;times&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
                &lt;span class="ident"&gt;roll_many&lt;/span&gt; &lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;5&lt;/span&gt;
                &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
            &lt;span class="keyword"&gt;end&lt;/span&gt;
            &lt;span class="ident"&gt;roll_many&lt;/span&gt; &lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;5&lt;/span&gt;

            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;200&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score a dutch-200, strike-spare, correctly&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="number"&gt;10&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;times&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
                &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
                &lt;span class="ident"&gt;roll_many&lt;/span&gt; &lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;5&lt;/span&gt;
            &lt;span class="keyword"&gt;end&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;200&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;should score all 5's game as 150&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll_many&lt;/span&gt; &lt;span class="number"&gt;21&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;5&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;150&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score a perfect game correctly&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll_many&lt;/span&gt; &lt;span class="number"&gt;12&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;300&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should not count a 0, 10 roll as a strike&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
            &lt;span class="ident"&gt;roll_many&lt;/span&gt; &lt;span class="number"&gt;18&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;29&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="ident"&gt;describe&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Scoring for open games&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score just an open frame&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;4&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;3&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;7&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score just a spare&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll_many&lt;/span&gt; &lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;5&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score partial game with spare and following frame only&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll_many&lt;/span&gt; &lt;span class="number"&gt;3&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;5&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;20&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score an opening turkey correctly&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll_many&lt;/span&gt; &lt;span class="number"&gt;3&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;60&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="ident"&gt;describe&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Scoring open game starting with a srike&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
        &lt;span class="ident"&gt;before&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:each&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;
        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score partial game with only strike&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score partial game with strike and half-open frame&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;4&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;18&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score partial game with strike and open frame&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;3&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;6&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;28&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score partial game with strike and spare&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;3&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;7&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;30&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="ident"&gt;describe&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Open game starting with two Strikes&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
        &lt;span class="ident"&gt;before&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:each&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should have a score of 30&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;30&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score correctly with following non-mark&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;4&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;42&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score correclty with third frame open&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;4&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;3&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;48&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;


	&lt;p&gt;&lt;i&gt;&lt;b&gt;bowling_score_card.rb&lt;/i&gt;&lt;/b&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;BowlingScoreCard&lt;/span&gt;
    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;initialize&lt;/span&gt;
        &lt;span class="attribute"&gt;@rolls&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;[]&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;roll&lt;/span&gt; &lt;span class="ident"&gt;value&lt;/span&gt;
        &lt;span class="attribute"&gt;@rolls&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="ident"&gt;value&lt;/span&gt;
        &lt;span class="attribute"&gt;@rolls&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt; &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;first_throw_is_strike?&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;score&lt;/span&gt;
        &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;..&lt;/span&gt;&lt;span class="number"&gt;10&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;inject&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;score&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;score&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="ident"&gt;score_for&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;score_for&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;
        &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="ident"&gt;strike_score_for&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt; &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;is_strike_at?&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;
        &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="ident"&gt;spare_score_for&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt; &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;is_spare_at?&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;
        &lt;span class="ident"&gt;open_score_for&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;first_throw_is_strike?&lt;/span&gt;
        &lt;span class="ident"&gt;is_first_throw_in_frame?&lt;/span&gt; &lt;span class="punct"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="attribute"&gt;@rolls&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;last&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;is_first_throw_in_frame?&lt;/span&gt;
        &lt;span class="attribute"&gt;@rolls&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;length&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;odd?&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;open_score_for&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;
        &lt;span class="ident"&gt;first_throw_for&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="ident"&gt;second_throw_for&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;);&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;spare_score_for&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;
        &lt;span class="ident"&gt;open_score_for&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="ident"&gt;first_throw_for&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;next_frame&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;))&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;strike_score_for&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;
        &lt;span class="ident"&gt;score&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;open_score_for&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="ident"&gt;open_score_for&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;next_frame&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;))&lt;/span&gt;
        &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;is_strike_at?&lt;/span&gt; &lt;span class="ident"&gt;next_frame&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
            &lt;span class="ident"&gt;score&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="ident"&gt;first_throw_for&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;next_frame&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;next_frame&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;)))&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;
        &lt;span class="ident"&gt;score&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;next_frame&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;
        &lt;span class="ident"&gt;frame&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;is_spare_at?&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;
        &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;open_score_for&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt; &lt;span class="punct"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="ident"&gt;is_strike_at?&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="constant"&gt;false&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;is_strike_at?&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;
        &lt;span class="ident"&gt;first_throw_for&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;first_throw_for&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;
        &lt;span class="ident"&gt;score_at_throw&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;index_for&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;))&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;second_throw_for&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;
        &lt;span class="ident"&gt;score_at_throw&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;index_for&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;index_for&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;
        &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;frame&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt; &lt;span class="number"&gt;2&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;score_at_throw&lt;/span&gt; &lt;span class="ident"&gt;index&lt;/span&gt;
        &lt;span class="attribute"&gt;@rolls&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;length&lt;/span&gt; &lt;span class="punct"&gt;&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;index&lt;/span&gt; &lt;span class="punct"&gt;?&lt;/span&gt; &lt;span class="attribute"&gt;@rolls&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;index&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;:&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;</description>
      <pubDate>Thu, 01 Oct 2009 13:37:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:5144dc80-1acc-4f58-9c87-60971b35354b</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2009/10/01/bowling-game-kata-in-ruby</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>Ruby</category>
      <category>bowling</category>
      <category>kata</category>
      <category>RSpec</category>
    </item>
    <item>
      <title>Notes from the OkC Dojo 2009-09-30</title>
      <description>&lt;p&gt;Tonight we had a small group of die-hard practitioners working with Ruby and RSpec. We intended to use the Randori style, but it was a small enough group that we were a bit more informal than that.&lt;/p&gt;


	&lt;p&gt;We tried the Shunting Yard Algorithm again and it worked out fairly well. The level of experience in Ruby was low to moderate (which is why we wanted to get people a chance to practice it) and the RSpec experience was generally low (again, great reason to give it a try).&lt;/p&gt;


We had several interesting (at least to me) side discussions on things such as:
	&lt;ul&gt;
	&lt;li&gt;Forth&lt;/li&gt;
		&lt;li&gt;Operator precedence&lt;/li&gt;
		&lt;li&gt;Operator associativity&lt;/li&gt;
		&lt;li&gt;L-Values and R-Values&lt;/li&gt;
		&lt;li&gt;Directed Acyclic Graphis&lt;/li&gt;
		&lt;li&gt;In-fix, pre-fix, post-fix binary tree traversal&lt;/li&gt;
		&lt;li&gt;Abstract Syntax Trees (AST)&lt;/li&gt;
		&lt;li&gt;The list goes on, I&amp;#8217;m a big-time extrovert, so I told Chad to occasionally tell me to shut the heck up&lt;/li&gt;
	&lt;/ul&gt;


The Shunting Yard Algorithm is a means of translating an in-fix expression into a post-fix expression (a.k.a. reverse polish notation &amp;#8211; used by the best calculators in the world, HP [I also prefer vi, fyi!-] ). For example:
	&lt;ul&gt;
	&lt;li&gt;1 + 3 becomes 1 3 +&lt;/li&gt;
		&lt;li&gt;a = b = 17 becomes a b 17 = =&lt;/li&gt;
		&lt;li&gt;2 + 3 * 5 becomes 2 3 5 * +&lt;/li&gt;
		&lt;li&gt;2 * 3 + 5 becomes 2 3 * 5 +&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;One typical approach to this problem is to develop an &lt;span class="caps"&gt;AST&lt;/span&gt; from the in-fix representation and then recursively traversing the &lt;span class="caps"&gt;AST&lt;/span&gt; using a recursive post-fix traversal.&lt;/p&gt;


	&lt;p&gt;What I like about he Shunting Yard Algorithm is it takes a traditionally recursive algorithm (DAG traversal, where a binary tree is a degenerate &lt;span class="caps"&gt;DAG&lt;/span&gt;) and writes it iteratively using it&amp;#8217;s own stack (local or instance variable) storage versus using the program stack to store activation records (OK stack frames). Essentially, the local stack is used for pending work.&lt;/p&gt;


	&lt;p&gt;This is one of those things I think is a useful skill to learn: writing traditionally recursive algorithms using a stack-based approach. This allows you to step through something (think iteration) versus having to do things whole-hog (recursively, with a block (lambda) passed in). In fact, I bought a used algorithm book 20 years ago because it had a second on this subject. And looking over my left shoulder, I just saw that book. Nice.&lt;/p&gt;


	&lt;p&gt;To illustrate, here&amp;#8217;s the &lt;span class="caps"&gt;AST&lt;/span&gt; for the first example:&lt;p/&gt;
&lt;img src="http://yuml.me/3e75c5ce" /&gt;&lt;/p&gt;


Since the group had not done a lot with recursive algorithms (at least not recently), we discussed a short hand way to remember the various traversal algorithms using three letters: L, R, P
	&lt;ul&gt;
	&lt;li&gt;L -&amp;gt; Go Left&lt;/li&gt;
		&lt;li&gt;R -&amp;gt; Go Right&lt;/li&gt;
		&lt;li&gt;P -&amp;gt; Print (or process)&lt;/li&gt;
	&lt;/ul&gt;


Each of the three traditional traversal algorithms (for a binary tree) use just these three letters. And the way to remember each is to put the &amp;#8216;p&amp;#8217; where the name suggests. For example:
	&lt;ul&gt;
	&lt;li&gt;in-fix, in -&amp;gt; in between -&amp;gt; L &lt;b&gt;P&lt;/b&gt; R&lt;/li&gt;
		&lt;li&gt;pre-fix, pre, before -&amp;gt; &lt;b&gt;P&lt;/b&gt; L R&lt;/li&gt;
		&lt;li&gt;post-fix, post, after -&amp;gt; &lt;span class="caps"&gt;L R&lt;/span&gt; &lt;b&gt;P&lt;/b&gt;&lt;/li&gt;
	&lt;/ul&gt;


Then, given the graph above, you can traverse it as follows:
	&lt;ul&gt;
	&lt;li&gt;in-fix: Go left, you hit the 1, it&amp;#8217;s a leaf note so print it, go up to the +, print it, go to the right, you end up with 1 + 3&lt;/li&gt;
		&lt;li&gt;post-fix: Go left you hit the 1, it&amp;#8217;s a leaf node, print it, go back to the +, since this is post-fix, don&amp;#8217;t print yet, go to the right, you get the 3, it&amp;#8217;s a leaf node, print it, then finally print the +, giving: 1 3 +&lt;/li&gt;
		&lt;li&gt;pre-fix: start at + and print it, then go left, it&amp;#8217;s a leaf note, print it, go right, it&amp;#8217;s a leaf node, print it, so you get: + 1 3 &amp;#8211; which looks like a function call (think operator+(1, 3))&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;It&amp;#8217;s not quite this simple &amp;#8211; we actually looked at larger examples &amp;#8211; but this gets the essence across. And to move from a tree to a &lt;span class="caps"&gt;DAG&lt;/span&gt;, simply iterate over all children, printing before or after the complete iteration; in-fix doesn&amp;#8217;t make as much sense in a general &lt;span class="caps"&gt;DAG&lt;/span&gt;. We also discussed tracking the visited nodes if you&amp;#8217;ve got a graph versus an acyclic graph.&lt;/p&gt;


	&lt;p&gt;After we got a multi-operator expression with same-precedence operators working, e.g., 1 + 3 &amp;#8211; 2, which results in: 1 3 + 2 -, we moved on to handling different operator precedence.&lt;/p&gt;


	&lt;p&gt;Around this time, there was some skepticism that post-fix could represent the same expression as in-fix. This is normal, if you have not seen these kinds of representations. And let&amp;#8217;s be frank, how often do most of us deal with these kinds of things? Not often.&lt;/p&gt;


	&lt;p&gt;Also, there was another question: &lt;span class="caps"&gt;WHY&lt;/span&gt;?&lt;/p&gt;


	&lt;p&gt;In a nutshell, with a post-fix notation, you do not need parentheses. As soon as an operator is encountered, you can immediately process it rather than waiting until the next token to complete the operator (no look-ahead required). This also led to HP developing a calculator in 1967 (or &amp;#8216;68) that was &amp;lt; 50 pounds and around &lt;span class="caps"&gt;USD&lt;/span&gt; $5,000 that could add, subtract, multiply and divide, which was&lt;i&gt; &lt;b&gt;huge&lt;/b&gt;&lt;/i&gt; at the time (with a stack size of 3 &amp;#8211; later models went to a stack size of 4, giving us the x, y, z and t registers).&lt;/p&gt;


	&lt;p&gt;During this rat-hole, we discussed associativity. For example, a = b = c is really (a = (b = c))&lt;/p&gt;


	&lt;p&gt;That&amp;#8217;s because the assignment operator is right-associative. This lead into r-values and l-values.&lt;/p&gt;


Anyway, we&amp;#8217;re going to meet again next week. Because we (read this as me) were not disciplined in following the Randori style, these side discussions lead to taking a long to fix a problem. We should have &amp;#8220;hit the reset button&amp;#8221; sooner, so next time around we&amp;#8217;re going to add a bit more structure to see what happens:
	&lt;ul&gt;
	&lt;li&gt;The driver finishes by writing a new failing test.&lt;/li&gt;
		&lt;li&gt;The driver commits the code with the newest failing test (we&amp;#8217;ll be using git)&lt;/li&gt;
		&lt;li&gt;Change drivers and give him/her some time-box (5 &amp;#8211; 10 minutes)&lt;/li&gt;
		&lt;li&gt;If, at the end of the current time-box, the current driver has all tests passing, go back to the first bullet in this list.&lt;/li&gt;
		&lt;li&gt;If at the end, the same test that was failing is still failing, (fist time only) give them a bit more time.&lt;/li&gt;
		&lt;li&gt;However, if any other tests are failing, then we revert back to the last check in and switch drivers.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Here&amp;#8217;s an approximation of these rules using &lt;a href="http://yuml.me"&gt;yuml.me&lt;/a&gt;:
&lt;img src="http://yuml.me/704421f3" /&gt;&lt;/p&gt;


And here&amp;#8217;s the syntax to create that diagram:
&lt;pre&gt;
(start)-&amp;gt;(Create New Failing Test)-&amp;gt;(Commit Work)-&amp;gt;(Change Drivers)
(Change Drivers)-&amp;gt;(Driver Working)
(Driver Working)-&amp;gt;&amp;lt;d1&amp;gt;[tick]-&amp;gt;(Driver Working)
&amp;lt;d1&amp;gt;[alarm]-&amp;gt;(Check Results)-&amp;gt;([All Tests Passing])-&amp;gt;(Create New Failing Test)
(Check Results)-&amp;gt;([Driver Broke Stuff])-&amp;gt;(git -reset hard)-&amp;gt;(Change Drivers)
(Check Results)-&amp;gt;([First Time Only and Still Only Newest Test Failing])-&amp;gt;(Give Driver A Touch More Time)-&amp;gt;(Check Results)
&lt;/pre&gt;

	&lt;p&gt;Note that this is not a strict activity diagram, the feature is still in beta, and creating this diagram as I did made the results a bit more readable. Even so, I like this tool so I wanted to throw another example in there (and try out this diagram type I have not used before &amp;#8211; at least not with this tool, I&amp;#8217;ve created too many activity diagrams). If you&amp;#8217;d like to see an accurate activity diagram, post a comment and I&amp;#8217;ll draw one in Visio and post it.&lt;/p&gt;


	&lt;p&gt;Anyway, we&amp;#8217;re going to try to move to a weekly informal practice session with either bi-weekly or monthly &amp;#8220;formal&amp;#8221; meetings. We&amp;#8217;ll keep switching out the language and the tools. I&amp;#8217;m even tempted to do design sessions &amp;#8211; &lt;span class="caps"&gt;NO CODING&lt;/span&gt;?! What?! Why not. Some people still work that way, so it&amp;#8217;s good to be able to work in different modes.&lt;/p&gt;


	&lt;p&gt;If you&amp;#8217;re in Oklahoma City, hope to see you. If not, and I&amp;#8217;m in your town, I&amp;#8217;d be interested in dropping into your dojos!&lt;/p&gt;</description>
      <pubDate>Wed, 30 Sep 2009 22:57:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:10b4fa5b-d8fa-4c4a-aabf-53130760201e</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2009/09/30/notes-from-the-okc-dojo-2009-09-30</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>dojo</category>
      <category>kata</category>
      <category>shunting</category>
      <category>yard</category>
      <category>algorithm</category>
      <category>computer</category>
      <category>science</category>
      <category>ast</category>
      <category>TDD</category>
      <category>bdd</category>
      <category>RSpec</category>
      <category>Ruby</category>
      <category>yuml.me</category>
    </item>
    <item>
      <title>Improving Testability of GUI Code, an Eample</title>
      <description>&lt;p&gt;Just finished first draft. More to come, questions/comments appreciated.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://schuchert.wikispaces.com/tdd.Refactoring.UiExample"&gt;http://schuchert.wikispaces.com/tdd.Refactoring.UiExample&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Thu, 10 Sep 2009 23:08:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:02584823-cab7-4003-8a06-87e6767455fb</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2009/09/10/improving-testability-of-gui-code-an-eample</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>test</category>
      <category>gui</category>
      <category>SRP</category>
      <category>welc</category>
      <category>refactoring</category>
      <category>legacy</category>
    </item>
    <item>
      <title>Pair with one of us at Agile 2009</title>
      <description>&lt;p&gt;Dean, Uncle Bob, Michale Feathers and I will be spending time in our Agile 2009 booth working on problems and pairing with volunteers.&lt;/p&gt;


	&lt;p&gt;If you&amp;#8217;d like to join us for some pairing, please stop by.&lt;/p&gt;


	&lt;p&gt;We&amp;#8217;ll give you an autographed &amp;#8220;code monkey&amp;#8221; for your efforts.&lt;/p&gt;</description>
      <pubDate>Mon, 24 Aug 2009 16:43:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:92de7123-c005-47d4-b68c-ad32f62c0a4e</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2009/08/24/pair-with-one-of-us-at-agile-2009</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>agile2009</category>
      <category>pairing</category>
      <category>TDD</category>
    </item>
    <item>
      <title>The Daily Scrum Exercise Program</title>
      <description>&lt;p&gt;Yesterday I was in a chicken in a scrum meeting. I made the observation that
the Daily Scrum was called that and not a &amp;#8220;Stand-up meeting.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;Standing up is a mechanism for making the meeting fast. Someone mentioned that
they actually used a weight in a previous team. You hand to hold the weight while talking.&lt;/p&gt;


	&lt;p&gt;This logically leads to a workout program. You start with a weight and, as 
people get used to it, you increase it. Start with 5 pounds, work up to 45.
The problem with this is you&amp;#8217;ll end up with inconsistent development. You&amp;#8217;ll
have a bunch of developers with strong, wide upper bodies but weak, pipe-like legs.&lt;/p&gt;


	&lt;p&gt;So the next logical step is to rotate the exercises used while reporting on
what you did, what you&amp;#8217;re going to do and roadblocks.&lt;/p&gt;


So maybe something like:
	&lt;ul&gt;
	&lt;li&gt;Monday, upper body, dumbbells held out in front or to the side (depending on where you need more definition.&lt;/li&gt;
		&lt;li&gt;Tuesday, cardio, jog in place, kicking your knees up high.&lt;/li&gt;
		&lt;li&gt;Wednesday, lower body, squat with your feet pointing at 45 degrees and legs apart.&lt;/li&gt;
		&lt;li&gt;Thursday, cardio, jog in place, kicking your feet into your rear&lt;/li&gt;
		&lt;li&gt;Friday, mid section, alternatively lift your knees to the opposite side of your body while twisting to the size of leg you are lifting.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;You get the idea. Of course, you&amp;#8217;d customize the workouts to at least the team or maybe even the developer.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;d like to be on&lt;i&gt; &lt;b&gt;that&lt;/b&gt;&lt;/i&gt; team!&lt;/p&gt;</description>
      <pubDate>Fri, 31 Jul 2009 13:53:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:4f59439e-28e9-4a29-9b10-d801ddba9e44</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2009/07/31/the-daily-scrum-exercise-program</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>scrum</category>
      <category>exercise</category>
      <category>humor</category>
    </item>
  </channel>
</rss>

