<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
    <channel>
        <title>The Commonwealth of Massadrewsetts</title>
        <link>http://www.andrewherbst.net/</link>
        <description>Too doggone cold</description>
        <language>en</language>
        <copyright>Copyright 2009</copyright>
        <lastBuildDate>Fri, 30 Jan 2009 15:59:34 -0500</lastBuildDate>
        <generator>http://www.sixapart.com/movabletype/</generator>
        <docs>http://www.rssboard.org/rss-specification</docs>
        
        <item>
            <title>Google Apps for Domains</title>
            <description><![CDATA[<p>Since my provider doesn&#8217;t provide SSL, IMAP or a decent webmail reader, I decided to take the plunge today and switch to Google Apps for Domains. <span class="mt-enclosure mt-enclosure-image"><img alt="logo.gif" src="http://www.andrewherbst.net/logo.gif" width="143" height="59" class="mt-image-right" style="float: right; margin: 0 0 20px 20px;"/></span>Obviously it&#8217;ll take some time to see if it&#8217;s worth it, but so far I&#8217;m liking it. One thing that I was eager to do was move my email to IMAP to take advantage of it&#8217;s synchronization features. Seeing as how there are no free import tools from Apple Mail to GMail, I came with an ad-hoc approach that worked for my purposes:</p>

<ul>
<li>Archive your Mail inbox to a backup file and then delete your account out of Mail.</li>
<li>Set up Mail to use your new GMail IMAP account and verify that it works.</li>
<li>Import your backed up inbox to Apple Mail. This will create a new folder separate from your GMail stuff.</li>
<li>This is the slow part. Drag about 300 messages at a time into your new GMail inbox folder. Mail will sync these new messages from your machine to the GMail servers while removing them from your import inbox. I had to go through about 3000 messages, so this took about an hour or so.</li>
</ul>

<p>Your messages will appear in the GMail inbox in the correct date order, but if you sync with an iPhone, you&#8217;ll only get the most recently <strong>added</strong> 50 messages, which are most likely the ones you just imported and are quite old. To get around this, I found this technique in Google groups which worked like a charm:</p>

<blockquote>
  <p>In your inbox, select all messages (ALL, not just the first page!)
  Then give them a dummy label like &#8220;sort label&#8221;.  Once you&#8217;ve applied
  this label only to the messages you want to be sorted in your inbox,
  select all inbox messages again and click &#8220;Archive&#8221;.
  This won&#8217;t delete your messages, just move them out of the inbox and
  into the &#8220;All Mail&#8221; folder.  Once your inbox is empty, click on the
  label you made in the sidebar (e.g. click on &#8220;sort label&#8221;) to pull up
  those messages with that label.  Then, select all (ALL) messages with
  that label, and in the drop-down menu above select &#8220;Move to inbox.&#8221;
  Once you do this, you can delete that label (it won&#8217;t delete your
  messages) and your inbox messages will now sort correctly on the
  iPhone. </p>
</blockquote>
]]></description>
            <link>http://www.andrewherbst.net/2009/01/google-apps-for-domains.html</link>
            <guid>http://www.andrewherbst.net/2009/01/google-apps-for-domains.html</guid>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">gmail</category>
            
            <pubDate>Fri, 30 Jan 2009 15:59:34 -0500</pubDate>
        </item>
        
        <item>
            <title>The Fractal Geometry of iPhone App Design</title>
            <description><![CDATA[<p>Brent Simmons has a <a href="http://inessential.com/?comments=1&amp;postid=3565">post</a> up about the amount of polish and thought that goes into an iPhone app. It&#8217;s true&#8212;I&#8217;ve never put as much effort into the details of an application as I&#8217;ve put into the app I&#8217;m working on.</p>

<p>Case in point: the initial settings dialog that&#8217;s presented when a user first loads our app. This dialog gathers the user account information necessary to login to our service. It also persists the information into our root.plist file so it can later be edited by the iPhone settings application (I hate shunting our users to another application just to edit login credentials, but that&#8217;s a rant for another time).</p>

<p>Our initial architecture put a simple &#8220;Welcome! Enter your information, etc.&#8221; sort of message at the top of the screen and a group-style UITableView below it with cells corresponding to each user credential item (username, password, etc.) When the user touched a cell, we pushed in an editing view that allowed them to set the credential item. The editing view consisted of a single UITableViewCell with an embedded UITextView, and the iPhone keyboard for text entry.</p>

<p>The user interaction worked like this:</p>

<ul>
<li>Tap an item in the settings dialog to edit</li>
<li>The app slides you over to the editing view controller and displays the iPhone keyboard to do your editing</li>
<li>Tap the <strong>Done</strong> button in the upper right when you&#8217;ve completed editing.</li>
<li>The app slides you back to the settings dialog and displays your newly edited item</li>
</ul>

<p>So this worked fine. It was solid, gathered the data properly and got the job done. </p>

<p>But it bugged me that there had to be so much moving around just to edit these couple of fields. When I would debug the app&#8217;s initial load experience, I&#8217;d have to blow away the app each time on the simulator to go through this process literally dozens of times. And sometimes I&#8217;d forget where I was in the process and type in the wrong credential. Sometimes I&#8217;d get so tired of the whole back-and-forth process, I&#8217;d hardcode credentials for the debugging session just to avoid having to enter into the dialog at all. </p>

<p>Warning bells. This was a point of friction in the interface. A small point, but frustrating for me. True, I was going through the process dozens of times, but it still bugged me. If I was having these issues as <strong>the developer of the application with a debugger in front of me</strong>, our users would be guaranteed to have issues. Not showstopper-type issues, but I&#8217;d hear about it.</p>

<p>So I took a few hours yesterday and did something about it. I decided that our screen should work almost exactly like the iPhone settings app&#8212;if a user interface works and works well, copy what it does.</p>

<p>I reworked the editing mechanism. Gone is the movement to a separate screen for editing. In it&#8217;s place are text fields embedded in the table view cells that are activated when the user taps a credential item in the initial screen, allowing for in-line editing of this information. This brought up a second problem. When the user tapped on a field toward the bottom of the screen and the iPhone keyboard was displayed, the keyboard hid the field. This was a stumper. No amount of calls to selectRowAtIndexPath:animated:scrollPosition: would work. Finally, a bit of googling revealed this <a href="http://cocoawithlove.com/2008/10/sliding-uitextfields-around-to-avoid.html">gem by Matt Gallagher</a> to get me over the top. The view would now automatically scroll to display the selected field if it was occluded by the keyboard. </p>

<p>So the final result? Let&#8217;s check out the user&#8217;s interaction with this dialog again:</p>

<ul>
<li>Tap an item to edit</li>
<li>iPhone keyboard slides up and you edit the item</li>
<li>Hit return or select another field to continue, or hit the &#8220;Save&#8221; button to exit the dialog altogether</li>
</ul>

<p>That&#8217;s around 1-2 fewer steps, with the added bonus that users have a very clear context in their minds of what they&#8217;re editing&#8212;something which they didn&#8217;t have when they were forced to another screen each time to edit a simple text field. </p>

<p>I never would&#8217;ve done this with a desktop application. It wouldn&#8217;t have been an issue. Need to gather user information? Put together a dialog with the correct number of text fields, some labels and an OK button and you&#8217;re done. Not enough real estate? Resize the canvas. </p>

<p>Not so with the iPhone. Since the platform is so limited, the thought you put into an interface affects your users an order of magnitude more than it would on a desktop app. It&#8217;s a bit like a fractal&#8212;the deeper you think about your user&#8217;s interaction with your app, the more interaction scenarios you uncover, the more code you write to handle these interactions, the more rewarding your app is to use.</p>
]]></description>
            <link>http://www.andrewherbst.net/2008/11/brent-simmons-has-a-posthttpin.html</link>
            <guid>http://www.andrewherbst.net/2008/11/brent-simmons-has-a-posthttpin.html</guid>
            
            
            <pubDate>Sat, 29 Nov 2008 09:09:12 -0500</pubDate>
        </item>
        
        <item>
            <title>Traits of a Good Developer</title>
            <description><![CDATA[<p>There are a few things I think are essential to being a good developer. I'm probably parroting Joel Spolsky here, but I wanted to get them down while they're fresh in my mind:</p>

<p><strong>Exposure to more than one platform and language</strong></p>

<p>If your only experience is with one language on one platform (i.e., perl on Linux, C# on Windows, etc.), this is a signal to me that you're inflexible and not willing to stretch yourself to do new things. It's definitely uncomfortable to do try new languages and OSes, but that's the only way to stretch yourself and get better. </p>

<p><strong>Exposure to pointers</strong></p>

<p>Lack of exposure to pointers is one of Joel's pet peeves and I've adopted it as one of mine as well. Where I went to school, Java was the language of choice for freshman year CS courses. This was a bad decision since the first sophomore year course was Architecture and Assembly language, something which Java does precious little to prepare you for. </p>

<p>When I first started in industry, my first language again was Java and then C#. Another bad experience, since this left me with a rather steep learning curve for my next experience, working with low-level C++ code on HP-UX. But, to tie in with my previous point, I specifically went after this position because I saw a gaping hole in my experience and wanted to fill it in. And I'm much better off for it. I'm confident with my feel for how memory is being managed and manipulated during the course of a program's execution, be it managed, unmanaged, embedded or desktop. </p>

<p>But I sure wish I'd had the low-level introduction to C in my first year as a CS student.</p>

<p><strong>Exposure to things that are not code</strong></p>

<p>I'm talking about documentation, gathering requirements, interacting with users and customers, creating a design document or diagram. These are the things that you will most certainly <em>not</em> learn in college, and they're definitely not as fun as just coding all day, but they're essential to being anything more than a coding monkey. </p>

<p>There's probably more that I'm forgetting, but if I'm going to interview you or be interviewed by you, these are the big things I'm going to be looking for besides competency with your hard skillset.</p>
]]></description>
            <link>http://www.andrewherbst.net/2008/11/traits-of-a-good-developer.html</link>
            <guid>http://www.andrewherbst.net/2008/11/traits-of-a-good-developer.html</guid>
            
            
            <pubDate>Thu, 20 Nov 2008 10:21:21 -0500</pubDate>
        </item>
        
        <item>
            <title>On Do(ugh)nuts</title>
            <description><![CDATA[<p>I'm taking it upon myself as part of my ongoing community service to educate the public about the different sorts of donuts out there and their relative merits. So, here's a quick summary:</p>

<ul>
<li><strong>Krispy Kreme</strong>: Famous for their hot glazed donuts and nothing else really. They possess a light, airy texture and aren't overly sweet or doughy. </li>
<li><strong>Dunkin' Donuts</strong>: Basic donuts for when you're in a bind and need one quick. Not a lot positive to say here. Cakey, mass-produced and not very good. My personal favorite is their jelly, which is usually pretty generously filled and covered with a healthy dose of powdered sugar. I really wish Dunkins would divert some of their resources from developing new 1000-calorie monster flatbread sandwiches to developing a better donut. </li>
<li><strong>Honey Dew</strong>: See Dunkin' Donuts</li>
<li><strong>Grocery Store Donuts</strong>: Don't. Just...don't.</li>
<li><strong>Top Pot Doughnuts</strong>: My current favorite. They started offering these at Starbucks a year or so ago and quickly ascended to the top of my list. When consumed cold, you're basically eating a rock, but a warmed-up Top Pot is something to savor. Plenty of texture, and very filling. Their chocolate glazed leaves something to be desired, however. It lacks any sort of chocolaty flavor and tastes more like their plain glazed version only...off somehow.</li>
</ul>

<p>Still on my list to try: About a million mom-and-pop donut places in greater Boston, including <strong>Verna's</strong> in East Boston.</p>
]]></description>
            <link>http://www.andrewherbst.net/2008/10/on-doughnuts.html</link>
            <guid>http://www.andrewherbst.net/2008/10/on-doughnuts.html</guid>
            
            
            <pubDate>Sat, 04 Oct 2008 10:33:44 -0500</pubDate>
        </item>
        
        <item>
            <title>Acalculia</title>
            <description><![CDATA[<p>Watch this <a href="http://www.youtube.com/watch?v=Tr1qee-bTZI">video</a>. </p>

<p>It&#8217;s somewhat disturbing for me to think that the young people of our country can&#8217;t do basic math, but then they sky seems to be falling on our mathematics education standards with the start of every new school year. I wonder if I should start administering a basic math skills assessment when I interview potential engineers.</p>

<p>The basic problem here seems to be lack of class time. The meteorologist in the video states that children don&#8217;t receive enough teaching on the basic algorithms of mathematics&#8212;how to perform double digit multiplication, long division, etc. The curriculum she rails against instead teaches more abstract approaches to solving these problems&#8212;breaking down a long double digit multiplication into smaller pieces and then adding those pieces up, for instance.</p>

<p>I&#8217;m of two minds about this, as with most things. I agree that not teaching children so that they can evaluate math problems mechanically with a foolproof algorithm so that they can be guaranteed to arrive at the correct answer seems to be a mistake. It&#8217;s creating a culture where nobody can do arithmetic anymore without a calculator and that clearly isn&#8217;t a good thing.</p>

<p>On the other hand, only knowing how to mechanically solve problems doesn&#8217;t prepare children for the inevitable moment when they encounter a problem that doesn&#8217;t fit into the algorithm, a problem that requires more analytical, critical thinking. I solve both types of problems every day as an engineer, and we need people who can handle both. </p>
]]></description>
            <link>http://www.andrewherbst.net/2008/09/acalculia.html</link>
            <guid>http://www.andrewherbst.net/2008/09/acalculia.html</guid>
            
            
            <pubDate>Sun, 07 Sep 2008 10:57:41 -0500</pubDate>
        </item>
        
        <item>
            <title>On iPhone Development</title>
            <description><![CDATA[<p>I work on a team at my company that, among many varying responsibilities, develops mobile applications that interface with our core on-demand web app. The idea being that a cellphone web browser is a less than optimal interface to our services and that a slimmed down, streamlined UI is a better approach. And what with the iPhone being the next big thing, it&#8217;s obviously next on our list of mobile platforms to develop for.</p>

<p><span class="mt-enclosure mt-enclosure-image"><img alt="10-15-07-iphone.jpg" src="http://www.andrewherbst.net/10-15-07-iphone.jpg" width="440" height="305" class="mt-image-center" style="float: center; margin: 0 20px 20px 0;"/></span></p>

<p>So. This is something of a departure for me, coming from a mostly C++/Java on Windows background, but this is also an opportunity to develop new skills and learn a platform that will be invaluable in the coming years. Here are my initial observations:</p>

<ul>
<li><p>Xcode is just plain awful when you compare it with Visual Studio. It&#8217;s clearly a far more immature product and it shows, from the brain-dead window management philosophy to the debugging tools to the keyboard shortcuts. Don&#8217;t get me wrong; I&#8217;m not whining because it&#8217;s different. I use vi for half my day when I&#8217;m coding on my Linux VM and get by with minimal fuss. I&#8217;m whining because there are clearly established UI standards for IDEs and for editors that have been proven over the years and Xcode just ignores them, doesn&#8217;t implement them or takes a completely different and wrong direction.</p></li>
<li><p>Interface Builder is&#8230;OK. It&#8217;s a different UI design and layout mechanism than I&#8217;m used to, but once you grasp how the controls you&#8217;re laying out in a NIB/XIB interact with and are represented by the objects in your code, it&#8217;s pretty painless. I don&#8217;t  like having to drop into another app every time I want to tweak my UI however.</p></li>
<li><p>The supporting platform libraries and API are likewise just OK. Cocoa Touch brings over almost everything you would want from regular Cocoa, with the notable exception of a few selectors (why doesn&#8217;t [NSDateFormatter initWithDateFormat] work?). However, I really, <strong>really</strong> wish they&#8217;d ported Core Data or a subset thereof. My data-driven app would be about half the size and would have been done weeks ago. I think I understand why Apple chose to exclude CD from the iPhone API&#8212;it&#8217;s a behemoth and performance might have been unacceptable. But I spend <strong>way</strong> too much time writing sqlite database glue and plumbing code and it&#8217;s a bit frustrating.</p></li>
<li><p>Objective-C is fun. I enjoy the dynamic nature of the language. I suspect I&#8217;ve made the inexperienced ObjC developer mistake of abusing categories, but I&#8217;ve put a few on NSString and NSDate and they&#8217;re just so useful I don&#8217;t see how you can&#8217;t get by without them. The release/retain memory management approach also takes a bit of adjustment but it&#8217;s not without it&#8217;s merits. I&#8217;m not sure if I wouldn&#8217;t rather trade a few CPU cycles for a garbage collector however&#8212;maybe I&#8217;m just lazy.</p></li>
</ul>

<p>Given these criticisms, you might gather that I&#8217;m somewhat down on the platform, but my overall experience has been quite to the contrary. It&#8217;s been a pleasure, and part of the reason why is that it&#8217;s so easy to create a polished, professional UI that just looks like it belongs on my iPhone. This is due to the tools Apple gives you&#8212;the default controls, views and behavior you get out of the box put you on a straight path to a nice UI. You don&#8217;t get it for free; you have to constantly tweak and work at it, but compared to Windows Forms or MFC, it&#8217;s like night and day. </p>

<p>Let me say this more clearly: It doesn&#8217;t matter how pristine, well-architected and beautiful the code supporting an app is&#8212;if the UI isn&#8217;t intuitive for your users or is so obviously different from the rest of the platform and it&#8217;s standards that using your app becomes a jarring experience, <strong>you&#8217;ve failed</strong>. This is where the iPhone SDK shines and why I&#8217;ll be actively developing for it in the future.</p>
]]></description>
            <link>http://www.andrewherbst.net/2008/09/on-iphone-development.html</link>
            <guid>http://www.andrewherbst.net/2008/09/on-iphone-development.html</guid>
            
            
            <pubDate>Sat, 06 Sep 2008 11:26:00 -0500</pubDate>
        </item>
        
        <item>
            <title>This has all happened before and it will all happen again</title>
            <description><![CDATA[<p>I'm learning Ruby as a sort of professional development effort and I like what I see so far. Ruby's a quick, concise and rich language that brings a lot to the table in terms of language constructs and platform support. Or so it would seem; I reserve the right to rescind this endorsement until I've spent a good month or so working with it in depth. In any case, I'm having fun with my first new language in a year or so.</p>

<p>One aspect that I find merits further thought is this notion of <a href="http://en.wikipedia.org/wiki/Duck_typing">duck typing</a>. What is duck typing you say? I'm glad you asked. It boils down to this oft-used analogy:</p>

<blockquote>
  <p>If it walks like a duck and quacks like a duck, I would call it a duck.</p>
</blockquote>

<p>That is to say, if the object I'm working with behaves like an instance of a duck, it's a duck for all intents and purposes. Or, more bluntly, invoke whatever operation you want on an object, as long as it says it can do it. But what does this get us? It's not immediately obvious that it's all that quicker to code with these looser typing restrictions. Consider the following C++ function:</p>

<pre><code>class Duck
{
    public:
        virtual string Quack()
        {
            return "Quack!";
        }
};

void QuackLikeADuck( const Duck&amp; aDuck )
{
    std::cout &lt;&lt; aDuck.Quack() &lt;&lt; "!" &lt;&lt; std::endl;
}
</code></pre>

<p>And now the same code in Ruby:</p>

<pre><code>class Duck
    def Quack
        return "Quack!"
    end
end

def QuackLikeADuck( duck )
    if duck.respond_to?("Quack")
        puts duck.Quack();
    else
        raise "Called with an invalid object type"
    end
end
</code></pre>

<p>The Ruby version seems a bit more verbose, but this is a contrived example and I would concede that the sort of type checking in that function wouldn't always be necessary. If you're the only one using that code, you can make certain assumptions about those objects that will be passed into that function.</p>

<p>But where this sort of agility really shines is in it's dynamic nature. What if my application now demands the introduction of a Human type, but for some reason it needs to quack like a duck too? Consider the C++ approach:</p>

<pre><code>class Human : public Duck
{
    public:
        string Quack()
        {
            return "Ceci n'est pas un duck!";
        }
};
</code></pre>

<p>A brittle class hierarchy to be sure. To be able to use the <code>QuackLikeADuck</code> as originally declared, I've been forced to have my Human subclass Duck. What if a previous class hierarchy had already been established and there were other classes that needed to <code>QuackLikeADuck</code> too? Sounds like a long of afternoon of refactoring and unit testing to me.</p>

<p>Now look at the Ruby approach:</p>

<pre><code>class Human
    def Quack
        return "Ceci n'est pas un duck!"
    end
end
</code></pre>

<p>And that's it. No tortured class hierarchy, no tedious error-prone refactoring. Just add the method and you're good to go.</p>

<p>I'm of two minds about this flexibility. On the one hand, it allows you to get things done much quicker and not sweat the object-oriented design cruft that can so often pollute a design when requirements change. On the other hand, it puts a lot of responsibility on the developer to correctly anticipate ways in which their code might be used and to handle error conditions gracefully (a tall order for some developers I've encountered). </p>

<p>Which brings us back to the title of this entry. This has all happened before and it will all happen again (Battlestar Galactica was on last night). I would argue that for most of the 90's and the early part of this decade, strongly typed languages were in vogue (C++, Java, .NET, etc.) Right now, the hip language paradigm pendulum has definitely swung to the dynamic typing side (Ruby, Python, PHP). But for me, it doesn't really matter. Strong typing, dynamic typing, it's all the same--I'll just choose the one that let's me get my job done quickly and easily and right now that's looking a lot like Ruby.</p>
]]></description>
            <link>http://www.andrewherbst.net/2008/04/this-has-all-happened-before-a.html</link>
            <guid>http://www.andrewherbst.net/2008/04/this-has-all-happened-before-a.html</guid>
            
            
            <pubDate>Sat, 26 Apr 2008 10:23:31 -0500</pubDate>
        </item>
        
        <item>
            <title>Outside Projects</title>
            <description><![CDATA[<p>I first got hooked on programming when my dad got us a copy of QuickBasic for our family's Macintosh Plus. Later in high school, I graduated to coding in ThinkPascal on Mac LCs. And one of the first moments when I surprised myself at what I could do with these machines was when I completed my first render of the Mandelbrot set. It took me a week to figure out how to render pixels to screen (we were stuck on console programs at the time in class) and another week to figure out an algorithm that would actually do the calculations correctly. </p>

<p>So I took some time this morning to stroll down memory lane and see how far my programming skills had progressed since then. I decided I would code up a little Mandelbrot set plotter using Windows Forms. It took me about two hours of Googling and Wikipediaing to get here:</p>

<p><span class="mt-enclosure mt-enclosure-image"><a href="http://www.andrewherbst.net/Capture.html" onclick="window.open('http://www.andrewherbst.net/Capture.html','popup','width=941,height=750,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://www.andrewherbst.net/Capture-thumb-400x318.jpg" width="400" height="318" alt="mandel.JPG" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></a></span></p>

<p>This was already further than I ever got in high school--we didn't even have color screens back then. </p>

<p>I realized that this was pretty dull without a zoom feature, so I implemented a little zoom box that you can set by clicking and dragging on the fractal. Then I realized I have a dual-core laptop, so why not parallelize the code a bit? Fractals are perfect for this sort of thing--there aren't any data dependencies so synchronization isn't much of an issue. I moved the actual fractal calculation code to a thread and parametrized the coordinate window it would draw so I could render it in two threads (one for the left half, one for the right). I could subdivide the coordinate window as much as a I wanted depending on the number of cores on the machine, but that's a project for another day. Also, I set pixels directly in a Bitmap object in the calculation thread, so there actually is a little bit of locking there that could probably be optimized away (because we all know how expensive a lock is, right?)</p>

<p>But I digress. My point is, this is what's so fun about a project like this. <strong>It helps to keep your love of programming alive when your day job is burning you out.</strong> I could optimize and tweak this thing for weeks. Why not implement the calculations as integer math and see if it's any better than the default floating point code? What about checking for periodicity and bailing out early? How about customizable color maps? Different fractals? Real-time zooming? How do we provide progress feedback to the user on a long render using multiple threads? The options are endless and I probably just lost my whole weekend to this thing. Sounds good to me.</p>
]]></description>
            <link>http://www.andrewherbst.net/2008/03/i-first-got-hooked-on.html</link>
            <guid>http://www.andrewherbst.net/2008/03/i-first-got-hooked-on.html</guid>
            
            
            <pubDate>Sat, 15 Mar 2008 12:54:27 -0500</pubDate>
        </item>
        
        <item>
            <title>MFC -&gt; .NET</title>
            <description><![CDATA[<p>So I work with MFC-based legacy applications for most my day. None of them were designed particularly well. They were created seven or eight years ago to satisfy a particular requirement. They did their job well but then mutated over the years to satisfy other requirements. With no eye to design or architecture, these changes were added piecemeal until present day, when what we have is a ball of code full of hacks, workarounds and general feature-aggregation. </p>

<p>Saying this is problematic to maintain would be an understatement. With no unit tests, or any tests at all (except loading it up and making sure it doesn't format the hard disk by accident), regressions are a very real possiblity and happen far too often. </p>

<p>This being said, we're limited in our options of what to do. We can: </p>

<ul>
<li>Stick it out, leave it be and continue on course to a code armageddon. Not my favorite option.</li>
<li>Scrap the applications altogether and rewrite them in C# or Managed C++. Not really a good option either since, as bad as these apps are maintenance-wise, they do very complicated jobs somewhat well. We'd be lucky to code up a new app in six months that does 1/4 of what they do now. Fun for developers, bad for business. </li>
<li>Keep the codebase as is, but roll in .NET on a feature-by-feature basis. This is the best of both worlds--we keep our legacy code and all of it's (mostly working) warts, but are able to introduce .NET here and there with an eye to eventually replacing all of the legacy code with .NET in a few years. </li>
</ul>

<p>Can you guess which choice we're going with? The silver bullet here and the reason we're able to do this is a magical language I call Managed C++. Microsoft has done plenty of evil things (or so I read), but the interoperability of Managed C++ with legacy code is not one of them. </p>

<p>Since these apps are all MFC, we're able to load them up in Visual Studio 2005 (moving from VS6, itself a rather painful transition we made last year), throw the /clr compiler switch and, after a fixing a few compiler errors (mostly due to not using the _T macro with strings as much as we should) we automagically have support for the CLR in our app. </p>

<p>The first thing I'm doing is implementing a C# User Control for inclusion on one of our data entry forms. This is a pretty simple thing to do. You just drop a static control on your form where you want the User Control to go and create a data member in your dialog class like so:</p>

<pre><code>class CMFC01Dlg : public CDialog
{
    // ...
    // Data member for the .NET User Control:
    // (note: ctrl_lib is a user created control assembly)
    CWinFormsControl&lt;ctrl_lib::usercontrol1&gt; m_ctrl1;
}
</code></pre>

<p>Then, in your ::DoDataExchange method, just add the following:</p>

<pre><code>void CMFC01Dlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    DDXManagedControl(pDX, IDCCTRL1, m_ctrl1);
}
</code></pre>

<p>Congratulations, you now have a .NET User Control on your MFC form with about 6 lines of code. </p>

<p>The point here is that very often there's a way to keep your legacy code while also transitioning to newer technologies. It may not always be easy or particularly fun, but your customers will thank you and so will your company.</p>
]]></description>
            <link>http://www.andrewherbst.net/2008/02/mfc-net.html</link>
            <guid>http://www.andrewherbst.net/2008/02/mfc-net.html</guid>
            
            
            <pubDate>Sat, 23 Feb 2008 10:20:38 -0500</pubDate>
        </item>
        
        <item>
            <title>Working from Home</title>
            <description><![CDATA[For my entire career until I joined my current company about a year ago, I worked in pretty much every conceivable office configuration. Huge cube farms, small team bullpens and everything in between. I even had an office once (how that happened is another story). But now, I work from home almost all the time. This isn't a personal choice, it was a requirement for the job. In fact all engineers at my company (all 13 of us) work from home, leaving the support and sales folks as the only people in the office. <br /><br />It was a huge adjustment coming from large offices to working in solitude at my house. Letting people work from home when they want can be a boost for
morale and tells me that a company values it's employees
well-being. But, like most things, it has its pros and cons:<br /><br /><b>PROS:</b><br /><ul><li>I can work in blessed silence all day long</li><li>I can play my music as loud as I want<br /></li><li>I can change my venue when the mood strikes me--Starbucks, the Library, Quincy Market, wherever, so long as I can get a network connection.</li><li>I don't need to worry about when I arrive in the morning or leave at night. As long as my stuff is getting done and it works, we're all good (within reason of course--if I get something done two weeks ahead of time, I can't take two weeks off of work)<br /></li><li>I don't have to drive anywhere. If I need to go into the office (on the rare occasion I do), the T is nearby.</li></ul><b>CONS:</b><br /><ul><li>It's isolating. I have weeks where I don't leave my apartment complex. <br /></li><li>Communications can be a problem. We work via email and IM, with the occasional voice chat and desktop sharing session when things get too complicated to explain via text. This works relatively well, but there are definitely times when I wish we were all in the same office and I could just pop into someone's cube or office instead of sending them an email and waiting potentially hours for an answer.</li><li>I haven't really gotten to know the rest of the company. Remember when I mentioned the support and sales folks above? I only know their names from email and when I see people in the office, it can be somewhat awkward. You can't really develop the kind of relationships you sometimes need in an office to get things done.</li></ul>And while it's not really a pro or a con, you have to be <b>very </b>self-directed. Just like I said there's no one there watching when you come in and when you leave, there's also no one there watching your current activities and forcing you to be on task. And because you're at home, temptations abound. You have to be in a job where you <b>want </b>to work all day on whatever it is you do. If you don't like what you're doing, working from home will most likely be a disaster.<br /><br />So, after doing the office thing and the work from home thing, I'd say the best work experience would be a combination of the two. Come in one or two days a week to say hi to people and have meetings, and then work from home the rest of the week. Thankfully, our office has expanded and this approach may be an option for me in the near future.<br /> ]]></description>
            <link>http://www.andrewherbst.net/2008/01/working-from-home.html</link>
            <guid>http://www.andrewherbst.net/2008/01/working-from-home.html</guid>
            
            
            <pubDate>Thu, 10 Jan 2008 16:46:04 -0500</pubDate>
        </item>
        
        <item>
            <title>Get the Tiger Menu Bar Back in Leopard</title>
            <description><![CDATA[<pre>sudo defaults write /System/Library/LaunchDaemons/com.apple.WindowServer 'EnvironmentVariables' -dict 'CI_NO_BACKGROUND_IMAGE' 1</pre>
That is all.]]></description>
            <link>http://www.andrewherbst.net/2007/11/get-the-tiger-menu-bar-back-in.html</link>
            <guid>http://www.andrewherbst.net/2007/11/get-the-tiger-menu-bar-back-in.html</guid>
            
            
            <pubDate>Thu, 22 Nov 2007 11:08:50 -0500</pubDate>
        </item>
        
        <item>
            <title>Fighting an API</title>
            <description><![CDATA[Sometimes, when working with a certain codebase or API, you find yourself working on a problem or feature that just won't fit given the constraints of said codebase. I ran into such a problem the other day working with the MFC CRecordset class and probably spent a full day thrashing against it's walls, trying in vain to figure out a way around it's limitations. This is fighting an API.<br /><br />I find that it's usually a good idea to take a walk for a bit to clear your head and maybe think about taking another approach, because when you're spending that much time working around an API, you're doing something wrong--your overall design is probably flawed and you're just going to run into more problems like this down the road. <br /><br />But what to do if you can't backtrack and redo your flawed design due to time constraints and legacy concerns? This is the situation I found myself in right now--we were using autonumbers is an odd way that just wasn't going to work. I eventually found a pretty ugly workaround, but it's only going to be a losing battle from here on out with this app. Hopefully, I'll get the chance to rewrite this thing and do it right.<br /> ]]></description>
            <link>http://www.andrewherbst.net/2007/11/fighting-an-api.html</link>
            <guid>http://www.andrewherbst.net/2007/11/fighting-an-api.html</guid>
            
            
            <pubDate>Wed, 21 Nov 2007 14:12:52 -0500</pubDate>
        </item>
        
        <item>
            <title>Airport Extreme</title>
            <description><![CDATA[I picked a new Airport Extreme yesterday to replace an aging and somewhat flaky Linksys WRT54G. I never really believed that the Apple touch could extend to routers (it's a router, how much design does could it possibly need?), but now I'm convinced, and as always the most impressive thing is the software accompanying the hardware.<br /><br />When I first set it up, I noted with some dismay the lack of a web administration interface, which I thought was pretty standard on most modern home routers. What you get instead is this nifty little application:<div><br class="webkit-block-placeholder" /></div><div><span class="mt-enclosure mt-enclosure-image"><img alt="airport.png" src="http://www.andrewherbst.net/imgs/airport.png" class="mt-image-left" style="margin: 0pt 20px 20px 0pt; float: left;" height="464" width="684" /></span>It enumerates any detected Apple network hardware and walks you through the setup process in a mostly painless fashion. All you have to do is give the app a name for the base station and wireless network, a wireless network password, set some other easy options and you're off to the races. Want more control? There's a "Manual Setup" option that'll let you configure the router to your heart's content -- I needed this to configure port forwarding for my development server so I could access it from places external to my network.&nbsp;<div><br /><div>What it all comes down to is usability. Sure, I could've probably purchased a more advanced home router with more features/options for a cheaper price, but I don't have the inclination to spend any more of my time configuring such a beast. I want most of my hardware to function like an appliance: plug it in, set a few options and let it do it's thing. Software that accomplishes that while keeping the more advanced options available yet neatly tucked away impresses the hell out of me (compare and contrast with this&nbsp;<a href="http://www.andrewherbst.net/2007/11/psa-comcast-cable-modem-activa.html">abomination.)</a></div></div></div><div><br /></div>]]></description>
            <link>http://www.andrewherbst.net/2007/11/airport-extreme.html</link>
            <guid>http://www.andrewherbst.net/2007/11/airport-extreme.html</guid>
            
            
            <pubDate>Sun, 11 Nov 2007 19:09:19 -0500</pubDate>
        </item>
        
        <item>
            <title>PSA: Comcast Cable Modem Activator Software</title>
            <description><![CDATA[Short version: <br /><br />Did the Bluetooth module on your Mac disappear after running Comcast's modem activation software? <b>Zap the PRAM</b> (restart and hold down Command-Option-P-R).<br /><br />Long version:<br /><br />Having immense difficulties doing a video chat with my dad, I went to the handy Circuit City Connect store near me to swap my cable modem for a new one assuming that it may be a network problem. The Comcast people complied and even rejiggered my plan to give me a $20/month discount to boot. Good deal. The trouble started when I plugged the new modem into my existing network and tried to get back on the Internet.<br /><br />As it turns out, Comcast's network somehow detects a new modem and forces you to a re-activation page when you load your browser. Fine, I get it, they don't want people swapping cable modems willy-nilly. They provide you a link to a program that, according to the page, must be run on your local machine to complete the process. <b>This was the first red flag.&nbsp; </b>The second<b> r</b>ed flag<b> </b>was the installer needing administrative privileges. My impatience got the best of me and I entered my credentials allowing it to continue and restart my computer. I opened Safari and attempted to navigate to a site. Only problem was, my keyboard wasn't working. Odd, I thought. Opening System Preferences told me the whole story.<br /><br />The Comcast software had somehow managed to <b>delete the Bluetooth module from my Mac.</b> Which was a problem, seeing as how I needed to, you know, <b>type</b> things from time to time. Luckily I had a spare USB Bluetooth dongle that worked as a temporary fix. Shutting down, and pressing the Command-Option-P-R keys on my keyboard forced the PRAM to be cleared and that seemed to force my machine to re-discover the internal module. I then noticed in the Network Preference pane that the Comcast installer had <b>completely dicked up</b> my network settings and deleted all my network connections. Yikes. Way to test your software guys.<br /><br /> ]]></description>
            <link>http://www.andrewherbst.net/2007/11/psa-comcast-cable-modem-activa.html</link>
            <guid>http://www.andrewherbst.net/2007/11/psa-comcast-cable-modem-activa.html</guid>
            
            
            <pubDate>Mon, 05 Nov 2007 15:53:01 -0500</pubDate>
        </item>
        
        <item>
            <title>C++, or The Crucible In Which Good Developers Are Forged</title>
            <description><![CDATA[I code in C++ a lot at my job. Well, more like MFC, which is technically a set of C++ wrappers around Win32, but is about as far from plain-vanilla standard C++ as you can get. And I find myself raising my fists like little balls of rage to the heavens every few days when I see something like this:<br /><br /> <pre><br />class SomeBigClass<br />{<br />    private:<br />       HelperClass *m_pHelper;<br />       ImportantPointer *m_pImportant;<br />    public:<br />       ImportantPointer *GetImportantPointer()<br/>       {<br/>           return m_pImportant;<br/>       }<br /><br />       SomeBigClass() <br />       {<br />       	   m_pHelper = new HelperClass(this);<br />	   m_pImportant = new ImportantPointer();<br />       }<br />       <br />       void DoSomethingInteresting()<br />       {<br />           m_pHelper->DoSomethingHelpful();<br />           m_pImportant->DoImportantOperation();<br />       }<br />}<br /><br /></pre><br />and then, lo and behold after many access violations, wailing, and gnashing of teeth, the following is discovered in the source for HelperClass:<br /><br /><pre><br />HelperClass::DoSomethingHelpful()<br />{<br />    // blah blah blah<br />    // ...<br />    delete m_pSomeBigClass->GetImportantPointer();<br />}<br /><br /></pre>Now, the argument could and should be made that a helper class should never be deleting pointers that it doesn't own--this is just bad design. But what does one do when encountering such a problem? Refactor? Work around it in the consuming code?<br /><br />I don't think there's a good answer, at least not without having more information about the context. But now that I have a few years of experience under my belt as a software-talking-guy, I understand that half the battle is simply recognizing these anti-patterns and <b>just dealing with them</b>. <br /><br />This problem's an easy one. Refactor it. Work around it. Rewrite the method. But I've learned that if you want to be something more than a junior developer toiling away in the junior developer salt mines, you have to take the initiative and <b>fix stuff that's broke when you see it.</b><br /> ]]></description>
            <link>http://www.andrewherbst.net/2007/11/c-or-the-crucible-in-which-good-developers-are-forged.html</link>
            <guid>http://www.andrewherbst.net/2007/11/c-or-the-crucible-in-which-good-developers-are-forged.html</guid>
            
            
            <pubDate>Thu, 01 Nov 2007 17:18:06 -0500</pubDate>
        </item>
        
    </channel>
</rss>
