<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Sarah Taraporewalla's Technical Ramblings]]></title>
  <link href="http://sarahtaraporewalla.com/atom.xml" rel="self"/>
  <link href="http://sarahtaraporewalla.com/"/>
  <updated>2012-01-29T11:02:09+10:00</updated>
  <id>http://sarahtaraporewalla.com/</id>
  <author>
    <name><![CDATA[Sarah Taraporewalla]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Experience Report: Feature Toggling]]></title>
    <link href="http://sarahtaraporewalla.com/design/experience-report-feature-toggling"/>
    <updated>2011-07-15T05:59:30+10:00</updated>
    <id>http://sarahtaraporewalla.com/design/experience-report-feature-toggling</id>
    <content type="html"><![CDATA[<p>Last week, I shared <a href="http://sarahtaraporewalla.com/design/experience-report-branch-by-feature/" title="Experience Report: Git and Branch By Feature" target="_blank">my experiences with git and feature branching</a>. As I mentioned, we moved away from this and towards <a href="http://martinfowler.com/bliki/FeatureToggle.html" title="Feature Toggle" target="_blank">feature toggles</a> and <a href="http://continuousdelivery.com/2011/05/make-large-scale-changes-incrementally-with-branch-by-abstraction/" title="Branch By Abstraction" target="_blank">branch by abstraction</a>. This is what happened when we did&#8230;</p>

<p>Our focus on feature toggles and branch by abstraction was quite accidental. We were changing a fundamental way our system handled calculations by moving from doing them ourselves to asking an external service to perform key calculations for us. As with many an integration point, the external system was not quite ready by the time we started to introduce the modifications, so testing our side was proving to be tricker than initially anticipated. One day, the pair working on the story came to me and said &#8220;Sarah, we are having problems changing our tests. We are going to need to change a whole bunch of tests, because they all rely on this value to be calculated on the fly but we now go out to the external system&#8221;[1]. We started spitballing ideas, when suddenly, it came to me in a light bulb moment. &#8220;Why don&#8217;t we wrap this class with a switcher&#8221;, I said. &#8220;The switcher can be told which calculator to use - the existing one, or the new external service&#8221;. BAM. All of a sudden, it made brilliant sense.</p>

<p>You see, one we had this switcher in, we were then free to continue developing this new feature, share the code with everyone and not stuff up our testing in the process[2]. So we continued along, quite happily, with our QA toggling the switch when he wanted to test the new stuff, and switching it back when he wanted to do testing on the other features.</p>

<p>That might have been the end of the story, the brilliance of this solution being completely lost, until the inevitable happened[3]. The external team delivered working code, but it was not production ready - it was way too slow for us to use it in the specified manner. Uhoh! Here come the managers in a series of crisis meetings. After various performance tests, back-and-fro with the other team, and debating what the performance should be, our business sponsors were faced with a dilemma. What should they do? They can&#8217;t release the software with the way it was performing, but they had a whole bunch of other features in that release that they were desperate to deploy.</p>

<p>&#8220;I can always turn off that feature&#8221;, I said timidly in one meeting. &#8220;We haven&#8217;t removed the ability to calculate internally, we have just hidden it behind a switch. All we need to do is release the current version with that switch turned to internal calculations. Then, when the performance has improved, we can switch the calculations to use the external system. We don&#8217;t even need a new deployment for that. It will happen automatically with a simple configuration change on the fly&#8221;. Silence. The room was gobsmacked. &#8220;You mean, the business has control of when this feature is to be deployed?&#8221;, they thought. Of course. That is how it should be.</p>

<p>This incident was probably the only time when my sponsor came to me and told me that I had done a brilliant job[4], that I had saved the company a lot of money by having the foresight to have this architecture in place.</p>

<p>Our imagination and innovation grew from there.</p>

<p>There was a feature in the UI that our product owner wanted to get approval from the rest of the business to remove but it was taking a while to jump through all the necessary[5] hoops. As a release was scheduled for the next day and the next not for another month it was really important to get approval ASAP. But we didn&#8217;t get approval in time and the product owner didn&#8217;t care. You see, we added in another toggle around the visibility of that feature. That way when the decision finally came through, one week after the release, the business turned it off and started to see the reward immediately without waiting another 3 weeks for the next release train to come along. Yet another time when we saved the company valuable money.</p>

<p>I also started to talk about allowing our super users to have the external calculations for their plans, and internal calculations for all other uses so that we could get first hand feedback to determine when the performance was indeed good enough. The performance had not improved by the time I rolled off, but we were certainly starting to put thought into this plan.</p>

<p>My mind races to think of all the other uses. Take AB testing for instance. How easy would it be to use these to gather statistics, then discard the unpopular path. BAM - mind explosion.</p>

<p>You see, Feature Toggling is not just a different way to achieve feature branching. It is an architectural choice that, sure, helps with maintaining mainline development but the power is that it hands back control of what features should be enabled and when to the business. And it is there, ready for you to harness. No extra steps required. As awesome as Git is[6], you just cannot compete with something that allows you to not only control what features go into a release but what features are live at any one time[7].</p>

<p>So now you know how we were able to save money by introducing Feature Toggles. What could you do, if you had feature toggles?</p>

<hr/>


<p><strong>Update 16 July 2011</strong>
<em>Whenever you write an experience report, you run the risk of missing out some of your thoughts, assuming that they come across clearly. Thank you to everyone who has given me feedback on this post. I am adding answers at the bottom to address some of the questions that have been raised since originally posting this.</em></p>

<p><em>How do you ensure that what is going into prod works?</em>
We achieved this by making the default configuration always be that of production. So, for our QA to test a certain incomplete feature in our QA environment, he had to turn it on explicitly. When a new build was pushed out, the configuration had to be changed again.
My friend, <a href="http://www.christopherbird.co.uk" title="@chrisabird">Chris Bird</a> recommends that you could consider separating feature flags from the deploy package and make it environmental config. This would mean the QA would not be configuring after each deployment. Perhaps considering tools like Chef to control the environmental config?</p>

<p><em>How do you know what toggle is on?</em>
We had an application configuration page which showed really cool things such as build numbers, db migration version and configuration values of the properties (and where the configuration was set eg app.config, prod.config). This page also exposed the values of all known feature toggles.</p>

<p><em>When do you remove the toggle? And who makes that decision?</em>
I would agree with everyone that they have a TTL. Although we didn&#8217;t do this, you could put a TTL on the configuration page&#8230;or how long it has been in place. Then, after it hits a threshold you remove it. On the project, once it was live we tidied up the code following the boyscout rule. You could also have a TTL wall, making it visible to everybody.
Also, if you know how long the feature has been there without being turned on, you could get that stats for monitoring waste.
As to who makes the decision, I would say that if the business knows you have these toggles, talk to them about keeping them in vs taking them out and the risk/debt you are carrying as a result.
My friend, <a href="http://www.christopherbird.co.uk" title="@chrisabird">Chris Bird</a> recommends marking the toggles with expirations through a mechanism like ignore attributes in the code. When those ignores expire it breaks a test (and then the build) to warn you about removing these attributes. This could also be a nice technique for reminding you when these things need to be addressed.</p>

<p><em>Don&#8217;t you get an explosion of combination of toggles?</em>
Yes, so remove them if they are no longer needed.</p>

<p><em>If you switch it on in prod, what about testing? How can you ensure that it is tested?</em>
Doing this was completely to get around the fact that the business wouldn&#8217;t let us release more frequently. We pushed and pushed and pushed really hard, but we were only able to do fortnightly releases twice before they thought the overhead was too much. What we did was to test it in UAT with the different combinations, so even though we switched it on in prod, we tested it thoroughly in UAT first. I would prefer to just push out a new release, but failing that, this was a good alternative. And I appreciate that that sentiment is not clear in the post, so I hope this clears things up.</p>

<hr/>


<p>[1] full confession - our tests were too unwieldy and smelly. This challenge just highlighted to me the problems with our tests.
[2] before this, we were faced with keeping the code on a separate branch, but with the amount of refactoring that was going on in that crucial area, we were not too keen on the day we had to merge back into master
[3] to be fair, given my talk on integration systems, I should have known better&#8230;
[4] if you ever wanted to hear a case study of how negative reinforcing loops impacts team morale, I have some stories for you&#8230;
[5] let&#8217;s face it - they weren&#8217;t necessary
[6] and it truly is awesome
[7] yes, I know the argument is to remove the toggles once it is turned on, which of course simplifies the code. I leave it as an exercise for the reader to determine the best course of action</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Experience Report: Branch by Feature]]></title>
    <link href="http://sarahtaraporewalla.com/design/experience-report-branch-by-feature"/>
    <updated>2011-07-08T12:45:06+10:00</updated>
    <id>http://sarahtaraporewalla.com/design/experience-report-branch-by-feature</id>
    <content type="html"><![CDATA[<p>I have been made aware of some negative responses to <a href="http://martinfowler.com/" title="Martin Fowler" target="_blank">Martin Fowler</a> &amp; <a href="http://mikemason.ca/blog/" target="_blank">Mike Mason</a>&#8217;s <a href="http://www.thoughtworks.com/perspectives/30-06-2011-continuous-delivery">discussion on Branch By Feature</a>.</p>

<p>Perhaps unsurprisingly, I agree with Martin &amp; Mike&#8217;s view on branching. I have been on several projects that have adopted various strategies like branching by features, feature toggling &amp; branching by abstraction so I have personal history to back up what others say about branching. But, the argument goes that that was when we were using source control systems that made branching and merging difficult and painful, like CVS, subversion and Perforce. This is true. But on my last client, we used git and branch by feature. This is my experience working in this way&#8230;.</p>

<p>At my last client, we used started by using Git and branch-by-feature[1]. Features would take anywhere from 1 day to 5 days to complete. At the end of the feature, it would be merged back to master (having been good little girls and boys and continuously merging from master &#8230;that is CI isn&#8217;t it???)[2], pushed and then CI would trigger.</p>

<p>Guess what happened - tests on CI would fail because CI was running a bigger suite of tests than our cmd line. Ok, so we didn&#8217;t have CI running on the branch, but really - what harm did it do? So you had to spend a little extra time fixing those tests&#8230;.we&#8217;re not buying that whole &#8220;you&#8217;re not really doing CI&#8221; argument. Branch by Feature is cool - look - you can clearly see which changes relate to a story and you can back them all out if you need to.</p>

<p>Then, QA gets their mits on it for the first time. Those little devils..they&#8217;re raising little pink stickies on my story! Well, better go fix them&#8230;.on master. Wait - so the paradigm of branch-by-feature is only until the dev&#8217;s think its finished?[3]</p>

<p>But lol - a nice big juicy refactor story comes along. You know the one - the kind where you roll up your sleeve, batten down the hatch cause you are going to be there for a while. After 5 -7 days, you poke your head up again, and decide - jobs a goodin&#8217;, lets merge and push to master. But despite how well git handles merges, if you have removed/renamed/modified a method that a new piece of code relies on, git cannot help you. So you fix all compilation problems, and run tests (of course, we&#8217;re agile) and BOOOM!!! failed tests. They are harder to decipher. And didn&#8217;t we fix half of these before? grrr&#8230;.so, 5-7 days after you finished the refactor, you spend another 1-2 days in merge hell&#8230;and this was with GIT!!!</p>

<p>Boy, you think we would&#8217;ve learnt that first time. But in spectacular face-palm fashion, we persevered with branch-by-feature always promising we would do it better next time. Fool me once, shame on — shame on you. Fool me — You can&#8217;t get fooled again.</p>

<p>Don&#8217;t worry - we did learn. We added feature toggles to help with the testing of a story (also using branch-by-abstraction). Then, when the 3rd party the new code was talking to wasn&#8217;t ready by the release date, we switched the toggle back to the old way, released all the other new features, thoroughly impressed the client (who believed that we would need to wait another 3 months for the 3rd party) and felt chuffed ourselves. After that, we hopped onto the release train, all stories developed on master with feature toggles where necessary and got the business back into fortnightly cycles, without the pain of branching-per-release[4]</p>

<p>Next time, I don&#8217;t think that I would be so diplomatic towards branch-by-feature&#8230;.if I see it again, I think that I might stamp it out straight away. Every time I have seen it (and this is on 6 mthly branches, monthly branches, fortnightly, weekly &amp; daily) the same problems keep coming up[5].</p>

<p>[1] actually - to clarify&#8230;when I rolled onto the project, that is what the team was doing so I decided to see how well it would go&#8230;
[2] for those who are sarcastically-challenged, that was said tongue-in-cheek.
[3] that wasn&#8217;t the only strategy tried..but it was the quickest for small fixes&#8230;for larger change there was a debate as to whether you should create a new branch or just merge current master into the old branch and continue&#8230;both send shivers down my spine&#8230;
[4] we also tried various techniques with branching-per-release&#8230;we had another Go pipeline setup so that any releases or hotfixes would move through that. For a little while, this was important as UAT uncovered some stuff to fix, but in the end it was unnecessary as we just released whatever was the lastest good build - and toggled off all the other incomplete features.
[5] actually&#8230;git&#8217;s branching does make it really cool for spikes and helping you work out how to refactor a piece of code&#8230;but once discovered, ditch it and start from scratch on master</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Easy A]]></title>
    <link href="http://sarahtaraporewalla.com/agile/easy-a"/>
    <updated>2011-06-06T11:56:45+10:00</updated>
    <id>http://sarahtaraporewalla.com/agile/easy-a</id>
    <content type="html"><![CDATA[<p>I have heard the car metaphor many times before - you know the one - &#8220;are we building a ford, or a ferrari?&#8221;. But that metaphor though has never really sat well with me - I couldn&#8217;t relate to it, and everyone always says &#8220;oh no, we are building a ford&#8221; and then proceed to describe the bells and whistles. Lately, I have started to look at other metaphors, and I have found one that is currently working for me.</p>

<p>At school, there were some subjects that I really wanted to do well in, and get As. Then there were subjects that I needed to take for prerequisites, but all I needed was to pass, so a C in that (or even a D) was perfectly fine by me.</p>

<p>When we develop software, there are some features that we really want to do well in and get right - these are our distinguishers. Then, there are other features that we just need to (e.g. to keep up with the market), but they don&#8217;t distinguish us from our competitors, so we want to spend only enough effort to get it in, without doing something distinguishing.</p>

<p>At school, there were also subjects that were basically easy As - I could put very little effort into studying for them, and I could take home top marks. Then, there also subjects that no matter how hard I studying, how much effort I put in, all I could pull off was a C.</p>

<p>When we develop software, there are some features that we can do really well at, for minimum effort. Then, there are features that are really trying to get in, and when we do, they might be a bit clunky or constantly requiring effort to maintain.</p>

<p>At school, there was also a limit to the number of subjects I could study at once. If I took more subjects then my normal limit, then they would all suffer - even the easy A weren&#8217;t so achievable. And I swapping between them all the time was difficult, so I would dedicate time to study on one at a time (usually half a day before I switched).</p>

<p>I think you can see where I am going&#8230;fill in the blanks about Work in Progress limits and &#8220;multi&#8221;-tasking.</p>

<p>So, thinking about stories and requests as school grades now gives a different perspective to prioritisation and valuing. We can start talking about getting outstanding As or just passing, about how some stories are easy to do well at (so let&#8217;s just do them) and others will take an effort to just pass (is that effort worth it in the end? Perhaps the time could be used for other features?). And for me, this metaphor is much more accessible - I have been there, I remember what it was like to study hard for subjects and get no where, and others be really easy and I remember prioritising my subjects based on how difficult it was (a really hard subject taken with an easy subject was the way to do it).</p>

<p>So - what grade would you like for that?</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How to Mug Tiny Types]]></title>
    <link href="http://sarahtaraporewalla.com/design/how-to-mug-tiny-types"/>
    <updated>2011-04-15T16:05:49+10:00</updated>
    <id>http://sarahtaraporewalla.com/design/how-to-mug-tiny-types</id>
    <content type="html"><![CDATA[<p>I love tiny types. I love how they make me feel, how they make me laugh, how easy it is to understand what is going on when they are around. The one annoying aspect, however, is when they have to cross application boundaries. Whenever you need to persist them, or present them onto the screen, in order to get to the value, you usually expose the underlying wrapped primitive. This always feels so icky reaching into them and stealing their values. But, on my current project, we up with some neat ideas as to how to rob our tiny types for their precious.</p>

<p>Here is how it works:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">interface</span> <span class="n">IVictim</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="k">void</span> <span class="nf">MuggedBy</span><span class="p">(</span><span class="n">IRobber</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">robber</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">public</span> <span class="k">interface</span> <span class="n">IRobber</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="n">T</span> <span class="nf">StealFrom</span><span class="p">(</span><span class="n">IVictim</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">victim</span><span class="p">);</span>
</span><span class='line'>  <span class="k">void</span> <span class="nf">Steal</span><span class="p">(</span><span class="n">T</span> <span class="n">valuables</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">Percentage</span> <span class="p">:</span> <span class="n">IVictim</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="k">private</span> <span class="k">readonly</span> <span class="kt">decimal</span> <span class="n">percentage</span><span class="p">;</span>
</span><span class='line'>  <span class="k">public</span> <span class="nf">Percentage</span><span class="p">(</span><span class="kt">decimal</span> <span class="n">percentage</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="k">this</span><span class="p">.</span><span class="n">percentage</span> <span class="p">=</span> <span class="n">percentage</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">public</span> <span class="k">void</span> <span class="nf">MuggedBy</span><span class="p">(</span><span class="n">IRobber</span><span class="p">&lt;</span><span class="kt">decimal</span><span class="p">&gt;</span> <span class="n">robber</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="n">robber</span><span class="p">.</span><span class="n">Steal</span><span class="p">(</span><span class="n">percentage</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">ValuablesRobber</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="p">:</span> <span class="n">IRobber</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="k">private</span> <span class="n">T</span> <span class="n">stolenGoods</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">public</span> <span class="n">T</span> <span class="nf">StealFrom</span><span class="p">(</span><span class="n">IVictim</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">victim</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="n">victim</span><span class="p">.</span><span class="n">MuggedBy</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
</span><span class='line'>      <span class="k">return</span> <span class="n">stolenGoods</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">public</span> <span class="k">void</span> <span class="nf">Steal</span><span class="p">(</span><span class="n">T</span> <span class="n">valuables</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="n">stolenGoods</span> <span class="p">=</span> <span class="n">valuables</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">PercentageFormatter</span> <span class="p">:</span> <span class="n">IFormatter</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="k">public</span> <span class="kt">string</span> <span class="nf">Format</span><span class="p">(</span><span class="kt">object</span> <span class="n">toFormat</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="n">toFormat</span> <span class="p">==</span> <span class="k">null</span><span class="p">)</span> <span class="k">return</span> <span class="kt">string</span><span class="p">.</span><span class="n">Empty</span><span class="p">;</span>
</span><span class='line'>      <span class="n">var</span> <span class="n">percentage</span> <span class="p">=</span> <span class="p">(</span><span class="n">Percentage</span><span class="p">)</span><span class="n">toFormat</span><span class="p">;</span>
</span><span class='line'>      <span class="n">var</span> <span class="k">value</span> <span class="p">=</span> <span class="k">new</span> <span class="n">ValuablesRobber</span><span class="p">&lt;</span><span class="kt">decimal</span><span class="p">&gt;().</span><span class="n">StealFrom</span><span class="p">(</span><span class="n">percentage</span><span class="p">);</span>
</span><span class='line'>      <span class="k">return</span> <span class="k">value</span><span class="p">.</span><span class="n">ToString</span><span class="p">(</span><span class="s">&quot;0.00&quot;</span><span class="p">)</span> <span class="p">+</span> <span class="s">&quot;%&quot;</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Pagination Made Easy]]></title>
    <link href="http://sarahtaraporewalla.com/design/pagination-made-easy"/>
    <updated>2011-04-15T15:37:39+10:00</updated>
    <id>http://sarahtaraporewalla.com/design/pagination-made-easy</id>
    <content type="html"><![CDATA[<p>Ok, so I am doing a little happy dance right now, because I managed to get pagination into our application in less than a day. It is not your traditional pagination: where you specify the page number (and if you are lucky enough, also the page size). I find no real user meaning behind this. Instead, it allows you to specfy the range you want to look at. So, for the first 20 items, you would look at the items starting at 1 and ending at 20. To look at the next 20 items, you start at 21 and ending at 40. So far, that is just a different implementation to Page 2. Now, suppose the items that are actually interesting to you are items 10-30. In the Page model, you need to go back and forth between page 1 and 2. In this model, you only need to look at items starting at 10 and ending at 30. Brilliant huh! Nice implementations of this would be sliding windows, facebook style &#8220;more items&#8221;, and the version that we have (a hybrid between predefined pages and the ability to specify an exact range).</p>

<p>Here is how I did it (tests and other junk removed for readability):</p>

<p><strong>.Net Code</strong></p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
<span class='line-number'>73</span>
<span class='line-number'>74</span>
<span class='line-number'>75</span>
<span class='line-number'>76</span>
<span class='line-number'>77</span>
<span class='line-number'>78</span>
<span class='line-number'>79</span>
<span class='line-number'>80</span>
<span class='line-number'>81</span>
<span class='line-number'>82</span>
<span class='line-number'>83</span>
<span class='line-number'>84</span>
<span class='line-number'>85</span>
<span class='line-number'>86</span>
<span class='line-number'>87</span>
<span class='line-number'>88</span>
<span class='line-number'>89</span>
<span class='line-number'>90</span>
<span class='line-number'>91</span>
<span class='line-number'>92</span>
<span class='line-number'>93</span>
<span class='line-number'>94</span>
<span class='line-number'>95</span>
<span class='line-number'>96</span>
<span class='line-number'>97</span>
<span class='line-number'>98</span>
<span class='line-number'>99</span>
<span class='line-number'>100</span>
<span class='line-number'>101</span>
<span class='line-number'>102</span>
<span class='line-number'>103</span>
<span class='line-number'>104</span>
<span class='line-number'>105</span>
<span class='line-number'>106</span>
<span class='line-number'>107</span>
<span class='line-number'>108</span>
<span class='line-number'>109</span>
<span class='line-number'>110</span>
<span class='line-number'>111</span>
<span class='line-number'>112</span>
<span class='line-number'>113</span>
<span class='line-number'>114</span>
<span class='line-number'>115</span>
<span class='line-number'>116</span>
<span class='line-number'>117</span>
<span class='line-number'>118</span>
<span class='line-number'>119</span>
<span class='line-number'>120</span>
<span class='line-number'>121</span>
<span class='line-number'>122</span>
<span class='line-number'>123</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">Pagination</span><span class="p">&lt;</span><span class="n">PaginatedType</span><span class="p">&gt;</span> <span class="p">:</span> <span class="n">IEnumerable</span><span class="p">&lt;</span><span class="n">Pagination</span><span class="p">&lt;</span><span class="n">PaginatedType</span><span class="p">&gt;.</span><span class="n">Page</span><span class="p">&gt;</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="k">private</span> <span class="k">readonly</span> <span class="n">IList</span><span class="p">&lt;</span><span class="n">Page</span><span class="p">&gt;</span> <span class="n">pages</span> <span class="p">=</span> <span class="k">new</span> <span class="n">List</span><span class="p">&lt;</span><span class="n">Page</span><span class="p">&gt;();</span>
</span><span class='line'>  <span class="k">private</span> <span class="k">readonly</span> <span class="n">Page</span> <span class="n">currentPage</span><span class="p">;</span>
</span><span class='line'>  <span class="k">private</span> <span class="k">readonly</span> <span class="n">IEnumerable</span><span class="p">&lt;</span><span class="n">PaginatedType</span><span class="p">&gt;</span> <span class="n">paginatedCollection</span><span class="p">;</span>
</span><span class='line'>  <span class="k">private</span> <span class="k">readonly</span> <span class="kt">int</span> <span class="n">maximumCount</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">public</span> <span class="nf">Pagination</span><span class="p">(</span><span class="n">IEnumerable</span><span class="p">&lt;</span><span class="n">PaginatedType</span><span class="p">&gt;</span> <span class="n">paginatedCollection</span><span class="p">,</span> <span class="kt">int</span> <span class="n">maxCount</span><span class="p">,</span> <span class="n">Page</span> <span class="n">currentPage</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="k">this</span><span class="p">.</span><span class="n">maximumCount</span> <span class="p">=</span> <span class="n">maxCount</span><span class="p">;</span>
</span><span class='line'>      <span class="k">this</span><span class="p">.</span><span class="n">paginatedCollection</span> <span class="p">=</span> <span class="n">paginatedCollection</span><span class="p">;</span>
</span><span class='line'>      <span class="n">var</span> <span class="n">pageSize</span> <span class="p">=</span> <span class="n">currentPage</span><span class="p">.</span><span class="n">PageSize</span><span class="p">();</span>
</span><span class='line'>      <span class="k">for</span> <span class="p">(</span><span class="n">var</span> <span class="n">i</span> <span class="p">=</span> <span class="m">1</span><span class="p">;</span> <span class="n">i</span> <span class="p">&lt;</span> <span class="n">maxCount</span><span class="p">;</span> <span class="n">i</span><span class="p">+=</span><span class="n">pageSize</span><span class="p">)</span>
</span><span class='line'>      <span class="p">{</span>
</span><span class='line'>          <span class="n">pages</span><span class="p">.</span><span class="n">Add</span><span class="p">(</span><span class="k">new</span> <span class="n">Page</span> <span class="p">{</span><span class="n">StartingAt</span> <span class="p">=</span> <span class="n">i</span><span class="p">,</span> <span class="n">EndingAt</span> <span class="p">=</span> <span class="n">i</span><span class="p">+</span><span class="n">pageSize</span><span class="p">-</span><span class="m">1</span><span class="p">});</span>
</span><span class='line'>      <span class="p">}</span>
</span><span class='line'>      <span class="k">this</span><span class="p">.</span><span class="n">currentPage</span> <span class="p">=</span> <span class="n">currentPage</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">public</span> <span class="n">IEnumerable</span><span class="p">&lt;</span><span class="n">PaginatedType</span><span class="p">&gt;</span> <span class="n">PaginatedCollection</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="n">paginatedCollection</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">public</span> <span class="kt">int</span> <span class="n">MaximumCount</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="n">maximumCount</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">public</span> <span class="n">Page</span> <span class="n">CurrentPage</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="n">currentPage</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">public</span> <span class="kt">bool</span> <span class="nf">IsTheCurrentPage</span><span class="p">(</span><span class="n">Page</span> <span class="n">page</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="k">return</span> <span class="n">currentPage</span><span class="p">.</span><span class="n">Equals</span><span class="p">(</span><span class="n">page</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">public</span> <span class="n">IEnumerator</span><span class="p">&lt;</span><span class="n">Page</span><span class="p">&gt;</span> <span class="n">GetEnumerator</span><span class="p">()</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="k">return</span> <span class="n">pages</span><span class="p">.</span><span class="n">GetEnumerator</span><span class="p">();</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">IEnumerator</span> <span class="n">IEnumerable</span><span class="p">.</span><span class="n">GetEnumerator</span><span class="p">()</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="k">return</span> <span class="nf">GetEnumerator</span><span class="p">();</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">public</span> <span class="k">struct</span> <span class="nc">Page</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="k">public</span> <span class="kt">int</span> <span class="n">StartingAt</span><span class="p">;</span>
</span><span class='line'>      <span class="k">public</span> <span class="kt">int</span> <span class="n">EndingAt</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>      <span class="k">public</span> <span class="kt">string</span> <span class="nf">Name</span><span class="p">()</span>
</span><span class='line'>      <span class="p">{</span>
</span><span class='line'>          <span class="k">return</span> <span class="kt">string</span><span class="p">.</span><span class="n">Format</span><span class="p">(</span><span class="s">&quot;{0}-{1}&quot;</span><span class="p">,</span> <span class="n">StartingAt</span><span class="p">,</span><span class="n">EndingAt</span><span class="p">);</span>
</span><span class='line'>      <span class="p">}</span>
</span><span class='line'>      <span class="k">public</span> <span class="kt">int</span> <span class="nf">PageSize</span><span class="p">()</span>
</span><span class='line'>      <span class="p">{</span>
</span><span class='line'>          <span class="k">return</span> <span class="n">EndingAt</span> <span class="p">-</span> <span class="n">StartingAt</span> <span class="p">+</span> <span class="m">1</span><span class="p">;</span>
</span><span class='line'>      <span class="p">}</span>
</span><span class='line'>      <span class="k">public</span> <span class="kt">bool</span> <span class="nf">IsValid</span><span class="p">()</span>
</span><span class='line'>      <span class="p">{</span>
</span><span class='line'>          <span class="k">return</span> <span class="n">StartingAt</span> <span class="p">&lt;=</span> <span class="n">EndingAt</span> <span class="p">&amp;</span><span class="n">amp</span><span class="p">;&amp;</span><span class="n">amp</span><span class="p">;</span> <span class="n">StartingAt</span> <span class="p">&gt;</span> <span class="m">0</span><span class="p">;</span>
</span><span class='line'>      <span class="p">}</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">public</span> <span class="k">interface</span> <span class="n">IWillFindYouTreasures</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="n">Pagination</span><span class="p">&lt;</span><span class="n">Treasure</span><span class="p">&gt;</span> <span class="n">FindTreasuresFor</span><span class="p">(</span><span class="n">Pagination</span><span class="p">&lt;</span><span class="n">Treasure</span><span class="p">&gt;.</span><span class="n">Page</span> <span class="n">page</span><span class="p">);</span>
</span><span class='line'>  <span class="n">Pagination</span><span class="p">&lt;</span><span class="n">Treasure</span><span class="p">&gt;.</span><span class="n">Page</span> <span class="n">FirstPage</span><span class="p">();</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">PaginatedTreasureFinder</span> <span class="p">:</span> <span class="n">IWillFindYouTreasures</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="k">private</span> <span class="k">readonly</span> <span class="n">IPropertyStore</span> <span class="n">propertyStore</span><span class="p">;</span>
</span><span class='line'>  <span class="k">public</span> <span class="nf">PaginatedTreasureFinder</span><span class="p">(</span><span class="n">IPropertyStore</span> <span class="n">propertyStore</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="k">this</span><span class="p">.</span><span class="n">propertyStore</span> <span class="p">=</span> <span class="n">propertyStore</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">public</span> <span class="n">Pagination</span><span class="p">&lt;</span><span class="n">Treasure</span><span class="p">&gt;</span> <span class="n">FindTreasureFor</span><span class="p">(</span><span class="n">Pagination</span><span class="p">&lt;</span><span class="n">Treasure</span><span class="p">&gt;.</span><span class="n">Page</span> <span class="n">page</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(!</span><span class="n">page</span><span class="p">.</span><span class="n">IsValid</span><span class="p">())</span>
</span><span class='line'>      <span class="p">{</span>
</span><span class='line'>          <span class="k">return</span> <span class="k">new</span> <span class="n">Pagination</span><span class="p">&lt;</span><span class="n">Treasure</span><span class="p">&gt;(</span><span class="k">new</span> <span class="n">Treasure</span><span class="p">[]</span> <span class="p">{},</span> <span class="n">Treasure</span><span class="p">.</span><span class="n">Count</span><span class="p">,</span> <span class="n">FirstPage</span><span class="p">());</span>
</span><span class='line'>      <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>      <span class="n">var</span> <span class="n">criteria</span> <span class="p">=</span> <span class="n">DetachedCriteria</span><span class="p">.</span><span class="n">For</span><span class="p">&lt;</span><span class="n">Treasure</span><span class="p">&gt;()</span>            
</span><span class='line'>          <span class="p">.</span><span class="n">SetFirstResult</span><span class="p">(</span><span class="n">page</span><span class="p">.</span><span class="n">StartingAt</span><span class="p">-</span><span class="m">1</span><span class="p">)</span>
</span><span class='line'>          <span class="p">.</span><span class="n">SetMaxResults</span><span class="p">(</span><span class="n">page</span><span class="p">.</span><span class="n">PageSize</span><span class="p">());</span>
</span><span class='line'>
</span><span class='line'>      <span class="n">var</span> <span class="n">treasures</span> <span class="p">=</span> <span class="n">ActiveRecordMediator</span><span class="p">&lt;</span><span class="n">Treasure</span><span class="p">&gt;.</span><span class="n">FindAll</span><span class="p">(</span><span class="n">criteria</span><span class="p">);</span>
</span><span class='line'>      <span class="k">return</span> <span class="k">new</span> <span class="n">Pagination</span><span class="p">&lt;</span><span class="n">Treasure</span><span class="p">&gt;(</span><span class="n">treasures</span><span class="p">,</span> <span class="n">Treasures</span><span class="p">.</span><span class="n">Count</span><span class="p">,</span> <span class="n">page</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">public</span> <span class="n">Pagination</span><span class="p">&lt;</span><span class="n">Treasure</span><span class="p">&gt;.</span><span class="n">Page</span> <span class="n">FirstPage</span><span class="p">()</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="n">var</span> <span class="n">endingAt</span> <span class="p">=</span> <span class="n">propertyStore</span><span class="p">.</span><span class="n">Get</span><span class="p">(</span><span class="n">ApplicationProperty</span><span class="p">.</span><span class="n">FirstPageEndingAt</span><span class="p">).</span><span class="n">AsIntOr</span><span class="p">(</span><span class="m">1</span><span class="p">);</span>
</span><span class='line'>      <span class="k">return</span> <span class="k">new</span> <span class="n">Pagination</span><span class="p">&lt;</span><span class="n">Treasure</span><span class="p">&gt;.</span><span class="n">Page</span> <span class="p">{</span><span class="n">StartingAt</span> <span class="p">=</span> <span class="m">1</span><span class="p">,</span> <span class="n">EndingAt</span> <span class="p">=</span> <span class="n">endingAt</span><span class="p">};</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">TreasureController</span> <span class="p">:</span> <span class="n">Controller</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="k">private</span> <span class="k">readonly</span> <span class="n">IWillFindYouTreasures</span> <span class="n">treasureFinder</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">public</span> <span class="nf">TreasureController</span><span class="p">(</span><span class="n">IWillFindYouTreasures</span> <span class="n">treasureFinder</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="k">this</span><span class="p">.</span><span class="n">treasureFinder</span> <span class="p">=</span> <span class="n">treasureFinder</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="na"> [AcceptVerbs(HttpVerbs.Get)]</span>
</span><span class='line'>  <span class="k">public</span> <span class="n">ActionResult</span> <span class="nf">Show</span><span class="p">(</span><span class="kt">int</span> <span class="n">id</span><span class="p">,</span> <span class="kt">int</span> <span class="n">startingAt</span><span class="p">,</span> <span class="kt">int</span> <span class="n">endingAt</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="n">var</span> <span class="n">page</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Pagination</span><span class="p">&lt;</span><span class="n">Treasure</span><span class="p">&gt;.</span><span class="n">Page</span> <span class="p">{</span><span class="n">StartingAt</span> <span class="p">=</span> <span class="n">startingAt</span><span class="p">,</span> <span class="n">EndingAt</span> <span class="p">=</span> <span class="n">endingAt</span><span class="p">};</span>
</span><span class='line'>      <span class="n">var</span> <span class="n">treasures</span> <span class="p">=</span> <span class="n">treasureFinder</span><span class="p">.</span><span class="n">FindTreasureFor</span><span class="p">(</span><span class="n">page</span><span class="p">);</span>
</span><span class='line'>      <span class="n">ViewData</span><span class="p">[</span><span class="s">&quot;Pages&quot;</span><span class="p">]</span> <span class="p">=</span> <span class="n">treasures</span><span class="p">;</span>
</span><span class='line'>      <span class="k">return</span> <span class="nf">View</span><span class="p">(</span><span class="s">&quot;Show&quot;</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p><strong>View</strong></p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt">&lt;div&gt;</span>
</span><span class='line'>  <span class="nt">&lt;span&gt;</span>There are currently <span class="nt">&lt;span</span> <span class="na">class=</span><span class="s">&quot;treasure-count&quot;</span><span class="nt">&gt;</span><span class="err">&lt;</span>%= Pages.MaximumCount %&gt;<span class="nt">&lt;/span&gt;</span> treasures available.<span class="nt">&lt;/span&gt;</span>
</span><span class='line'><span class="nt">&lt;/div&gt;</span>
</span><span class='line'>
</span><span class='line'><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;pagination custom-page-select&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>  <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;options&quot;</span><span class="nt">&gt;</span>To view specific treasures, please enter the number to start at <span class="err">&lt;</span>%= (RawHtml)Html.TextBox(&quot;StartingAt&quot;, Pages.CurrentPage.StartingAt)%&gt; and to finish at <span class="err">&lt;</span>%= (RawHtml)Html.TextBox(&quot;EndingAt&quot;, Pages.CurrentPage.EndingAt)%&gt; and click <span class="err">&lt;</span>%=(RawHtml)Html.ActionLink(&quot;Go&quot;, &quot;Show&quot;, &quot;Treasure&quot;, new { }, new { id = &quot;paginateDirectly&quot; })%&gt;<span class="nt">&lt;/div&gt;</span>
</span><span class='line'>  <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;clear&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'><span class="nt">&lt;/div&gt;</span>
</span><span class='line'>
</span><span class='line'><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;treasures-list&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>  <span class="err">&lt;</span>% new TreasuresRenderer().RenderTreasures(Pages.PaginatedCollection); %&gt;
</span><span class='line'><span class="nt">&lt;/div&gt;</span>
</span><span class='line'>
</span><span class='line'><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;pagination menu&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>  <span class="nt">&lt;span</span> <span class="na">class=</span><span class="s">&quot;info&quot;</span><span class="nt">&gt;</span>Please select a range of treasures to view.<span class="nt">&lt;/span&gt;</span>
</span><span class='line'>  <span class="nt">&lt;ul&gt;</span>
</span><span class='line'>      <span class="err">&lt;</span>% foreach (var page in Pages) { %&gt;
</span><span class='line'>      <span class="nt">&lt;li</span> <span class="na">class=</span><span class="s">&quot;pages&lt;%= Pages.IsTheCurrentPage(page)? &quot;</span> <span class="na">currentPage</span><span class="err">&quot;</span> <span class="na">:</span> <span class="na">string</span><span class="err">.</span><span class="na">Empty</span> <span class="err">%</span><span class="nt">&gt;</span>&quot;&gt;<span class="err">&lt;</span>%=(RawHtml) Html.ActionLink(page.Name(), &quot;Show&quot;, &quot;Treasure&quot;, new {startingAt=page.StartingAt,endingAt=page.EndingAt}, new {}) %&gt;<span class="nt">&lt;/li&gt;</span>
</span><span class='line'>      <span class="err">&lt;</span>% } %&gt;
</span><span class='line'>  <span class="nt">&lt;/ul&gt;</span>
</span><span class='line'><span class="nt">&lt;/div&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p><strong>Helpful Javascript</strong></p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">function</span> <span class="nx">SetupPagination</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;.pages a&quot;</span><span class="p">).</span><span class="nx">click</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span><span class='line'>      <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#content-main-container&quot;</span><span class="p">).</span><span class="nx">load</span><span class="p">(</span>
</span><span class='line'>                  <span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">attr</span><span class="p">(</span><span class="s1">&#39;href&#39;</span><span class="p">),</span>
</span><span class='line'>                  <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span><span class='line'>                      <span class="nx">SetupPagination</span><span class="p">();</span>
</span><span class='line'>                  <span class="p">});</span>
</span><span class='line'>      <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;a#paginateDirectly&#39;</span><span class="p">).</span><span class="nx">click</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span><span class='line'>      <span class="kd">var</span> <span class="nx">url</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">attr</span><span class="p">(</span><span class="s1">&#39;href&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39;?StartingAt=&#39;</span> <span class="o">+</span> <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;input[name=&quot;StartingAt&quot;]&#39;</span><span class="p">).</span><span class="nx">val</span><span class="p">()</span> <span class="o">+</span> <span class="s1">&#39;&amp;amp;EndingAt=&#39;</span> <span class="o">+</span> <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;input[name=&quot;EndingAt&quot;]&#39;</span><span class="p">).</span><span class="nx">val</span><span class="p">();</span>
</span><span class='line'>      <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;#content-main-container&quot;</span><span class="p">).</span><span class="nx">load</span><span class="p">(</span>
</span><span class='line'>                  <span class="nx">url</span><span class="p">,</span>
</span><span class='line'>                  <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span><span class='line'>                      <span class="nx">SetupPagination</span><span class="p">();</span>
</span><span class='line'>                  <span class="p">});</span>
</span><span class='line'>      <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;input[name=&quot;StartingAt&quot;]&#39;</span><span class="p">).</span><span class="nx">numeric</span><span class="p">().</span><span class="nx">limit</span><span class="p">(</span><span class="mi">9</span><span class="p">);</span>
</span><span class='line'>  <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;input[name=&quot;EndingAt&quot;]&#39;</span><span class="p">).</span><span class="nx">numeric</span><span class="p">().</span><span class="nx">limit</span><span class="p">(</span><span class="mi">9</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;input[name=&quot;EndingAt&quot;]&#39;</span><span class="p">).</span><span class="nx">keyup</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="kd">var</span> <span class="nx">key</span> <span class="o">=</span> <span class="nx">e</span><span class="p">.</span><span class="nx">charCode</span> <span class="o">?</span> <span class="nx">e</span><span class="p">.</span><span class="nx">charCode</span> <span class="o">:</span> <span class="nx">e</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">?</span> <span class="nx">e</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">:</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'>      <span class="c1">// return should trigger the pagination</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="nx">key</span> <span class="o">==</span> <span class="mi">13</span><span class="p">)</span> <span class="p">{</span> <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;a#paginateDirectly&#39;</span><span class="p">).</span><span class="nx">click</span><span class="p">();</span> <span class="p">}</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Code Contracts in .Net4.0: First impressions]]></title>
    <link href="http://sarahtaraporewalla.com/testing/code-contracts-in-net4-0-first-impressions"/>
    <updated>2011-04-05T14:44:37+10:00</updated>
    <id>http://sarahtaraporewalla.com/testing/code-contracts-in-net4-0-first-impressions</id>
    <content type="html"><![CDATA[<p><a href="http://msdn.microsoft.com/en-us/devlabs/dd491992">Code Contracts</a> is one of the new features in .Net4.0 which brings a little bit of formal specification to .Net applications. As someone who has a background in <a href="http://en.wikipedia.org/wiki/Formal_specification">formal specifications</a>[1] I thought it might be interesting to see what this new tool offers .Net developers.</p>

<p><strong>What is formal specification?</strong>
Formal specification is a way that allows us to mathematically analyse our programs to formally verify that it is correct according to the specification. There are 3 basic constructs: pre condition,  post condition and invariant. Preconditions are the rules which describe the state of the world before an action, post conditions are the rules which describe the state of the world after an action, and invariants are the rules which are always true. Using a trivial example of a bank account (which is not allowed to go in the red):</p>

<p>Pre condition to Withdraw: withdraw amount > 0
Post condition to Deposit: balance > deposit amount
Invariant: account balance > 0</p>

<p>So, then a valid program would look something like:</p>

<p>account = new Account()
account.deposit(200)
account.withdraw(100)</p>

<p>All good there. Now what happens when I do the following?</p>

<p>account = new Account()
account.deposit(200)
account.withdraw(600)</p>

<p>My formal specification analysis would (should) verify that the last withdraw would mean balance is -400 &lt; 0 which fails the invariant. So the program has a problem. Note that according to formal specification if you actually ran this invalid program, the result would be indeterminate: that is to say that (formally speaking) we cannot tell you what would happen (it may fail gracefully or blow up dramatically).</p>

<p>Ok, so good so far but can you see where this stuff might be useful? Do you ever explicitly write precondition code? The type that looks something like:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">class</span> <span class="nc">Account</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="k">public</span> <span class="k">void</span> <span class="nf">Deposit</span><span class="p">(</span><span class="kt">int</span> <span class="n">amount</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="n">amount</span> <span class="p">&lt;</span> <span class="m">0</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="p">}</span> <span class="c1">// or throw exception or something else horrible</span>
</span><span class='line'>      <span class="c1">//else continue</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">MyBanks</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="k">private</span> <span class="n">Account</span> <span class="n">account</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Account</span><span class="p">();</span>
</span><span class='line'>  <span class="k">public</span> <span class="k">void</span> <span class="nf">Deposit</span><span class="p">(</span><span class="kt">int</span> <span class="n">amount</span><span class="p">){</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="n">amount</span> <span class="p">&lt;</span> <span class="m">0</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="p">}</span>
</span><span class='line'>      <span class="n">account</span><span class="p">.</span><span class="n">Deposit</span><span class="p">(</span><span class="n">amount</span><span class="p">)</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>I have seen this style a lot, especially when people heavily unit test each class for every possibility that could happen. In reality, your other classes bomb out before you get to the if statement in Account, but you really want to describe a precondition on deposit. I have felt that being able to unobtrusively define pre conditions, post conditions and invariants on classes has been lacking in common programming languages/ecosystems. So, lets take a look at CodeContracts which is coming bundled with .Net 4.0</p>

<p><strong>.Net 4.0 Code Contracts</strong>
Code contracts support pre-, post-conditions and invariants. They have the same meaning as I previously described. They can statically analyse your solution on compilation and also dynamically analyse during runtime. What would our previous solution look like:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">class</span> <span class="nc">Account</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="k">private</span> <span class="kt">int</span> <span class="n">balance</span>
</span><span class='line'><span class="na"> </span>
</span><span class='line'><span class="na"> [ContractInvariantMethod]</span>
</span><span class='line'>  <span class="k">private</span> <span class="k">void</span> <span class="nf">BalanceHasToAlwaysBeInTheBlack</span><span class="p">()</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="c1">// Note to reader: only conditions can be in here</span>
</span><span class='line'>      <span class="n">Contract</span><span class="p">.</span><span class="n">Invariant</span><span class="p">(</span><span class="n">balance</span> <span class="p">&gt;=</span> <span class="m">0</span><span class="p">)</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  
</span><span class='line'>  <span class="k">public</span> <span class="k">void</span> <span class="nf">Deposit</span><span class="p">(</span><span class="kt">int</span> <span class="n">amount</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="n">Contract</span><span class="p">.</span><span class="n">Requires</span><span class="p">(</span><span class="n">amount</span> <span class="p">&gt;</span> <span class="m">0</span><span class="p">)</span>
</span><span class='line'>      <span class="n">Contract</span><span class="p">.</span><span class="n">Ensures</span><span class="p">(</span><span class="n">balance</span> <span class="p">&gt;</span> <span class="n">amount</span><span class="p">)</span>   <span class="c1">// Note to reader: you can also ensure on the returned object e.g. Contract.Ensures(Contract.Result&lt;int&gt;() &gt; 0)</span>
</span><span class='line'>
</span><span class='line'>      <span class="n">balance</span> <span class="p">+=</span> <span class="n">amount</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  
</span><span class='line'>  <span class="k">public</span> <span class="k">void</span> <span class="nf">Withdraw</span><span class="p">(</span><span class="kt">int</span> <span class="n">amount</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="n">Contract</span><span class="p">.</span><span class="n">Requires</span><span class="p">(</span><span class="n">amount</span> <span class="p">&gt;</span> <span class="m">0</span><span class="p">)</span>
</span><span class='line'>      
</span><span class='line'>      <span class="n">balance</span> <span class="p">-=</span> <span class="n">amount</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Running statical analysis (hint: turn it on in the Properties tab panel) on <em>account.Deposit(-400)</em> would show produce a warning to say that this breaks the precondition however <em>if (amount > 0){ account.Deposit(amount)} </em>would be validated. If you did not listen to the warning and carried on regardless, in production the application would throw an exception.</p>

<p>So, what do you think? In my opinion, it is an interesting idea and in theory I would love to use it. However, Microsoft&#8217;s execution has a lot to be desired. The analysis does not seem to find everything (the analysis checker said that <em>balance/50</em> would break the invariant). I don&#8217;t think it is unobtrusive. Perhaps you can farm the Contracts off to a meaningfully-named method but I&#8217;m not sure that it works like that.</p>

<p>I am also a little worried about the implications of this. I was talking to a few people who didn&#8217;t write tests: they believed that unit tests were not DRY so they don&#8217;t like doing it so they were really excited by code contracts because it made the specification DRY. However, effective TDD is more around understanding what to test than the tests themselves and it is the same thought process involved when formally specifying the system. I worry the level of false confidence this gives to developers who are not used to writing effective tests now.</p>

<p>I am eager to work with them properly and explore how they can be used successfully. There is some good in there, so that I don&#8217;t want to throw the baby out with the bathwater.</p>

<p>[1] for my university honours project I was working on a theorem prover in <a href="http://en.wikipedia.org/wiki/Prolog">prolog</a> for formal specifications written in <a href="http://en.wikipedia.org/wiki/B-Method">B</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Conferences: SDC and GoTo]]></title>
    <link href="http://sarahtaraporewalla.com/agile/conferences-sdc-and-goto"/>
    <updated>2011-04-04T06:47:59+10:00</updated>
    <id>http://sarahtaraporewalla.com/agile/conferences-sdc-and-goto</id>
    <content type="html"><![CDATA[<p>I have been getting my speaking voice ready, and now I am getting set to use it. This week, I am speaking about how to integrate with other systems in my talk titled <a href="http://www.scandevconf.se/2011/conference/speakers/sarah-taraporewalla/?backlnk=dp&tgday=togglewrap1">The Three Pronged Approach To Integrating Systems</a> at <a href="http://www.scandevconf.se/2011/conference/detailed-program/">Scandinavian Developer Conference 2011</a> in Gothenburg, Sweden. I am also running a conversation corner about feedback. If you want to follow what is going on, the hash tag is <a href="http://twitter.com/#!/search/%23scandev">#scandev</a></p>

<p>Next month, I will be speaking at <a href="http://gotocon.com/cph-2011/">Goto CPH</a> (in Copenhagen of course) in a talk titled <a href="http://gotocon.com/cph-2011/speaker/Sarah+Taraporewalla">What about People over Process</a>? I am really looking forward to this one - the form is a little looser than I usually go for but it is an accumulation of all the psychology books I have been reading of late.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[TED Talk: Sheryl Sandberg: Why we have too few women leaders]]></title>
    <link href="http://sarahtaraporewalla.com/women-in-it/ted-talk-sheryl-sandberg-why-we-have-too-few-women-leaders"/>
    <updated>2011-03-04T08:16:26+10:00</updated>
    <id>http://sarahtaraporewalla.com/women-in-it/ted-talk-sheryl-sandberg-why-we-have-too-few-women-leaders</id>
    <content type="html"><![CDATA[<p>Do you like TED? I have been enjoying the TED app on the iPad lately, and I recently saw the TED talk given by Sheryl Sandberg, Facebook&#8217;s COO - <em>Why we have too few women leaders</em>.</p>

<p>This talk was really interesting, and I highly recommend watching it. In it, she gives three really great pieces of advice for fellow females:</p>

<ol>
<li><p><strong>Sit at the table</strong> - women systematically underrate their own abilities. As a result, women don&#8217;t negotiate for themselves in the workplace. Women attribute success to external factors, men attribute success to themselves. No one gets to the corner office by sitting on the side not at the table and no one gets the promotion if they don&#8217;t think they deserve their success or they don&#8217;t know their own success. Unfortunately, success and likability are correlated positively for men and correlated negatively for women. How good are we as managers for seeing that men are reaching for opportunities more than the women?</p></li>
<li><p><strong>Make your partner a real partner</strong> - make your partnership an equal partnership. Be kind to the fathers at Mummy &amp; Me classes. Make childrearing as important a job as any others, for both men and women. Societal pressures are just as hard for men who want to stay home to look after the kids, whilst their wives are at work, as it is for the wives to be leaders. We can&#8217;t solve the problems of the lack of female leaders if we neglect to also solve the problems of the lack of stay-at-home fathers</p></li>
<li><p><strong>Don&#8217;t leave before you leave</strong> - basically, don&#8217;t back away from opportunities because you don&#8217;t think you would be able to fit it in with a family life or maternity leave, which could happen sometime in the future, but is not in your reality right now. From the moment a women starts having a child, and she starts thinking of how to make room for that child in her already busy life. And from that moment, she doesn&#8217;t raise her hand any more, look for a promotion, start a new project. The problem is that even if she were to get pregnant that day, with 9 months incubation, a year maternity leave and a few months getting back into work, it is almost 2 years before she can think of raising her hand again. And the reality of the situation is that it is usually a few years before she even starts to have children - in a lot of cases, before she even has a partner. Sheryl&#8217;s words are inspiring - Keep your foot on the gas pedal until you actually leave.</p></li>
</ol>


<p>Sheryl is very engaging in this talk, and I throughly recommend watching this video!</p>

<object width="446" height="326"><param name="movie" value="http://video.ted.com/assets/player/swf/EmbedPlayer.swf"></param><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always"/><param name="wmode" value="transparent"></param><param name="bgColor" value="#ffffff"></param> <param name="flashvars" value="vu=http://video.ted.com/talks/dynamic/SherylSandberg_2010W-medium.flv&su=http://images.ted.com/images/ted/tedindex/embed-posters/SherylSandberg-2010W.embed_thumbnail.jpg&vw=432&vh=240&ap=0&ti=1040&introDuration=15330&adDuration=4000&postAdDuration=830&adKeys=talk=sheryl_sandberg_why_we_have_too_few_women_leaders;year=2010;theme=new_on_ted_com;theme=celebrating_tedwomen;theme=not_business_as_usual;event=TEDWomen;&preAdTag=tconf.ted/embed;tile=1;sz=512x288;" /><embed src="http://video.ted.com/assets/player/swf/EmbedPlayer.swf" pluginspace="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" wmode="transparent" bgColor="#ffffff" width="446" height="326" allowFullScreen="true" allowScriptAccess="always" flashvars="vu=http://video.ted.com/talks/dynamic/SherylSandberg_2010W-medium.flv&su=http://images.ted.com/images/ted/tedindex/embed-posters/SherylSandberg-2010W.embed_thumbnail.jpg&vw=432&vh=240&ap=0&ti=1040&introDuration=15330&adDuration=4000&postAdDuration=830&adKeys=talk=sheryl_sandberg_why_we_have_too_few_women_leaders;year=2010;theme=new_on_ted_com;theme=celebrating_tedwomen;theme=not_business_as_usual;event=TEDWomen;"></embed></object>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How Gender Stereotypes Influence Emerging Career Aspirations]]></title>
    <link href="http://sarahtaraporewalla.com/women-in-it/how-gender-stereotypes-influence-emerging-career-aspirations"/>
    <updated>2010-11-24T22:20:57+10:00</updated>
    <id>http://sarahtaraporewalla.com/women-in-it/how-gender-stereotypes-influence-emerging-career-aspirations</id>
    <content type="html"><![CDATA[<div>I have just finished watching <a href="http://www.stanford.edu/dept/soc/people/shelleycorrell/shelleycorrell.html" target="_blank">Shelly Correll</a>&#8217;s talk on <a href="http://www.youtube.com/watch?v=jwviTwO8M8Q" target="_blank">How Gender Stereotypes Influence Emerging Career Aspirations</a>, a video filled with really great research to back up what I have been thinking about of late. I don&#8217;t want to summarise too much, I would say go and watch it, but for the main highlights&#8230;</div>




<div>Shelly is a professor of Sociology at Stamford University. She chose to research the affect of gender stereotypes on students choosing their careers, especially as they make decisions to enter Science Technology Engineering or Maths (STEM) subjects. She conducted numerous controlled experiments to find out how stereotypes influence the performance of tasks and also the subject&#8217;s self assessment of their ability to do the task. She found that when the subjects were primed with negative stereotypes prior, even when it was a simple as filling in demographic information, they performed worse that subjects who were not primed. Even more interesting, was subjects that were primed with positive stereotypes prior to the tasks performed better than the control group.</div>




<div>Another study conducted at Stamford compared the self assessment of male and female students who were equal in terms of grades and marks on tests. She found that the girls were more likely to underrate their ability than the boys were. She further showed that a person&#8217;s belief in their ability was a strong contributing factor for determining if they would pursue careers where that ability was needed. She therefore concluded that as girls underrate their ability in areas like maths and science, they don&#8217;t gravitate to subjects like AP Calculus in senior grades. She also showed that the opposite effect encouraged more girls into those subjects.</div>




<div>There is often outcry around attracting more women to STEM that either women are not capable or that they have no interested in these subjects. She brilliantly debunked these myths. The first by showing the bell curve of men vs women SAT maths scores, and proved that there was no significant difference between the two curves and the second myth by displaying a graph which showed a rise (trending upward) in the percentage of women represented in physics courses from 1977 to 2006, corresponding to a lot of time, money and effort spent by the National Science Foundation to encouraging women into these fields which indicates that it is working and that something can be done to make women more interested (good news for us).</div>




<div>She argues that there are four basic principals of how gender stereotypes affect people:

<ul>
    <li>Stereotypic biases often occur out of awareness</li>
    <li>Biases are more extreme in uncertain settings - when people don&#8217;t know what to do, gender stereotypes fill in the gaps</li>
    <li>The impact of stereotypes change when beliefs in the local setting change</li>
    <li>Stereotypes also bias the standards gatekeepers use to assess competence</li>
</ul>
</div>


<div>This last point is interesting and she showed a few studies to support this point:
<ul>
    <li>Experimental study of the evaluation of engineering internship application finds that women are judged by a harsher standard</li>
    <li>Experimental study of the evaluation of police chief candidates find that evaluations change criteria when evaluating women vs men</li>
    <li>Study of student evaluation of professors show female professors judged more harshly</li>
    <li>Women leaders experience a double bind - when they wish to prove that they belong, they come across assertive and are not liked</li>
    <li><span style="font-size: 13px; line-height: 19px;">Since stereotypes affect judgements of others we must change gender beliefs that are operating in an organisation not just change individual women&#8217;s beliefs. Therefore we need to fix organisations rather than fixing women.</li>
</ul>
</div>


<div>So, what can be done? Shelley suggests three ways:</div>


<div>Control the message: what are the gender beliefs that are operating in the organisation? How does the organisation present itself? e.g. Carnie Mellon changed the way people saw computer science away from just geek which led in an increase in the percentage of women from 7% to 42%. In another study, two videos were shown to elite female maths students at Stamford about further education in maths; one video showed images with a balanced proportion of male and female engineers, and the other had an unbalanced group of mainly men - apart from the images the videos were identical. They found that the women who watched the balanced video had a more positive effect that the women who saw the unbalanced video, but even more interestingly there was a physical reaction to the unbalanced video, one which sociologists also see when people feel like they don&#8217;t belong.</div>


<div>Make performance standards clearer and communicate them clearly. Teach tacit knowledge. e.g. when female students dropped out of engineering courses they were asked their reason, which was in the majority that their grades were too low. However, these students were achieving higher grades than men that stayed in the course. By making the performance standards explicit, the students could have seen that their grades were satisfactory for the course and that low grades did not indicate failure in the course.</div>


<div>Hold gatekeepers accountable for gender disparities. It is important to keep thinking about how our policies and procedures affect career relevant decisions.</div>


<div>It was a great presentation, and she finished with three things that individuals can do - understand how stereotypes might affect your own career decision making; realize that negative feedback is common and productive; and promote organisation change.</div>




<div>
<object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/jwviTwO8M8Q?fs=1&amp;hl=en_US"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/jwviTwO8M8Q?fs=1&amp;hl=en_US" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object>
</div>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How to decrease risk when designing integrated systems]]></title>
    <link href="http://sarahtaraporewalla.com/agile/design/how-to-decrease-risk-when-designing-integrated-systems"/>
    <updated>2010-11-08T22:07:32+10:00</updated>
    <id>http://sarahtaraporewalla.com/agile/design/how-to-decrease-risk-when-designing-integrated-systems</id>
    <content type="html"><![CDATA[<p>How often do you get to work on completely isolated systems? It is seemingly more and more common that your system needs to talk to another system to function, whether that be a legacy system, an external API or even one that has not been developed yet. Every system that you talk to adds risk to your project; technical risk, quality risk and delivery risk. But never fear - help is at hand.</p>

<p>Come to my <strong>London Dot Net User Group talk next Thursday (18th November)</strong> at <strong>Skills Matter</strong> and you will hear about how to design your system to decrease this risk, how to ensure the quality of the overall system and how to manage the successful delivery of the system. Not only that, but you will hear real-life cases, some success stories but also many failures and you too can learn from the mistakes I witnessed. Have questions around the integration points in your ecosystem? Fire them up, and lets see if we can work through them together.</p>

<p>Registration is at <a href="http://skillsmatter.com/podcast/open-source-dot-net/how-to-design-your-system-to-decrease-risks" target="_blank">http://skillsmatter.com/podcast/open-source-dot-net/how-to-design-your-system-to-decrease-risks</a></p>

<p>Thanks to <a href="http://www.dnug.org.uk/" target="_blank">LDNUG</a>, <a href="http://skillsmatter.com/" target="_blank">Skills Matter</a> and <a href="http://www.rachellaycock.com/" target="_blank">Rachel Laycock</a> for finding me a soap box to stand on.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Working With Integration Points: Simulators]]></title>
    <link href="http://sarahtaraporewalla.com/design/working-with-integration-points-simulators"/>
    <updated>2010-01-31T22:03:10+10:00</updated>
    <id>http://sarahtaraporewalla.com/design/working-with-integration-points-simulators</id>
    <content type="html"><![CDATA[<div>In my last post about <a href="http://sarahtaraporewalla.com/thoughts/design/working-with-integration-points-anticorruption-layer/">working with integration points</a> I described how I use anti-corruption layers (wrappers) to hide away any warts of the integration point. In this post, I will explain how I used these wrappers to help develop against an integration point which was also under development.</div>


<div>The problem with two systems being developed concurrently is that it is rare that they are developed at the same rates, or even in the same priority. That means that the consumer can often be left waiting for functionality to be delivered before they can start developing against it. And that assumes that it all works (not a wise assumption if my previous projects are anything to go by).</div>


<div>There is another way however - by using simulators to develop against. The simulators can be as sophisticated as you need them be - either returning pre-canned values or randomising the responses. They can live in-memory or they can be across the wire depending on what your focus is. Or have both types and simulate less and less and you move through the CI pipeline. An in-memory simulator can replace your wrapper easily using your DI container (it also helps draw the distinction between logic for the business service and logic for the wrapper).</div>


<div><a href="http://sarahtaraporewalla.com/wp-content/uploads/2010/01/simulators.jpg"><img class="aligncenter size-medium wp-image-302" title="simulators" src="http://sarahtaraporewalla.com/wp-content/uploads/2010/01/simulators-300x201.jpg" alt="" width="300" height="201" /></a></div>


<div>The main importance of simulators is that they let you develop independently of other teams. An added benefit is that they help you define a consumer-driven contract (if you are the consumer). You can also use the simulators to help identify problems with the system - if it works against the simulator and not against the real integration system, then there is a problem with the integration system. If there is a problem even with the simulator then there is a problem in your system. If it works against the in-memory simulator but not against the simulator across the wire, then your problem lies somewhere on the wire.</div>


<div>Simulators can really help you in your development - don&#8217;t be afraid by the effort you need to spend to create them. Obviously you need to weigh up the benefits of the sophistication of the simulator with the effort to maintain them but there is often a nice balance to strike.</div>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Working With Integration Points: Anticorruption Layer]]></title>
    <link href="http://sarahtaraporewalla.com/design/working-with-integration-points-anticorruption-layer"/>
    <updated>2010-01-31T21:09:48+10:00</updated>
    <id>http://sarahtaraporewalla.com/design/working-with-integration-points-anticorruption-layer</id>
    <content type="html"><![CDATA[<div>On my last few projects we had a requirement to integrate our application with another system. Adding to this complexity was the fact that these other systems where also still being developed. I learned a few tricks on the first of these types of projects which really helped the latter projects which I shall share with a wider audience here.</div>


<div>The first of these tricks was to enforce a strict layering of my application and introduce an anti-corruption layer. This layer was responsible for dealing with the interface to the other system, and often hiding any crapiness of either the api or transport protocol from the rest of the application. It ensured that any business logic remained in the business services layer and any api/transport logic remained in the anti-corruption layer (which we called a wrapper).</div>


<div><a href="http://sarahtaraporewalla.com/wp-content/uploads/2010/01/layered-diagram.jpg"><img class="size-medium wp-image-291 aligncenter" style="margin: 10px;" title="AntiCorruptionLayer" src="http://sarahtaraporewalla.com/wp-content/uploads/2010/01/layered-diagram-300x201.jpg" alt="" width="300" height="201" /></a></div>


<div>The main reason for this was to limit the amount of damage that would occur should the api change (i.e. try to decrease the amount of coupling between the two systems). To support this, the wrapper would talk to the business services in domain language and pass around domain objects which it would transform into the required transport objects.</div>


<div>

There are a few cases where the wrappers proved their worth:
<ul>
    <li>when the service did not populate all the necessary fields for the domain object</li>
    <li>when the domain object did not logically contain a field necessary for the transport</li>
    <li>when the business layers dealt in synchronous calls, and the api dealt with asynchronous calls</li>
    <li>when the a wcf object type changed</li>
</ul>
</div>


<div>It was sometimes hard, especially when dealing with a crappy api that we could not alter, to know if a piece of logic should reside in the business service or in the wrapper. The general rule of thumb we followed was to ask ourselves &#8220;if we ever changed this integration point to a different system, would we still need this bit of logic?&#8221;. [The crappier the api the harder it was to answer].</div>


<div>However, despite what I considered to be the obvious benefits of introducing this layer, I faced a lot of resistance introducing it, especially when it looked like the business service was just a pass through to the wrapper i.e. when the method only had one line in it _wrapper.Foo() (actually it turned out that the only reason the service was pass through was because there were fat controllers - pushing the logic from the controller into the service made it look a lot healthier but that is a whole other discussion). What irked me the most is when people invoked YAGNI as a reason not to add a new object. Although that debate is a whole entire post in itself, all I am going to mention here is that YAGNI does not trump SOLID and that anti-corruption layers is nothing more than Single Responsibility Principle (i.e. Separation of Concerns) [and seriously - are you really telling me that adding another object is time consuming, in the world of resharper/intelli-j].</div>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[I don't believe in NFRs]]></title>
    <link href="http://sarahtaraporewalla.com/agile/design/i-dont-believe-in-nfrs"/>
    <updated>2010-01-31T12:10:12+10:00</updated>
    <id>http://sarahtaraporewalla.com/agile/design/i-dont-believe-in-nfrs</id>
    <content type="html"><![CDATA[<p>There is something about the phrase <em><a title="Wikipedia: Non Functional Requirements" href="http://en.wikipedia.org/wiki/Non-functional_requirement" target="_blank">Non Functional Requirements</a></em> that I don&#8217;t really like. It&#8217;s the <em>Non</em> bit which gets me - I think that word makes them feel unimportant and therefore there is no pressing need to explore how they will affect the system. I have seen on many projects teams procrastinating in defining how the &#8220;NFRs&#8221; will affect what they are building - usually in the metrics around performance.</p>

<p>On my current project we have decided to appease my sensibilities and have called these <em><strong>Cross Functional Requirements</strong></em> to better express what they truly represent - requirements which cross all the functions we are building. So far the wording works - but we have only finished the 2nd week of inception.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[The Importance of Words]]></title>
    <link href="http://sarahtaraporewalla.com/design/the-importance-of-words"/>
    <updated>2009-12-15T08:33:27+10:00</updated>
    <id>http://sarahtaraporewalla.com/design/the-importance-of-words</id>
    <content type="html"><![CDATA[<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">The english language is a very complex beast which can easily strike confusion in the most unsuspecting moment. Take, for example, the word &#8220;lollies&#8221;. Did your mind immediately jump to a bag of gummy bears, redskins, bananas or milk bottles that you get from the garage? Or instead did you start thinking of a frozen dessert on a stick? If you thought the former, then, like me, you probably are Australian. Because the English term for it is sweets, and the American version is candy (although I doubt that they have such wonderful lollies as bananas and milk bottles). And the frozen-dessert-on-a-stick - thats an iceblock for me!</div>


<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Take another example - when Sisqo&#8217;s Thong Song came out I didn&#8217;t really understand why someone dedicate an entire song to $1 rubber plugs - until I watched the video clips and I realised that he wasn&#8217;t referring to &#8220;flip flops&#8221;.</div>


<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">The lesson that I have learnt living in the UK is that I have to be very careful with the words that I use, lest I cause confusion by saying that someone was running around with their pants* off**.</div>


<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">And this is also applies to the words and language that we use around our business, between developers and in our code. Too often, we describe concepts by words like &#8220;that thing&#8221; or &#8220;this stuff&#8221; which can obfuscate what it really is, and hence hinder our ability to model it. I often see complexity, misunderstandings and hacks creep into code bases when the original designer has referred to an information concept as &#8220;this thing&#8221; without taking the time to name it. I find that spending the energy, talking to the business to understand what you are really producing helps clarify understanding which in turn distills the model into a simpler, easily understood model.</div>


<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">I had this demonstrated to me yesterday, when I came across a pair discussing how to &#8220;shove&#8221; this concept of &#8220;a thing that when clicked on opens up a popup with stuff in it&#8221; onto the model. As I listened to the conversation, I noticed just how muddled the model and the situation was becoming, so I decided to intervene with some of my words of wisdom about what they were trying to model. As soon as we worked out that the &#8220;a thing that when clicked on opens up a popup with stuff in it&#8221; translated into &#8220;a help message&#8221;, we were easily able to see exactly where in our model it should go.</div>


<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">So, never underestimate the power of the words we use. When faced with a confusing concepts strive to distill it into easily understood, well defined names.</div>


<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">* pants in Australia are trousers - pants in the English vernacular are what I call underpants.</div>


<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">** yes I have once said that at work after I saw a pair of jeans on the table and was a little confused by what someone must be wearing!</div>


<p>The English language is a very complex beast which can easily strike confusion in the most unsuspecting moment. Take, for example, the word &#8220;lollies&#8221;. Did your mind immediately jump to a bag of <a href="http://en.wikipedia.org/wiki/Gummi_bear" target="_blank">gummy bears</a>, <a href="http://en.wikipedia.org/wiki/Redskins_(confectionery)" target="_blank">redskins</a>, <a href="http://www.goodygoodygumdrops.com.au/shop/images/pi_418.jpeg" target="_blank">bananas</a> or <a href="http://www.lollyworld.com.au/images/Allens-Milk-Bottles.jpg" target="_blank">milk bottles</a> that you get from the garage? Or instead did you start thinking of a <a href="http://en.wikipedia.org/wiki/Ice_pop" target="_blank">frozen dessert on a stick</a>? If you thought the former, then, like me, you probably are Australian. Because the English term for it is sweets, and the American version is candy (although I doubt that they have such wonderful lollies as bananas and milk bottles). And the frozen-dessert-on-a-stick - thats an iceblock for me!</p>

<p>Take another example - when <a href="http://en.wikipedia.org/wiki/Thong_Song" target="_blank">Sisqo&#8217;s Thong Song</a> came out I didn&#8217;t really understand why someone dedicate an entire song to<a href="http://upload.wikimedia.org/wikipedia/commons/thumb/6/65/Havi-flip1.JPG/180px-Havi-flip1.JPG" target="_blank"> $1 rubber plugs</a> - until I watched the video clips and I realised that he wasn&#8217;t referring to &#8221;<a href="http://en.wikipedia.org/wiki/Flip-flops" target="_blank">flip flops</a>&#8221;.</p>

<p>The lesson that I have learnt living in the UK is that I have to be very careful with the words that I use, lest I cause confusion by saying that someone was running around with their pants* off**.</p>

<p>And this is also applies to the words and language that we use around our business, between developers and in our code. Too often we describe concepts by words like &#8220;that thing&#8221; or &#8220;this stuff&#8221; which can obfuscate what it really is, and hence hinder our ability to model it. I often see complexity, misunderstandings and hacks creep into code bases when the original designer has referred to an information concept as &#8220;this thing&#8221; without taking the time to name it. I find that spending the energy talking to the business to understand what you are really producing helps clarify understanding which in turn distills the model into a simpler, easily understood model.</p>

<p>I had this demonstrated to me yesterday, when I came across a pair discussing how to &#8220;shove&#8221; this concept of &#8220;a thing that when clicked on opens up a popup with stuff in it&#8221; onto the model. As I listened to the conversation, I noticed just how muddled the model and the situation was becoming, so I decided to intervene with some of my words of wisdom about what they were trying to model. As soon as we worked out that the &#8220;thing that when clicked on opens up a popup with stuff in it&#8221; translated into &#8220;a help message&#8221;, we were easily able to see exactly where in our model it should go.</p>

<p>So, never underestimate the power of the words we use. When faced with a confusing concepts strive to distill it into easily understood, well defined names.</p>

<ul>
<li>pants in Australia are trousers - pants in the English vernacular are what I call underpants.
** yes I have once said that at work after I saw a pair of jeans on the table and was a little confused by what someone must be wearing!</li>
</ul>


<div></div>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[JAOO and Women: Attendance at Conferences]]></title>
    <link href="http://sarahtaraporewalla.com/women-in-it/jaoo-and-women-attendance-at-conferences"/>
    <updated>2009-10-18T22:32:41+10:00</updated>
    <id>http://sarahtaraporewalla.com/women-in-it/jaoo-and-women-attendance-at-conferences</id>
    <content type="html"><![CDATA[<p>I was going to start <a href="http://sarahtaraporewalla.com/thoughts/women-in-it/jaoo-and-women/">this series</a> off talking about filters and the way that connections are made in your brain, but after hearing about the lap dances at the <a href="http://developer.yahoo.net/blog/archives/2008/09/taiwan_open_hac.html">Taiwan Yahoo! Hack Day</a>, I thought I might begin with addressing the issue of low attendance at conferences.</p>

<p>I think one of the biggest concerns that conference organisizers should be worrying about (and luckily <a href="http://jaoo.dk/">JAOO</a> did) is that the ratio of women at the conferences does not reflect the industry - I have heard that between 5-10% is considered good, where as I believe the industry is at about 20% (unconfirmed sources). I don&#8217;t want to start of speculating at why the numbers are so low, but what I can share is why I don&#8217;t attend conferences.</p>

<p>Conferences are quite expensive for your employer - not only do they need to purchase entry, but accommodation, meals and transfer to and from the conference, not to mention loss of &#8220;billable&#8221; work. So, usually they can only afford to send one or two people there. I have seen two ways that these tickets are distributed. The first is that the same people always seem to go to the conference. It is noticeably remarkable how many people you see at conferences that seem to be on the &#8220;conference circuit&#8221; - they have seen each other every month, following the conferences around the world. So, unless you already are in the conference circuit, it is really hard to enter it - as there are currently 5-10% women normally at conferences, and the same people keep attending, then this number won&#8217;t change. The other way that I have seen tickets distributed is by everyone-gets-a-turn selection. Lets say the industry average is 20% - then its only fair that for every five conferences that are attended (given one ticket per conference), a company would send a female to only one of them. From that point of view, it does not seem that unbelievable to me that the number of women is low in comparison.</p>

<p>So, I think it is up to conference organisers to think outside the box for different ways to attract females to conferences. For this, I would like to commend the people at <a href="http://www.trifork.com/">Trifork</a> who organised JAOO Aarhus 2009 as they did something a little different. For every full-paying ticket that you bought for JAOO, you were entitled to a free day pass for a person of the opposite sex. This wonderful scheme saw registrations jump from a lowly 3.7% to about 14%. I think that this shows that the arguments around women not able to travel to be not necessarily the driving factor behind the low attendance, and perhaps the key lies in being selected in your company to attend. For me it is certainly true that the main reason I don&#8217;t attend conferences is that I believe that the bought tickets should be distributed fairly.</p>

<p>I think, however, speaking at a conference is slightly a different manner. I read today (I tried to find the source, but I can&#8217;t seem to find it again) that the difference between a would-be male speaker and a would-be female speaker is that the female thinks &#8220;I don&#8217;t know everything about [topic], I don&#8217;t think I can speak&#8221; whereas a male thinks &#8220;I know a bit about [topic], I think I will speak&#8221;. I obviously don&#8217;t know if that is true for all men/some men/no men in as much as I can&#8217;t say that it speaks for all women/majority of women. What I can say is that it certainly rings true for me.</p>

<p>As anyone who has known me since I was three can testify, I like public speaking. I am comfortable on a stage, talking about what I feel passionate about. As a female software dev who loves public speaking, I feel that I should be one of those who help increase the numbers - but here&#8217;s the catch. I don&#8217;t want to get up and talk just because I am a woman. If I ever present at a conference, I want it to be primarily because I have something important to say about technology and -oh yeah- I happen to be a women. But I also don&#8217;t feel that I have anything that interesting worth presenting - I don&#8217;t know as much as those guys already presenting, so what would I have to give. I don&#8217;t know if this is a female trait - I would be interested to find out if others feel like this.</p>

<p>If this assertion is correct (that women don&#8217;t feel that they have anything to say), perhaps the conference old-timers could help these would-be presenters in recognising material that could be presented. Another way to know if you have something valuable to say is to go and attend a few conferences yourself - see what other newbies are presenting, and see if you can do as good a job (lets face it - there is no sense in comparing yourself to a Martin Fowler or a Neal Ford - compare yourself to someone who is in the same position as you are).</p>

<p>So, there are the reasons why I don&#8217;t attend or present at conferences. How do we adjust this? Well, JAOO certainly has set the standard - I hope other conferences follow suit and find new and innovative ways to get women to their conferences.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[JAOO and Women]]></title>
    <link href="http://sarahtaraporewalla.com/women-in-it/jaoo-and-women"/>
    <updated>2009-10-18T14:06:09+10:00</updated>
    <id>http://sarahtaraporewalla.com/women-in-it/jaoo-and-women</id>
    <content type="html"><![CDATA[<p>A few weeks ago, I was fortunate enough to attend <a href="http://jaoo.dk/">JAOO</a>, an awesome conference for software developers, architects and PMs, for one day. How did I get to? Well, a few weeks before the conference, the organisers (<a href="http://www.trifork.com/">Trifork</a>) noticed that while conferences usually have around 5-10% women attend (and that is considered good), JAOO only had about 3.7%. So, the organisers did a really cool thing&#8230;they decided that for any full paying pass that you bought, you could bring a person of the opposite sex free for a day! They also added a <a href="https://secure.trifork.com/aarhus-2009/freeevent/register.m?eventOID=2135">Women in IT meeting</a> to their user geek night. As a result, they managed to get a whopping 14% women attendance!</p>

<p>The Women in IT meeting was quite fun and well attended - it seemed like it was the first time many of the people there met with others to talk about being a women in IT. I was also glad to see that this was not attended only by women - four of our ThoughtMen came along. I thought this was fantastic - how cool is it that I work for a company where the guys not only want to find out more about the problem and help where they can but are also willing to miss out on other user groups, such as the Java and Ruby groups which also met at the same time.</p>

<p>During the session, we had three of the conferences speakers (who were also women) form a panel to share experiences and exchange ideas. These speakers were <a href="http://jaoo.dk/aarhus-2009/speaker/Rachel+Reinitz">Rachel Reinitz</a>, <a href="http://jaoo.dk/aarhus-2009/speaker/Linda+Rising">Linda Rising</a> and <a href="http://jaoo.dk/aarhus-2009/speaker/Rebecca+Parsons">Rebecca Parsons</a>. I have been to many of these sessions before, but I was entered a little skeptical and a bit jaded but I left reenergized to helping solve some of the problems.</p>

<p>During this discussion, I think I realised that the topic &#8220;Women in IT&#8221; was such a broad one, and there are so many issues surrounding it, that when you get a group of people to talk about it as a whole you get too many cross cutting conversations. So, I am going to attempt to list the issues that I see comprise the broader &#8220;Women in IT&#8221; &#8216;problem&#8217;.</p>

<ul>
<li>Not enough women entering maths/science/technology</li>
<li>Lack of self confidence to speak up</li>
<li>Lack of involvement in the community and open source projects</li>
<li>Lack of women at conferences (attendees as well as speakers)</li>
<li>Lack of role models</li>
<li>Perceived glass ceiling and salary offsets</li>
<li>Perception around women as mothers vs women as employees</li>
<li>Employees don&#8217;t do right for humans</li>
<li>Women are not networking as well as men are</li>
<li>Treatment of women at social events/in the workplace/lack of respect for other humans</li>
<li>When you try to do something positive, you get hit with people crying discrimination</li>
<li>Filters women apply to situation to make them seem worse than they actually are</li>
<li>Subvert harassment through jokes and conversations</li>
<li>Lack of awareness with men to understand what is OK</li>
<li>Women not respecting the problems other women have faced.</li>
</ul>


<p>I hope to build out a series of posts around these points, explaining what I believe is the issue, suggestions of some solutions, and what I have seen the community do to try to help address these problems.</p>

<p>If you think there are parts to the problem that I have missed, tell me about them in the comments section!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Slippers: How to click your heels]]></title>
    <link href="http://sarahtaraporewalla.com/Open/source/projects/slippers-how-to-click-your-heels"/>
    <updated>2009-10-14T07:13:28+10:00</updated>
    <id>http://sarahtaraporewalla.com/Open/source/projects/slippers-how-to-click-your-heels</id>
    <content type="html"><![CDATA[<p>In my l<a href="http://sarahtaraporewalla.com/thoughts/open-source-projects/slippers-introduction/">ast post</a> about <a href="http://slippersrb.com">Slippers</a>, I introduced it&#8217;s philosophy and the places that you could find it. In this post, I will introduce some of its constructs.</p>

<p>Rendering template of a string without any holes</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">template</span> <span class="o">=</span> <span class="s2">&quot;This is a string without any holes in it&quot;</span>
</span><span class='line'><span class="n">engine</span> <span class="o">=</span> <span class="no">Slippers</span><span class="o">::</span><span class="no">Engine</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">template</span><span class="p">)</span>
</span><span class='line'><span class="n">engine</span><span class="o">.</span><span class="n">render</span> <span class="c1">#=&gt; &quot;This is a string without any holes in it&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Filling in a hole within a template</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">template</span> <span class="o">=</span> <span class="s2">&quot;This is a string with a message of $message$&quot;</span>
</span><span class='line'><span class="n">engine</span> <span class="o">=</span> <span class="no">Slippers</span><span class="o">::</span><span class="no">Engine</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">template</span><span class="p">)</span>
</span><span class='line'><span class="n">engine</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="ss">:message</span> <span class="o">=&gt;</span> <span class="s2">&quot;hello world&quot;</span><span class="p">)</span> <span class="c1">#=&gt; &quot;This is a string with a message of hello world&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Rendering a subtemplate within a template</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">subtemplate</span> <span class="o">=</span> <span class="no">Slippers</span><span class="o">::</span><span class="no">Template</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s2">&quot;this is a subtemplate&quot;</span><span class="p">)</span>
</span><span class='line'><span class="n">template_group</span> <span class="o">=</span> <span class="no">Slippers</span><span class="o">::</span><span class="no">TemplateGroup</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="ss">:templates</span> <span class="o">=&gt;</span> <span class="p">{</span><span class="ss">:message</span> <span class="o">=&gt;</span> <span class="n">subtemplate</span><span class="p">})</span>
</span><span class='line'><span class="n">template</span> <span class="o">=</span> <span class="s2">&quot;This is a template and then $message()$&quot;</span>
</span><span class='line'><span class="n">engine</span> <span class="o">=</span> <span class="no">Slippers</span><span class="o">::</span><span class="no">Engine</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">template</span><span class="p">,</span> <span class="ss">:template_group</span> <span class="o">=&gt;</span> <span class="n">template_group</span><span class="p">)</span>
</span><span class='line'><span class="n">engine</span><span class="o">.</span><span class="n">render</span> <span class="c1">#=&gt; &quot;This is a template and then this is a subtemplate&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Applying an object to a subtemplate</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">subtemplate</span> <span class="o">=</span> <span class="no">Slippers</span><span class="o">::</span><span class="no">Template</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s2">&quot;this is a subtemplate with a message of $saying$&quot;</span><span class="p">)</span>
</span><span class='line'><span class="n">template_group</span> <span class="o">=</span> <span class="no">Slippers</span><span class="o">::</span><span class="no">TemplateGroup</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="ss">:templates</span> <span class="o">=&gt;</span> <span class="p">{</span><span class="ss">:message_subtemplate</span> <span class="o">=&gt;</span> <span class="n">subtemplate</span><span class="p">})</span>
</span><span class='line'><span class="n">template</span> <span class="o">=</span> <span class="s2">&quot;This is a template and then $message:message_subtemplate()$!&quot;</span>
</span><span class='line'><span class="n">engine</span> <span class="o">=</span> <span class="no">Slippers</span><span class="o">::</span><span class="no">Engine</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">template</span><span class="p">,</span> <span class="ss">:template_group</span> <span class="o">=&gt;</span> <span class="n">template_group</span><span class="p">)</span>
</span><span class='line'><span class="n">engine</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="ss">:message</span> <span class="o">=&gt;</span> <span class="p">{</span><span class="ss">:saying</span> <span class="o">=&gt;</span> <span class="s1">&#39;hello world&#39;</span><span class="p">})</span> <span class="c1">#=&gt; &quot;This is a template and then this is a subtemplate with a message of hello world!&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Applying an object to an anonymous subtemplate</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">template</span> <span class="o">=</span> <span class="s2">&quot;This is a template and then $message:{this is a subtemplate with a message of $saying$}$!&quot;</span>
</span><span class='line'><span class="n">engine</span> <span class="o">=</span> <span class="no">Slippers</span><span class="o">::</span><span class="no">Engine</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">template</span><span class="p">)</span>
</span><span class='line'><span class="n">engine</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="ss">:message</span> <span class="o">=&gt;</span> <span class="p">{</span><span class="ss">:saying</span> <span class="o">=&gt;</span> <span class="s1">&#39;hello world&#39;</span><span class="p">})</span> <span class="c1">#=&gt; &quot;This is a template and then this is a subtemplate with a message of hello world!&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Render a subtemplate using a different rendering technology</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">age_renderer</span> <span class="o">=</span> <span class="no">AgeRenderer</span><span class="o">.</span><span class="n">new</span>
</span><span class='line'><span class="n">subtemplate</span> <span class="o">=</span> <span class="no">Slippers</span><span class="o">::</span><span class="no">Engine</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s1">&#39;$first$ $last$&#39;</span><span class="p">)</span>
</span><span class='line'><span class="n">person</span> <span class="o">=</span> <span class="no">OpenStruct</span><span class="o">.</span><span class="n">new</span><span class="p">({</span><span class="ss">:name</span> <span class="o">=&gt;</span> <span class="p">{</span><span class="ss">:first</span> <span class="o">=&gt;</span> <span class="s1">&#39;Fred&#39;</span><span class="p">,</span> <span class="ss">:last</span> <span class="o">=&gt;</span> <span class="s1">&#39;Flinstone&#39;</span><span class="p">},</span> <span class="ss">:dob</span> <span class="o">=&gt;</span> <span class="no">Date</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="no">DateTime</span><span class="o">.</span><span class="n">now</span><span class="o">.</span><span class="n">year</span> <span class="o">-</span> <span class="mi">34</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">)})</span>
</span><span class='line'><span class="n">template_group</span> <span class="o">=</span> <span class="no">Slippers</span><span class="o">::</span><span class="no">TemplateGroup</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="ss">:templates</span> <span class="o">=&gt;</span> <span class="p">{</span><span class="ss">:name</span> <span class="o">=&gt;</span> <span class="n">subtemplate</span><span class="p">,</span> <span class="ss">:age</span> <span class="o">=&gt;</span> <span class="n">age_renderer</span><span class="p">})</span>
</span><span class='line'><span class="n">engine</span> <span class="o">=</span> <span class="no">Slippers</span><span class="o">::</span><span class="no">Engine</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s2">&quot;Introducing $name:name()$ who is $dob:age()$.&quot;</span><span class="p">,</span> <span class="ss">:template_group</span> <span class="o">=&gt;</span> <span class="n">template_group</span><span class="p">)</span>
</span><span class='line'><span class="n">engine</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">person</span><span class="p">)</span> <span class="c1">#=&gt; &quot;Introducing Fred Flinstone who is 34 years old.&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Select a renderer based on the type of the object to render</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">person</span> <span class="o">=</span> <span class="no">OpenStruct</span><span class="o">.</span><span class="n">new</span><span class="p">({</span><span class="ss">:name</span> <span class="o">=&gt;</span> <span class="p">{</span><span class="ss">:first</span> <span class="o">=&gt;</span> <span class="s1">&#39;Fred&#39;</span><span class="p">,</span> <span class="ss">:last</span> <span class="o">=&gt;</span> <span class="s1">&#39;Flinstone&#39;</span><span class="p">},</span> <span class="ss">:dob</span> <span class="o">=&gt;</span> <span class="no">Date</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="no">DateTime</span><span class="o">.</span><span class="n">now</span><span class="o">.</span><span class="n">year</span><span class="o">-</span><span class="mi">34</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">)})</span>
</span><span class='line'><span class="n">template_group</span> <span class="o">=</span> <span class="no">Slippers</span><span class="o">::</span><span class="no">TemplateGroup</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="ss">:templates</span> <span class="o">=&gt;</span> <span class="p">{</span><span class="ss">:name</span> <span class="o">=&gt;</span> <span class="no">Slippers</span><span class="o">::</span><span class="no">Engine</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s1">&#39;$first$ $last$&#39;</span><span class="p">),</span> <span class="no">Date</span> <span class="o">=&gt;</span> <span class="no">AgeRenderer</span><span class="o">.</span><span class="n">new</span><span class="p">})</span>
</span><span class='line'><span class="n">engine</span> <span class="o">=</span> <span class="no">Slippers</span><span class="o">::</span><span class="no">Engine</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s2">&quot;Introducing $name:name()$ who is $dob$.&quot;</span><span class="p">,</span> <span class="ss">:template_group</span> <span class="o">=&gt;</span> <span class="n">template_group</span><span class="p">)</span>
</span><span class='line'><span class="n">engine</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">person</span><span class="p">)</span> <span class="c1">#=&gt; &quot;Introducing Fred Flinstone who is 34 years old.&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Use the specified expression options to render list items</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">template</span> <span class="o">=</span> <span class="s1">&#39;This is a list of values $values; null=&quot;-1&quot;, seperator=&quot;, &quot;$&#39;</span>
</span><span class='line'><span class="n">engine</span> <span class="o">=</span> <span class="no">Slippers</span><span class="o">::</span><span class="no">Engine</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">template</span><span class="p">)</span>
</span><span class='line'><span class="n">engine</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="ss">:values</span> <span class="o">=&gt;</span> <span class="o">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="kp">nil</span><span class="o">]</span><span class="p">)</span> <span class="c1">#=&gt; &quot;This is a list of values 1, 2, 3, -1&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Slippers: Introduction]]></title>
    <link href="http://sarahtaraporewalla.com/Open/source/projects/slippers-introduction"/>
    <updated>2009-10-13T07:14:11+10:00</updated>
    <id>http://sarahtaraporewalla.com/Open/source/projects/slippers-introduction</id>
    <content type="html"><![CDATA[<p>There are many template engines that you can choose for the generation of views in your mvc application. The problem with most of the them, however, is that they are too permissive. These turing-complete engines allow for many complex constructs within the template, which begin at simple if statements and for loops, and expand to complex object traversal. While these permissive languages are intended to offer great flexibility, in reality they promote bad practices. Allowing logic to permeate your view is bad for many reasons: firstly, the code in views is rarely tested; secondly, the separation between the models and the view blurs and business logic creeps into the view.</p>

<p>All we want our template engine to do is read a string which has holes in it, and replace those holes with the desired string, much like mail merge. Luckily for me, there is already a templating engine which enforces strict separation of model and view by only supporting these strings with holes - String Template. <a href="http://www.stringtemplate.org">String Template</a> is originally created in Java, however there has been subsequent ports to C# and python. It is <a href="http://www.stringtemplate.org/about.html">opinionated</a>, and I like it&#8217;s opinions. (And if you prefer permissive views, I would recommend you reading about the origins of String Template before completely ruling it out.)</p>

<p>Unfortunately, when I started to try out <a href="http://www.ramaze.net">Ramaze</a> (a great web framework for ruby - much better than rails imho) I looked around for a port of String Template to ruby, but couldn&#8217;t find out. So, I decided that if no-one else would port it, I would&#8230;and so <a href="http://slippersrb.com">Slippers</a> was born.</p>

<p><a href="http://slippersrb.com">Slippers</a> is  a strict template engine for ruby, supporting the syntax from String Template including anonymous template, named templates and template group directories but also goes beyond this to allow you to use your own renderers. Nearly all the useful constructs from String Template have been ported, and you can see the comparison on the <a href="http://starapor.github.com/slippers/slippers_vs_string_template.html">Slippers vs String Template</a> page.</p>

<p>In creating Slippers, I have been surprised to find how many development tools for ruby can now be found &#8220;in the cloud&#8221; (ie on the web):</p>

<ul>
    <li>Slippers code repository is hosted on <a href="http://github.com/starapor/slippers">github</a>.</li>
    <li>Slippers has been test-driven, and I have a CI build at <a href="http://runcoderun.com/starapor/slippers">runcoderun.com</a>. As you can see, I have also made it Ruby 1.9 compatible.</li>
    <li>The gem can be found on <a href="http://gemcutter.org/">gemcutter</a>. To install: 
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1"># Run the following if you haven&#39;t done so before:</span>
</span><span class='line'><span class="err">$</span> <span class="n">gem</span> <span class="n">sources</span> <span class="o">-</span><span class="n">a</span> <span class="n">http</span><span class="ss">:/</span><span class="o">/</span><span class="n">gemcutter</span><span class="o">.</span><span class="n">org</span>
</span><span class='line'><span class="c1"># Install the gem:</span>
</span><span class='line'><span class="err">$</span> <span class="n">sudo</span> <span class="n">gem</span> <span class="n">install</span> <span class="n">slippers</span>
</span></code></pre></td></tr></table></div></figure>
</li>
</ul>


<p>Ramaze now supports Slippers as a view engine, as of gem <a href="http://gemcutter.org/gems/ramaze">version 2009.10</a> (also on gemcutter).</p>

<p>More information about Slippers can be found at <a href="http://slippersrb.com">http://slippersrb.com</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How to Refactor like a Something star]]></title>
    <link href="http://sarahtaraporewalla.com/design/how-to-refactor-like-a-something-star"/>
    <updated>2009-09-27T15:49:48+10:00</updated>
    <id>http://sarahtaraporewalla.com/design/how-to-refactor-like-a-something-star</id>
    <content type="html"><![CDATA[<div>Refactoring a piece of code can be such a thrilling experience when it&#8217;s finished, but at the same time can also act as the blackhole of time. Recently, I have been observing how other people refactor, watching their looks of happiness when they finish it and also their despaired faces when they have realized they have spent a week trying to add one new argument to their method.</div>




<div>I love refactoring and I think I do a good job at it now, but there was a time in the not-so-distant past where I was one of those despaired faces. I got to where I am now thanks to pairing with refactoring gurus and practice. Here are some of the tricks that I have picked up:
<ul>
<li><strong>Plan your refactoring</strong> Planning should never be considered overrated. Before I start a refactor, I like to assess everything that the existing code does, and map where I want that to sit. I also determine which angle is the best to start from after looking at all the possible combinations, so that I am always working with minimal changes. I like to use post-its to guide my work, so I usually start with a handful of post-its to show where I am going. If there are too many post-its, I also start questioning the scope of the refactor: what could I get done if I only had 2 days to do it in.</li>
<li><strong>Parallelize your work</strong> This really works well when, instead of shuffling bits around, you are actually doing a rewrite of the current functionality. For instance, the other day I rewrote the legacy login code to the application. Obviously I couldn&#8217;t be too ruthless as everyone needed to still login, and this code was not under test. So, I wrote the new login section alongside the existing code, and just swapping in my login code in the DI container on my local machine. When it was time to switch it over, we checked in the DI container change, and voila, everyone started using the new login code. This allowed us to check in frequently without breaking anyone regardless of it being incomplete. It also meant that we always had the original version to refer to as we proceeded</li>
<li><strong>Checkin often</strong> This is helped by either doing minimal changes at a time, or by parallelizing the work. Checkin frequently, checkin small. That way if you ever need to revert your changes, you know the brilliant work that you did before the &#8220;screwup&#8221; won&#8217;t be wasted. If you are working with a source control like mercurial or git, you are in an even better situation, as you still have source control without affecting the rest of your team with your breaking changes.</li>
<li><strong>Never be afraid to revert your changes</strong> This one is such a valuable lesson to learn and it feels so wrong when your doing faced with the possibility but when you have painted yourself into a corner, the best thing to do is to revert all changes. What it does mean, however, is that all the lessons that you learned from your first attempt will help guide your decisions the next time round.</li>
<li><strong>Prepare your system before you add new concepts</strong> I know that refactoring is all about improving your world without adding new functionality but sometimes people start adding new features before the world is setup for them. Ensuring that your world is good before you add new features will make your life simpler.</li>
<li><strong>Introduce new concepts top down</strong> Obvious? I thought so, but I have seen a refactoring go horribly wrong because it was started from the wrong place. When you change a class, you can isolate the changes within it, but every consumer of it will be affected. This bubbling effect can be catastrophic if you start from objects in the lowest level.</li>
<li><strong>Only have top level tests</strong> This one is slightly controversial, and I don&#8217;t know if I completely agree with it anyway, but if you only test your entry-point object, and never use fake objects during your testing (except to simulate external dependancies like databases or external services) then you will not have the annoyance of changing loads of unnecessary tests. You will also find that you can be 100% certain that your tests are still relevant without touching every single test file. </li>
<li><strong>Start with tests which pass</strong> Very important to ensure that you don&#8217;t break anything, so start with passing tests on the highest layer, whether that means browser based tests or controller tests. Make sure you have a test for all scenarios as that way you can easily test that your refactor has not changed the world.</li>
<li><strong>Making sure your world better than you found it (or at least no worse) reduces the number of big risky refactor adventures</strong></li>
</ul>
</div>


<div>
Do you have any other tricks that you use when you refactor?
</div>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Pairing 101: Skills Matter]]></title>
    <link href="http://sarahtaraporewalla.com/agile/pairing-101-skills-matter"/>
    <updated>2009-09-27T11:45:57+10:00</updated>
    <id>http://sarahtaraporewalla.com/agile/pairing-101-skills-matter</id>
    <content type="html"><![CDATA[<p>A few weeks ago, my good buddy <a href="http://christianralph.blogspot.com/">Christian Blunden</a> and myself presented at a London Geek Night. For us, it was quite fun and I hope people not only picked something up from it but also had a good time. The presentation was recorded and should be on <a href="http://skillsmatter.com/podcast/java-jee/pairing-101">skills matter</a> so check it out if your interested (she says cringing at watching herself on video).</p>
]]></content>
  </entry>
  
</feed>

