<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Chris Whitmore · Notes</title><link>https://chriswhitmore.com/tags/c%23/</link><language>en-us</language><author>Chris Whitmore</author><rights>(C) 2026</rights><updated>2009-07-22 15:22:00 +0000 UTC</updated><item><title>Loving SourceTree</title><link>https://chriswhitmore.com/2013/04/03/loving-sourcetree/</link><pubDate>Wed, 03 Apr 2013 07:15:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2013/04/03/loving-sourcetree/</guid><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Being a relative newbie to git I really appreciate the Atlassian's new &lt;a href="http://www.sourcetreeapp.com/"&gt;SourceTree&lt;/a&gt;&amp;nbsp;app. &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-4Nb3tA6N48g/UVw5eYtSF6I/AAAAAAAAG5Q/w_u4wQer0cI/s1600/branching.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="117" src="https://chriswhitmore.com/assets/branching.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;/div&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;Free&lt;/li&gt;&lt;li&gt;Easy to start&lt;/li&gt;&lt;li&gt;Deep feature set&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;The last few GUI git clients I've tried attempted to mask the complexity of the git feature-set whereas with SourceTree I feel like I can actually explore that feature set. I've already begun embracing branching way more as a result of the nice visualizations and as a bonus my command line git usage is also improving. Great little tool. &amp;nbsp;&lt;/div&gt;&lt;/div&gt;</description></item><item><title>iTerm2 vs Terminal.app (iTerm2 FTW!)</title><link>https://chriswhitmore.com/2013/02/16/iterm2-vs-terminal.app-iterm2-ftw/</link><pubDate>Sat, 16 Feb 2013 02:34:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2013/02/16/iterm2-vs-terminal.app-iterm2-ftw/</guid><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;I just switched from the built-in &lt;a href="http://www.apple.com/osx/apps/all.html#terminal"&gt;Terminal.app&lt;/a&gt; on Mac OS X (which I've always liked) to&lt;a href="http://www.iterm2.com/#/section/home"&gt; iTerm2&lt;/a&gt;. Here's some of what I like about iTerm2 :&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-yHD36K7ibOY/UR9egNdty-I/AAAAAAAAG48/Ga5rjNlFlPI/s1600/Screen+Shot+2013-02-15+at+3.49.16+PM.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="312" src="https://chriswhitmore.com/assets/Screen+Shot+2013-02-15+at+3.49.16+PM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;borderless windows&lt;/li&gt;&lt;li&gt;better scrolling and mouse support (or better defaults?) I can use my scrollwheel in vim by default and clicking on a word moves the cursor which is a nice bonus (behaves like unix)&amp;nbsp;&lt;/li&gt;&lt;li&gt;feels faster; I was having issues with Terminal which seemed to be related to using Microsoft's Consolas font coupled with transparency and blur which was causing ever so slight but hugely annoying key lag in vim. (key lag in vim? really?)&amp;nbsp;&lt;/li&gt;&lt;li&gt;remap the modifier keys!!! This was actually the reason I started looking for an alternative because my mac's "option" key is where I expect my control key to be and it was a source of continual frustration in vim and elsewhere. I remapped Left option to be a control key and life got better.&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Check out the features page for a full list of goodness offered over the default Terminal application shipping with Mac OS X 10.8 and below... bunch of features I have not even started using yet&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.iterm2.com/#/section/features/expose"&gt;http://www.iterm2.com/#/section/features/expose&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;</description></item><item><title>I am a technology tourist (or first impressions of Dart)</title><link>https://chriswhitmore.com/2013/02/15/i-am-a-technology-tourist-or-first-impressions-of-dart/</link><pubDate>Fri, 15 Feb 2013 15:35:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2013/02/15/i-am-a-technology-tourist-or-first-impressions-of-dart/</guid><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;So this week I met with someone who was very excited about working with &lt;a href="http://www.dartlang.org/"&gt;Google Dart&lt;/a&gt;, a web programming language aimed at being a better JavaScript running both on the server and ultimately the client where the VM could run in browsers (only chromium for now). When Google first announced Dart in September '11 I thought "cool, too bad it will never work" and basically dismissed the project as doomed since it would presumably face too much pressure from competitors and open standards. After the failures of Flash, Java (applets) and most recently Silverlight it's hard to imagine Google having an ability to convince the world to abandon JavaScript in favor of Dart. Even GWT seems to be losing Google's attention somewhat. Having just been burned my MSFT on Silverlight I am overly wary of any proprietary tech these days. &lt;br /&gt;&lt;br /&gt;But what I overlooked when I initially dismissed dart was the &lt;a href="http://www.dartlang.org/docs/dart2js/"&gt;dart2js compiler&lt;/a&gt;&amp;nbsp;and the fact that Dart doesn't really need the &lt;a href="http://www.dartlang.org/docs/standalone-dart-vm/"&gt;Dart VM&lt;/a&gt; to succeed for the language to get some traction. So skepticism temporarily put on hold I decided to port a small existing project from jQuery to Dart. The project was pretty simplistic, about 175 lines of Javascript served up statically and allowing users to navigate a full page grid with vim-like keybindings, entering free flowing text in "&lt;a href="http://html5demos.com/contenteditable"&gt;contenteditable&lt;/a&gt;" divs within the grid. &lt;br /&gt;&lt;br /&gt;Some thoughts on the experience:&lt;br /&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;Dart editor based on eclipse is handy and the integration with chromium made the whole experience of getting up and running with the SDK really easy&lt;/li&gt;&lt;li&gt;Classes! Optional Types! (or ?) Libraries! Isolates! Lexical Scoping! All very nice and immediately familiar in the resulting code.. although I did find myself&amp;nbsp;momentarily confused by:&amp;nbsp;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;lack of object notation (use Maps instead)&amp;nbsp;&lt;/li&gt;&lt;li&gt;lack of dot access to those map properties&lt;/li&gt;&lt;li&gt;lack of explicit private keyword &amp;nbsp;(use _prefix to indicate private)&amp;nbsp;&lt;/li&gt;&lt;li&gt;lack of string&amp;nbsp;concatenation (use string&amp;nbsp;&amp;nbsp;interpolation, which I actually really like)&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;handling of concurrency is really interesting not just in the Isolates but also in the "&lt;a href="http://blog.sethladd.com/2012/03/using-futures-in-dart-for-better-async.html"&gt;Future&lt;/a&gt;" type which makes for some really clean chaining of asynchronous calls such that you are not nesting N levels of callback functions. Didn't use them but they looked cool.&lt;/li&gt;&lt;li&gt;There are equivalents in the "&lt;a href="http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html#ch03-dart-html-using-html5-apis"&gt;dart:html&lt;/a&gt;" library for a lot of what you'd commonly reach for in jQuery, but in general I found myself writing more verbose code than what I was doing equivalently in jQuery. That said...&amp;nbsp;&lt;/li&gt;&lt;li&gt;I had WAY fewer error cycles in Dart, and the semi-static typing made the whole conversion process take only a couple hours including all the time spent looking things up..&lt;/li&gt;&lt;li&gt;... and looking things up was pretty easy, you can tell it's largely from Google but they are investing enough in their docs that it was always pretty easy to get what I needed&lt;/li&gt;&lt;li&gt;A nagging feeling... While dom manipulation was straight forward I found myself cut off from Javascript. It looks as though calling between them is totally doable but feels hacky as soon as you go down that path. Dart itself assumes just enough responsibility that leaving the core libraries feels like foreign territory effectively isolating you off from all of the innovation happening out there in Javascript land. I may be making a mountain out of a molehill here but having to choose between Dart native libraries and Javascript community for common tasks is not pleasant. &amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;So all in all it was a really &lt;span style="color: #0b5394;"&gt;positive experience&lt;/span&gt;, the tooling is solid, the language itself is very comfortable for someone with my background and I can see clear advantages especially on a larger project. &amp;nbsp;But I'm now at crossroads on this little project, &amp;nbsp;do I go with the comfortable tools and language with questions around the long term viability and community support for the proprietary Dart (to be fair it's open source, but open source doesn't remove the fact that this is very much a Google initiative) or do I stick with the "&lt;a href="http://en.wikipedia.org/wiki/Open_Web_Platform"&gt;open web&lt;/a&gt;" and just deal with all the pains?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-CG3hzDxXcB0/UR7FgzVPmbI/AAAAAAAAG4s/SiiIIegNq9E/s1600/choices.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="208" src="https://chriswhitmore.com/assets/choices.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;.....&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;After a couple days and writing this out I decided I just can't commit to Dart yet. There's too many exciting developments happening in the open web and Dart feels too much like unnecessary fragmentation of the collective efforts to improve things. &amp;nbsp;Will be keeping an eye on this though, just because it's cool. The project's ambition is admirable and it feels like they are just getting started.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;</description></item><item><title>How does vim keep sucking me in?</title><link>https://chriswhitmore.com/2013/02/14/how-does-vim-keep-sucking-me-in/</link><pubDate>Thu, 14 Feb 2013 20:59:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2013/02/14/how-does-vim-keep-sucking-me-in/</guid><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;span id="goog_1228771983"&gt;&lt;/span&gt;&lt;span id="goog_1228771984"&gt;&lt;/span&gt;I "grew up" on vim, which is to say my second professional programming job 15 years ago required me to spend vast quantities of time in a terminal to a Solaris machine on which I used vi exclusively to get work done. In those two years I got relatively proficient at navigation, search and replacing, using registers, and tweaking .vimrc with custom settings and macros. I did NOT get into folding, window management, syntax highlighting, or plugins. Things have changed a lot in vim-land.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/-WMClwINk5L8/UR22X-xqSHI/AAAAAAAAG4c/38-dxESgMI8/s1600/vi-sucks.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img alt="not sure who to credit for this image - taken from bulgarian forum ranting about joomla! http://www.predpriemach.com/showthread.php?t=32821" border="0" height="250" src="https://chriswhitmore.com/assets/vi-sucks.png" title="" width="400" /&gt;&lt;/a&gt;Watching a friend operate vim last week triggered weirdly intense pangs of jealousy and masochistic visions of how I too could suffer through horrible learning curves and bouts of frustration in order to&amp;nbsp;eke&amp;nbsp;out those extra few moments of productivity per day. How I too could spend hours meddling with plugins and hacks, custom scripts and a terminal to get features which every modern IDE user now takes for granted. I romantically pictured my hands rooted on the homekeys, flying through mountains of text like a boss, and the legions of adoring co-workers who would wonder at my elite skills. Totally will happen.&lt;br /&gt;&lt;br /&gt;So for what feels like the Nth time, I re-approached my old friend vim. It was shocking how much of my muscle memory had been retained, but it was also shocking how much I miss features like "find usages", "refactor...[anything]" and quick project based shortcuts for getting around files. &amp;nbsp;One of the plugins my friend was using was&amp;nbsp;&lt;b&gt;&lt;a href="http://www.vim.org/scripts/script.php?script_id=1658"&gt;NERDTree&lt;/a&gt;,&lt;/b&gt;&amp;nbsp; which provides a pretty nifty tree project/folder navigator as a window in vim. Almost but not quite a project view.&lt;br /&gt;&lt;br /&gt;And when it comes to plugins, all the cool kids these days are using the social git-goodness of &lt;a href="https://github.com/search?q=dotVim&amp;amp;type=Repositories&amp;amp;ref=simplesearch"&gt;github&lt;/a&gt; combined with a neat plugin called &lt;a href="https://github.com/tpope/vim-pathogen"&gt;Pathogen&lt;/a&gt; to create "dotVim" repositories which make the whole process of managing, sharing, and installing your &lt;i&gt;perfect&lt;/i&gt; vim environment far far simpler. Branch a dotVim repo, symlink it into your user folder and you're off. You'll find a ton of documentation out there on how to make it work so I won't repeat it here. &amp;nbsp;I based my latest attempt at vim heaven on&amp;nbsp;&lt;a href="https://github.com/codykrieger/dotvim"&gt;Kody Krieger's&lt;/a&gt;&amp;nbsp;dotVim,&amp;nbsp;which is a slimmed down version of Janus which uses Pathogen. I&amp;nbsp;particularly&amp;nbsp;liked that installation of this is bootstrapped so you can run a single command in the console to get started: (which of course I had to inspect before running because I'm paranoid like that)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #333333; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; line-height: 19px;"&gt;&lt;b&gt;curl https://raw.github.com/codykrieger/dotvim/master/bootstrap.sh -o - | sh&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Anyway, after dealing with some issues as a result of missing plugins (slim, which looks to be fixed since I installed) I was off and running. I ended up deleting the ruby specific plugins and adding a few color schemes but have otherwise only changed the .vimrc (macros, and tabs not spaces damnit! unless it's python, then spaces are ok)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;a href="http://www.vim.org/scripts/script.php?script_id=1658"&gt;NERDTree&lt;/a&gt;&lt;/b&gt; is great, but I find myself still relying on good ole :e for most things&lt;br /&gt;&lt;b&gt;&lt;a href="http://kien.github.com/ctrlp.vim/"&gt;Ctrl-P&lt;/a&gt;&lt;/b&gt; is fantastic but I find it doesn't always work, I'm guessing I need to feed more information about my context to it so that it searches the right paths. When it does work though it's basically :e on steroids.&lt;br /&gt;&lt;b&gt;&lt;a href="http://www.vim.org/scripts/script.php?script_id=2975"&gt;Fugitive&lt;/a&gt;&lt;/b&gt; is amazing, and the ability to quickly pull up a diff on what you're working on is lovely. I still hit the command line more often than I probably need to.&lt;br /&gt;&lt;br /&gt;There are a bunch of others in here that are probably making life nicer without me even knowing...still much to learn.&lt;br /&gt;&lt;br /&gt;I quite like the git repo approach and the fact that I was able to tweak everything on my laptop and then just clone to my desktop at home was pretty fantastic. I will say though that I find the sub-modules a bit of a nuisance. I don't really need to be on the bleeding edge of vim plugins and I'd rather have full control so I removed all of the submodule aspects to the above dotVim and will just pull updates when I hit bugs or need new features. The end result of my efforts are &lt;a href="https://bitbucket.org/chriswhitmore/dotvim/"&gt;on bitbucket&lt;/a&gt;.&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-KQ2nfYoMKH8/UR2x2TDWd1I/AAAAAAAAG4M/hWXSUwvWwjc/s1600/vi-commands.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="https://chriswhitmore.com/assets/vi-commands.png" /&gt;&lt;/a&gt;&lt;br /&gt;To commit myself more to learning the editor I've also started using it for writing simple text documents as well like the government forms I'm in the process of filling out. It's fun to make a terrible job an opportunity to refine your tool skills. &amp;nbsp;Vim out of the box is not great at handling paragraphs of text however and so a few tweaks are required. I have the following in my .vimrc which allows me to quickly enter "prose" mode (fixing line up line down in wrap mode being the biggest element for me)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace; font-size: x-small;"&gt;" setup the current vim instance for writing prose style&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace; font-size: x-small;"&gt;command! Prose call SetupForProse()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace; font-size: x-small;"&gt;function SetupForProse()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; "break lines visually, and don't group hardbreaks on previous word&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; set formatoptions=1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; set linebreak&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; set wrap&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; set nolist&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: Courier New, Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; "set breakat=\ |@-+;:,./?^|&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: Courier New, Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; "change default cursor keys to work on visual not actual lines&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; nnoremap j gj&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; nnoremap k gk&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; vnoremap j gj&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; vnoremap k gk&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: Courier New, Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; "border on the left hand side&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; set foldcolumn=7&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Courier New, Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: Courier New, Courier, monospace; font-size: x-small;"&gt;endfunction&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;On with the self torture!&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;</description></item><item><title>From GitHub to BitBucket in 60 seconds</title><link>https://chriswhitmore.com/2011/10/27/from-github-to-bitbucket-in-60-seconds/</link><pubDate>Thu, 27 Oct 2011 10:40:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2011/10/27/from-github-to-bitbucket-in-60-seconds/</guid><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Three weeks ago I finally decided to pay for GitHub so that I could keep some of my new projects private without giving up the&amp;nbsp;beauty&amp;nbsp;that is their cloud based source control. Last night I decided to try BitBucket's new FREE&amp;nbsp;offering and see whether I could save myself $7/month. Literally fifteen minutes later I was &lt;i&gt;deleting &lt;/i&gt;my private repo's on GitHub so that I could downgrade my account back to free.&lt;br /&gt;&lt;br /&gt;I am of two minds on this, because on the one hand I want to see GitHub succeed. They are the innovators as far as I'm concerned and I've been extremely happy using their service. BitBucket feels like a cheap knock-off in almost every way, which is great because it's familiar and easy, but I almost don't want to use it on principle. &amp;nbsp;On the other hand, I would rather clearly rather pay nothing then $84 a year for my personal projects which I want private. &amp;nbsp;Should any of these projects take off I will need to pay when the number of users goes past 5, which makes sense. Until then these projects don't have any monetary value anyway and so are not worth spending money on just for privacy. &lt;br /&gt;&lt;br /&gt;Anyway enough opinion.... here was the process :&lt;br /&gt;&lt;br /&gt;&lt;ol style="text-align: left;"&gt;&lt;li&gt;Create a user on&amp;nbsp;&lt;a href="http://bitbucket.org/"&gt;bitbucket.org&lt;/a&gt;. Love that they have OAuth support - but you do still need to pick a username and password for use from the git client.&amp;nbsp;&lt;/li&gt;&lt;ol&gt;&lt;li&gt;I was able to select the same username I had on GitHub which simplified moving things a bit&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Under the repository menu select "Import Repository", then select github, provide your credentials and click go&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-pbdCLi2TFOQ/TqmVAUoOLNI/AAAAAAAACeA/zunLp3Rt-NY/s1600/bitbucket_import.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="291" src="https://chriswhitmore.com/assets/bitbucket_import.PNG" width="400" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Magic! you have your repo moved along with all of your commits and history. Very simple. &amp;nbsp;&lt;/li&gt;&lt;li&gt;Go here and add your ssl key which you should already have from using GitHub (~/.ssl/id_rsa.pub) &amp;nbsp;&lt;/li&gt;&lt;li&gt;Now for each repository you moved, on each machine you use, edit the following file:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;/repo_location/.git/config&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;If you've kept the same username then the only change to make is the domain: (obviously change the username if you need to ;-) )&lt;br /&gt;&lt;br /&gt;OLD:&amp;nbsp;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;url = git@&lt;span class="Apple-style-span" style="color: red;"&gt;github.com&lt;/span&gt;:your_user_name/your_project.git&lt;br /&gt;NEW :&amp;nbsp;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;url = git@&lt;span class="Apple-style-span" style="color: blue;"&gt;bitbucket.org&lt;/span&gt;:your_user_name/your_project.git&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Done. Commit, push and pull as before. Your project is happily oblivious.&amp;nbsp;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So far the experience has been good. No mac client for bitbucket but I was having problems with the mac GUI client anyway and always ended up on the command line. The UI is familiar and because I hadn't really gotten into the social features and other aspects of github I have noticed no real difference in service.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I wonder how long before GitHub changes their model slightly to compete with this.... &amp;nbsp;&lt;/div&gt;&lt;/div&gt;</description></item><item><title>Timeline tools</title><link>https://chriswhitmore.com/2011/05/27/timeline-tools/</link><pubDate>Fri, 27 May 2011 09:45:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2011/05/27/timeline-tools/</guid><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;My memory is awful, it really is. I maintain a private personal blog which I use for capturing extremely short pieces of content that I want tagged and timestamped. Works well for those random thoughts that are maybe not suitable for sharing but which I want to capture nonetheless. Anyway, I'm looking for sometime similar to aid my memory at work and have been considering something more along the lines of a timeline of sorts where I can jot down major company moments, hires etc in a format that's easy to explore and I came across the following online timeline makers which all seem to fit the&amp;nbsp;mold&amp;nbsp;of what I need....&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;a href="http://www.dipity.com/"&gt;http://www.dipity.com/&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;a href="http://www.timetoast.com/"&gt;http://www.timetoast.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.timetoast.com/"&gt;&lt;/a&gt;&lt;a href="http://timerime.com/"&gt;http://timerime.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://timerime.com/"&gt;&lt;/a&gt;&lt;a href="http://www.preceden.com/"&gt;http://www.preceden.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.preceden.com/"&gt;&lt;/a&gt;&lt;a href="http://www.allofme.com/"&gt;http://www.allofme.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.allofme.com/"&gt;&lt;/a&gt;&lt;a href="http://www.xtimeline.com/"&gt;http://www.xtimeline.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Once I actually decide which one to go with I'll report back. Data portability will be important for me as I'll need to invest quite a bit of time into putting it together and would hate to lose it into the cloud. Easy of entry is probably second highest and visuals are third.&lt;br /&gt;&lt;br /&gt;Also check out &lt;a href="http://moreofit.com/"&gt;http://moreofit.com&lt;/a&gt;, great tool for finding competing tools/solutions once you have found one you like.&amp;nbsp;&lt;/div&gt;</description></item><item><title>lowering impedance of TDD with python mock</title><link>https://chriswhitmore.com/2010/10/07/lowering-impedance-of-tdd-with-python-mock/</link><pubDate>Thu, 07 Oct 2010 21:56:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2010/10/07/lowering-impedance-of-tdd-with-python-mock/</guid><description>&lt;p&gt;So after &lt;a href="http://somatose.com/2010/08/unicode-woes-and-python-unit-testing-in.html"&gt;my post about gaeunit&lt;/a&gt; a few weeks ago I&amp;rsquo;ve since completely thrown out what I was doing there and moved to vanilla python unit tests. I ended up making this move for a few reasons.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt; 1. I was never running my tests.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;GAEUnit was nice, but slow. Even when running tests in parallel I still had to go through the process of opening the browser, navigating to the right place and letting the tests run. Compare this to ctrl-f9 and seeing the following:  &lt;/li&gt;&lt;/ul&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_doSNwQwU8XA/TJi_N7-ALQI/AAAAAAAACCs/sQUKK_g3pdc/s1600/gae_too_slow.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="225" src="https://chriswhitmore.com/assets/gae_too_slow.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt; 2. AND I love seeing code coverage numbers and while it might actually be possible with GAEUnit, it wasn&amp;rsquo;t this easy&amp;hellip;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_doSNwQwU8XA/TJi_VdWvvKI/AAAAAAAACCw/U-7VJpB-oEk/s1600/pycoverage.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://chriswhitmore.com/assets/pycoverage.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;In the end it was relatively simple once I started employing mocking to deal with sessions and realized that I could actually issue real request objects to my handlers with relative ease&amp;hellip; &lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;    webObReq = Request.blank(url)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;    webApReq = webapp.Request(webObReq.environ)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;    handler.initialize(webApReq, webapp.Response())&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For the mocking I eventually decided to go with this framework:&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.voidspace.org.uk/python/mock/"&gt;&lt;a href="http://www.voidspace.org.uk/python/mock/"&gt;http://www.voidspace.org.uk/python/mock/&lt;/a&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;It has so far been fine for my needs and at least my handlers have almost achieved 100% coverage. The syntax is a little foreign compared to Moq, but hasn&amp;rsquo;t been a blocker to me actually getting work done so I&amp;rsquo;d recommend it.  &lt;/div&gt;&lt;/p&gt;</description></item><item><title>Engineering Management (link)</title><link>https://chriswhitmore.com/2010/09/21/engineering-management-link/</link><pubDate>Tue, 21 Sep 2010 21:48:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2010/09/21/engineering-management-link/</guid><description>&lt;p&gt;Great article(s) on some of the management principles in the engineering group at Facebook from &lt;a href="http://algeri-wong.com/yishan/"&gt;Yishan Wong&lt;/a&gt; who was at Facebook through some very interesting growth times. I found reading this to be inspirational so posting for posterity&amp;hellip;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://algeri-wong.com/yishan/engineering-management.html"&gt;&lt;a href="http://algeri-wong.com/yishan/engineering-management.html"&gt;http://algeri-wong.com/yishan/engineering-management.html&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>I just quit my job....</title><link>https://chriswhitmore.com/2010/09/15/i-just-quit-my-job..../</link><pubDate>Wed, 15 Sep 2010 22:18:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2010/09/15/i-just-quit-my-job..../</guid><description>&lt;p&gt;Ha! No I didn&amp;rsquo;t. But starting on the premise that I &lt;i&gt;had&lt;/i&gt; and I had already saved a bunch of cash and decided to finally become my own boss, what would I do first?&lt;br /&gt;&lt;br /&gt;For me this is hypothetical, but for my good friend who&amp;rsquo;s about to make the leap out of full time employment to self employment it is very very real. And so I will live vicariously and imagine what I&amp;rsquo;d do.&lt;br /&gt;&lt;br /&gt;The Goal:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;build a business that can at a minimum support me before my year of savings has run out so that I can continue to build said business long enough affect real change and or make loads of cash &lt;/li&gt;&lt;/ul&gt;&lt;div&gt;My Challenges:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;I have enough money to sustain myself for the year, or to invest and sustain myself for less&lt;/li&gt;&lt;li&gt;I love to program. I love to program, and specifically solve technical problems, so much that I focus on it to the detriment of other tasks. (like writing business plans, talking to users or bathing)&lt;/li&gt;&lt;li&gt;I have a set of real technical hurdles to clear in order to have anything of value&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;My Assets:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;A good idea&lt;/li&gt;&lt;li&gt;Mad programming skills&lt;/li&gt;&lt;li&gt;Friends in medium places&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_doSNwQwU8XA/TJGm1ymrPkI/AAAAAAAACCY/_W_5oUNEff8/s1600/profit.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="273" src="https://chriswhitmore.com/assets/profit.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;(caveat that this is an hour&amp;rsquo;s worth of dumping thoughts based on a few conversations and some latent thought) ;-)&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My first steps: &lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Set some very high level goals (these can change)&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Month 1 initial &lt;span class="Apple-style-span" style="color: orange;"&gt;Product Plan&lt;/span&gt; is ready (see below)&lt;/li&gt;&lt;li&gt;Month 1 website is up, domain is secured (even if a teaser)&lt;/li&gt;&lt;li&gt;Month 2 delivering live usable software with weekly updates for the remainder of the year&lt;/li&gt;&lt;li&gt;Month 3 gut check milestone - pull the plug or keep going?&lt;/li&gt;&lt;li&gt;Month 4 gut check milestone - go alone or go big? do I need more money?&lt;/li&gt;&lt;li&gt;Month 5 gut check milestone - pull the plug or keep going?&lt;/li&gt;&lt;li&gt;Month 6 target - engaged user community is built and driving the backlog (&lt;a href="http://uservoice.com/"&gt;uservoice&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;Month 6 target - marketing (adsense? viral? user communities?)&lt;/li&gt;&lt;li&gt;Month 8 target - earn my first dollar&lt;/li&gt;&lt;li&gt;Months 9  gut check - is this a venture someone would buy? should I start talking to those people?&lt;/li&gt;&lt;li&gt;months 10-11 - rinse and repeat, drive drive drive&lt;/li&gt;&lt;li&gt;Month 12 - profit! &lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Make a workspace&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Seclusion, &lt;a href="http://www.hanselman.com/blog/UltimateDeveloperPC20Part1BuildingAWEI79AndRFCForBuildingAGOMGodsOwnMachine.aspx"&gt;powerful machine&lt;/a&gt;, dual monitors, natural lighting, huge whiteboard, music and snacks&lt;/li&gt;&lt;li&gt;block &lt;a href="http://reddit.com/"&gt;reddit.com&lt;/a&gt; from this network&lt;/li&gt;&lt;li&gt;have a laptop available for games, surfing etc - try however possible to keep these separate&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Make a development environment&lt;/li&gt;&lt;ul&gt;&lt;li&gt;IDE, tools, etc&lt;/li&gt;&lt;li&gt;&lt;a href="http://github.com/"&gt;source control&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://martinfowler.com/articles/continuousIntegration.html"&gt;continuous integration&lt;/a&gt; with all the trimmings&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Start building! &lt;/li&gt;&lt;li&gt;For at least two days a week early on, or maybe a couple hours a day in the beginning besides building I would ALSO do the following&amp;hellip;.  (&lt;span class="Apple-style-span" style="color: orange;"&gt;Product Plan&lt;/span&gt;)&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Write myself a short &lt;a href="http://www.cmmiphilippines.com/vision-scope-document-creation.html"&gt;Vision and Scope&lt;/a&gt; document which would include:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;The elevator pitch, preferably in a single sentence which I would then post on a wall in my workspace&lt;/li&gt;&lt;li&gt;The high level guiding principles for the need I&amp;rsquo;m trying to solve, how I&amp;rsquo;ll translate that into some revenue (not overly specific), who I&amp;rsquo;m targeting, who my competitors may be and what the biggest risks are. &lt;/li&gt;&lt;li&gt;I would do this loosely, but I would do it. Just the act of looking and solidifying my direction would be motivating. &lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href="http://geekswithblogs.net/jkhines/archive/2009/05/27/building-a-backlog.aspx"&gt;Build a backlog&lt;/a&gt; of features, ideally written in the style of &amp;ldquo;As a &amp;lt;&amp;lt;user&amp;gt;&amp;gt; I want &amp;lt;&amp;lt;to do something&amp;gt;&amp;gt; so that &amp;lt;&amp;lt;some value&amp;gt;&amp;gt;&amp;quot; &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.stcsig.org/usability/topics/personas.html"&gt;Make a persona&lt;/a&gt; or two or three based on the largest value user segments&lt;/li&gt;&lt;li&gt;Pick one persona who I can deliver something of value to&lt;/li&gt;&lt;li&gt;Prioritize my backlog with this user type in mind, and work backwards to find the &lt;a href="http://www.netobjectives.com/blogs/more-insights-on-epics-vs-mmfs"&gt;minimum viable product&lt;/a&gt; that could actually be used by a user. This is my first milestone. &lt;/li&gt;&lt;li&gt;Look for ways to accelerate getting to revenue sooner. &lt;/li&gt;&lt;li&gt;Look around for ways to extend the 12 months without too much distraction (grants etc)&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Network network network. A lot of my milestones might be easier with help. Socialize that I&amp;rsquo;m up to something even if I&amp;rsquo;m not giving away the secret sauce. &lt;/li&gt;&lt;li&gt;Force myself to join some local developer user groups that align to my technology choices&lt;/li&gt;&lt;ul&gt;&lt;li&gt;force myself to attend some tech talks and socialize with other technologists&lt;/li&gt;&lt;li&gt;guarantee that at least some evenings are spent away from my work&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Refer to my 12 month road-map on a weekly basis. (Monday morning when I&amp;rsquo;m slow)&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Change it whenever&lt;/li&gt;&lt;li&gt;Where will I deploy? How will I deploy? I only have two months before it needs to be live in some form so figure that out. &lt;/li&gt;&lt;li&gt;Will finding my initial target user be difficult? Start hunting early&lt;/li&gt;&lt;li&gt;What questions will I need to ask in order to answer my gut check milestones? Ask those early.&lt;/li&gt;&lt;li&gt;Are there components I should look to buy or rent rather than build? How do those align to my backlog?&lt;/li&gt;&lt;li&gt;How could I accelerate delivery of features? Can some things be outsourced? Should my backlog be altered to allow my investment decision in month four?&lt;/li&gt;&lt;li&gt;What else might I need to make a go big decision in month four? Do I need a more formal business plan? Do I need to incorporate?&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Continue to build like mad!!&lt;/li&gt;&lt;li&gt;Profit!!  &lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/p&gt;</description></item><item><title>welcome criticism, be open to review and invest in process</title><link>https://chriswhitmore.com/2010/09/14/welcome-criticism-be-open-to-review-and-invest-in-process/</link><pubDate>Tue, 14 Sep 2010 14:20:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2010/09/14/welcome-criticism-be-open-to-review-and-invest-in-process/</guid><description>&lt;div style="border: 1px solid black; float: right; margin: 5px; padding: 5px;"&gt;&lt;b&gt;&lt;span id="goog_98300197"&gt;&lt;/span&gt;TLDR&lt;span id="goog_98300198"&gt;&lt;/span&gt;&lt;/b&gt;: &lt;br /&gt;&lt;ol&gt;&lt;li&gt;External audit and review is important&lt;br /&gt;and can have value not easily measured&lt;/li&gt;&lt;li&gt;Be open to investing in processes even&lt;br /&gt;if you think those processes are already&lt;br /&gt;optimal&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;When someone asks you why you aren't better at what you do, how do you react? Is your impulse to defend yourself? Do you look for comparables? Do you start to question yourself or your team? Can you begin to break down what exists today and imagine it built up in a new form?&lt;br /&gt;&lt;br /&gt;I work for people who are largely from a non-technical background. These same people are investing eight digit figures in our teams and products. Naturally they need to know that those dollars are being spent wisely, efficiently... &lt;i&gt;maximized&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;For myself, facing this question and having been so recently embedded in those same teams being questioned, I admit my impulse is to defend my&amp;nbsp;compatriots. I have a lot of trust in the people I've been in the trenches with and to a lesser degree trust in the process we've put in place there (which is in a word &lt;a href="http://www.scrumalliance.org/"&gt;scrum&lt;/a&gt;). This defensive impulse is well intentioned, but in my mind definitely the wrong place to start. &amp;nbsp;Of course I need to defend my peeps, but at the same time I need to be completely open to inspection, evaluation and change. (left brain fighting right brain)&lt;br /&gt;&lt;br /&gt;The inspection and change is taking the form of the following:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;A few day audit by a high priced and well networked consultant with a ton of experience in software&lt;/li&gt;&lt;li&gt;Scrum Training for our whole team&lt;/li&gt;&lt;li&gt;A week long more technically focused audit and coaching session&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;I was reticent about any of these at first, concerned that we were wasting money on a problem that could be tracked down to an inability on my part to assure my employers of the quality of our group. Despite my internal struggle with the idea of subjecting my teams to external audit, and the spending, and the potential for fallout, I &lt;i&gt;acted&lt;/i&gt; as best as I could to be open and welcome to the idea, knowing full well that anything else can be &amp;nbsp;suicide for the group. Before I understood the value in these&amp;nbsp;exercises&amp;nbsp;I already had a sense for the political dangers in what closing myself off to them would mean.&lt;br /&gt;&lt;br /&gt;It's a few weeks later now and we've already largely completed numbers 1 and 2. I have to say I'm pretty happy about the value for the money and the impact on us. For 1, it has been somewhat shocking to see the informal chat like approach the contractor has taken with us but it really has been somewhat shallow. Honestly what are you going to learn in a couple days anyway? My guess is that it's all going to be about structure, alignment of views and ultimately focus for the company. Very high level stuff. Despite the shallow nature of the actual time spent with this guy though, there was a very focused frenzy of activity to prepare for what we thought the audit would look like. In particular the questions ahead of our interviews and requests for particular types of documentation had me seeing our knowledge and goal management in a completely new light. The todo's that I have as a result of &lt;i&gt;preparing&lt;/i&gt; to be audited are immensely valuable. Another less tangible benefit was socializing the idea of the audit itself. I don't necessarily want us to feel complacent, and having someone external come look at you is a good way to fight that.&lt;br /&gt;&lt;br /&gt;The biggest surprise for me has been the training however. And maybe we were just lucky, but the scrum training we had was fantastic and had so many positive side-effects that I didn't anticipate. Here are a few examples...&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1. The value of common terminology&lt;/b&gt;. Simply having the same vocabulary does wonders for conversations around process and expectations. Not that we're 100% of the way there, but it really does make a huge difference in day to day conversations across our larger team and product management.&lt;br /&gt;&lt;b&gt;2. Bottom-up process improvement&lt;/b&gt;. The teams know best, and the learnings and suggestions coming from the people who are on the team are invaluable. The training really gave the team a collective voice to management that may have been lacking.&lt;br /&gt;&lt;b&gt;3. Hope/Change/Inspiration&lt;/b&gt;. Maybe these are&amp;nbsp;separate&amp;nbsp;points, but they are very related. Introspection and seeing the potential for positive change leads to hope which leads to inspiration. People were positively jacked coming out of the training sessions and very eager to put into action the incremental changes they discovered through the process.&lt;br /&gt;&lt;b&gt;4. Socializing. &amp;nbsp;&lt;/b&gt;The&amp;nbsp;group&lt;b&gt;&amp;nbsp;&lt;/b&gt;had basically two uninterrupted days together to socialize and work together on something other than the daily grind. Everyone got a little closer as a result and had this common vision they could work towards on leaving. So hard to measure, but very important.&lt;br /&gt;&lt;br /&gt;What's really amazing about the impact of the this is that the training was on a process we were already using. And in fact at the end of the day there was very little genuinely new learning. It was all small incremental change and having everyone look at the problems with fresh perspective and a critical eye.&lt;br /&gt;&lt;br /&gt;I think for me this highlights what would be my biggest challenges in running a business which is an openness to spend money. It's true of my house (in which I've only invested the bare minimum) and it would be true of my company I fear. &lt;a href="http://en.wikipedia.org/wiki/W._Edwards_Deming"&gt;Dr. Deming&lt;/a&gt; had a critical phrase for an accounting centric decision making process that I always loved &amp;nbsp;"&lt;i&gt;managing by the visible numbers only&lt;/i&gt;". As much as that resonated with me when I read his book a decade ago, I still catch myself getting caught up in the &lt;i&gt;visible&lt;/i&gt; numbers and missing the value that comes from investments like this training and audit. &lt;br /&gt;&lt;br /&gt;In any case, next time the external questions swirl around I'll definitely be a lot more open to what I may not know.</description></item><item><title>blogquotes version b02.1</title><link>https://chriswhitmore.com/2010/08/24/blogquotes-version-b02.1/</link><pubDate>Tue, 24 Aug 2010 21:50:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2010/08/24/blogquotes-version-b02.1/</guid><description>&lt;p&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;New release of&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt; &lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;a href="http://blogquotes.appspot.com/" style="color: #992211; text-decoration: none;"&gt;blogquotes&lt;/a&gt; is out&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;, with the biggest change being a switch from exclusive reliance on google accounts for login to leveraging a cool service at &lt;a href="http://www.janrain.com/"&gt;&lt;a href="http://www.janrain.com/"&gt;http://www.janrain.com/&lt;/a&gt;&lt;/a&gt; that gives me a simple way of integrating authentication from a bunch of different sources. So you no longer &lt;i&gt;need&lt;/i&gt; to be a google user to use blogquotes!  &lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;Note that if you were previously using google to login this should just work albeit with a slightly different UI. And if you find other methods to be more preferable they should also &amp;ldquo;just work&amp;rdquo; &lt;i&gt;provided&lt;/i&gt; that you use the same email address for those services. Note the logout button at the top of the page which will tell you what email or ID you&amp;rsquo;ve logged in with. So for example if I login with facebook all my old quotes are there, but if I login with blogger which doesn&amp;rsquo;t use the same email address I get nothing and am essentially starting fresh. &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;- &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;enhancement&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; : support for Facebook, Google, Windows Live ID (includes hotmail), Blogger, Wordpress and LiveJournal logins  &lt;i&gt;(have yet to validate Wordpress + LiveJournal)&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Courier New', Courier, monospace; font-size: small; line-height: 20px;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;- &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;bugfix&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; : javascript remote inclusion could still barf on some unicode, added clientside utf-8 handling&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;In the background I&amp;rsquo;ve also made a number of restructuring changes to the code which should help me release changes faster.  &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;Please leave comments on this post if you are having trouble getting access or for some reason can&amp;rsquo;t see the quotes you&amp;rsquo;ve already entered. (no data has been deleted!) &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;</description></item><item><title>Unicode woes and Python unit testing in GAE</title><link>https://chriswhitmore.com/2010/08/20/unicode-woes-and-python-unit-testing-in-gae/</link><pubDate>Fri, 20 Aug 2010 17:50:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2010/08/20/unicode-woes-and-python-unit-testing-in-gae/</guid><description>&lt;p&gt;One of the really cool aspects of deploying to &lt;a href="http://appspot.com/"&gt;Google&amp;rsquo;s cloud offering&lt;/a&gt; (GAE) versus the more machine oriented Microsoft &lt;a href="http://www.microsoft.com/windowsazure/"&gt;Azure &lt;/a&gt;and Amazon&lt;a href="http://aws.amazon.com/ec2/"&gt; EC2&lt;/a&gt; approaches are that you really are only dealing with computing resources. You deploy your app not to any particular server, but to the cloud itself. Despite the very real challenges in distributing work across data centers I am still filled with visions of automagical propagation and distribution and unlimited elastic computing. Beautiful. Anyway I was inspecting the logs and was SHOCKED to discover that there have been &lt;i&gt;&lt;b&gt;close to a thousand quotes&lt;/b&gt;&lt;/i&gt; added to system by&lt;i&gt; &lt;b&gt;37 users&lt;/b&gt;&lt;/i&gt;. THIRTY SEVEN USERS!! Now, these are small numbers I know, but given the only publicity I&amp;rsquo;ve ever given this has been the two posts on this blog I was absolutely amazed to find that people had not only managed to find the app but were able to &lt;i&gt;use&lt;/i&gt; it! (It&amp;rsquo;s quite ugly)&lt;br /&gt;&lt;br /&gt;There is nothing quite as motivating as having users.&lt;br /&gt;&lt;br /&gt;So I started looking at log files and discovered that I am actually throwing errors for at least some of those users who are not English speaking and are using Unicode characters. Oops. You&amp;rsquo;d think I&amp;rsquo;d know better by now.   See : &lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;a href="http://www.joelonsoftware.com/articles/Unicode.html"&gt;The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In most cases for these bugs it just meant calls to &lt;a href="http://docs.python.org/library/functions.html#unicode"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;unicode(var)&lt;/span&gt;&lt;/a&gt; rather than &lt;a href="http://docs.python.org/library/functions.html#str"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;str(var)&lt;/span&gt;&lt;/a&gt; . So for example when parsing url variables starting with the&lt;a href="http://code.google.com/appengine/articles/rpc.html"&gt; example provided here by Google&lt;/a&gt; and adding my own processing of an array of arguments to a method like so&amp;hellip;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;  def update_field(self, fieldName, *args):&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;    strings = [str(arg) for arg in args]&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;    &amp;hellip;.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;    return&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;and then calling that code with a unicode character such as &amp;lsquo;&amp;rsquo;–&amp;quot; would produce an error that looked like this&amp;hellip;&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="color: #cc0000;"&gt;UnicodeEncodeError: &amp;lsquo;ascii&amp;rsquo; codec can&amp;rsquo;t encode character u&amp;rsquo;\u2013&amp;rsquo; in position 0: ordinal not in range(128)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;the same code as above corrected is below. There were a few variants on this but this is a good example of a function where user defined input dictated a change to accommodate.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;  def update_field(self, fieldName, *args):&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;    strings = [&lt;b&gt;unicode&lt;/b&gt;(arg) for arg in args]&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;    &amp;hellip;.&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;    return&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;So in the course of digging in and finding/fixing these bugs I also recognized I was far overdue for some unit testing. So starting with the premise that I needed a way to reproduce the issue in the lab and write a failing test for this bug I went in search of the best method to do so. Python actually has [pretty good unit test support] built-in but I was also looking for something that would work in the context of GAE. It doesn&amp;rsquo;t take much looking before stumbling on &lt;a href="http://code.google.com/p/gaeunit/"&gt;GAEUnit&lt;/a&gt;, which is a useful extension that provides some scaffolding for tests that will run within GAE. The major negative to this is that your tests are part of your application, but I don&amp;rsquo;t have a problem with that as it&amp;rsquo;s easy to secure them to administrator access only but for some people it&amp;rsquo;s a block.&lt;br /&gt;&lt;br /&gt;The next issue I ran into with this was the fact that the python SDK for GAE doesn&amp;rsquo;t include a method for testing content behind authentication. So whereas &lt;a href="http://code.google.com/appengine/docs/java/tools/localunittesting.html#Writing_Authentication_Tests"&gt;in Java you can say this&lt;/a&gt; :&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Helvetica, Arial, sans-serif; font-size: small;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint" style="background-color: #fafafa; border-bottom-color: rgb(187, 187, 187); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(187, 187, 187); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(187, 187, 187); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(187, 187, 187); border-top-style: solid; border-top-width: 1px; color: #007000; font-family: monospace; font-size: 9pt; line-height: 15px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 1em; overflow-x: auto; overflow-y: auto; padding-bottom: 0.99em; padding-left: 0.99em; padding-right: 0.99em; padding-top: 0.99em; word-wrap: break-word;"&gt;&lt;span class="kwd" style="color: #000088;"&gt;private&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt; &lt;/span&gt;&lt;span class="kwd" style="color: #000088;"&gt;final&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt; &lt;/span&gt;&lt;span class="typ" style="color: #660066;"&gt;LocalServiceTestHelper&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt; helper &lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;=&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span class="kwd" style="color: #000088;"&gt;new&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt; &lt;/span&gt;&lt;span class="typ" style="color: #660066;"&gt;LocalServiceTestHelper&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;(&lt;/span&gt;&lt;span class="kwd" style="color: #000088;"&gt;new&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt; &lt;/span&gt;&lt;span class="typ" style="color: #660066;"&gt;LocalUserServiceTestConfig&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;())&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;.&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;setEnvIsAdmin&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;(&lt;/span&gt;&lt;span class="kwd" style="color: #000088;"&gt;true&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;).&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;setEnvIsLoggedIn&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;(&lt;/span&gt;&lt;span class="kwd" style="color: #000088;"&gt;true&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;);&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;    &lt;/span&gt;&lt;/pre&gt;&lt;span class="Apple-style-span" style="font-family: Helvetica, Arial, sans-serif; font-size: small;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint" style="background-color: #fafafa; border-bottom-color: rgb(187, 187, 187); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(187, 187, 187); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(187, 187, 187); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(187, 187, 187); border-top-style: solid; border-top-width: 1px; color: #007000; font-family: monospace; font-size: 9pt; line-height: 15px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 1em; overflow-x: auto; overflow-y: auto; padding-bottom: 0.99em; padding-left: 0.99em; padding-right: 0.99em; padding-top: 0.99em; word-wrap: break-word;"&gt;&lt;span class="pln" style="color: black;"&gt;&lt;/span&gt;&lt;span class="kwd" style="color: #000088;"&gt; public&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt; &lt;/span&gt;&lt;span class="kwd" style="color: #000088;"&gt;void&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt; testIsAdmin&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;()&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt; &lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;{&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span class="typ" style="color: #660066;"&gt;UserService&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt; userService &lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;=&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt; &lt;/span&gt;&lt;span class="typ" style="color: #660066;"&gt;UserServiceFactory&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;.&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;getUserService&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;();&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;&lt;br /&gt;        assertTrue&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;(&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;userService&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;.&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;isUserAdmin&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;());&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;But today there is no equivalent for that in python. I wasted a few hours trying to work around this issue before deciding to just login before I run tests. My login lasts for hours so this isn&amp;rsquo;t much of a constraint. In the long run I plan to drop Google&amp;rsquo;s authentication any and move to &lt;a href="https://rpxnow.com/"&gt;janrain/rpx&lt;/a&gt; to allow users to login using whatever they like. That will mean abandoning or at least shimming the infrastructure provided by GAE, but has the additional benefit of reducing my applications direct dependency on Google. Once I have my own definition of Session and session provider I can of course mock it out and control it a lot easier.&lt;br /&gt;&lt;br /&gt;Here&amp;rsquo;s the test, no asserts but if there is a problem we&amp;rsquo;ll see an exception&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;  def test_unicode_to_json_error(self):&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;      badQuote = q.Quote(quote=&amp;lsquo;hi there &amp;rsquo; + u&amp;quot;\u2013&amp;quot;)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;      result = badQuote.jsonSafe()&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;      simplejson.dumps(result)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So one error-type in the log file later I&amp;rsquo;ve spent a couple days, done a bunch of refactoring and have produced no new functionality&amp;hellip; but I do have this!&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_doSNwQwU8XA/TG7gKiiocTI/AAAAAAAACB0/WOXl-k6pC_0/s1600/test_pass.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="140" src="https://chriswhitmore.com/assets/test_pass.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Of course then, after all that I STILL ran into an error with the JavaScript, for which I have yet to add unit testing for. Sigh. I&amp;rsquo;ll have to choose between &lt;a href="http://docs.jquery.com/QUnit"&gt;qUnit &lt;/a&gt;which I&amp;rsquo;ve used before and &lt;a href="http://developer.yahoo.com/yui/yuitest/"&gt;YUI-test&lt;/a&gt; which is probably better aligned to the rest of my application.&lt;br /&gt;&lt;br /&gt;The JavaScript portion of this bug was basically because I was calling unescape() on a url-encoded variable. URL encoding though only supports 8-bit characters and doesn&amp;rsquo;t truly allow unicode, so my unicode characters became three ascii characters which could include control characters or other undesired results. There seems to be a lot of people standardizing on UTF-8 within url-encoded variables but it&amp;rsquo;s purely a convention at this point.  Thankfully I found &lt;a href="http://www.webtoolkit.info/javascript-utf8.html"&gt;this pre-written code on webtoolkit.info&lt;/a&gt; that knows how to do the look ahead at the next three characters in order to handle UTF-8 input properly.&lt;br /&gt;&lt;br /&gt;Now I hope it&amp;rsquo;s safe to say that  blogquotes can handle unicode! (and has some unit tests to boot!)&lt;/div&gt;&lt;/p&gt;</description></item><item><title>Blogquotes version b01.2</title><link>https://chriswhitmore.com/2010/08/09/blogquotes-version-b01.2/</link><pubDate>Mon, 09 Aug 2010 01:15:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2010/08/09/blogquotes-version-b01.2/</guid><description>&lt;p&gt;Didn&amp;rsquo;t expect to get more released this weekend or I would have combined these posts, but another quick release of &lt;a href="http://blogquotes.appspot.com/"&gt;blogquotes&lt;/a&gt;, the following are added :&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;- &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;enhancement&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; : quotes table is sortable by either &amp;ldquo;who&amp;rdquo; or &amp;ldquo;quote&amp;rdquo; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;- &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;enhancement&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; : click to edit on any cell in the table for convenient fixes &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;- &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;bugfix&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; : &lt;/span&gt;&lt;/span&gt;&lt;a href="http://www.niallkennedy.com/blog/2008/07/app-engine-optimization.html"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;missing robots.txt&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In the background I&amp;rsquo;ve also added analytics to the header so I can get a sense of how much traffic the site is seeing.&lt;br /&gt;&lt;br /&gt;The table features have both been things I&amp;rsquo;ve felt missing and which were remarkably easy to add since I&amp;rsquo;m just leveraging the Yahoo User Interface library &lt;a href="http://developer.yahoo.com/yui/"&gt;YUI&lt;/a&gt; for major widgets like the &lt;a href="http://developer.yahoo.com/yui/datatable/"&gt;table&lt;/a&gt;. Lots of low hanging fruit now that the guts are in place.&lt;/p&gt;</description></item><item><title>Blogquotes version b01.1</title><link>https://chriswhitmore.com/2010/08/07/blogquotes-version-b01.1/</link><pubDate>Sat, 07 Aug 2010 13:03:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2010/08/07/blogquotes-version-b01.1/</guid><description>&lt;p&gt;A new version of &lt;a href="http://blogquotes.appspot.com/"&gt;blogquotes&lt;/a&gt; has been published this morning. Not a lot of new features, but at least the wheels are turning again and some annoying bugs have been addressed.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;- &lt;b&gt;bugfix&lt;/b&gt;: adding quotes with some types of punctuation caused page errors&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;- &lt;b&gt;bugfix&lt;/b&gt;: unicode characters in quotes caused errors when pulling those quotes out for includes&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;- &lt;b&gt;bugfix&lt;/b&gt;: hitting enter on the &amp;ldquo;who&amp;rdquo; input field caused a page error, now hitting enter is equivalent to clicking &amp;ldquo;Add&amp;rdquo;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;- &lt;b&gt;enhancement&lt;/b&gt;: updated to a new faster version of the YUI data table&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;- &lt;b&gt;enhancement&lt;/b&gt;: moved quote entry form above the quote table to avoid scrolling down when adding to an already long list&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;- &lt;b&gt;enhancement&lt;/b&gt;: adding a quote will blank out the form and put focus back to the quote textbox&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;- &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: small;"&gt;&lt;b&gt;enhancement&lt;/b&gt;: &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: small;"&gt;more obvious navigation in left column for moving between managing and including quotes&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;- &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: small;"&gt;&lt;b&gt;enhancement&lt;/b&gt;: &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: small;"&gt;minor cosmetic improvements (title bar, fonts, spacing etc)&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;- &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: small;"&gt;&lt;b&gt;enhancement&lt;/b&gt;: &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: small;"&gt;new welcome page that includes more than the word &amp;ldquo;Login&amp;rdquo;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;- &lt;b&gt;degredation&lt;/b&gt; : banner ad now in right column (sorry&amp;hellip; appengine ultimately is not free and I&amp;rsquo;m worried about potential rising costs)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Please comment on this post if you use blogquotes and want to see specific features.&lt;/p&gt;</description></item><item><title>curiosity killed the addictive gamer in me</title><link>https://chriswhitmore.com/2010/06/30/curiosity-killed-the-addictive-gamer-in-me/</link><pubDate>Wed, 30 Jun 2010 00:25:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2010/06/30/curiosity-killed-the-addictive-gamer-in-me/</guid><description>&lt;p&gt;I can see it now. Homeless, slightly demented and jabbering about inane details of imaginary characters. This will be my life in six months from now after suffering through a debilitating addiction.  An addiction to the &lt;a href="http://www.halfsigma.com/2006/10/status_masturba.html"&gt;ridiculous time suck&lt;/a&gt; that is &lt;a href="http://en.wikipedia.org/wiki/World_of_Warcraft"&gt;world of warcraft&lt;/a&gt; (aka world of walking). I&amp;rsquo;m almost embarrassed to admit that I have now played through the 10 day free trial (damn you free trial!) and have &lt;em&gt;paid&lt;/em&gt; to play for another month. What happened?! How could I go from so jealously guarding my time to pissing it away into the ethereal fantasy world that is the &amp;ldquo;world&amp;rdquo; of warcraft?&lt;br /&gt;&lt;br /&gt;And yet&amp;hellip;. And yet, I am completely fascinated. I&amp;rsquo;ve read a few articles about professors studying the economics of  the game, and about the staggering number of people (11 million?) who play the game but never really understood the allure. In fact, just the idea of playing games &amp;ldquo;online&amp;rdquo; is largely unappealing to me. And by online I mean amongst hoards of teenage kids and angry shut-ins throwing slang at each other. I mean internet gaming, the kind where you show up and get completely slaughtered before you even know what&amp;rsquo;s going on.  LAN gaming on the other hand, with a room full of people you knew and could taunt&amp;hellip; that&amp;rsquo;s a different story. How old am I?&lt;br /&gt;&lt;br /&gt;I got to witness my young (11) cousin not too long ago playing on his XBox. It was eye opening to see the way his generation has adopted online anonymous gaming in a way that I have yet to really get to. Jump online, form casual alliances, piss some people off, play basically completely ad-hoc and move on to the next one. It&amp;rsquo;s social too, with banter and chat being casually tossed around. I still didn&amp;rsquo;t really get it though. (Is this just the introverted programmer in me?)&lt;br /&gt;&lt;br /&gt;[time passes]&lt;br /&gt;&lt;br /&gt;I started writing this post in December, and after five months of not playing the game I am all of a sudden well into this thing now. I had to stop playing after the holidays were over just to get back into work, and once I stopped I stopped. Course all it took was to login again after a stressful week at work and I was back at it.  No different than any other game I suppose except that this game has no ending. I really can see how this game could destroy school, relationships, careers. Thank god I already have a family.&lt;br /&gt;&lt;br /&gt;And I have to say after a few weeks the social elements are starting to be far less baffling to me. I still find that given constraints with kids in the house and limited time windows I rarely have the opportunity to commit to a game socially, (very poor form to just turn off the game midstream like I do when I play alone) but having now run a few quests both with planned partnerships and adhoc allegiances I am starting to really get the appeal.  It&amp;rsquo;s amazing too the diversity of people online (teens to doctors, moms to executives), and you have an ability to really choose who of that diverse group you actually interact with for the most part. The game includes two main modes of play, either player vs player or player vs environment. Both are collaborative, but PvE is primarily groups of humans versus AI and bosses.  I may yet play PvP but I fear that&amp;rsquo;s where you really lose control over your experience. I don&amp;rsquo;t relish the thought of being ambushed by a group of players who&amp;rsquo;s sole purpose is to run around finding people to annoy/destroy/humiliate.  And even when playing against the environment you still have arenas in which you can pit yourself against other players which honestly is enough for me.&lt;br /&gt;&lt;br /&gt;Biggest distraction for me so far? The remote auction house on my iPhone. I can be walking to a meeting and purchase or sell gear for my toon, check out upgrades etc. It&amp;rsquo;s insane.  I lament the thought of what these hours amount to in terms of lost productivity to global economies. ;-)&lt;br /&gt;&lt;br /&gt;Anyway this is way off topic but I&amp;rsquo;m cleaning up old posts and thought I&amp;rsquo;d get it out.  For the record I can&amp;rsquo;t yet say I&amp;rsquo;d ever recommend playing to my real-life friends, but these MMORPG worlds are insanely rich and engaging, not to mention wildly popular.&lt;/p&gt;</description></item><item><title>Flying at the right altitude - advice to a slightly younger me</title><link>https://chriswhitmore.com/2010/05/30/flying-at-the-right-altitude-advice-to-a-slightly-younger-me/</link><pubDate>Sun, 30 May 2010 23:06:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2010/05/30/flying-at-the-right-altitude-advice-to-a-slightly-younger-me/</guid><description>&lt;p&gt;No posts in five months! Almost exactly the same time I&amp;rsquo;ve been in a new position at work. &lt;div&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_doSNwQwU8XA/S_tTN6iRS1I/AAAAAAAAB-0/_tjfKF8yRX0/s1600/Screen+shot+2010-05-24+at+11.01.56+AM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="355" src="https://chriswhitmore.com/assets/Screen+shot+2010-05-24+at+11.01.56+AM.png" width="640" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Disturbing trends, this completely predates just the last six months&amp;hellip;. &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;I&amp;rsquo;ve moved from being a team lead to being the head of our R&amp;amp;D group. I now have as many teams (7) as I did people to think about, and a whole new world of politics, strategy and planning. With a group of this size HR issues seem to be at least a weekly occurrence and I am now fully and completely on &lt;a href="http://www.paulgraham.com/makersschedule.html"&gt;the manager&amp;rsquo;s schedule&lt;/a&gt;.   &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;However now that I&amp;rsquo;ve somewhat got my sea legs in this position I am increasingly allowing myself to get back into technical issues where I think I can add value. &amp;ldquo;Where I think I can add value&amp;rdquo; is the whole challenge here though. I have literally not opened visual studio in five months of running around like a chicken with my head cut off. How often does having the boss swoop  in and give their less informed perspective do more harm than good? Impossible to answer without knowing the boss in question of course, but surely there are ground rules some sage masters can teach me. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I have to say I really enjoy looking at things from this altitude, in that you really can see patterns in development across teams, opportunities for reuse or better design across teams, efficiencies to be gained etc. It all can be very fun, but at the same time I worry about losing relevance, and I worry about sidetracking teams. Even worse is the feeling that by interfering I actually hurt the autonomy and self-sufficiency of these teams by interfering (which &lt;i&gt;almost&lt;/i&gt; outweighs the fear of divergent or  teams).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here are some things I think I would tell the me of six months ago:  (advice to a new executive)&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;&lt;b&gt;Don&amp;rsquo;t stop the old routine completely&lt;/b&gt;.  I actually think a lot of my comfort these days is precisely because I&amp;rsquo;m getting back to things like my reader and blogger. Just imagine how nice it would be if I could do the occasional code review or bug fix! (unlikely) My life has gotten decidedly more stressful (father died, promotion, second child all within the last six months) and my routine has out of nowhere incorporated quite a bit of gaming all of sudden. (COD2 MW, WoW) Good stress releases but I need to get myself back into creating rather than just consuming things.  &lt;/li&gt;&lt;li&gt;&lt;b&gt;Embrace the manager&amp;rsquo;s schedule, but respect the maker&amp;rsquo;s schedule&lt;/b&gt;. It&amp;rsquo;s a very tricky thing not to let your new found schedule dictate awkward length and times for meetings with the people who are there to actually do the development. Resist the urge and find ways to be more effective with meetings. It is SO easy to forget the real costs around this.  &lt;/li&gt;&lt;li&gt;&lt;b&gt;Don&amp;rsquo;t seek consensus on every decision&lt;/b&gt;. It can work on a team of seven or eight to drive for consensus and try to win minds but on much larger teams you&amp;rsquo;re going to have to get used to making some calls without the comfort of knowing you have everyone on board. Of course reasonable efforts still need to be made but it becomes about key people and finding the influence in the group. &lt;/li&gt;&lt;li&gt;&lt;b&gt;Be open and give status frequently&lt;/b&gt;. Still one I struggle to do properly but it really is key. I am trying right now to really focus on problems at the request of my boss, but don&amp;rsquo;t forget to acknowledge the wins as well. The more open you are about the warts the easier it is to excise them. In my opinion, maybe counter intuitively, more shit should flow up and more sunshine down. (though that&amp;rsquo;s an easy one to over generalize)&lt;/li&gt;&lt;li&gt;&lt;b&gt;Trust and trusting your gut&lt;/b&gt;. Not really anything new to the position, but the frequency with which I&amp;rsquo;ve run into this has gone through the roof. You often just know the right course of action. Waiting to find out the hard way (or expensive way) that you were right can be painful.  Trusting yourself is only second to trusting your people. Trust your gut on your people, make sure you have the right people and put that trust in them. &lt;/li&gt;&lt;li&gt;&lt;b&gt;There will be a lot of water sprayed at your back, be the duck&lt;/b&gt;.  Or, in other words, find a way to regain your &lt;a href="http://en.wikipedia.org/wiki/Church_of_the_SubGenius#Slack"&gt;&lt;b&gt;slack&lt;/b&gt;&lt;/a&gt;. &lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/en/a/a3/Bobdobbs.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="https://chriswhitmore.com/assets/Bobdobbs.png" width="213" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/p&gt;</description></item><item><title>google chrome software updates make everything else feel broken</title><link>https://chriswhitmore.com/2009/12/14/google-chrome-software-updates-make-everything-else-feel-broken/</link><pubDate>Mon, 14 Dec 2009 22:59:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2009/12/14/google-chrome-software-updates-make-everything-else-feel-broken/</guid><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;I am growing more and more annoyed at the Apple's and the Adobe's of the world who are constantly interrupting my work to tell me that there are updates waiting for me to install. Why do I have to manage this? Yes I know that I can go in there and tweak the settings so that I don't get annoyed... but why should I even have to do that? I would need to do that across every user account on every machine I use on a regular basis! (5) This is noise, and it isn't at all necessary for me to have to think about it.&lt;br /&gt;&lt;br /&gt;I believe this is part of the convenience of applications delivered in the cloud. (sorry to throw that term out there) It is part of the convenience that has me accepting fewer features in order to get that functionality.&lt;br /&gt;&lt;br /&gt;There are companies out there who understand this, and are working hard to create a better user experience. Google for example went to great lengths in order to be able to update their entire browser in under 100 KB of download just to make the experience more efficient, user friendly and safer. Not only that but chrome updates happen automatically, again to help with security. It's very close to the experience I get by logging into gmail, which is always up to date. &amp;nbsp;Now I can already hear rattles of complaint about "control" over your own machine, but I have to ignore this or I'll get completely derailed. I'll say in short that I think that control is an illusion, and the alternatives are worse.&lt;br /&gt;&lt;br /&gt;If you have not already read this post by the chrome developers I highly&amp;nbsp;recommend&amp;nbsp;it.&lt;br /&gt;&lt;a href="http://blog.chromium.org/2009/07/smaller-is-faster-and-safer-too.html"&gt;http://blog.chromium.org/2009/07/smaller-is-faster-and-safer-too.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And then you have the Apple, who has gone from a position of pushing hard to avoid needing to reset the operating system unless absolutely needed to requiring reboots for Quicktime, Safari and sometimes even iTunes (especially in windows). &amp;nbsp;You can argue all you want that it's because of kernel extensions or who knows what else - but at the end of the day it doesn't matter why. This is bad design and leads to a diminished user experience.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_doSNwQwU8XA/SycwnSDhxMI/AAAAAAAAB1A/YJu_6bXy3Zs/s1600-h/softwareupdate.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="320" src="https://chriswhitmore.com/assets/softwareupdate.png" width="299" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;It seems like more and more often I am prompted with a software update dialog that looks like this one. Three out of four of the updates require a reboot! Are you serious? And chances are good that I will continue to ignore this dialog because closing all of my browser sessions, and ending the long running handbrake encode, and stopping the download I have going, and turning off the TV program I'm watching all amount to a whole lot of trouble for something I don't think I should even have to think about.&lt;br /&gt;&lt;br /&gt;Seriously what is so special about Safari that they require me to download 36.2 MB and restart my machine for a point release?? Maybe this didn't seem so offensive before Chrome, but now it feels dated and clunky.&lt;br /&gt;&lt;br /&gt;I really should pick on Adobe here for the &lt;a href="http://www.google.ca/search?hl=en&amp;amp;q=hate+adobe+updater&amp;amp;btnG=Search&amp;amp;meta=&amp;amp;aq=f&amp;amp;oq="&gt;horror that is the Adobe Updater&lt;/a&gt;, but honestly I really do expect more from Apple. Adobe is too easy of a target.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;Please fix this Apple, you can do better. &amp;nbsp;Where is the Steve Jobs who wanted to&lt;a href="http://www.folklore.org/StoryView.py?project=Macintosh&amp;amp;story=Saving_Lives.txt"&gt; save lives by reducing boot times&lt;/a&gt;??</description></item><item><title>build it (so it's easy) and they will come (make the right decision)</title><link>https://chriswhitmore.com/2009/12/05/build-it-so-its-easy-and-they-will-come-make-the-right-decision/</link><pubDate>Sat, 05 Dec 2009 22:59:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2009/12/05/build-it-so-its-easy-and-they-will-come-make-the-right-decision/</guid><description>&lt;p&gt;One of the biggest lessons I think I&amp;rsquo;ve learned over the past few years is that you have to be very careful with what you make easy to do in a software system.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://chriswhitmore.com/assets/pathofleast.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="166" src="https://chriswhitmore.com/assets/pathofleast.JPG" width="320" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;When you are working within a preexisting system, it is very hard to work &lt;i&gt;effectively&lt;/i&gt; outside the bounds of that system. Whether you are limited by time constraints, peer pressure, political decisions or just pure technical inertia, those early/legacy decisions in a system will have long reaching impacts on the decisions of those who follow.&lt;br /&gt;&lt;br /&gt;I&amp;rsquo;ll give you an example. On a product I worked on for years, the decision to use an &lt;a href="http://www.agiledata.org/essays/mappingObjects.html"&gt;object relational mapper&lt;/a&gt; (ORM) in early stages was based on a desire to eliminate boilerplate code, reduce the learning curve for new developers and generally push the development of new entities down to the entire team rather than specializing this role in one person.  All in all the reasoning was sound, but the inability to see some of the psychological aspects that would impact the future had some serious impact on the future of the system.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Developers stop thinking about database impacts because they never really SEE the database&lt;/li&gt;&lt;li&gt;The object model and the schema become inexorably tied &lt;em&gt;&lt;/li&gt;&lt;li&gt;Accessibility to the &lt;a href="http://en.wikipedia.org/wiki/Data_access_layer"&gt;DAL&lt;/a&gt; ends up being given to junior developers who may not have otherwise dealt with it yet.** &lt;/li&gt;&lt;li&gt;Things that could reasonably be built OUTSIDE the ORM end up dropped in without consideration because developers are following the template. &lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;i&gt;&lt;/em&gt; This can be avoided by having data contracts that are specific to the DAL&lt;/i&gt;&lt;br /&gt;&lt;i&gt;** There is nothing inherently wrong with ORM, and if your DAL is properly abstracted so that the ORM isn&amp;rsquo;t propagated throughout the stack then this too isn&amp;rsquo;t necessarily a problem. &lt;/i&gt;&lt;br /&gt;&lt;br /&gt;I add those two caveats because I really don&amp;rsquo;t have an issue with ORM, in fact I think used properly it makes way more sense then to waste days of development doing repetitive and simple &lt;a href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete"&gt;CRUD&lt;/a&gt; work.&lt;br /&gt;&lt;br /&gt;However the deeper issues that arose for us still focused on convenience. It was convenient to expose the friendly querying methods of the domain objects that mapped to our tables directly to the business logic assemblies. It was convenient to let junior developers write code that accessed those objects as if retrieval and persistence were magically &lt;a href="http://en.wikipedia.org/wiki/Constant_time"&gt;O(1)&lt;/a&gt; operations. Of course in reality we discovered embarrassingly late that we had more than a few graphs of objects that were being loaded upon traversal, leading to a separate mapper triggered SELECT for each object and its children. This is the kind of thing that only becomes apparent when you test with large datasets and get off of your local machine and see some real latency.&lt;br /&gt;&lt;br /&gt;And yes, in this case, I think you could argue that QA dropped the ball here. But as a professional software developer you really never want to see issues like this get that far. &lt;br /&gt;&lt;br /&gt;I&amp;rsquo;ve picked one example, but there are many many others in the system I&amp;rsquo;m referring to. Including but not limited to a proliferation of configuration options and files, heavy conceptual reuse of classes and functionality that are only tangentially related to each other, and an increasing reliance on a &amp;ldquo;simple&amp;rdquo; mechanism to do work outside the main code base.&lt;br /&gt;&lt;br /&gt;Ultimately, this post has less to do with ORM and proper abstraction and more to do with understanding how your current (and future) developers will react to those decisions. I think a conscious effort has to be paid to how a human will game your system. You need to come up with penalties for doing dumb things if possible, and the path of least resistance for the right ones.  There are &lt;a href="http://www.amazon.com/Framework-Design-Guidelines-Conventions-Libraries/dp/0321246756/ref=sr_1_2?ie=UTF8&amp;amp;s=books&amp;amp;qid=1260082319&amp;amp;sr=8-2"&gt;entire books&lt;/a&gt; dedicated to framework and platform development that encompass some of these ideas, but they apply at every level really in my opinion. (except maybe the one man shop?)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/p&gt;</description></item><item><title>way to go, LRO</title><link>https://chriswhitmore.com/2009/09/23/way-to-go-lro/</link><pubDate>Wed, 23 Sep 2009 23:36:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2009/09/23/way-to-go-lro/</guid><description>&lt;p&gt;LRO does it again, water on the moon! That&amp;rsquo;s so cool! NASA is important people, we&amp;rsquo;re laying the foundation for future generations here. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.space.com/scienceastronomy/090923-moon-water-discovery.html"&gt;&lt;a href="http://www.space.com/scienceastronomy/090923-moon-water-discovery.html"&gt;http://www.space.com/scienceastronomy/090923-moon-water-discovery.html&lt;/a&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And of course finding water is not the same as finding lakes, but imagine the potential for fuel sources and or human sustenance. Water is damn heavy, and not something we can easily take with us. &lt;br /&gt;&lt;br /&gt;Pretty cool stuff.&lt;/p&gt;</description></item><item><title>hanselman tools 2009!!</title><link>https://chriswhitmore.com/2009/09/02/hanselman-tools-2009/</link><pubDate>Wed, 02 Sep 2009 20:58:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2009/09/02/hanselman-tools-2009/</guid><description>&lt;p&gt;Saw this on reddit tonight, hanselman has updates his legendary &lt;a href="http://www.hanselman.com/tools"&gt;tools list for 2009&lt;/a&gt;. So what was going to be an evening of actual coding is slowing turning into an evening of trying out cool new tools that have made his list.&amp;#160; (I’m writing this blog post in windows Live Writer after seeing it in the list) &lt;/p&gt; &lt;p&gt;But what’s an hour or two of my time compared to the time that must go into compiling this list? Totally worth checking out, especially if you’ve never had a look before. &lt;/p&gt; &lt;p&gt;It’s nice, my mac envy always takes a slight dip in moments like these. &lt;/p&gt;</description></item><item><title>LRO sends us some underwhelming evidence!</title><link>https://chriswhitmore.com/2009/09/01/lro-sends-us-some-underwhelming-evidence/</link><pubDate>Tue, 01 Sep 2009 23:07:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2009/09/01/lro-sends-us-some-underwhelming-evidence/</guid><description>&lt;p&gt;I remain a huge fan of projects like LRO, and personally &lt;a href="http://somatose.com/2008/11/lunar-reconnaissance-orbiter.html"&gt;still believe that the disbelievers are crackpots&lt;/a&gt; but I also have to admit to being a little underwhelmed by the photos listed here on NASA&amp;rsquo;s site for the Lunar Reconnaissance Orbiter.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.nasa.gov/mission_pages/LRO/multimedia/lroimages/apollosites.html"&gt;&lt;a href="http://www.nasa.gov/mission_pages/LRO/multimedia/lroimages/apollosites.html"&gt;http://www.nasa.gov/mission_pages/LRO/multimedia/lroimages/apollosites.html&lt;/a&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Still, I&amp;rsquo;m excited &amp;ldquo;we&amp;rsquo;re&amp;rdquo; (go NASA) going back, and if anything this just really highlights for me how damn big our &amp;ldquo;little&amp;rdquo; moon is. Easy to forget that the satellite that&amp;rsquo;s taking those photos is still 50 kilometers! away from the surface, so somewhat understandable that we&amp;rsquo;re not getting the close ups I&amp;rsquo;d love to see. &lt;br /&gt;&lt;br /&gt;There is a pretty cute video of the LRO launch party &lt;a href="http://www.nasa.gov/mission_pages/LRO/main/index.html"&gt;here&lt;/a&gt; (check side bar) that is worth checking out. The highlight for me was seeing the communications in action, the &lt;a href="http://lrolr.gsfc.nasa.gov/index.html"&gt;laser ranging support&lt;/a&gt; for the data coming from LRO looks like a large robot with big green blinking eyes.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://lrolr.gsfc.nasa.gov/images/lasermoon.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="296" src="https://chriswhitmore.com/assets/lasermoon.jpeg" width="420" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Congratulations and good luck LRO team, if you can now &lt;a href="http://www.sarahfobes.com/science/lunar-reconnaissance-orbiter-camera/"&gt;just convince Sarah&lt;/a&gt; then your mission can surely be called a great success.&lt;/p&gt;</description></item><item><title>lessons learned from online gambling - predicting scalability</title><link>https://chriswhitmore.com/2009/09/01/lessons-learned-from-online-gambling-predicting-scalability/</link><pubDate>Tue, 01 Sep 2009 22:42:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2009/09/01/lessons-learned-from-online-gambling-predicting-scalability/</guid><description>&lt;p&gt;I work with someone who has spent a few years working for an online poker company who shall remain nameless. This company was responsible for a poker platform that supported both their own branded poker offering as well as being an engine for other companies who would layer on their branding. My colleague played an important role in taking their fairly well built existing system from thousands of users to tens of thousands of users, and in the process exposing a large handful of very deep bugs, some of which were core design issues.&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Looking at this site &lt;a href="http://www.pokerlistings.com/texas-holdem"&gt;&lt;a href="http://www.pokerlistings.com/texas-holdem"&gt;http://www.pokerlistings.com/texas-holdem&lt;/a&gt;&lt;/a&gt; and seeing just this small sample of some of the top poker sites is a bit insane.  We&amp;rsquo;re talking close to 100,000 concurrent players at peak hours JUST from the 16 top &amp;ldquo;texas hold-em&amp;rdquo; sites listed here. Who are these people? (I&amp;rsquo;m totally gonna waste some money online one of these days by the way) I&amp;rsquo;m sure this is just the tip of the iceberg too.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;It&amp;rsquo;s a great domain for learning critical systems in my opinion. Real time, high concurrency, real money, third party integrations for credits and tournaments and the vast reporting that goes on for all that data being generated.&lt;br /&gt;&lt;br /&gt;My colleague&amp;rsquo;s experience in dealing with real time load and breaking the barriers of scalability are truly fascinating and a good source of learning for me. While I realize &lt;a href="http://hurvitz.org/blog/2008/06/linkedin-architecture"&gt;there are bigger puzzles out there&lt;/a&gt;, but it&amp;rsquo;s not every day you have direct access to that experience where you work.  In any case, one such learning that I am in the process of trying to apply is a more forward looking approach to load modeling. That is, rather than to simply design and test for scalability; to actually drill down into the &lt;i&gt;theoretical&lt;/i&gt; limit of what you are building in an attempt to &lt;b&gt;predict failure&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;This prediction can mean a lot of different things of course, being on a spectrum with something like a vague statement about being IO bound to much more complicated models of actual transactions and usage to enable extrapolating much richer information about those weak points in the system. In at least one case, my boss has taken this to the point where the model of load was expressed as differential equations prior to any code being written at all. Despite my agile leanings I have to say I&amp;rsquo;m extremely impressed by that. Definitely something I&amp;rsquo;d throw on my resume. So I&amp;rsquo;m simultaneously excited and intimidated at the prospect of delving into our relatively new platform that we&amp;rsquo;re building in the hopes of producing something similar. I definitely see the value in at least the first few iterations of highlighting weak points and patterns and usage. How far I can go from there will be a big question mark.&lt;br /&gt;&lt;br /&gt;For now I&amp;rsquo;ll be starting at &lt;a href="http://www.tpc.org/information/benchmarks.asp"&gt;&lt;a href="http://www.tpc.org/information/benchmarks.asp"&gt;http://www.tpc.org/information/benchmarks.asp&lt;/a&gt;&lt;/a&gt; and then moving into as exhaustive list as I can of the riskiest elements of our system. From there I&amp;rsquo;ll need to prioritize and find the dimensions that will impact our ability to scale. I expect with each there will be natural next steps to removing the barrier (caching, distributing load, eliminating work, etc) and I hope to be able to put a cost next to each of those.&lt;br /&gt;&lt;br /&gt;Simple!&lt;/p&gt;</description></item><item><title>sometimes it's helpful to think about what NOT to do</title><link>https://chriswhitmore.com/2009/09/01/sometimes-its-helpful-to-think-about-what-not-to-do/</link><pubDate>Tue, 01 Sep 2009 21:52:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2009/09/01/sometimes-its-helpful-to-think-about-what-not-to-do/</guid><description>&lt;p&gt;Came across this list of &amp;ldquo;anti-patterns&amp;rdquo; on wikipedia tonight. I&amp;rsquo;m tempted just to copy and paste the contents here but that would make me feel dirty.&lt;br /&gt;&lt;br /&gt;Definitely a good list though and something worth reminding ourselves of every once in a while when thinking about the systems we build.&lt;br /&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;a href="http://en.wikipedia.org/wiki/Anti-pattern"&gt;&lt;a href="http://en.wikipedia.org/wiki/Anti-pattern"&gt;http://en.wikipedia.org/wiki/Anti-pattern&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>the rise and fall of myspace (and twitter)</title><link>https://chriswhitmore.com/2009/08/07/the-rise-and-fall-of-myspace-and-twitter/</link><pubDate>Fri, 07 Aug 2009 21:11:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2009/08/07/the-rise-and-fall-of-myspace-and-twitter/</guid><description>&lt;p&gt;This is a great post on how myspace rose and fall and how the same thing applies to Twitter (and I&amp;rsquo;d imagine Facebook as well) Some really good thoughts. Getting popular before you have your mission can forever trap you into that identity vacuum where popularity is everything. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://codybrown.name/2009/08/06/myspace-is-to-facebook-as-twitter-is-to-______/"&gt;&lt;a href="http://codybrown.name/2009/08/06/myspace-is-to-facebook-as-twitter-is-to-______/"&gt;http://codybrown.name/2009/08/06/myspace-is-to-facebook-as-twitter-is-to-______/&lt;/a&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A good read, and the level of blogging I&amp;rsquo;d like to work towards (more pictures!).&lt;/p&gt;</description></item><item><title>manager schedule vs maker schedule</title><link>https://chriswhitmore.com/2009/07/23/manager-schedule-vs-maker-schedule/</link><pubDate>Thu, 23 Jul 2009 01:09:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2009/07/23/manager-schedule-vs-maker-schedule/</guid><description>&lt;p&gt;Popular comp-sci essayist and lisp hacker extraordinaire Paul Graham recently posted this article on the difference between a manager&amp;rsquo;s schedule and a maker&amp;rsquo;s schedule. This is really inline with my own views on this issue and really sums up a big problem we have where I work with meetings being scheduled with the makers and the impact that has. We&amp;rsquo;ve had tons of discussions around the cost of mental context switching, but even that&amp;rsquo;s an understatement of the problem&amp;hellip; &lt;br /&gt;&lt;br /&gt;Great work, it&amp;rsquo;s always helpful hearing echoes of these types of thoughts beyond my own everyday sphere. Who knows maybe I can use to add some weight to my arguments. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://paulgraham.com/makersschedule.html"&gt;&lt;a href="http://paulgraham.com/makersschedule.html"&gt;http://paulgraham.com/makersschedule.html&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>performance tuning to an insane level</title><link>https://chriswhitmore.com/2009/07/22/performance-tuning-to-an-insane-level/</link><pubDate>Wed, 22 Jul 2009 15:22:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2009/07/22/performance-tuning-to-an-insane-level/</guid><description>&lt;p&gt;Ok, so I have to admit that I&amp;rsquo;ve been one to disregard figures around performance when arguing with co-workers over the merit of managed code vs C/C++. I&amp;rsquo;ve even used the argument that statically typed languages like Java and C# offer more hints to the compiler that allow for optimizations not possible in unmanaged code. I still have a fairly pragmatic view of the spectrum of cost to deliver (skill set/maintainability) vs performance gains&amp;hellip; but regardless of all that&amp;hellip;.. wow this article completely humbled and inspired me. &lt;br /&gt;&lt;br /&gt;I don&amp;rsquo;t know shit. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://stellar.mit.edu/S/course/6/fa08/6.197/courseMaterial/topics/topic2/lectureNotes/Intro_and_MxM/Intro_and_MxM.pdf"&gt;&lt;a href="http://stellar.mit.edu/S/course/6/fa08/6.197/courseMaterial/topics/topic2/lectureNotes/Intro_and_MxM/Intro_and_MxM.pdf"&gt;http://stellar.mit.edu/S/course/6/fa08/6.197/courseMaterial/topics/topic2/lectureNotes/Intro_and_MxM/Intro_and_MxM.pdf&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>taking a step back/up/sideways (thebrain)</title><link>https://chriswhitmore.com/2009/05/11/taking-a-step-back/up/sideways-thebrain/</link><pubDate>Mon, 11 May 2009 22:39:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2009/05/11/taking-a-step-back/up/sideways-thebrain/</guid><description>&lt;p&gt;Around 2003, 2004 I had a bit of a mild obsession with organizing my life into digital form, creating as many mappings as I could from my everyday existence into some kind of digital form. This of course included ideas and thoughts, writings and paintings, music and movies, friends and bits of information about those friends etc. This amass of data have gone from one disjointed medium to another (.txt files in folders, emails, blog posts, napkins) without ever really achieving any chohesiveness or real improvement in my ability to actually synthesize or act on all that information.&lt;br /&gt;&lt;br /&gt;At that time the closest tool I found that could come close to mapping ideas and thoughts in a way that made sense to me was &amp;ldquo;&lt;a href="http://thebrain.com"&gt;TheBrain&lt;/a&gt;&amp;rdquo; a piece of software intended for visualizing information, and as importantly, the links between that information. As a user, you add &amp;ldquo;thoughts&amp;rdquo; to your brain which become nodes in a large graph of ideas, thoughts, attributes, urls etc. You can then very quickly build child, parent and sibling links between those nodes to add more context and information. Those links can then be categorized to add even more context to the relationship between ideas which is often very important information. Unlike a lot of &amp;ldquo;mind mapping&amp;rdquo; tools I&amp;rsquo;ve used though, the brain does not force you into a tree structure. Your thoughts can have multiple parents and siblings or &amp;ldquo;jumps&amp;rdquo; to thoughts anywhere else in your brain, whether they are directly related or not. Hyperlinks, imagine that! I think for the actual exercise of brainstorming and free flow thought this is critical. It also mimicks how I visualize my own thoughts working. I&amp;rsquo;ve since tried personal wiki&amp;rsquo;s which give you a lot of the same flexibility but lack the very fast keyboard entry for connections and nodes and force you to think at the level &amp;ldquo;inside&amp;rdquo; the node, by editing the page. Whereas the brain allows you to think and work at the level of the topology, which is really effective.&lt;br /&gt;&lt;br /&gt;I stopped using the software basically because of the overhead of attempting to keep the futile mapping exercise up to date. Imagine if every idea and thought you had needed to be compulsively cataloged manually into a program in order to keep the overall picture intact. It just doesn&amp;rsquo;t work, at least not for me, and not for long and detracts from my overall goals. I found that every time I opened my brain there was just too much catchup work to do in order to get things synced up and in order.&lt;br /&gt;&lt;br /&gt;The other thing that changed for me since 2004 has been search. Between Google and Spotlight on my mac I basically stopped categorizing information in the same ways I used to have to. It becomes less and less necessary to build nested categories of programs or emails or documents etc. Search has exposed the entire hierarchy in a glance, in many cases keeping the context intact that would have derived the categories. Still there is value in the information of that structure, but in a far less visible way. &lt;br /&gt;&lt;br /&gt;Well I&amp;rsquo;ve resurrected the brain and am using it in a new way that seems to be actually working for me. For starters I don&amp;rsquo;t keep any notes or real content in the brain, this is one of the clumsiest facets of the tool and almost seems like an afterthought. It really is all about the topology, which for me is fine since the bulk of what I need is often in dedicated stores (subversion, sharepoint, team foundation server) I&amp;rsquo;ve found any attempt to use the clumsy palettes and data entry forms to just be too cumbersome to bother with. &lt;br /&gt;&lt;br /&gt;Focusing on the nodes and connections, and learning all the keyboard shortcuts have enabled me to use the brain in a way that is a lot like I sometimes use notepad when I need to brainstorm. Except rather than dashes, asterisks and plus-signs I&amp;rsquo;m using jumps, parents and children of small snippets of text. It&amp;rsquo;s really a cool feeling being able to navigate this very large graph of interrelated concerns and ideas with very little effort. Wiki&amp;rsquo;s and other hypertextual forms have served me well too, but never with so little impediment.&lt;br /&gt;&lt;br /&gt;For high level thinking and free form brainstorming this tool is the best I&amp;rsquo;ve used. And provided I keep it to just the free flowing jumping and navigating it&amp;rsquo;s incredibly useful.&lt;/p&gt;</description></item><item><title>Simple Extensibility in .NET</title><link>https://chriswhitmore.com/2009/05/08/simple-extensibility-in-.net/</link><pubDate>Fri, 08 May 2009 22:03:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2009/05/08/simple-extensibility-in-.net/</guid><description>&lt;p&gt;I&amp;rsquo;ve used this approach a few times when I essentially need a really simple plugin / provider model within my applications so I thought I&amp;rsquo;d jot down the relevant details here for posterity using an old project for adding post commit hooks to subversion. &lt;br /&gt;&lt;br /&gt;Consider this a somewhat simplistic approach, not suitable for production code without a bit more plumbing. If you are going all out and need true add-in&amp;rsquo;s for your .NET based product I recommend checking out the &lt;a href="http://msdn.microsoft.com/en-us/library/bb384241.aspx"&gt; managed add-in framework &lt;/a&gt;, very robust stuff and not that hard to implement. In a lot of cases though the isolation, discoverability, communication pipelines etc are a bit overkill. The example I&amp;rsquo;ll show is a subversion hook that allows for very simple addition of new .NET &amp;ldquo;actions&amp;rdquo; to execute on PostCommit. In this case the &amp;ldquo;add-ins&amp;rdquo; are only written in house, and editing a config file to hook them up is completely acceptable etc etc. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: x-large;"&gt;The solution&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Subversion.Contracts&lt;/b&gt; : This project is the bridge between our dispatcher and the plugins that will do the work.&lt;br /&gt;&lt;b&gt;Subversion.Plugins&lt;/b&gt; : Any of the actions we wish to take post commit are added here, but could just as easily be distributed across as many assemblies and projects as necessary as long as they reference the contracts.&lt;br /&gt;&lt;b&gt;Subversion.Dispatcher&lt;/b&gt; : This is the console application that actually receives the arguments from subversion and translates them into our contracts, then executes the appropriate actions (note no references to the plugins project)&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_doSNwQwU8XA/SgO5c86TnqI/AAAAAAAABh0/YQilvT2hh4A/s1600-h/plugin_sln.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://chriswhitmore.com/assets/plugin_sln.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: x-large;"&gt;The Contract&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The contracts are relatively simple, but whatever you put in them this is the interface for the &amp;ldquo;plugin&amp;rdquo; that will need to implement. In our case this is IPostCommitHandler :&lt;br /&gt;&lt;br /&gt;&lt;pre name="code"&gt;using System;&lt;br /&gt;&lt;br /&gt;namespace Subversion.Contracts&lt;br /&gt;{&lt;br /&gt; public interface IPostCommitHandler&lt;br /&gt; {&lt;br /&gt; void ExecuteCommand(PostCommitArgs a);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Pretty simple, essentially just a &amp;ldquo;do whatever you want&amp;rdquo; method that passes the arguments from subversion wrapped up in a simple class. See the attached zip if you want the guts of the subversion specific stuff. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: x-large;"&gt;The Plugin&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code"&gt;using System;&lt;br /&gt;using Subversion.Contracts;&lt;br /&gt;&lt;br /&gt;namespace Subversion.Plugins&lt;br /&gt;{&lt;br /&gt; public class ExecuteForAllCommits : IPostCommitHandler&lt;br /&gt; {&lt;br /&gt; #region IPostCommitHandler Members&lt;br /&gt;&lt;br /&gt; public void ExecuteCommand(PostCommitArgs a)&lt;br /&gt; {&lt;br /&gt; SendEmailNotification.SendEmail(a.Argument, a.Revision);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; #endregion&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Again, very simple and in this case we&amp;rsquo;re passing off the execution to a static class that again is not shown, but what gets executed isn&amp;rsquo;t all that important in this case.. simply fill in what you need. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: x-large;"&gt;The Dispatcher (Plugin Host)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code"&gt;using System;&lt;br /&gt;using System.Collections;&lt;br /&gt;using System.Text.RegularExpressions;&lt;br /&gt;using System.Configuration;&lt;br /&gt;using Subversion.Contracts;&lt;br /&gt;&lt;br /&gt;namespace Subversion.Dispatcher&lt;br /&gt;{&lt;br /&gt; ///&lt;br /&gt; /// &lt;summary&gt;&lt;br /&gt; /// Summary description for PostCommit.&lt;br /&gt; /// &lt;/summary&gt;&lt;br /&gt; class PostCommit&lt;br /&gt; {&lt;br /&gt;&lt;br /&gt; private static string subversionPath = ConfigurationSettings.AppSettings[&amp;ldquo;SubversionPath&amp;rdquo;];&lt;br /&gt;&lt;br /&gt; static void Main(string[] args)&lt;br /&gt; {&lt;br /&gt; SubversionRevision rev = ParseRevision(args);&lt;br /&gt; ArrayList commands = DispatchGlobalCommands(rev);&lt;br /&gt; DispatchNamedCommands(rev, commands);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private static SubversionRevision ParseRevision(string[] args)&lt;br /&gt; {&lt;br /&gt; SubversionRevision rev;&lt;br /&gt; if (args.Length == 2)&lt;br /&gt; {&lt;br /&gt; rev = new SubversionRevision(subversionPath, args[0], args[1]);&lt;br /&gt; }&lt;br /&gt; else&lt;br /&gt; {&lt;br /&gt; rev = new SubversionRevision(subversionPath, string.Empty, string.Empty);&lt;br /&gt; }&lt;br /&gt; return rev;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private static void DispatchNamedCommands(SubversionRevision rev, ArrayList commands)&lt;br /&gt; {&lt;br /&gt; string[] commitLines = rev.CommitLog.Split(Environment.NewLine[0]);&lt;br /&gt; // Handle Named Commands&lt;br /&gt; string registeredCommands = String.Join(&amp;quot;|&amp;quot;, (string[])commands.ToArray(typeof(string)));&lt;br /&gt; Regex CommandSearch = new Regex(@&amp;quot;(&amp;quot; + registeredCommands + @&amp;quot;)\s*:\s*(.+)?&amp;quot;, RegexOptions.IgnoreCase);&lt;br /&gt; foreach (string line in commitLines)&lt;br /&gt; {&lt;br /&gt; string lowerline = line.ToLower();&lt;br /&gt; for (Match Matches = CommandSearch.Match(lowerline); Matches.Success; Matches = Matches.NextMatch())&lt;br /&gt; {&lt;br /&gt; string handlerString = ConfigurationSettings.AppSettings[&amp;ldquo;command:&amp;rdquo; + Matches.Groups[1].ToString()];&lt;br /&gt; DispatchCommand(handlerString, Matches.Groups[2].ToString(), rev);&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private static ArrayList DispatchGlobalCommands(SubversionRevision rev)&lt;br /&gt; {&lt;br /&gt; // Handle global commands &lt;br /&gt; ArrayList commands = new ArrayList();&lt;br /&gt; for (int i = 0; i &amp;lt; ConfigurationSettings.AppSettings.Count; i++)&lt;br /&gt; {&lt;br /&gt; string key = ConfigurationSettings.AppSettings.GetKey(i);&lt;br /&gt; string val = ConfigurationSettings.AppSettings.Get(i);&lt;br /&gt; string[] cmdParts = key.Split(&amp;rsquo;:&amp;rsquo;);&lt;br /&gt; if (cmdParts.Length == 2 &amp;amp;&amp;amp; cmdParts[0] == &amp;ldquo;command&amp;rdquo;)&lt;br /&gt; {&lt;br /&gt; if (cmdParts[1].StartsWith(&amp;quot;&lt;em&gt;&amp;quot;))&lt;br /&gt; {&lt;br /&gt; DispatchCommand(val, cmdParts[1].Substring(cmdParts[1].IndexOf(&amp;quot;,&amp;quot;) + 1), rev);&lt;br /&gt; }&lt;br /&gt; else&lt;br /&gt; {&lt;br /&gt; commands.Add(cmdParts[1]);&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt; return commands;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; /// &lt;summary&gt;&lt;br /&gt; /// Call the appropriate method for the command name given with the argument given&lt;br /&gt; /// no processing of the argument happens here. &lt;br /&gt; /// &lt;/summary&gt;&lt;br /&gt;private static void DispatchCommand(string handlerString, string argument, SubversionRevision rev)&lt;br /&gt; {&lt;br /&gt; // We don&amp;rsquo;t want properly configured commands to stop working because of errors so trap&lt;br /&gt; // everything here&amp;hellip;&lt;br /&gt; try&lt;br /&gt; {&lt;br /&gt; if (handlerString != null &amp;amp;&amp;amp; handlerString.Length &amp;gt; 0)&lt;br /&gt; {&lt;br /&gt; string[] typeAndAssembly = handlerString.Split(&amp;rsquo;,&amp;rsquo;);&lt;br /&gt; if (typeAndAssembly.Length == 2)&lt;br /&gt; {&lt;br /&gt; System.Reflection.Assembly a = System.Reflection.Assembly.Load(typeAndAssembly[1]);&lt;br /&gt; System.Type t = a.GetType(typeAndAssembly[0], true);&lt;br /&gt; object handler = System.Activator.CreateInstance(t);&lt;br /&gt; if (handler is IPostCommitHandler)&lt;br /&gt; {&lt;br /&gt; ((IPostCommitHandler)handler).ExecuteCommand(new PostCommitArgs(argument,rev));&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt; catch (Exception) &lt;br /&gt; { //TODO: log errors &lt;br /&gt; }&lt;br /&gt; } &lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;There is some plumbing in this class that isn&amp;rsquo;t directly related to this post, but I&amp;rsquo;ve left it all anyway. Subversion will run this command every time a checkin is made, and the process ends and starts over again each time. This allows for some pretty simple handling of loaded assemblies and whatnot, if you have a longer running process or are dealing with some scale be cautious. ;-) &lt;br /&gt;&lt;br /&gt;The Main function has two jobs, parse and create the revision, then read the application configuration file and start issueing commands for the received revision. Commands are in two parts, those defined in config to be executed always (global commands) and those that are interpreted from the subversion commit log itself, parsed out and executed with arguments from the revision log. &lt;br /&gt;&lt;br /&gt;Here are some example commands defined in the config&lt;br /&gt;&lt;pre name="code"&gt;&amp;lt;!&amp;ndash; Commands &amp;ndash;&amp;gt;&lt;br /&gt;&amp;lt;add key=&amp;ldquo;command:&lt;/em&gt;,chris&amp;rdquo; value=&amp;ldquo;Subversion.Plugins.ExecuteForAllCommits,Subversion.Plugins&amp;rdquo; /&amp;gt;&lt;br /&gt;&amp;lt;add key=&amp;ldquo;command:&lt;em&gt;,check-ins&amp;rdquo; value=&amp;ldquo;Subversion.Plugins.ExecuteForAllCommits,Subversion.Plugins&amp;rdquo; /&amp;gt;&lt;br /&gt;&amp;lt;add key=&amp;ldquo;command:bug&amp;rdquo; value=&amp;ldquo;Subversion.Plugins.UpdateBugTracker,Subversion.Plugins&amp;rdquo; /&amp;gt;&lt;br /&gt;&amp;lt;add key=&amp;ldquo;command:cc&amp;rdquo; value=&amp;ldquo;Subversion.Plugins.SendEmailNotification,Subversion.Plugins&amp;rdquo; /&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt; in the key we have &amp;ldquo;command:[name]&amp;rdquo; signifies a command arriving in a revision where somewhere in the revision log we&amp;rsquo;ll see the command name followed by a colon, anything following the colon is then passed to the plugin as an argument. If the name is an asterisk then we simply execute for all, with an optional argument being passed to the plugin. (so the first example emails chris for all revisions, and the second emails an account named check-ins &lt;/li&gt;&lt;li&gt; the value portion here is what directs the program where to look for the appropriate plugin and class to execute. I copied the format I found in a web.config file which is to put the class name followed by the assembly name separated by a comma. &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;In retrospect if I were doing something similar again I&amp;rsquo;d probably create a better structured format rather than relying on all this string parsing&amp;hellip; but old code is what it is in this case. &lt;br /&gt;&lt;br /&gt;Finally we call DispatchCommand for each parsed out command which is the last piece of this old code that I&amp;rsquo;m attempting to document here for reuse. DispatchCommand will read the class name and assembly name, load the assembly name and attempt to instantiate the class/type named in order to call it using our IPostCommitHandler interface. &lt;br /&gt;&lt;br /&gt;There are a few ways to do this, and for this project I&amp;rsquo;m simply calling &amp;ldquo;&lt;a href="http://msdn.microsoft.com/en-us/library/system.reflection.assembly.load.aspx"&gt;System.Reflection.Assembly.Load&lt;/a&gt;&amp;rdquo; which relies on the fact that my plugins are located in my bin directory. I&amp;rsquo;ve also done this using a &amp;ldquo;plugin store&amp;rdquo; which is a fancy way to say I had a dynamic path configured that I could read my assemblies from. In this case you can use &lt;a href="http://msdn.microsoft.com/en-us/library/system.reflection.assembly.loadfile.aspx"&gt;LoadFile&lt;/a&gt; or &lt;a href="http://msdn.microsoft.com/en-us/library/system.reflection.assembly.loadfrom.aspx"&gt;LoadFrom&lt;/a&gt;, LoadFrom will load dependencies automatically while LoadFile loads just the assembly and will potentially load duplicate copies. (see the documentation) In order to get the dll&amp;rsquo;s in place for this project we just simply add a post build event like so&amp;hellip; &lt;br /&gt;&lt;br /&gt;&lt;pre name="code"&gt;copy $(TargetDir)&lt;/em&gt;.* $(SolutionDir)\Subversion.Dispatcher$(OutDir)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If after instantiating the named type from the loaded assembly we actually have an IPostCommitHandler then make the call! Done. &lt;br /&gt;&lt;br /&gt;&lt;pre name="code"&gt;System.Reflection.Assembly a = System.Reflection.Assembly.Load(typeAndAssembly[1]);&lt;br /&gt;System.Type t = a.GetType(typeAndAssembly[0], true);&lt;br /&gt;object handler = System.Activator.CreateInstance(t);&lt;br /&gt;if (handler is IPostCommitHandler)&lt;br /&gt;{&lt;br /&gt; ((IPostCommitHandler)handler).ExecuteCommand(new PostCommitArgs(argument,rev));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So that&amp;rsquo;s that. You can &lt;a href="http://chris.whitmore.googlepages.com/Subversion_PostCommit.zip"&gt;download the code here&lt;/a&gt; - it should basically work as is if you are looking for a shortcut to extending subversion with .NET. I was relatively lazy with getting this posted - so if you got this far, can use the code, and have problems with it leave a comment and I&amp;rsquo;ll try to help if I can.&lt;/p&gt;</description></item><item><title>Transcendent Man!</title><link>https://chriswhitmore.com/2009/05/06/transcendent-man/</link><pubDate>Wed, 06 May 2009 20:49:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2009/05/06/transcendent-man/</guid><description>&lt;p&gt;I read the singularity is near last year and really enjoyed it, despite a few misgivings for Kurzweil&amp;rsquo;s ego and some dubious use of statistics. One of the things I found myself really intrigued by was Kurweil himself and this movie looks like a fun look at the man and his ideas. &lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/ntY01qoIdus&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en&amp;feature=player_embedded&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/ntY01qoIdus&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en&amp;feature=player_embedded&amp;fs=1" type="application/x-shockwave-flash" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Do I believe him? Part of me wants to, definitely. The ultimate end-game of the singularity is fascinating and wondrous, but I actually found some of the more intermediate steps in his projections to be more fascinating. Maybe that&amp;rsquo;s just a factor of what I can relate to. One example of this was the idea that nano-technology will lead us to self-assembling products from base materials and an instruction set transmitted as information. So much of my life is already so information focused that the idea of being able to go 100% information based and the implications on how society is structured etc&amp;hellip; it&amp;rsquo;s mind numbingly cool. Try to imagine how much energy, time and effort we put into moving goods around this planet and how incredible it would be for all of that to end. &lt;br /&gt;&lt;br /&gt;Anyway, looking forward to renting this one when it becomes available.&lt;/p&gt;</description></item><item><title>From test spy to Verify() with Moq</title><link>https://chriswhitmore.com/2009/04/30/from-test-spy-to-verify-with-moq/</link><pubDate>Thu, 30 Apr 2009 13:12:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2009/04/30/from-test-spy-to-verify-with-moq/</guid><description>&lt;p&gt;&lt;a href="http://code.google.com/p/moq/"&gt;Moq&lt;/a&gt; is now my favorite unit testing framework for .NET, and a great poster child for the power of the lambda expression support added to C#. If you are not doing unit tests or Test Driven Development you should, and if you already are and have not checked out Moq, you should.&lt;br /&gt;&lt;br /&gt;My tests previous to Moq were using NMock, a very handy tool that looks like a lot of other mock frameworks. In order to setup a mock call you would write something similar to this :&lt;br /&gt;&lt;br /&gt;[Simple NMock example]&lt;br /&gt;&lt;pre name="code" id="code"&gt;Mockery mocks = new Mockery();&lt;br /&gt; IWidgetAdapter mockAdapter = mocks.NewMock&lt;iwidgetadapter&gt;();&lt;br /&gt;&lt;br /&gt; IList&lt;widget&gt; mockWidgets = new List&lt;widget&gt;();&lt;br /&gt; Widget mockWidget = new Widget();&lt;br /&gt; mockWidget.Name = &amp;ldquo;Mock Widget&amp;rdquo;;&lt;br /&gt; mockWidgets.Add(mockWidget);&lt;br /&gt;&lt;br /&gt; Stub.On(mockAdapter).Method(&amp;ldquo;LoadWidgets&amp;rdquo;).WithNoArguments().Will(Return.Value(mockWidgets));&lt;br /&gt; WidgetManager widgetManager = new WidgetManager(mockAdapter);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The ugliest thing in the expression above for me was the literal string that describes the method name that will be called. All of a sudden my fancy refactoring tools don&amp;rsquo;t quite reach all of my code and things become brittle. Sure you say, but I run these tests all the time! So it is caught right away anyway right? Yeah, but who wants to be searching and replacing these values after every refactor? Just does not feel right.&lt;br /&gt;&lt;br /&gt;Here&amp;rsquo;s the Moq equivelent:&lt;br /&gt;&lt;br /&gt;[simple Moq Example]&lt;br /&gt;&lt;pre name="code"&gt;IList&lt;widget&gt; mockWidgets = new List&lt;widget&gt;();&lt;br /&gt; Widget mockWidget = new Widget();&lt;br /&gt; mockWidget.Name = &amp;ldquo;Mock Widget&amp;rdquo;;&lt;br /&gt; mockWidgets.Add(mockWidget);&lt;br /&gt;&lt;br /&gt; Mock&lt;iwidgetadapter&gt; mockAdapter = new Mock&lt;iwidgetadapter&gt;();&lt;br /&gt; mockAdapter.Setup(cmd =&amp;gt; cmd.LoadWidgets(It.IsAny&lt;loadwidgetrequest&gt;())).Returns(mockWidgets);&lt;br /&gt; WidgetManager widgetManager = new WidgetManager(mockAdapter.Object);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;See that the &amp;ldquo;LoadWidgets&amp;rdquo; string disappears, and refactoring code now properly refactors tests right along with it, very very handy. Some find the need to add .Object when referencing the underlying mocked type annoying (on the call to WidgetManager) but personally I find this a small price to pay. &lt;br /&gt;&lt;br /&gt;When I first started using Moq a few weeks ago I didn&amp;rsquo;t go much beyond that example. Which speaks to Moq in that it is VERY easy to get started without much effort and more advanced features really don&amp;rsquo;t get in the way of the simple features.&lt;br /&gt;&lt;br /&gt;For a while I was able to do a lot of the testing I had in place by Asserting on values I either had access to or were being returned to me. In those cases where the values I needed were being returned to someone else (say a Service for example) I was in the habit of building stub classes (Test Spy in this case) to handle the outgoing data.&lt;br /&gt;&lt;br /&gt;So using the generic service as an example, and wanting to observe and Assert that I am sending the correct requests to that service my previous code would have looked something like this:&lt;br /&gt;&lt;br /&gt;[Test spy example]&lt;br /&gt;&lt;pre name="code"&gt;public class AuthenticationSpy : IAuthenticationService&lt;br /&gt;{&lt;br /&gt; #region Test Helpers&lt;br /&gt; public IList&lt;requestcontext&gt; ReceivedReqeustContexts = new List&lt;requestcontext&gt;();&lt;br /&gt; public AuthenticationResponse ExpectedResponse { get; set; }&lt;br /&gt; #endregion&lt;br /&gt;&lt;br /&gt; public AuthenticationResponse AuthenticateUser(AuthenticationRequest request)&lt;br /&gt; {&lt;br /&gt; return ExpectedResponse; &lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public AuthenticationResponse RenewAuthenticationTicket(RequestContext context)&lt;br /&gt; {&lt;br /&gt; this.ReceivedReqeustContexts.Add(context);&lt;br /&gt; return ExpectedResponse;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[TestMethod]&lt;br /&gt;public void RenewExpiredTicketTest()&lt;br /&gt;{&lt;br /&gt; AuthenticationSpy _authenticationMock = new AuthenticationSpy();&lt;br /&gt; Mock&lt;irespondingservice&gt; _respondingMock = new Mock&lt;irespondingservice&gt;();&lt;br /&gt;&lt;br /&gt; Mock&lt;iserviceproxyprovider&gt; mockServices = new Mock&lt;iserviceproxyprovider&gt;();&lt;br /&gt; mockServices.Setup(cmd =&amp;gt; cmd.GetAuthenticationService(It.IsAny&lt;string&gt;())).Returns(_authenticationMock);&lt;br /&gt; mockServices.Setup(cmd =&amp;gt; cmd.GetRespondingService(It.IsAny&lt;string&gt;())).Returns(_respondingMock.Object);&lt;br /&gt;&lt;br /&gt; ServiceWrapper.Current.ServiceProvider = mockServices.Object;&lt;br /&gt;&lt;br /&gt; _authenticationMock.ExpectedResponse = GetGoodAuthenticationResponse(DateTime.UtcNow.Add(ServiceWrapper.Current.TimerSleepTimeSpan.Subtract(TimeSpan.FromMinutes(1))));&lt;br /&gt;&lt;br /&gt; // initialize will call authenticate() in the service wrapper&lt;br /&gt; ServiceWrapper.Current.Initialize(&amp;ldquo;testing&amp;rdquo;, &amp;ldquo;Password1&amp;rdquo;, &amp;ldquo;http://auth&amp;rdquo;, &amp;ldquo;http://resp&amp;rdquo;);&lt;br /&gt;&lt;br /&gt; // now setup and call any method to trigger a renew of our now expired authentication ticket&lt;br /&gt; SetupCreateResponse(Guid.NewGuid());&lt;br /&gt; SurveyController.StartSurvey(new StartSurveyArgs());&lt;br /&gt;&lt;br /&gt; // confirm renew was actually called&lt;br /&gt; Assert.IsTrue(_authenticationMock.ReceivedReqeustContexts.Count == 1);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This works, and in some cases the control given to you with your test spy can be really helpful, but if I can avoid it I will every time. More classes and more code means more maintenance, even if it is in the test code. So I finally read the docs on the Verify() method on Moq objects and it is awesome. ;-) Here&amp;rsquo;s the same code handled with Moq properly and without the need for a whole new class imitating the authentication service. &lt;br /&gt;&lt;br /&gt;[using Verify example]&lt;br /&gt;&lt;pre name="code"&gt;[TestMethod]&lt;br /&gt;public void RenewExpiredTicketTest()&lt;br /&gt;{&lt;br /&gt; Mock&lt;iauthenticationservice&gt; _authenticationMock = new Mock&lt;iauthenticationservice&gt;();&lt;br /&gt; Mock&lt;irespondingservice&gt; _respondingMock = new Mock&lt;irespondingservice&gt;();&lt;br /&gt;&lt;br /&gt; Mock&lt;iserviceproxyprovider&gt; mockServices = new Mock&lt;iserviceproxyprovider&gt;();&lt;br /&gt; mockServices.Setup(cmd =&amp;gt; cmd.GetAuthenticationService(It.IsAny&lt;string&gt;())).Returns(_authenticationMock.Object);&lt;br /&gt; mockServices.Setup(cmd =&amp;gt; cmd.GetRespondingService(It.IsAny&lt;string&gt;())).Returns(_respondingMock.Object);&lt;br /&gt;&lt;br /&gt; ServiceWrapper.Current.ServiceProvider = mockServices.Object;&lt;br /&gt;&lt;br /&gt; _authenticationMock.Setup(cmd =&amp;gt; cmd.AuthenticateUser(It.IsAny&lt;authenticationrequest&gt;()))&lt;br /&gt; .Returns(GetGoodAuthenticationResponse(DateTime.UtcNow.Add(ServiceWrapper.Current.TimerSleepTimeSpan.Subtract(TimeSpan.FromMinutes(1)))));&lt;br /&gt;&lt;br /&gt; // initialize will call authenticate() in the service wrapper&lt;br /&gt; ServiceWrapper.Current.Initialize(&amp;ldquo;testing&amp;rdquo;, &amp;ldquo;Password1&amp;rdquo;, &amp;ldquo;http://auth&amp;rdquo;, &amp;ldquo;http://resp&amp;rdquo;);&lt;br /&gt; &lt;br /&gt; // now setup and call any method to trigger a renew of our now expired authentication ticket&lt;br /&gt; SetupCreateResponse(Guid.NewGuid());&lt;br /&gt; SurveyController.StartSurvey(new StartSurveyArgs());&lt;br /&gt;&lt;br /&gt; // confirm renew was actually called&lt;br /&gt; _authenticationMock.Verify(cmd =&amp;gt; cmd.RenewAuthenticationTicket(It.IsAny&lt;requestcontext&gt;()), Times.AtLeastOnce());&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Check out &lt;a href="http://www.codethinked.com/post/2009/03/10/Beginning-Mocking-With-Moq-3-Part-2.aspx"&gt;Part 2&lt;/a&gt; in the 4 part series &amp;ldquo;&lt;a href="http://www.codethinked.com/post/2009/03/13/Beginning-Mocking-With-Moq-3-Part-1.aspx"&gt;Beginning Mocking with Moq 3&lt;/a&gt; &amp;rdquo; gives a short description of how Validate works.&lt;br /&gt;&lt;br /&gt;Not bad eh? Again the power of the lambda expression here jumps out at you. Full intellisense and compiler support for describing exactly what you expect that method to receive. The &amp;ldquo;It&amp;rdquo; class allows for no description &amp;ldquo;It.IsAny&amp;lt;t&amp;gt;()&amp;rdquo; or very precise description as above. The &amp;ldquo;Times&amp;rdquo; check also allows you to narrow  Significant savings in code and maintenance and actually using the testing framework as intended (imagine that) ! My only slight annoyance so far is in having to keep count of the number of times a method has been called in order to check that the last piece of code actually resulted in a call and not some code way earlier.&lt;/p&gt;</description></item><item><title>silverlight 3 - after the high</title><link>https://chriswhitmore.com/2009/03/25/silverlight-3-after-the-high/</link><pubDate>Wed, 25 Mar 2009 09:40:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2009/03/25/silverlight-3-after-the-high/</guid><description>&lt;p&gt;I failed to convince my manager at work that sending me and a few members of my team to MIX was a worthwhile expense in this economy. So instead I spent a couple days this sprint with &lt;a href="http://live.visitmix.com/"&gt;&lt;a href="http://live.visitmix.com/"&gt;http://live.visitmix.com/&lt;/a&gt;&lt;/a&gt; on one screen and visual studio in the other. I have to say, Microsoft did an amazing job with MIX in terms of getting me excited and having me &amp;ldquo;tuned in&amp;rdquo;. If you are at all interested in web development on the Microsoft stack and  haven&amp;rsquo;t checked out the keynote I&amp;rsquo;d recommend it. I really enjoyed Buxton&amp;rsquo;s presentation and Guthrie was amusing. &lt;br /&gt;&lt;br /&gt;So now that it&amp;rsquo;s been a week, and &amp;ldquo;&lt;a href="http://weblogs.asp.net/scottgu/"&gt;the Gu&lt;/a&gt;&amp;rdquo; and all those dancing flashy lights are no longer influencing my opinion&amp;hellip; I&amp;rsquo;m STILL excited about Silverlight 3. Sadly the development tools can&amp;rsquo;t be run in parallel with Silverlight 2 and we&amp;rsquo;re near the end of our sprint so can&amp;rsquo;t afford the risk. Which is really too bad because one of the things our current application is leveraging is the wcf duplex polling module. A lovely little COMET like implementation for server push. The version of the duplex polling that made it into the Silverlight 2 toolkit was a little more bare than your typical Microsoft module. And while it works pretty well, it leaves a lot of plumbing code in the hands of the programmer, specifically a lot of asynchronous channel handling code that is  a bit of pain to deal with. (though a bit educational too) Anyways, this is one of those areas that Microsoft is improving on in Silverlight 3, and one of those things I&amp;rsquo;m excited about. Right next to the &lt;b&gt;simpler duplex polling usage&lt;/b&gt; for me is the introduction of &lt;b&gt;binary serialization for web services&lt;/b&gt; (including duplex!). When comparing to Flex and the myriad of tools and options for using &lt;a href="http://en.wikipedia.org/wiki/Action_Message_Format"&gt;AMF &lt;/a&gt;Silverlight was really behind the ball on this one. When we eventually decided to build our tool in Silverlight as opposed to Flex we basically committed ourselves to rolling our own binary serialization.  I&amp;rsquo;m very happy we&amp;rsquo;re not going to have to follow through on that.  Read more from the web services team :&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Calibri&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 11.0pt; mso-ansi-language: EN-US; mso-bidi-font-family: &amp;quot;Times New Roman&amp;quot;; mso-bidi-language: AR-SA; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin;"&gt;&lt;a href="http://blogs.msdn.com/silverlightws/archive/2009/03/20/what-s-new-with-web-services-in-silverlight-3-beta.aspx"&gt;&lt;a href="http://blogs.msdn.com/silverlightws/archive/2009/03/20/what-s-new-with-web-services-in-silverlight-3-beta.aspx"&gt;http://blogs.msdn.com/silverlightws/archive/2009/03/20/what-s-new-with-web-services-in-silverlight-3-beta.aspx&lt;/a&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Calibri; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Calibri; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px;"&gt;Another great addition in the realm of things-that-were-annoying-but-possible-and-already-in-flex is the new navigation uri support within Silverlight 3. Check out Tim Heuer&amp;rsquo;s typically &lt;a href="http://timheuer.com/blog/archive/2009/03/18/silverlight-3-whats-new-a-guide.aspx#nav"&gt;great post on all the silverlight changes&lt;/a&gt; here.  (link specifically to the nav)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Calibri; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Calibri; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px;"&gt;Lastly to round out my list of really exciting enhancements to SL3 are the network monitoring API, which gives developers events to subscribe to detect when the network is and isn&amp;rsquo;t present - as well as assembly caching which is huge, allowing Silverlight to cache assemblies  like the toolkit so that once a user has been exposed to it they don&amp;rsquo;t necessarily have to download it again until a new version is required. This in turns makes XAP&amp;rsquo;s smaller which is always a good thing. &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Calibri; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Calibri; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px;"&gt;So to summarize, I think the top five features from the slew of enhancements that I&amp;rsquo;m looking forward to are : &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-family: Calibri; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px;"&gt;Binary Serialization&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: Calibri; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px;"&gt;Duplex  polling enhancements&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: Calibri; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px;"&gt;Network detection API&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: Calibri; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px;"&gt;Assembly Caching&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: Calibri; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px;"&gt;Navigation and Deep Linking suport&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Calibri; font-size: 15px;"&gt;My perspective on Silverlight is very biased to the needs of our application of course. And our application will live and die on the network, with &lt;b&gt;performance &lt;/b&gt;being a top concern in everything we do.  Controls are nice but we can buy those from vendors like Telerik, animation and media are cool for demos but likely won&amp;rsquo;t do much for us in the short term. The out of browser story is huge, but again with a SaaS app that relies on the network we don&amp;rsquo;t envision a whole lot of offline work happening in the early versions of our app. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Calibri; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Calibri; font-size: medium;"&gt;&lt;span class="Apple-style-span" style="font-size: 15px;"&gt;Honorable mentions for features go to GPU acceleration (performance) and the SaveFileDialog (control) and Expression Blend 3. I don&amp;rsquo;t use Blend much myself, but the current version is a huge pain for our team. Maybe more on that in a separate post.  &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description></item><item><title>decision making : flip a coin then check your gut</title><link>https://chriswhitmore.com/2009/02/18/decision-making-flip-a-coin-then-check-your-gut/</link><pubDate>Wed, 18 Feb 2009 15:53:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2009/02/18/decision-making-flip-a-coin-then-check-your-gut/</guid><description>&lt;p&gt;I once heard an interesting anecdote about how to make a difficult decision between two paths. When you find yourself spinning, alternating between one choice and then the other, it can be helpful to simply assign each choice &amp;ldquo;heads&amp;rdquo; or &amp;ldquo;tails&amp;rdquo; and flip a coin. When you reveal what side the coin landed on pay attention to your emotional reaction&amp;hellip; are you relieved or are you disappointed?  Try it sometime, it really can work.&lt;br /&gt;&lt;br /&gt;I recently spent about three weeks or so doing an in-depth analysis of Adobe Flex vs Microsoft Silverlight for an enterprise application and I really feel like I ultimately decided via the coin flip method (without actually flipping the coin). Our company is about to embark on a new product aimed at the enterprise that will require levels of functionality and control that Ajax alone can not provide. We are essentially looking to take a workflow that has been heavily dominated by Word and Outlook and drag it into the future with real-time collaborative tools in the spirit of Google Docs.&lt;br /&gt;&lt;br /&gt;I ended up choosing Silverlight, despite the potential risk adoption may pose. At the end of the day we believe our target market will be willing to accept the Silverlight install process, and that the underlying engine (.net) provides far more robustness for building the kind of application we&amp;rsquo;re looking to build. Honestly this is a whole other post, but the nail in the coffin for Flex ended up being the lack of threading support for developers. On nearly every other level the two were neck and neck, with very subjective &amp;ldquo;wins&amp;rdquo; for either and Flash being the clear winner when it comes to adoption etc.&lt;br /&gt;&lt;br /&gt;What&amp;rsquo;s interesting though is that my first choice was Flex. After weeks of agonizing I decided we needed to build this thing in Flex, working around the lack of threading where necessary and going with the safe route of next to zero adoption barriers. It only took a weekend after making that decision to flip-flop. I was supposed to be making the call as if this were my company on the line, and with a clear vision of the unknowable future&amp;hellip; at the end of the day though taking the safe and compromised route just didn&amp;rsquo;t feel right. I could see the complexity of our application snowballing in the future, I could see the legacy of the flash runtime catching up with us, I could see a competitor choosing to build their offering in Silverlight and spanking us in the next year. Making the decision from a technical standpoint the only winner was Silverlight, if the business deemed the adoption risk too great then fine we could do Flex, I was prepared for either.&lt;br /&gt;&lt;br /&gt;My proverbial flip of the coin had basically taken those three weeks of opinions and research and testimonials and flame wars had all gelled together once I had made an actual commitment to choosing Flex. It was only then that my gut told me what I needed to know and I have not looked back from Silverlight since.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: -webkit-monospace; font-size: small;"&gt;&lt;span style="font-size: 12px; line-height: 15px; white-space: pre-wrap;"&gt;&lt;span style="font-family: 'Times New Roman'; font-size: medium;"&gt;&lt;span style="font-size: 16px; line-height: normal; white-space: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description></item><item><title>Flex data services limitations (FlexBuilder generated wsdl code sucks)</title><link>https://chriswhitmore.com/2009/02/12/flex-data-services-limitations-flexbuilder-generated-wsdl-code-sucks/</link><pubDate>Thu, 12 Feb 2009 08:54:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2009/02/12/flex-data-services-limitations-flexbuilder-generated-wsdl-code-sucks/</guid><description>&lt;p&gt;The post saved me a ton of time. It&amp;rsquo;s a bit embarrassing for Adobe in my mind to ship something this buggy. I was seriously running into these issues within an hour of trying to connect Flex to our .NET Soap based services.&lt;br /&gt;&lt;blockquote&gt;&amp;ldquo;MyMethod can’t return an object of with the type name MyMethodResult.&amp;quot;&lt;/blockquote&gt;You&amp;rsquo;re fracking kidding me right?  Wow. (and there are more along these lines)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lukesh.wordpress.com/2008/11/24/very-important-limitations-of-flex-data-services/"&gt;&lt;a href="http://lukesh.wordpress.com/2008/11/24/very-important-limitations-of-flex-data-services/"&gt;http://lukesh.wordpress.com/2008/11/24/very-important-limitations-of-flex-data-services/&lt;/a&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;After fighting with the above and other bugs I was rewriting a lot of the generated code from FlexBuilder and it was just pointless. And sure, generated code isn&amp;rsquo;t the greatest to rely on anyway, but give me a break. In the end I used &lt;a href="http://www.themidnightcoders.com/products/weborb-for-net/overview.html"&gt;the WebORB presentation server&lt;/a&gt; to handle the communication to our .NET code, as well as for generation of the initial proxy classes for the client and I have to say it was an excellent experience compared to the crap built into FlexBuilder.&lt;/p&gt;</description></item><item><title>QWERTY Myth and the entrenchment of Flash</title><link>https://chriswhitmore.com/2009/01/31/qwerty-myth-and-the-entrenchment-of-flash/</link><pubDate>Sat, 31 Jan 2009 19:54:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2009/01/31/qwerty-myth-and-the-entrenchment-of-flash/</guid><description>&lt;p&gt;This is a great article about the myth of how the best technology doesn&amp;rsquo;t necessarily win. Granted, sometimes the best technology does not win, but there is a persistent and pervasive sense that the populous often chooses the &amp;ldquo;VHS&amp;rdquo; over the far superior alternative. The article addresses the VHS vs Beta debate directly as well as the victory over Dvorak by QWERTY. To encourage you to read the original I won&amp;rsquo;t reveal the clever arguments made. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.reason.com/news/show/29944.html"&gt;&lt;a href="http://www.reason.com/news/show/29944.html"&gt;http://www.reason.com/news/show/29944.html&lt;/a&gt;&lt;/a&gt;   (Read Me!) &lt;br /&gt;&lt;br /&gt;I&amp;rsquo;m posting this because there seems to be a real sense of fait accompli when it comes to the Flash vs Silverlight debate. Critical mass has already been acheived, why would content producers or development shops choose to target any other platform than the Flash runtime when users have clearly already made their choice? How could Beta possibly make a resurgence against an already entrenched VHS? It would take an entire round of evolution before DVD would come along and supplant the status quo. There are a couple reasons why this article has relevance for Silverlight, and why the VHS / Beta argument doesn&amp;rsquo;t hold water. &lt;br /&gt;&lt;ol&gt;&lt;li&gt;Flash vs Silverlight is about a producer investment in technology NOT a consumer investment. Machines are powerful enough, and installations simple enough that the relative cost of owning both technologies is nothing like owning two peices of hardware. &lt;/li&gt; &lt;ol&gt;&lt;li&gt;If there is a competitive advantage for a producer to be gained via a specific technology they will use it. Any differentiators in a competitive field like software has a high potential of making a return. This is a very different decision process than it is for consumers. &lt;/li&gt;&lt;li&gt;Consumers don&amp;rsquo;t really care or even know which technology is driving their rich content. They care that it &amp;ldquo;just works&amp;rdquo; (like flash based video in comparison to WMP or Quicktime) and that the functionality they desire is there. Without a right-click most users won&amp;rsquo;t even realize which is which behind the curtain once they have both installed. &lt;/li&gt;&lt;li&gt;&amp;ldquo;Owning&amp;rdquo; everyone (high adoption) is really not that big a deal when your competition can also have 100% adoption at the same time. This is not like choosing a computer or an operating system. Only Microsoft can prevent themselves from achieving their penetration goals.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Better technology does win. I&amp;rsquo;m not saying that Silverlight is necessarily the better technology right now, Flash maintains an edge on some specific rendering speeds it appears, and their designer tools are clearly better&amp;hellip; but Silverlight has the benefit of coming at this with second mover advantage. They didn&amp;rsquo;t start from scratch, they built out a proven technology (.NET) into new ground by largely copying and improving on the entrenched technology. (sure looks copied from my perspective but that&amp;rsquo;s a different post) The .NET runtime, threading, compiled/managed code and the lack of legacy in Silverlight will all combine to produce demonstrations of browser based technology that will be extremely difficult and expensive to reproduce on the Flash runtime. &lt;/li&gt;&lt;li&gt;Silverlight does not have to &amp;ldquo;kill&amp;rdquo; Flash to win, it only needs to join Flash in the 90% adoption numbers to be a great success. &lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;I like both technologies by the way, I&amp;rsquo;m just entertained by some of the almost religious like statements on those on the Flash side that sound a lot like any attempt to improve or even add to the status quo is a total waste of time. (or somehow an affront to their own efforts)&lt;/p&gt;</description></item><item><title>Silverlight controls</title><link>https://chriswhitmore.com/2009/01/28/silverlight-controls/</link><pubDate>Wed, 28 Jan 2009 16:59:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2009/01/28/silverlight-controls/</guid><description>&lt;p&gt;Silverlight 2 may not have the control set that Flex developers are used to seeing out of the box but there are a significant number of control vendors who are stepping up to the plate to fill the void. It seems as though Microsoft&amp;rsquo;s strategy has been to get the Silverlight 2 runtime out as quickly as possible (and as lean as possible) always knowing that this type of extension to the framework would exist.&lt;br /&gt;&lt;br /&gt;I do still hope to see Microsoft push a little further in controls that are downloaded once and only once with the framework itself thereby making our applications leaner - but it&amp;rsquo;s a pretty serious tradeoff until the runtime has the kind of penetration that Flash enjoys.&lt;br /&gt;&lt;br /&gt;Anyway, here&amp;rsquo;s a nice post from Tim Heuer that does a good round up of where to find those missing controls.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://timheuer.com/blog/archive/2009/01/28/comprehensive-list-of-silverlight-controls.aspx"&gt;&lt;a href="http://timheuer.com/blog/archive/2009/01/28/comprehensive-list-of-silverlight-controls.aspx"&gt;http://timheuer.com/blog/archive/2009/01/28/comprehensive-list-of-silverlight-controls.aspx&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>1 TB drive won't format using Disk Utility</title><link>https://chriswhitmore.com/2008/12/31/1-tb-drive-wont-format-using-disk-utility/</link><pubDate>Wed, 31 Dec 2008 16:43:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/12/31/1-tb-drive-wont-format-using-disk-utility/</guid><description>&lt;p&gt;I just bought a 1TB external HD, the &amp;ldquo;Maxtor OneTouch 4 Plus&amp;rdquo; this weekend on sale at London Drugs. A bit of an impulse purchase but I&amp;rsquo;ve been digiizing all of our dvd&amp;rsquo;s lately into iTunes and had completely run out of space&amp;hellip;&lt;br /&gt;&lt;br /&gt;The drive has a bunch of automated backup features I&amp;rsquo;ll never use, so I skipped all the software and went to use the drive directly from Mac OS X.  First step here is to convert the format of the drive from it&amp;rsquo;s default of NTFS to something Mac can natively use. My impulse was to simply &amp;ldquo;format&amp;rdquo; and continue but unfortunately every time I tried the format disk utility would abort with nothing useful showing in the console logs. I went through this a few times with different file system settings and nothing worked. (See this &lt;a href="http://arstechnica.com/journals/apple.ars/2007/05/18/pick-the-right-file-system-for-your-macs-internal-or-external-storage"&gt;ArsTechnica link for how to choose your filesystem&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;Odd.&lt;br /&gt;&lt;br /&gt;I then tried to partition the drive - and two partitions or more would all of a sudden work. Again odd, but I didn&amp;rsquo;t want more than one partition in this case, but reverting back to one partition would cause the same problem all over again.  I resorted to Google at this point and came across this very useful although somewhat poorly formatted post on Seagate forums. (seems to be a generic problem with  disk utility)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://forums.seagate.com/stx/board/message?board.id=freeagent&amp;amp;thread.id=1062"&gt;&lt;a href="http://forums.seagate.com/stx/board/message?board.id=freeagent&amp;amp;amp;thread.id=1062"&gt;http://forums.seagate.com/stx/board/message?board.id=freeagent&amp;amp;amp;thread.id=1062&lt;/a&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The gist of the problem being that the default partition table format needs to be changed to GUID. You can apparently only acheive this by partitioning (in this case to two partitions) so you can change the setting for partition table format and then partitioning again back to one partition with the new partition table format intact. Annoying but easily worked around once you stumble on the right answer.&lt;br /&gt;&lt;br /&gt;Note this issue is actually new to 10.5.* and you can also solve the problem by formatting from an older version of Mac OS X (from a boot CD for example).&lt;/p&gt;</description></item><item><title>FlexBuilder 3 First Impressions</title><link>https://chriswhitmore.com/2008/12/21/flexbuilder-3-first-impressions/</link><pubDate>Sun, 21 Dec 2008 21:27:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/12/21/flexbuilder-3-first-impressions/</guid><description>&lt;p&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Where we&amp;rsquo;re coming from&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;So at the beginning of the year I was tasked with evaluating a number of technologies for &lt;a href="http://en.wikipedia.org/wiki/Rich_Internet_application"&gt;RIA&lt;/a&gt; development for the next evolution of my company&amp;rsquo;s product. Up to this point we had been relying extensively on ASP.NET forms with a traditional post-back model that was responsible for a lot of wasted time and bandwidth. We&amp;rsquo;ve leveraged a lot of Ajax in the past few years, starting with simple fixes like trees and list based controls that use load on demand and going all the way up to full fledged single page applications that consumed purely services.&lt;br /&gt;&lt;br /&gt;This has worked, but the cost is overwhelming for a development team of our size and makeup. We hire smart generalists for the most part, favoring developers with C++/Java/C# backgrounds. Some of our developers have acquired some deeper skills on the client side, but where possible we attempt to leverage control vendors like &lt;a href="http://telerik.com/"&gt;Telerik &lt;/a&gt; and &lt;a href="http://componentart.com/"&gt;ComponentArt &lt;/a&gt; as much as possible. They do an excellent job of hiding some of the complexity involved in cross browser web interfaces, but you will inevitably have to &amp;ldquo;hit the metal&amp;rdquo; and get your hands dirty. Relying on third parties also removes a lot of the control needed to do things the way you need them done. Regardless despite being a huge fan of the &lt;a href="http://docs.google.com/"&gt;&lt;a href="http://docs.google.com"&gt;http://docs.google.com&lt;/a&gt;&lt;/a&gt; suite of tools, I have witnessed far too much ugliness in our organization with supporting multiple browsers (including having to support IE 6) and pushing the limits of complicated UI in the browser. As the size of the DOM increases and the size of our data sets increase we see wild variance in client performance with respect to things like drag and drop. I know it can be done, I know we are not at the limit yet, but seriously this is not pragmatic for our software and our market and our developers. I am a big fan of the view that &lt;a href="http://www.google.ca/search?hl=en&amp;amp;q=javascript+is+the+assembly+language+of+web&amp;amp;btnG=Search&amp;amp;meta="&gt;JavaScript is becomming the assembly of the web&lt;/a&gt;, those who do this shit well, do it well by lifting themselves out of the muck with good abstractions &lt;a href="http://code.google.com/webtoolkit/"&gt;like GWT&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;One thing I think should add here in defense of Ajax though; UI design plays a really important role in the effectiveness of the DHTML approach and honestly I believe part of our problem has been designing a far richer interface than we could afford in the technology we were leveraging at the time. Take a close look at Google&amp;rsquo;s lack of decoration, images etc. These things certainly matter.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Next steps&amp;hellip; evaluation&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Anyway, I&amp;rsquo;m getting off topic as usual. In the beginning of 2008 my feature matrix analysis really narrowed our options from about a dozen technologies (including XUL, ActiveX, Applets, JavaFX, Silverlight, ClickOnce, Ajax, Flex) down to three. Silverlight, Flex or Ajax. At the time of my evaluation Flex was at version 2, JavaFX was vapourware and Silverlight2 was in Beta. Given that we are a .NET shop and already have the C# programmers, the Silverlight option was looking like it was going to cleanly win out over Flex. Ajax was honestly only at the table still because we needed to justify our position and show we clearly evaluated all our options. Flex was seen as less desirable due to being based on ECMAScript and having to retool and retrain.&lt;br /&gt;&lt;br /&gt;For the most part we&amp;rsquo;ve seen this as two relatively equivalent technologies with different stories for the developers. While there are important differences between how code is delivered and executed in Flex vs Silverlight, but at a high level we believe technically we can deliver our application in either technology very effectively. We prefer to keep working in C#, but the limited penetration of Silverlight is a serious risk for an application delivered in a SaaS model. That single fact has transformed the whole exercise into largely a business decision.  I don&amp;rsquo;t doubt Microsoft will be able to push their offering significantly, but I would not bet money on where they will be in 1 year. (Windows Media Player STILL doesn&amp;rsquo;t equal flash in penetration)&lt;br /&gt;&lt;br /&gt;Tool support however remains something that is extremely important to developers, and is one of those things Microsoft often trots out in arguing the superiority of their platform. We swallowed that line pretty easily at first, knowing that under the hood all the code written for Flex is just a variation of ECMAScript (JavaScript) is enough to scare us off. How can you acheive the refactorability and tool support provided by current and future versions of Visual Studio with a loosely typed language like ActionScript?&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Trying it out&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;This week I downloaded FlexBuilder3 after one of our senior executives setup a call for us with Adobe evangelists to get more details on why to go with Flex. Again the motivation for this coming back to penetration and wanting to ensure we are making the right decision for what will become a million plus dollar iniitiave to re-engineer. I wanted to get some hands on time with the latest version of FlexBuilder (3) that had come out since our initial research.&lt;br /&gt;&lt;br /&gt;I was immediately surprised by the leaps Flex had taken since I last really dived in. I&amp;rsquo;ll admit there was some bias here though as I am also a huge fan of Eclipse, so the fact that FlexBuilder is built on Eclipse is in my mind a huge win. (not new btw)&lt;br /&gt;&lt;br /&gt;The effort in actually building an application that connected to our existing .NET web services was embarrassingly trivial. FlexBuilder has a simple tool for generating and managing proxy classes to represent your web services. So after literally pasting a url into a wizard I had code for talking to our .NET SOAP based web services. (seemed to only support SOAP 1_0 not 1_2)  I then got started with the Form Designer and had a simple application talking to our backend in under an hour even counting the little things that tripped me up like where to add my event handlers which wasn&amp;rsquo;t immediately apparent. (too reliant on double clicking controls apparently ;-)   hint : &amp;lt;mx:Script&amp;gt; tags and dom style event callouts)&lt;br /&gt;&lt;br /&gt;The concept of states in Flex and the ease with which I was able to create a number of them in the designer and bind those to a dropdown for switching between them was pretty eye opening. A state in Flex is defined by the differences between your main UI (or just another state) and the state you wish to have/be in. The IDE allows you to visually manage these states and then visually modify each one to represent application states. I don&amp;rsquo;t have an early sense of whether this actually scales for complex applications, but at first glance it&amp;rsquo;s very cool. (Think hierarchical state machine)  Couple this with the &lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=databinding_2.html"&gt;data binding model&lt;/a&gt; and you have some very effective UI management tools at your disposal. Maybe this only looks cool coming from our antiquated asp.net approaches, but this stuff is exciting. (Silverlight/WPF have the same capability, maybe even a little more advanced but with more overhead in my opinion) Having your model drive all changes is so much more manageable,  scalable&amp;hellip; and just correct than having explicit assignments in page PreRender methods that set visibility based on the state of that model. Barf.&lt;br /&gt;&lt;br /&gt;The control toolkit out of the box with Flex is also extremely impressive. Check out this post for a list of all the &lt;a href="http://somatose.com/2008/12/flexbuilder-3-controls.html"&gt;FlexBuilder 3 Controls included out of the box&lt;/a&gt; . For now at least this control set will mean being highly more productive in the early stages of development than if we were either having to roll our own or rely on third party vendors. And of course you can roll your own in both Silverlight and Flex and each can be just about anything imaginable.&lt;br /&gt;&lt;br /&gt;So I&amp;rsquo;m sold, at least sold on the fact that Flex deserves considerably more attention than what we had previously given it. I&amp;rsquo;ve bought the &amp;ldquo;Flex 3 Cookbook&amp;rdquo;, and &amp;ldquo;Adobe Flex 3 Training From the Source&amp;rdquo; and I&amp;rsquo;m intending on spending at least some of this Christmas holiday catching up on just what&amp;rsquo;s possible with that silly little flash technology.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/p&gt;</description></item><item><title>FlexBuilder 3 Controls</title><link>https://chriswhitmore.com/2008/12/17/flexbuilder-3-controls/</link><pubDate>Wed, 17 Dec 2008 15:17:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/12/17/flexbuilder-3-controls/</guid><description>&lt;p&gt;Controls included with FlexBuilder 3 out of the box below&amp;hellip; &lt;a href="http://flex.org/software/components"&gt;check out some third party components here&lt;/a&gt; .&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Notes will be updated as I actually get a chance to put some of these to use.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;table border="1" cellpadding="1" cellspacing="0" style="border-color: #ccc;"&gt;&lt;tbody&gt;&lt;tr&gt; &lt;th colspan="2"&gt;FlexBuilder 3 Controls &lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;Control Name &lt;/th&gt; &lt;th&gt;Notes &lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=advdatagrid_02.html"&gt;AdvancedDataGrid &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;em&gt;Professional version only&lt;/em&gt;&lt;br /&gt;+ multi column sorting&lt;br /&gt;+ grouping&lt;br /&gt;+ tree view&lt;br /&gt;+ printing support&lt;br /&gt;&amp;ndash; Still no paging support out of the box&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=controls_19.html"&gt;AlertControl &lt;/a&gt; &lt;/td&gt;&lt;td&gt;not sure how this gets grouped with these other controls as it is not an explicit control but a static method &amp;ldquo;show()&amp;rdquo; which can be used from where ever. &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=controls_04.html"&gt;Button &lt;/a&gt; &lt;/td&gt;&lt;td&gt;check out the FlexLib CanvasButton for a more flexible option&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=controls_09.html"&gt;CheckBox &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=controls_18.html"&gt;ColorPicker &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=dpcontrols_5.html"&gt;ComboBox &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=dpcontrols_6.html"&gt;DataGrid &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;a href="http://gurufaction.blogspot.com/2007/02/flex-datagrid-paging-example-with.html"&gt;See this article for some hints on implementing paging&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=controls_12.html"&gt;DateChooser &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=controls_12.html"&gt;DateField &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=controls_14.html"&gt;HSlider &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=dpcontrols_3.html"&gt;HorizontalList &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=controls_16.html"&gt;Image &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=textcontrols_06.html"&gt;Label &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=dpcontrols_2.html"&gt;List &lt;/a&gt; &lt;/td&gt;&lt;td&gt;very fast and flexible, lots of issues with scrolling but workable&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=controls_13.html"&gt;LinkButton&lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=controls_11.html"&gt;NumericStepper &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;img border="0" src="https://chriswhitmore.com/assets/numberStepper.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=olapdatagrid_1.html"&gt;OLAPDataGrid &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;em&gt;Professional version only&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=controls_05.html"&gt;PopUpButton &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=menucontrols_7.html"&gt;PopUpMenuButton &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=controls_20.html"&gt;ProgressBar &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=controls_10.html"&gt;RadioButton &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=controls_10.html"&gt;RadioButtonGroup &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Repeater&lt;/td&gt;&lt;td&gt;SLOOOW when binding to many objects, look at List based controls instead&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=textcontrols_10.html"&gt;RichTextEditor &lt;/a&gt; &lt;/td&gt;&lt;td&gt;Limited html formatting, seems to work ok&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=controls_15.html"&gt;SWFLoader &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=textcontrols_08.html"&gt;Text &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=textcontrols_09.html"&gt;TextArea &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=textcontrols_07.html"&gt;TextInput &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=dpcontrols_4.html"&gt;TileList &lt;/a&gt; &lt;/td&gt;&lt;td&gt;see list, very fast control but takes a bit more work for smooth work&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=dpcontrols_8.html"&gt;Tree &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=controls_14.html"&gt;VSlider &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=controls_17.html"&gt;VideoDisplay &lt;/a&gt; &lt;/td&gt;&lt;td&gt;FLV based video player with simple cue and playback control &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt; &lt;th colspan="2"&gt;FlexBuilder 3 Chart Controls &lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=charts_types_02.html"&gt;AreaChart &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=charts_types_03.html"&gt;BarChart &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=charts_types_04.html"&gt;BubbleChart &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=charts_types_05.html"&gt;CandleStickChart &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=charts_types_06.html"&gt;ColumnChart &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=charts_types_07.html"&gt;HLOCChart &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=charts_displayingdata_12.html"&gt;Legend &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=charts_types_08.html"&gt;LineChart &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=charts_types_09.html"&gt;PieChart &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=charts_types_10.html"&gt;PlotChart &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt; &lt;th colspan="2"&gt;FlexBuilder 3 Navigation Controls &lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=navigators_5.html"&gt;Accordion &lt;/a&gt; &lt;/td&gt;&lt;td&gt;Great control, but needed to go custom almost immediately ( see FlexLib for custom header) &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=controls_06.html"&gt;ButtonBar &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=controls_07.html"&gt;LinkBar &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=menucontrols_5.html"&gt;Menu &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=menucontrols_6.html"&gt;MenuBar &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=controls_08.html"&gt;TabBar &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=navigators_4.html"&gt;TabNavigator &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=controls_06.html"&gt;ToggleButtonBar &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=navigators_3.html"&gt;ViewStack &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt; &lt;th colspan="2"&gt;FlexBuilder 3 Layout Controls &lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=layouts_06.html"&gt;ApplicationControlBar &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=layouts_03.html"&gt;Canvas &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=layouts_05.html"&gt;ControlBar &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=layouts_08.html"&gt;Form &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=layouts_08.html"&gt;FormHeading &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=layouts_09.html"&gt;Grid &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=layouts_04.html"&gt;HBox &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=layouts_07.html"&gt;HDividedBox &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=controls_21.html"&gt;HRule &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=navigators_3.html"&gt;ModuleLoader &lt;/a&gt; &lt;/td&gt;&lt;td&gt;not really a layout control? ModuleLoader allows you to load components of the application on demand, lowering initial download size and improving encapsulation&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=layouts_10.html"&gt;Panel &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=controls_21.html"&gt;Scrollbar&lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Spacer &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=layouts_11.html"&gt;Tile &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=layouts_12.html"&gt;TitleWindow &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=layouts_04.html"&gt;VBox &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=layouts_07.html"&gt;VDividedBox &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://livedocs.adobe.com/flex/3/html/help.html?content=controls_21.html"&gt;VRule &lt;/a&gt; &lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt; &lt;/table&gt;&lt;/p&gt;</description></item><item><title>visual c++ lesson 0.0.0.0.1 precompiled headers</title><link>https://chriswhitmore.com/2008/12/15/visual-c-lesson-0.0.0.0.1-precompiled-headers/</link><pubDate>Mon, 15 Dec 2008 16:03:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/12/15/visual-c-lesson-0.0.0.0.1-precompiled-headers/</guid><description>&lt;p&gt;I come from a background of managed memory and interpreted languages. I&amp;rsquo;m a big proponent of pragmatic approaches to problems and as little re-inventing of the wheel as humanly possible. I don&amp;rsquo;t think the world needs another text editor, and I personally don&amp;rsquo;t feel the need to write my own version of the stack I rely on for application development. (.NET Framework and IIS)&lt;br /&gt;&lt;br /&gt;This however gives me less credibility with all those &amp;ldquo;real&amp;rdquo; programmers out there. The ones who read assembly for fun and don&amp;rsquo;t believe in memory management or virtual runtimes/machines.  I consistently find myself in battles with control freaks who argue that building an application on top of an application server like Tomcat or IIS is dangerous and excessive when it&amp;rsquo;s so much simpler to just write your own daemon and connection handling.&lt;br /&gt;&lt;br /&gt;Regardless. It is difficult to argue without having credible experience with the alternatives. Not only that, but a number of my dream jobs require extensive C/C++ knowledge (Google) and many important FOSS projects require the same. So I am finally diving in and (re-)learning some C++ with an initial task of writing an XML to &lt;a href="http://en.wikipedia.org/wiki/Asn.1"&gt;ASN.1&lt;/a&gt; converter. (don&amp;rsquo;t ask why)&lt;br /&gt;&lt;br /&gt;I&amp;rsquo;m doing this in visual studio 2008 with Visual C++, which as I&amp;rsquo;m learning has it&amp;rsquo;s own learning associated with it. First is the question of &lt;a href="http://en.wikipedia.org/wiki/Active_Template_Library"&gt;ATL&lt;/a&gt; , &lt;a href="http://en.wikipedia.org/wiki/Microsoft_Foundation_Classes"&gt;MFC&lt;/a&gt; , &lt;a href="http://en.wikipedia.org/wiki/WIN32"&gt;WIN32 &lt;/a&gt; or just Blank. Visual studio doesn&amp;rsquo;t give you a whole lot of background on why you might choose one or the other, but some simple wikipedia reading spelled out that for my project I wanted the simplest option. So I went ahead with Win32 Console as it seemed to have the least amount of overhead with easiest start.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_doSNwQwU8XA/SUc8qcjS8hI/AAAAAAAABWg/yqujArdgAWo/s1600-h/newprojectcpp.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://chriswhitmore.com/assets/newprojectcpp.JPG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;span style="font-size: x-small;"&gt;(Why would anyone use the C++ CLR option?)&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;From here I moved to some very simple HelloWorld love with some file IO. I&amp;rsquo;ve taken a course that used C for half of the assignments so I am not completely new to this, but I definitely needed a reminder. Here again I was presented with another option, &lt;a href="http://en.wikipedia.org/wiki/Stdio"&gt;stdio &lt;/a&gt; or &lt;a href="http://en.wikipedia.org/wiki/Iostream"&gt;iostream&lt;/a&gt; ? More wikipedia love, apparently stdio is the old C way of doing things and iostream is the new object oriented way of doing things. There seems to be a lot of contention still about when to use which when, but for my purposes the stream approach seemed more appropriate.&lt;br /&gt;&lt;br /&gt;And include how?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span style="font-size: small;"&gt;#include &amp;ldquo;iostream&amp;rdquo;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span style="font-size: small;"&gt;//OR&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span style="font-size: small;"&gt;#include &amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span style="font-size: small;"&gt;//OR&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span style="font-size: small;"&gt;#include &amp;lt;iostream.h&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Well visual studio doesn&amp;rsquo;t allow the last one so that&amp;rsquo;s easy. Using either of the first two work though works because using the double quotes option will check for an implementation defined location for the file before falling back to the same behavior provided by using the angle brackets. Ok, one more down.&lt;br /&gt;&lt;br /&gt;Don&amp;rsquo;t forget that in Visual C++ adding the above import does not explicitly import the associated namespace. So in order to actually use cin or cout you need to either prefix every instance with std::cin or use the statement &amp;ldquo;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span style="font-size: small;"&gt;using namespace std;&lt;/span&gt;&lt;/span&gt;&amp;rdquo; in order to simply use those identifiers normally.&lt;br /&gt;&lt;br /&gt;The next couple hours were learning how to create classes, use namespaces and some simple iterative build up of some basic classes to represent the document I needed to import. Still barely outside the realm of a hello world really.&lt;br /&gt;&lt;br /&gt;Now, for this little project I am actually more interested in the ASN part of the problem than I am in the XML parsing so I looked for a parser. I came across the &lt;a href="http://code.google.com/p/autumnframework/"&gt;autumn project&lt;/a&gt; which references a parser written by &lt;a href="http://www.applied-mathematics.net/"&gt;Dr. Ir. Frank Vanden Berghen&lt;/a&gt; which was appealing as it was relatively small, portable and self contained. You can&lt;a href="http://code.google.com/p/autumnframework/source/browse/#svn/trunk/src/autumnframework"&gt; find the files here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Now for the fun part. When attempting to compile my newly added class was throwing a dozen or so errors that didn&amp;rsquo;t exactly make sense to me. I was prepared for some pretty ugly work in trying to port this thing from GCC to the Microsoft compiler, so I didn&amp;rsquo;t really question these errors. To begin with it was mostly types that were missing. So I would search for the definition of that type and find it in a header file that I was sure was being included. At this point I naively began to move code around in an effort to understand the error. Moving one struct from the header to the cpp file seemed to resolve one error and cause a few more. This seemed to validate my guess that the header was somehow not being included. I had no expectation that this should just work out of the box of course though, so perhaps some of this code was just wrong. I started to chase down the parts of the code that were dependent on flags such as #ifdef WIN32 (I really like how visual studio grays out the code that will not be included based on those conditionals, very nice).&lt;br /&gt;&lt;br /&gt;This went on for maybe an hour before I was convinced that this had to be easier. Looking more closely at the build output rather than the error log (which should always be done much sooner than this) revealed this warning :&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;1&amp;gt;c:\documents and settings\c\my documents\visual studio 2008\projects\xmltoasn\xmltoasn\xmlparser.cpp(82) : warning C4627: &amp;lsquo;#include &amp;lt;Windows.h&amp;gt;&amp;rsquo;: skipped when looking for precompiled header use&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;1&amp;gt;        Add directive to &amp;lsquo;stdafx.h&amp;rsquo; or rebuild precompiled header&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This is one of those steps where I know I should have asked more questions when I first started my project. The project by default included my &amp;ldquo;main&amp;rdquo; file, but it also included these two stdafx files (header and cpp) which I briefly looked at but didn&amp;rsquo;t dig into. The comment at the top of stdafx.h shows this :&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;// stdafx.h : include file for standard system include files,&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;// or project specific include files that are used frequently, but&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;// are changed infrequently&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Which if you don&amp;rsquo;t know what pre-compiled headers are may not make a ton of sense. And it sounds to me like this is optional in any case. Well, it isn&amp;rsquo;t, at least not if you have the build options on your project set to use precompiled headers which by default I did. Simply adding &amp;ldquo;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;#include &amp;lt;windows.h&amp;gt;&lt;/span&gt;&lt;/span&gt;&amp;rdquo; to the stdafx.h file resolved all the problems. So in fact the xmlParser module WAS portable, and I just didn&amp;rsquo;t have a clue.&lt;br /&gt;&lt;br /&gt;The other way to solve this problem is to actually change the precompiled headers setting for your project to not use precompiled headers at all.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_doSNwQwU8XA/SUfZL5JHHSI/AAAAAAAABWo/8Y8jXRblZmw/s1600-h/precompiledHeaderOption.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://chriswhitmore.com/assets/precompiledHeaderOption.JPG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;So this was a bit frustrating, but all in all a good first foray into this shit, and I&amp;rsquo;m at least a few steps closer to having a program that actually does something.&lt;/p&gt;</description></item><item><title>ajax for mac lovers</title><link>https://chriswhitmore.com/2008/12/12/ajax-for-mac-lovers/</link><pubDate>Fri, 12 Dec 2008 15:05:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/12/12/ajax-for-mac-lovers/</guid><description>&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: Calibri, sans-serif; font-size: 11pt;"&gt;Another Ajax Framework : &amp;nbsp;(or rather, an Application Framework)&lt;br /&gt;&lt;a href="http://cappuccino.org/"&gt;http://cappuccino.org/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://cappuccino.org/learn/"&gt;http://cappuccino.org/learn/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;Demo app built using it:&lt;br /&gt;&lt;a href="http://280slides.com/"&gt;http://280slides.com/&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Calibri; font-size: 15px;"&gt;And a teaser for all those interface builder lovers out there :&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span style="font-family: Calibri, sans-serif; font-size: 11pt;"&gt;&lt;a href="http://ajaxian.com/archives/nib2cib-use-interface-builder-to-design-your-ajax-apps"&gt;http://ajaxian.com/archives/nib2cib-use-interface-builder-to-design-your-ajax-apps&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: Calibri; font-size: 15px;"&gt;I came across this in reader this morning and was totally &amp;nbsp;blown away by how well the 280 slides application &amp;nbsp;worked. It's really impressive... on non IE browsers. I sent the link to a co-worker to check out and he basically dismissed it as too slow and unresponsive, "typical web app". It took a minute or two to realize the browser was the problem at which point I launched the app in IE 8 Beta (IE 8!) and it performed terribly.It looked terrible, it was jerky and generally just a big let down after the speed of Chrome.&amp;nbsp;&lt;/span&gt;&lt;a href="http://4.bp.blogspot.com/_doSNwQwU8XA/SULyoMFbB0I/AAAAAAAABWA/76Tx2GExYKE/s1600-h/chromeIE280slides.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;span class="Apple-style-span" style="font-family: Calibri; font-size: 15px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://4.bp.blogspot.com/_doSNwQwU8XA/SULyoMFbB0I/AAAAAAAABWA/76Tx2GExYKE/s1600-h/chromeIE280slides.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://chriswhitmore.com/assets/chromeIE280slides.JPG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Calibri; font-size: 15px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Calibri; font-size: 15px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Calibri; font-size: 15px;"&gt;Whatever the technical reasons are, it sucks. Let's hope the new generation of javascript engines (FF3.1 and Chrome) are able to push Microsoft into stepping up. I'm excited about Flex and Silverlight and JavaFX but really I want to believe we can keep pushing the browser without the plugin.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;</description></item><item><title>C++ linking</title><link>https://chriswhitmore.com/2008/11/28/c-linking/</link><pubDate>Fri, 28 Nov 2008 12:55:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/11/28/c-linking/</guid><description>&lt;p&gt;This is a post for myself, to basically bookmark the excellent work of someone else. My post is contributing practically nothing (maybe adding some context/weight for his article) but here it is anyway. ;-)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blog.copton.net/articles/linker/index.html"&gt;&lt;a href="http://blog.copton.net/articles/linker/index.html"&gt;http://blog.copton.net/articles/linker/index.html&lt;/a&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Despite not being an active user of C++ I really enjoyed this post. I actually feel a little smarter and better informed for having read it. Despite the mess in the C++  tool chain being described, this kind of reading actually makes me feel more inclined to dig into this stuff not less. Anyway, filing this one away as something to potentially come back to.&lt;/p&gt;</description></item><item><title>Lunar Reconnaissance Orbiter</title><link>https://chriswhitmore.com/2008/11/11/lunar-reconnaissance-orbiter/</link><pubDate>Tue, 11 Nov 2008 14:31:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/11/11/lunar-reconnaissance-orbiter/</guid><description>&lt;p&gt;A &lt;a href="http://www.sarahfobes.com/"&gt;good friend of mine Sarah&lt;/a&gt; believes that the moon landings were a hoax. Despite being a &lt;a href="http://www.google.ca/search?hl=en&amp;amp;q=site:sarahfobes.com+science+OR+space&amp;amp;btnG=Search&amp;amp;meta="&gt;huge science geek&lt;/a&gt; , a &lt;a href="http://www.sarahfobes.com/science/happy-50th-nasa/"&gt;fan of NASA&lt;/a&gt; and &lt;a href="http://www.sarahfobes.com/video/im-in-space-right-now/"&gt;a member of the planetary society&lt;/a&gt; she subscribes to the idea that man has not in fact walked on the moon, and the entire thing was a lie perpetrated in an effort to win the political war with the USSR. Or something along those lines.&lt;br /&gt;&lt;br /&gt;Somehow this deeply disturbs me. Anything coming from Sarah carries considerable weight, so I can&amp;rsquo;t just discard her opinion. How could it be that the same person avidly following the mars rover mission also believes that we couldn&amp;rsquo;t land someone on the moon (or rather, didn&amp;rsquo;t)? I can say that I have not watched/read/been brain washed by the same materials that she has, but I&amp;rsquo;m expecting to be convinced to do so after this post.&lt;br /&gt;&lt;br /&gt;Skepticism is vitally important to science, no doubt. I think scientific thinkers must challenge anything that doesn&amp;rsquo;t make sense to them. I myself am open to hearing the counter arguments, and I even spent a half hour or so reading the respective wikipedia articles on the matter&amp;hellip;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Apollo_Moon_Landing_hoax_accusations"&gt;&lt;a href="http://en.wikipedia.org/wiki/Apollo_Moon_Landing_hoax_accusations"&gt;http://en.wikipedia.org/wiki/Apollo_Moon_Landing_hoax_accusations&lt;/a&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Independent_evidence_for_Apollo_Moon_landings"&gt;&lt;a href="http://en.wikipedia.org/wiki/Independent_evidence_for_Apollo_Moon_landings"&gt;http://en.wikipedia.org/wiki/Independent_evidence_for_Apollo_Moon_landings&lt;/a&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I also think while conspiracy theories are fun (x-files we miss you) they are also wrong 99.99% of the time. In a time where science is considered elitist and unnecessary in one of the most important political, economic and scientific centers on earth, and when NASA continues to face diminishing budgets and smaller mandates it seems terribly unproductive to undermine those efforts being made by real engineers and scientists by giving credence to crack pot theories about hoaxes.&lt;br /&gt;&lt;br /&gt;Consider how difficult it is to keep a secret. Imagine the incentive to those cynical people out there who wish to undermine the real achievements of science. Remember the movie contact and &lt;a href="http://en.wikipedia.org/wiki/Ocham's_razor"&gt;Ocham&amp;rsquo;s Razor&lt;/a&gt;? Do we make hundreds of assumptions about the ability for hundreds of people in the government, at NASA and elsewhere all keeping a secret about the landings? That the telemetry mirrors left behind were done by unmanned missions (and that we had the robotics capable at that time to do so?) That the long documentation trail left behind from all the steps leading up to Apollo 11 were somehow part of it? That the &lt;a href="http://en.wikipedia.org/wiki/Moon_landing"&gt;FIVE additional moon landings&lt;/a&gt; (after the public had already lost interest) were also faked just to add weight to the first faked landing? Or can we assume that no such plot exists and that NASA&amp;rsquo;s account is roughly accurate? I realize you can flip this and play the other side, but you can read the articles for the details rather than me iterating through the arguments that have already been made on both sides.&lt;br /&gt;&lt;br /&gt;I have to admit, I want to believe. I want to believe that we really did achieve the mantel of a moon landing. That we as a culture were able to step outside of our regular bullshit to come together and accomplish something truly spectacular for mankind.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_doSNwQwU8XA/SRoZAOoCMzI/AAAAAAAABS4/v1i3-cuu7gc/s1600-h/lro.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://chriswhitmore.com/assets/lro.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;span style="font-style: italic;"&gt;LRO - finally time to shut up the crackpots&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;In any case, the only real reason I started this post, besides to provoke you Sarah, was so that I could mention the upcoming &lt;a href="http://en.wikipedia.org/wiki/Lunar_Reconnaissance_Orbiter"&gt;Lunar Reconnaissance Orbiter&lt;/a&gt; , a mission I will be really looking forward to. It looks like we&amp;rsquo;re going to get a lot more familiar with our friend the moon. This can only be a good thing as privatized space exploration steps up and produces more tourism and public interest in things beyond our humble planet. The moon may seem a bit provincial at this point, but if you were to seriously consider visiting it (when you make your millions on the internet) do you not get totally stoked? It seems like the next logical jumping point for our more grandiose visions. LRO is launching in early 2009 from Cape Canaveral this mission will include (from wikipedia)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: '-webkit-sans-serif'; font-size: 13px; line-height: 19px;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: '-webkit-sans-serif'; font-size: 13px; line-height: 19px;"&gt;&lt;ul style="line-height: 1.5em; list-style-image: url(http://en.wikipedia.org/skins-1.5/monobook/bullet.gif); list-style-type: square; margin-bottom: 0px; margin-left: 1.5em; margin-right: 0px; margin-top: 0.3em; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;ul style="line-height: 1.5em; list-style-image: url(http://en.wikipedia.org/skins-1.5/monobook/bullet.gif); list-style-type: square; margin-bottom: 0px; margin-left: 1.5em; margin-right: 0px; margin-top: 0.3em; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;ul style="line-height: 1.5em; list-style-image: url(http://en.wikipedia.org/skins-1.5/monobook/bullet.gif); list-style-type: square; margin-bottom: 0px; margin-left: 1.5em; margin-right: 0px; margin-top: 0.3em; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;li&gt;&lt;a class="extiw" href="http://en.wiktionary.org/wiki/selenodetic" style="-webkit-background-clip: initial; -webkit-background-origin: initial; background-attachment: initial; background-color: initial; background-image: none; background-position: initial initial; background-repeat: initial; color: #3366bb; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none;" title="wiktionary:selenodetic"&gt;Selenodetic&lt;/a&gt; global &lt;a href="http://en.wikipedia.org/wiki/Topography" style="-webkit-background-clip: initial; -webkit-background-origin: initial; background-attachment: initial; background-color: initial; background-image: none; background-position: initial initial; background-repeat: initial; color: #002bb8; text-decoration: none;" title="Topography"&gt;topography&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;ul style="line-height: 1.5em; list-style-image: url(http://en.wikipedia.org/skins-1.5/monobook/bullet.gif); list-style-type: square; margin-bottom: 0px; margin-left: 1.5em; margin-right: 0px; margin-top: 0.3em; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;ul style="line-height: 1.5em; list-style-image: url(http://en.wikipedia.org/skins-1.5/monobook/bullet.gif); list-style-type: square; margin-bottom: 0px; margin-left: 1.5em; margin-right: 0px; margin-top: 0.3em; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;li&gt;Characterization of deep space &lt;a href="http://en.wikipedia.org/wiki/Ionizing_radiation" style="-webkit-background-clip: initial; -webkit-background-origin: initial; background-attachment: initial; background-color: initial; background-image: none; background-position: initial initial; background-repeat: initial; color: #002bb8; text-decoration: none;" title="Ionizing radiation"&gt;radiation&lt;/a&gt; in Lunar orbit&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;ul style="line-height: 1.5em; list-style-image: url(http://en.wikipedia.org/skins-1.5/monobook/bullet.gif); list-style-type: square; margin-bottom: 0px; margin-left: 1.5em; margin-right: 0px; margin-top: 0.3em; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;ul style="line-height: 1.5em; list-style-image: url(http://en.wikipedia.org/skins-1.5/monobook/bullet.gif); list-style-type: square; margin-bottom: 0px; margin-left: 1.5em; margin-right: 0px; margin-top: 0.3em; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;li&gt;The lunar &lt;a href="http://en.wikipedia.org/wiki/Polar_region" style="-webkit-background-clip: initial; -webkit-background-origin: initial; background-attachment: initial; background-color: initial; background-image: none; background-position: initial initial; background-repeat: initial; color: #002bb8; text-decoration: none;" title="Polar region"&gt;polar regions&lt;/a&gt;, including possible &lt;a href="http://en.wikipedia.org/wiki/Ice" style="-webkit-background-clip: initial; -webkit-background-origin: initial; background-attachment: initial; background-color: initial; background-image: none; background-position: initial initial; background-repeat: initial; color: #002bb8; text-decoration: none;" title="Ice"&gt;water ice&lt;/a&gt; deposits and the lighting environment&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;ul style="line-height: 1.5em; list-style-image: url(http://en.wikipedia.org/skins-1.5/monobook/bullet.gif); list-style-type: square; margin-bottom: 0px; margin-left: 1.5em; margin-right: 0px; margin-top: 0.3em; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;ul style="line-height: 1.5em; list-style-image: url(http://en.wikipedia.org/skins-1.5/monobook/bullet.gif); list-style-type: square; margin-bottom: 0px; margin-left: 1.5em; margin-right: 0px; margin-top: 0.3em; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;li&gt;&lt;span style="color: red;"&gt;High-resolution mapping&lt;/span&gt; (max 0.5 m) to assist in the selection and characterization of future landing sites&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;And onboard instrumentation will most importantly include :&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="color: #666666;"&gt;LROC&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #666666;"&gt; — The Lunar Reconnaissance Orbiter Camera (LROC) has been designed to address the measurement requirements of landing site certification and polar illumination.&lt;/span&gt;&lt;sup class="reference" id="cite_ref-10"&gt;&lt;a href="http://en.wikipedia.org/wiki/Lunar_Reconnaissance_Orbiter#cite_note-10" style="-webkit-background-clip: initial; -webkit-background-origin: initial; background-attachment: initial; background-color: initial; background-image: none; background-repeat: initial;" title=""&gt;&lt;span style="font-size: 13px; text-decoration: none;"&gt;&lt;span style="color: #666666;"&gt;[&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 13px; text-decoration: none;"&gt;&lt;span style="color: #666666;"&gt;11&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 13px; text-decoration: none;"&gt;&lt;span style="color: #666666;"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;span style="color: #666666;"&gt; LROC comprises a pair of narrow-angle cameras (NAC) and a single wide-angle camera (WAC). LROC will fly several times over the historic &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Apollo_program" style="-webkit-background-clip: initial; -webkit-background-origin: initial; background-attachment: initial; background-color: initial; background-image: none; background-repeat: initial;" title="Apollo program"&gt;&lt;span style="text-decoration: none;"&gt;&lt;span style="color: #666666;"&gt;Apollo&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #666666;"&gt; &lt;/span&gt;&lt;a class="mw-redirect" href="http://en.wikipedia.org/wiki/Lunar_landing" style="-webkit-background-clip: initial; -webkit-background-origin: initial; background-attachment: initial; background-color: initial; background-image: none; background-repeat: initial;" title="Lunar landing"&gt;&lt;span style="text-decoration: none;"&gt;&lt;span style="color: #666666;"&gt;lunar landing&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #666666;"&gt; &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/List_of_Apollo_missions" style="-webkit-background-clip: initial; -webkit-background-origin: initial; background-attachment: initial; background-color: initial; background-image: none; background-repeat: initial;" title="List of Apollo missions"&gt;&lt;span style="text-decoration: none;"&gt;&lt;span style="color: #666666;"&gt;sites&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #666666;"&gt;, with the camera&amp;rsquo;s high resolution, the &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Lunar_rover" style="-webkit-background-clip: initial; -webkit-background-origin: initial; background-attachment: initial; background-color: initial; background-image: none; background-repeat: initial;" title="Lunar rover"&gt;&lt;span style="text-decoration: none;"&gt;&lt;span style="color: #666666;"&gt;lunar rovers&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #666666;"&gt; and &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Apollo_Lunar_Module" style="-webkit-background-clip: initial; -webkit-background-origin: initial; background-attachment: initial; background-color: initial; background-image: none; background-repeat: initial;" title="Apollo Lunar Module"&gt;&lt;span style="text-decoration: none;"&gt;&lt;span style="color: #666666;"&gt;Lunar Module&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #666666;"&gt; descent stages and their respective shadows will be clearly visible. It is expected that this photography will boost public acknowledgement of the validity of the  landings, and discredit the &lt;/span&gt;&lt;a class="mw-redirect" href="http://en.wikipedia.org/wiki/Apollo_Moon_Landing_hoax_theories" style="-webkit-background-clip: initial; -webkit-background-origin: initial; background-attachment: initial; background-color: initial; background-image: none; background-repeat: initial;" title="Apollo Moon Landing hoax theories"&gt;&lt;span style="text-decoration: none;"&gt;&lt;span style="color: #666666;"&gt;Apollo conspiracy theories&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="color: #666666;"&gt;.&lt;/span&gt;&lt;sup class="reference" id="cite_ref-11"&gt;&lt;a href="http://en.wikipedia.org/wiki/Lunar_Reconnaissance_Orbiter#cite_note-11" style="-webkit-background-clip: initial; -webkit-background-origin: initial; background-attachment: initial; background-color: initial; background-image: none; background-repeat: initial;" title=""&gt;&lt;span style="font-size: 13px; text-decoration: none;"&gt;&lt;span style="color: #666666;"&gt;[&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://en.wikipedia.org/wiki/Lunar_Reconnaissance_Orbiter#cite_note-11" style="-webkit-background-clip: initial; -webkit-background-origin: initial; background-attachment: initial; background-color: initial; background-image: none; background-repeat: initial;" title=""&gt;&lt;span style="font-size: 13px; text-decoration: none;"&gt;&lt;span style="color: #666666;"&gt;12&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href="http://en.wikipedia.org/wiki/Lunar_Reconnaissance_Orbiter#cite_note-11" style="-webkit-background-clip: initial; -webkit-background-origin: initial; background-attachment: initial; background-color: initial; background-image: none; background-repeat: initial;" title=""&gt;&lt;span style="font-size: 13px; text-decoration: none;"&gt;&lt;span style="color: #666666;"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/div&gt;&lt;/span&gt;&lt;span style="font-family: '-webkit-sans-serif'; font-size: 13px; line-height: 19px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It will be nice to put this to rest. Long live Elvis.&lt;/p&gt;</description></item><item><title>What you are reading is consuming energy</title><link>https://chriswhitmore.com/2008/11/09/what-you-are-reading-is-consuming-energy/</link><pubDate>Sun, 09 Nov 2008 22:56:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/11/09/what-you-are-reading-is-consuming-energy/</guid><description>&lt;div dir="ltr"&gt;Consumption is one of those things that is on my mind a lot. Both economically as I aim to live debt free and with as little "stuff" as really needed as well as in other forms of energy. Buy local, buy less packaging, drive less, eat less! It goes on and on. &lt;br /&gt;&lt;br /&gt;One of the really interesting things with looking at google appengine is their metering and logging of your application. The GAE has limits on how much disk, cpu and bandwidth your application can consume before you have to pay for those resources.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_doSNwQwU8XA/SRfaOboA-PI/AAAAAAAABSw/9Oqc7BSHVn0/s1600-h/appenginestats.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://chriswhitmore.com/assets/appenginestats.JPG" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;i&gt;(some stats on a very infrequently used blogquotes app)&lt;/i&gt;&lt;/span&gt; &lt;/div&gt;&lt;br /&gt;&lt;br /&gt;This model of utility computing has been something that has been kicked around and toyed with for literally four or five decades. In the beginning it was envisioned that computing would be just like the electrical grid, and you would pay for computing resources in much the same way as you do now. This was back when no one ever believed that a household could use or would need a computer that took up an entire room. &lt;br /&gt;&lt;br /&gt;That of course all changed, and we drifted to the current state where everyone has their own (or three). Are we are drifting back to a utility model again with the usefulness of having your data live in the cloud? I know I certainly care less and less about the machine I happen to be using when accessing my data.&amp;nbsp; If the data is in the cloud and therefore accessible anywhere you go, and more importantly from any device you choose (iPhone!) then it naturally just makes sense to perform operations on that data within the cloud as well. Why bring it all down to the client to compute values? Why own multiple computers and have idle processors and half empty disks? (wish I had that problem actually) I think it's a bit early to signal the death knell for the personal computer, far from it, but it certainly gets you thinking. &lt;br /&gt;&lt;br /&gt;In terms of energy consumption these are all having significant impact on the overall picture. There still exists an incredible amount of power on the client machine that is largely going untapped with increasingly thin clients (but of course that is reversing now too) and that power is going under utilized when we have servers that are performing the same poorly crafted functions doing the work millions of times over for every page view etc. &lt;br /&gt;&lt;br /&gt;There was &lt;a href="http://ecoiron.blogspot.com/2007/01/black-google-would-save-3000-megawatts.html"&gt;a blog post&lt;/a&gt; in Jan 2007 that talked about how much energy would be saved if google switched from white to black. This post evolved into a &lt;a href="http://ecoiron.blogspot.com/2007/08/history-in-january-2007-mark-ontkush.html"&gt;full on article on the topic&lt;/a&gt;, and a website (&lt;a href="http://blackle.com/"&gt;Blackle&lt;/a&gt;) with a counter for energy saved. &lt;br /&gt;&lt;br /&gt;This is all very interesting to me, but to get to my point... Using GAE and looking at very precise measurements of the resources my code and application are using was an incredible moment of perspective for me. Here I am, looking at a direct correlation to the algorithm I choose and a measurable amount of resources being consumed by that decision, amazing really. This is just profiling on the aggregate, but it feels profound. Somehow being in the utility computing frame of mind and looking at my "bill" I am compelled to rethink every aspect of my design to find ways to use less resources. This can only be a good thing. &lt;br /&gt;&lt;/div&gt;</description></item><item><title>software fundamentals are exciting?</title><link>https://chriswhitmore.com/2008/11/08/software-fundamentals-are-exciting/</link><pubDate>Sat, 08 Nov 2008 13:47:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/11/08/software-fundamentals-are-exciting/</guid><description>&lt;p&gt;I came across a nice list of fundamental axioms of development on &lt;a href="http://www.reddit.com/r/programming/comments/7c5he/frequently_forgotten_fundamental_facts_about/"&gt;reddit&lt;/a&gt; this morning that made me a little pumped. Pumped because I&amp;rsquo;m in the middle of a big transition at work that in a lot of respects has me starting over with a new team and a new mandate.&lt;br /&gt;&lt;br /&gt;I&amp;rsquo;ll be focusing on solutions, custom work and a view towards short term revenue vs long term research and development for products. Given the economic climate, it&amp;rsquo;s a shift I can understand and on a personal level one I&amp;rsquo;m looking forward to. I am saddened of course to be leaving the product I&amp;rsquo;ve spent the last four years working on, but at the end of the day software is software and this is going to be a big challenge for me.   &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Here&amp;rsquo;s the list &lt;/b&gt;(&lt;a href="http://www2.computer.org/portal/web/buildyourcareer/fa035"&gt;&lt;a href="http://www2.computer.org/portal/web/buildyourcareer/fa035"&gt;http://www2.computer.org/portal/web/buildyourcareer/fa035&lt;/a&gt;&lt;/a&gt;) highlights for me : &lt;br /&gt;&lt;blockquote&gt;EF1. Efficiency is more often a matter of good design than of good coding. So, if a project requires efficiency, efficiency must be considered early in the life cycle.&lt;br /&gt;&lt;br /&gt;Q4. Trying to improve one quality attribute often degrades another. For example, attempts to improve efficiency often degrade modifiability.&lt;br /&gt;&lt;br /&gt;T1. Most software tool and technique improvements account for about a 5- to 30-percent increase in productivity and quality. But at one time or another, most of these improvements have been claimed by someone to have &amp;ldquo;order of magnitude&amp;rdquo; (factor of 10) benefits. Hype is the plague on the house of software.&lt;/blockquote&gt;&lt;br /&gt;T1 I believe after having fallen for the tools pitch more than a  few times. At the same time though I think one of the differences in the &amp;ldquo;great programmers are 30 times more efficient than mediocre programmers&amp;rdquo; comes down to mastery of the tool set. Watch a proficient developer fly through their code and it&amp;rsquo;s easy to see. On the other hand I&amp;rsquo;ve seen excellent &amp;ldquo;users&amp;rdquo; who fly through a terrible design and become constrained by EF1.&lt;br /&gt;&lt;br /&gt;Anyway, for me this is reminscent of the &lt;a href="http://www.pragmaticprogrammer.com/"&gt;pragmatic programmers&lt;/a&gt; list, which as obvious as a lot of it is really made me focus on the core of my craft. See Jeff Atwood&amp;rsquo;s site for a quick reference if you have not seen this list before : &lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.codinghorror.com/blog/files/Pragmatic%20Quick%20Reference.htm"&gt;&lt;a href="http://www.codinghorror.com/blog/files/Pragmatic%20Quick%20Reference.htm"&gt;http://www.codinghorror.com/blog/files/Pragmatic%20Quick%20Reference.htm&lt;/a&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;While I&amp;rsquo;m at this, I&amp;rsquo;ve had some accumulated Martin Fowler wisdom around estimates and scoping that I&amp;rsquo;ve been meaning to post about. Working in custom solutions will mean writing a lot of proposals and giving fixed cost estimates which is going to be a new game for me&amp;hellip;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Martin Fowler: Estimates &lt;/u&gt;&lt;br /&gt;&lt;a href="http://www.martinfowler.com/bliki/ThrownEstimate.html"&gt;&lt;a href="http://www.martinfowler.com/bliki/ThrownEstimate.html"&gt;http://www.martinfowler.com/bliki/ThrownEstimate.html&lt;/a&gt;&lt;/a&gt;   &amp;lt;&amp;ndash; Technical debt, casting quick estimates&lt;br /&gt;&lt;a href="http://martinfowler.com/bliki/XpVelocity.html"&gt;&lt;a href="http://martinfowler.com/bliki/XpVelocity.html"&gt;http://martinfowler.com/bliki/XpVelocity.html&lt;/a&gt;&lt;/a&gt;    &amp;lt;- Nebulous Units of Time&lt;br /&gt;&lt;br /&gt;&lt;u&gt;and on dealing with fixed scope&amp;hellip;.&lt;/u&gt;&lt;br /&gt;&lt;a href="http://martinfowler.com/bliki/ScopeLimbering.html"&gt;&lt;a href="http://martinfowler.com/bliki/ScopeLimbering.html"&gt;http://martinfowler.com/bliki/ScopeLimbering.html&lt;/a&gt;&lt;/a&gt;  &amp;lt;&amp;ndash; dragging clients towards a more agile process&lt;br /&gt;&lt;a href="http://martinfowler.com/bliki/FixedPrice.html"&gt;&lt;a href="http://martinfowler.com/bliki/FixedPrice.html"&gt;http://martinfowler.com/bliki/FixedPrice.html&lt;/a&gt; &lt;/a&gt;&lt;br /&gt;&lt;a href="http://martinfowler.com/bliki/FixedScopeMirage.html"&gt;&lt;a href="http://martinfowler.com/bliki/FixedScopeMirage.html"&gt;http://martinfowler.com/bliki/FixedScopeMirage.html&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>frequent beachballs in mac os x caused by bad fonts</title><link>https://chriswhitmore.com/2008/09/06/frequent-beachballs-in-mac-os-x-caused-by-bad-fonts/</link><pubDate>Sat, 06 Sep 2008 21:46:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/09/06/frequent-beachballs-in-mac-os-x-caused-by-bad-fonts/</guid><description>&lt;p&gt;I&amp;rsquo;ve been testing the latest nightly builds of firefox 3.1 over the past few days and while generally impressed with the performance improvements in javascript was quite disapointed that it was causing my iMac to go into frequent hangs where I would see the spinning beachball of death for many seconds before I could continue working again. It became bad enough that I finally had to ditch my firefox testing efforts. &lt;br /&gt;&lt;br /&gt;Much to my chagrin the problem continued well after I had stopped using good ole Minefield. I began to explore running processes via activity explorer and just generally clean up my machine. So after uninstalling a bunch of apps and services I wasn&amp;rsquo;t running anymore and still experiencing the same problem.&lt;br /&gt;&lt;br /&gt;At this point I was worried because the cpu was not the issue, iTunes would continue to play with no problem (and even respond to the hotkeys on my keyboard for switching tracks) it was just the UI that was freezing, and generally as I was opening files. Disk issue? Memory? Maybe even something where the network was introducing some latency? After some googling and consternation over my potentially failing disk I finally did what I should have in the first place and started to dig into the system logs via Console.&lt;br /&gt;&lt;br /&gt;Sure enough one group of messages stood out right away&amp;hellip;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;06/09/08 9:21:29 PM com.apple.ATSServer[14462] ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ &lt;br /&gt;06/09/08 9:21:29 PM com.apple.ATSServer[14462] 2008.09.06 21:21:29.63 &lt;br /&gt;06/09/08 9:21:29 PM com.apple.ATSServer[14462] ATSServer got a fatal error (status: -4) while processing a message (id: 20) from pid=14309. &lt;br /&gt;06/09/08 9:21:29 PM com.apple.launchd[386] (com.apple.ATSServer) Throttling respawn: Will start in 10 seconds &lt;br /&gt;06/09/08 9:21:39 PM com.apple.ATSServer[14465] ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ &lt;br /&gt;06/09/08 9:21:39 PM com.apple.ATSServer[14465] 2008.09.06 21:21:39.90 &lt;br /&gt;06/09/08 9:21:39 PM com.apple.ATSServer[14465] ATSServer got a fatal error (status: -4) while processing a message (id: 20) from pid=14309. &lt;br /&gt;06/09/08 9:21:39 PM com.apple.launchd[386] (com.apple.ATSServer) Throttling respawn: Will start in 10 seconds &lt;br /&gt;06/09/08 9:21:41 PM quicklookd[14463] [QL ERROR] &amp;lsquo;Creating thumbnail&amp;rsquo; timed out for &amp;lsquo;&amp;lt;QLThumbnailRequest /Library/Fonts/LiberationSans-Regular.ttf&amp;gt;&amp;rsquo; &lt;br /&gt;06/09/08 9:21:50 PM Console[14309] Failure with ATSFontGetUnicodeCharacterCoverage(). Disabling font fallback optimization for characters not renderable. &lt;br /&gt;06/09/08 9:21:51 PM com.apple.ATSServer[14468] ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ &lt;/blockquote&gt;&lt;br /&gt;So the ATSServer (Apple Type Server) was choking and it looks like the beachballs I was seeing were related to the throttling of the respawn of the server. So I&amp;rsquo;d be staring at a beachball for up to 10 seconds while the rest of the OS hummed along fine. A quick google search revealed the most common reason for this kind of failure is a corrupt font. At this point I shot around in my chair and asked my wife pleadingly and only somewhat accusatorily whether she had by any remote chance installed any fonts lately&amp;hellip;..  Yes.  So I gave her control of my screen so she could clean up what had been added and like magic the beachballs ended. No reboot or anything required, ATSServer has not crashed since and I am writing this in Minefield 3.1b1pre with no problems! (sorry to blame you firefox)&lt;br /&gt;&lt;br /&gt;Sadly I do not have the patience to go through the exercise of finding which fonts specifically caused the problems. I really don&amp;rsquo;t have much use for the extra fonts so I&amp;rsquo;m just as happy to have them all gone. Still hopefully this helps someone. &lt;br /&gt;&lt;br /&gt;Now if I could just clean up all these damn mds errors that keep cropping up &amp;hellip;&lt;br /&gt;&lt;blockquote&gt;mds[34]: (Error) Import: importer:0x84b600 Importer start failed for 501 (kr:268435459 (ipc/send) invalid destination port)&lt;/blockquote&gt;&lt;/p&gt;</description></item><item><title>From Chrome with Love</title><link>https://chriswhitmore.com/2008/09/03/from-chrome-with-love/</link><pubDate>Wed, 03 Sep 2008 08:38:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/09/03/from-chrome-with-love/</guid><description>&lt;p&gt;A million bloggers all posting on the same topic, why shouldn&amp;rsquo;t I join in. The Google chrome team has got to be enjoying themselves right now. I &lt;a href="http://www.google.com/googlebooks/chrome/index.html"&gt;read the comic yesterday&lt;/a&gt; and really enjoyed it. Seeing a company I can&amp;rsquo;t help but admire sit down and rethink the browser in so thorough of a manner is inspiring. Even just the QA involved is pretty damn impressive.&lt;br /&gt;&lt;br /&gt;I&amp;rsquo;ve been using the &lt;a href="http://www.google.com/chrome"&gt;chrome browser&lt;/a&gt; for a day now and have to same I&amp;rsquo;m pretty happy with it. I can already feel a need for some of the firefox extensions that I rely on so heavily, but at the same time I feel more productive and less distracted in this browser than I do in firefox. It&amp;rsquo;s FAST, really fast on my machine at work. I can&amp;rsquo;t wait until this is available for my mac.&lt;br /&gt;&lt;br /&gt;I really enjoyed this article from John Siracusa, it sums up nicely what I find so inspiring about this and points out the real motivation for Google to create yet another browser.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://arstechnica.com/staff/fatbits.ars/2008/09/02/straight-out-of-compton"&gt;&lt;a href="http://arstechnica.com/staff/fatbits.ars/2008/09/02/straight-out-of-compton"&gt;http://arstechnica.com/staff/fatbits.ars/2008/09/02/straight-out-of-compton&lt;/a&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;(I&amp;rsquo;m almost regretting my recent commitment to developing an RIA in silverlight! Where oh where are my first class developer tools for browser based development&amp;hellip;. )&lt;/p&gt;</description></item><item><title>Regression Ratios</title><link>https://chriswhitmore.com/2008/08/09/regression-ratios/</link><pubDate>Sat, 09 Aug 2008 00:12:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/08/09/regression-ratios/</guid><description>&lt;p&gt;Regression is a nasty issue. Ongoing regression from bug fixes can be a pretty clear indicator that there are some serious problems with your code base, your process, your team or all of the above. As an example case consider the effect of moving from 1 in 5 of all bug fixes causing an unrelated issue to crop up to 1 in 10. Given an imaginary scenario where 1000 bugs are found (a medium size project) and a team is closing 20 of those bugs a day then in an extremely simple model we have just added two weeks to our timeline simply from regression issues.  (handy chart from google spreadsheets below) &lt;br /&gt;&lt;br /&gt;&lt;img height="294" src="http://spreadsheets.google.com/pub?key=pwMHpVsfIVWrxJsaRJxoEFA&amp;amp;oid=1&amp;amp;output=image" width="420" /&gt;&lt;br /&gt;&lt;br /&gt;Of course its much more insidious then that though in the real world. For one, regression bugs only pop out at you the minute they are introduced if you&amp;rsquo;re lucky (they are obvious). More likely is that about half of them will show themselves and the other half will start cropping up near the release date during regression passes. If you alter the model above to show that you&amp;rsquo;ll see little bulges near the end of the line that start to make time lines feel very elusive and untrustworthy. And given that no QA process is perfect you have to believe that whatever is causing you to introduce those bugs that you are seeing is also causing bugs that are yet to be found.&lt;br /&gt;&lt;br /&gt;The importance of quality can never be over-stated, and the effect of poor quality can have a really dramatic impact on a team as well as your customers. Here you are, slaving over your own code, crafting a well thought out and tested solution to a problem, only to have someone else come along and break your code with their fix. Here you are, proudly about to successfully bring a feature out of the QA phase and into the hands of customers and all these elements that you had already seen work are failing. How quickly your trust in your fellow developer begins to wane.&lt;br /&gt;&lt;br /&gt;Here though is a problem that I have come to see the light on as being truly systemic. Yes there are horrid developers, and yes there are some difficult technologies, and yes some level of regression is inevitable&amp;hellip;. but levels of regression like those that I&amp;rsquo;ve seen can usually be traced back to process, to your design and architecture, to your requirements and most importantly to your culture. &lt;br /&gt;&lt;br /&gt;In terms of process there are some stock answers to bringing this number down like TDD and constant refactoring. I believe in both of these, but in my experience these can be difficult to enfuze into a culture. Without full buy-in and a cultural shift in developers these are just more TLA&amp;rsquo;s to throw on the steaming pile of buzzwords that will help you magically improve.&lt;br /&gt;&lt;br /&gt;Having just come to the end of a release of our product in the past few weeks I am looking forward to whittling away at our own regression ratios.&lt;br /&gt;&lt;br /&gt;Changes we&amp;rsquo;re making :&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;No more sharing of the bug load.&lt;/span&gt; Every developer owns their module/feature/code from design through to maintenance. This include assigning ownership to old modules whose owners may no longer be around. If you write bad code, you will fix more bugs. If you fix more bugs, you will have less time to spend on new bug-ridden features. This will mean our actual bug trends won&amp;rsquo;t be the pretty descent we&amp;rsquo;ve worked so hard on achieving. But the overall effect of a self correcting system should help. &lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;More atomic checkins&lt;/span&gt;. Checkins that span branch points, or handling merges of bugs can be extremely error prone with subversion and our current branching strategy. We hope to address this somewhat by eliminating bug fixes that span multiple revisions&amp;hellip; Ideally this will involve :&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Patch files attached to the bugtracker for code reviews to avoid multiple checkins when reviews spot errors&lt;/li&gt;&lt;li&gt;When changes still need to be made to a bug when things are caught in QA then we also revert the original checkin, and checkin again with all changes at once in the new revision. &lt;/li&gt;&lt;li&gt;Bugs will be closed diligently and new bugs opened rather than morphing the bug over time as new side effects or slightly related bugs are spotted. &lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;More automated testing&lt;/span&gt;. This is last on the list not because it&amp;rsquo;s least important, but because we don&amp;rsquo;t expect as quick of an impact as with the other two steps. A major number of the issues we run into remain UI issues. And while WatiN does do wonders for us, it&amp;rsquo;s painstakingly slow to get the number of tests to where they should be (and keep them up to date). &lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Lastly just for interest here&amp;rsquo;s the graph of how we&amp;rsquo;ve actually done. Black shade are high severity bugs. The first mountain was the release previous where we amalgamated all previous releases into this (migration of existing clients) we had some pretty serious regression in that release after Christmas. The  second range is the most recent release which is looking amazing in comparison, though at this resolution you are missing some definite climbs amongst that fall. Definite progress anyway&amp;hellip;. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_doSNwQwU8XA/ST9CYWjWR1I/AAAAAAAABVU/ru4In38-Mug/s1600-h/yearbugs.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://chriswhitmore.com/assets/yearbugs.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/p&gt;</description></item><item><title>Documenting architecture</title><link>https://chriswhitmore.com/2008/07/21/documenting-architecture/</link><pubDate>Mon, 21 Jul 2008 17:51:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/07/21/documenting-architecture/</guid><description>&lt;div dir="ltr"&gt;One of my side projects at work right now is documenting the architecture of a product that has already been built but will be going through a re-architecting with a focus on a more robust schema and applying some of the learning we've gone through in discovering exactly how our product is being used and ways in which our users want to extend the platform. &lt;a href="http://msdn.microsoft.com/en-us/architecture/aa699384.aspx"&gt;SaaS&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/architecture/aa948857.aspx"&gt;SOA &lt;/a&gt;are two good buzz words we'll be throwing around a lot, although to be honest we've been in the SaaS model for years now, just not following all of the best practises. (examples, check out &lt;a href="http://www.codeplex.com/LitwareHR"&gt;litwareHR&lt;/a&gt;) &lt;br /&gt;&lt;br /&gt;So despite documentation being at the heart of the architect's role I find it extremely difficult to find good documentation on how to approach a task like this. I have &lt;a href="http://www.librarything.com/work/details/2928078"&gt;Craig Larman's book Applying UML Patterns &lt;/a&gt;which I've enjoyed, but I still find myself grappling for where to even begin sometimes. &lt;br /&gt;&lt;br /&gt;These articles on IBM have been good reads for this and I'd reccommend giving them a read if you are facing similar challenges.&lt;br /&gt;&lt;br /&gt;Part1&lt;br /&gt;&lt;a href="http://www.ibm.com/developerworks/library/ar-archdoc1/index.html?S_TACT=105AGX20&amp;amp;S_CMP=EDU"&gt;http://www.ibm.com/developerworks/library/ar-archdoc1/index.html?S_TACT=105AGX20&amp;amp;S_CMP=EDU&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Part2&lt;br /&gt;&lt;a href="http://www.ibm.com/developerworks/library/ar-archdoc2/index.html?S_TACT=105AGX20&amp;amp;S_CMP=EDU"&gt;http://www.ibm.com/developerworks/library/ar-archdoc2/index.html?S_TACT=105AGX20&amp;amp;S_CMP=EDU&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Part 3&lt;br /&gt;&lt;a href="http://www.ibm.com/developerworks/library/ar-archdoc3/index.html?S_TACT=105AGX20&amp;amp;S_CMP=EDU"&gt;http://www.ibm.com/developerworks/library/ar-archdoc3/index.html?S_TACT=105AGX20&amp;amp;S_CMP=EDU&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I'm assuming there will be more of these which I'm looking forward to.</description></item><item><title>Networks, Assignment 1</title><link>https://chriswhitmore.com/2008/07/20/networks-assignment-1/</link><pubDate>Sun, 20 Jul 2008 16:39:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/07/20/networks-assignment-1/</guid><description>&lt;p&gt;I just finished my first assignment in a beginning networking course I&amp;rsquo;m taking and I am so far pretty impressed with how interesting this stuff is. I have a working knowledge of networking that includes decent understanding of the application layer, high level knowledge of the transport layer and basically just awareness of the link layer. It&amp;rsquo;s pretty rare that in my position as a developer that I need to answer questions about the link layer. (thank you my friends in IT)&lt;br /&gt;&lt;br /&gt;Some of the questions are actually kind of fun in that they had me visualizing data flowing through networks in ways I had not before. For example given a link between two hosts X km apart, with a transmission rate of R and a propagation delay of N&amp;hellip;. &lt;br /&gt;&lt;br /&gt;&lt;b id="mvmc7"&gt;&lt;span id="mvmc8" style="color: rgb(0, 0, 0);"&gt;      2.4.d&lt;/span&gt;&lt;/b&gt; What is the width (in meters) of a bit in the link? Is it longer than a football field? &lt;br /&gt;&lt;br /&gt;Kind of useless, but super fascinating at the same time, imagining the physical manifestation of all this work I do day in and day out. Pulling these bits from all over the world is so effortless, so fast and so transparent that it&amp;rsquo;s easy to forget the actual resources behind it. &lt;br /&gt;&lt;div id="q_k-8" style="color: rgb(153, 153, 153);"&gt;&lt;/div&gt;The football field question actually relates to a pretty interesting concept called bandwidth-delay, which refers to the amount of data that exists &amp;ldquo;on the wire&amp;rdquo; or &amp;ldquo;on the air&amp;rdquo; at any given moment. Data that has been sent but not yet acknowledged. It&amp;rsquo;s helpful in determining minimum buffer sizes for receivers and transmitters over a given link.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Bandwidth-delay_product"&gt;&lt;a href="http://en.wikipedia.org/wiki/Bandwidth-delay_product"&gt;http://en.wikipedia.org/wiki/Bandwidth-delay_product&lt;/a&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Another element to this first assignment was to setup apache as a proxy server on your local machine which was a bit surprising. I assumed at first that the assignment meant squid, but no, apparently apache itself can be configured to be a proxy server for a number of protocols including both ftp and http traffic.There are numerous articles out there on using it as a personal ad blocker, or caching server.&lt;br /&gt;&lt;br /&gt;For reference this is what I had to do to Httpd.conf to make it work :&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;font size="2"&gt;&lt;span id="zgi1" style="font-family: Courier New;"&gt;LoadModule disk_cache_module modules/mod_disk_cache.so&lt;/span&gt;&lt;/font&gt;&lt;br id="y3dn1" style="font-family: Courier New;" /&gt;&lt;font size="2"&gt;&lt;span id="zgi10" style="font-family: Courier New;"&gt;LoadModule proxy_module modules/mod_proxy.so&lt;/span&gt;&lt;/font&gt;&lt;br id="y3dn2" style="font-family: Courier New;" /&gt;&lt;font size="2"&gt;&lt;span id="zgi11" style="font-family: Courier New;"&gt;LoadModule proxy_http_module modules/mod_proxy_http.so&lt;/span&gt;&lt;/font&gt;&lt;br id="y3dn3" style="font-family: Courier New;" /&gt;&lt;font size="2"&gt;&lt;span id="zgi12" style="font-family: Courier New;"&gt;LoadModule proxy_connect_module modules/mod_proxy_connect.so&lt;/span&gt;&lt;/font&gt;&lt;br id="y3dn4" style="font-family: Courier New;" /&gt;&lt;br id="d8ue1" style="font-family: Courier New;" /&gt;&lt;font size="2"&gt;&lt;span id="zgi13" style="font-family: Courier New;"&gt;&amp;lt;IfModule mod_proxy.c&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;br id="d8ue2" style="font-family: Courier New;" /&gt;&lt;font size="2"&gt;&lt;span id="zgi14" style="font-family: Courier New;"&gt;ProxyRequests On&lt;/span&gt;&lt;/font&gt;&lt;br id="d8ue3" style="font-family: Courier New;" /&gt;&lt;font size="2"&gt;&lt;span id="zgi15" style="font-family: Courier New;"&gt;&amp;lt;Proxy *&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;br id="d8ue4" style="font-family: Courier New;" /&gt;&lt;font size="2"&gt;&lt;span id="zgi16" style="font-family: Courier New;"&gt;Order deny,allow&lt;/span&gt;&lt;/font&gt;&lt;br id="d8ue5" style="font-family: Courier New;" /&gt;&lt;font size="2"&gt;&lt;span id="zgi17" style="font-family: Courier New;"&gt;Deny from all&lt;/span&gt;&lt;/font&gt;&lt;br id="d8ue6" style="font-family: Courier New;" /&gt;&lt;font size="2"&gt;&lt;span id="zgi18" style="font-family: Courier New;"&gt;Allow from 10.0.1.2/255.255.255.0&lt;/span&gt;&lt;/font&gt;&lt;br id="d8ue7" style="font-family: Courier New;" /&gt;&lt;font size="2"&gt;&lt;span id="zgi19" style="font-family: Courier New;"&gt;&amp;lt;/Proxy&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;br id="d8ue8" style="font-family: Courier New;" /&gt;&lt;font size="2"&gt;&lt;span id="zgi110" style="font-family: Courier New;"&gt;&amp;lt;/IfModule&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;br id="d8ue9" style="font-family: Courier New;" /&gt;&lt;br id="rd1a" style="font-family: Courier New;" /&gt;&lt;font size="2"&gt;&lt;span id="zgi111" style="font-family: Courier New;"&gt;&amp;lt;IfModule mod_disk_cache.c&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;br id="rd1a0" style="font-family: Courier New;" /&gt;&lt;font size="2"&gt;&lt;span id="zgi112" style="font-family: Courier New;"&gt;CacheRoot &amp;ldquo;c:\apachecache&amp;quot;&lt;/span&gt;&lt;/font&gt;&lt;br id="rd1a1" style="font-family: Courier New;" /&gt;&lt;font size="2"&gt;&lt;span id="zgi113" style="font-family: Courier New;"&gt;CacheDirLevels 5&lt;/span&gt;&lt;/font&gt;&lt;br id="rd1a2" style="font-family: Courier New;" /&gt;&lt;font size="2"&gt;&lt;span id="zgi114" style="font-family: Courier New;"&gt;CacheDirLength 3&lt;/span&gt;&lt;/font&gt;&lt;br id="rd1a3" style="font-family: Courier New;" /&gt;&lt;font size="2"&gt;&lt;span id="zgi115" style="font-family: Courier New;"&gt;&amp;lt;/IfModule&amp;gt;&lt;/span&gt;&lt;/font&gt;&lt;/blockquote&gt;&lt;div style="font-family: inherit;"&gt;&lt;/div&gt;&lt;font size="2"&gt;&lt;span id="zgi115" style="font-family: Courier New;"&gt;&lt;font face="inherit" style="font-family: inherit;"&gt;Interestingly if you get that configuration wrong, you actually get a big &amp;ldquo;It Works!&amp;rdquo; page shown in your browser for any page you try to visit. Go figure. My mistake at that point was just not having uncommented the right modules, so apache was just serving the It Works page rather than attempting to proxy my request. &lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;font size="2"&gt;&lt;span id="zgi115" style="font-family: Courier New;"&gt; &lt;/span&gt;&lt;/font&gt;&lt;/p&gt;</description></item><item><title>blogquotes prototype is working</title><link>https://chriswhitmore.com/2008/07/19/blogquotes-prototype-is-working/</link><pubDate>Sat, 19 Jul 2008 21:50:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/07/19/blogquotes-prototype-is-working/</guid><description>&lt;p&gt;I&amp;rsquo;m supposed to be studying for a challenge exam I&amp;rsquo;m writing this week in &lt;a href="http://scis.athabascau.ca/html/course/COMP315/"&gt;&amp;ldquo;Advanced&amp;rdquo; Operating Systems&lt;/a&gt;. Instead I spend a good chunk of the day today working on &lt;a href="http://blogquotes.appspot.com/"&gt;blogquotes&lt;/a&gt; in between watching/playing with &lt;a href="http://maggiewhitmore.blogspot.com/"&gt;my daughter&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;I can justify this time spent because I did all of this work exclusively from a bash shell using vi to refresh myself on some of the content for the course. In this session I was able to use wget,grep,awk,vi,a shell script and some file permissions. I&amp;rsquo;m not so sure that will get me through the exam but it was fun and I was finally able to put some time towards my random quote include for the blog. &lt;br /&gt;&lt;br /&gt;You can see the quotes being pulled in now in the top right hand corner of this page. So far only my wife and I are using it, as this is very much a proof of concept. It works basically from end to end, but without a lot of features that are going to be necessary as this grows. Paging, searching, caching, tags, some UI polish, and some testing. It&amp;rsquo;s very gratifying though to reach this first phase and actually get something working. Adding features will probably happen a lot quicker now that I actually have a user. ;-) &lt;br /&gt;&lt;br /&gt;I also took the opportunity to try out some of &lt;a href="http://developer.yahoo.com/yui/datatable/"&gt;Yahoo&amp;rsquo;s client side api&amp;rsquo;s in the YUI&lt;/a&gt;. Currently I&amp;rsquo;m using XHR, Layout and DataTable. I was amazed at how quick it was to basically &amp;ldquo;assemble&amp;rdquo; my application. Google&amp;rsquo;s app engine makes the CRUD a total cake-walk, and yahoo&amp;rsquo;s user interface library has no dependencies on server side code but works seamlessly with a JSON backed RPC scheme in Python. It&amp;rsquo;s a whole new world! Now as long as my application doesn&amp;rsquo;t get popular and I have to start paying for resources. ;-)&lt;br /&gt;&lt;br /&gt;Some interesting snags while working on this latest revision: &lt;br /&gt;&lt;ul&gt;&lt;li&gt; &lt;a href="http://groups.google.com/group/google-appengine/browse_thread/thread/5a27d210a06cc550/363502ea2291e01d?#363502ea2291e01d"&gt;Randomly selecting an entity in GQL&lt;/a&gt; &lt;/li&gt;&lt;li&gt; Django Utils simplejson can&amp;rsquo;t serialize google&amp;rsquo;s db.Model classes, so I had to actually proxy my model class to a simpler structure that I serialize to the client via JSON and XHR&lt;/li&gt;&lt;li&gt; &lt;a href="http://code.google.com/appengine/docs/users/userobjects.html"&gt;No unique id&amp;rsquo;s for google user accounts&lt;/a&gt;, all you have is email which isn&amp;rsquo;t exactly something people are going to appreciate me passing on url&amp;rsquo;s for the random inclusion widget. The solution was simple for what I needed, a user preference entity keyed on google&amp;rsquo;s User db type and storing a UUID as the publishingKey, that id now becomes my unique id which won&amp;rsquo;t change even if you change your google account name&lt;/li&gt;&lt;li&gt; Google has a very cool &lt;a href="http://code.google.com/apis/ajaxlibs/"&gt;AJAX Library SDK&lt;/a&gt; for sharing hosting/serving up of all the most popular frameworks like dojo and jquery&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;I think I&amp;rsquo;ll use google code to start some documentation around bugs and features for this tool rather than simply the blog so look for those details elsewhere.&lt;/p&gt;</description></item><item><title>code samples in blogger are a pain</title><link>https://chriswhitmore.com/2008/07/17/code-samples-in-blogger-are-a-pain/</link><pubDate>Thu, 17 Jul 2008 22:58:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/07/17/code-samples-in-blogger-are-a-pain/</guid><description>&lt;p&gt;I can&amp;rsquo;t say I enjoy writing in the blogger post interface, in fact it&amp;rsquo;s pretty frustrating. For a while there I was using &lt;a href="http://docs.google.com/"&gt;google docs&lt;/a&gt; to write posts(which I loved), then I would just publish to my blog. That actually worked great until the actual publishing process which doesn&amp;rsquo;t allow you to control the title very effectively and totally messed up my rss feed even if I did fix the title. Then I tried &lt;a href="http://www.scribefire.com/"&gt;scribefire &lt;/a&gt;which again was really promising but it&amp;rsquo;s a cramped UI and again the publishing process was really clunky for my workflow. (things remain drafts for me for weeks at a time)&lt;br /&gt;&lt;br /&gt;Anyway, I&amp;rsquo;m looking at my last post and those code samples are embarrassingly poorly formatted. Not only that but if you check the source the blogger editor is introducing tons of html space entities which drives me nuts considering I&amp;rsquo;m using whitespace:pre on my blockquotes anyway.&lt;br /&gt;&lt;br /&gt;I&amp;rsquo;m really inclined to just use the tools I have when it comes to this site, primarily so that I focus on writing and not tinkering. Since moving my website from a hosted environment to blogger I have actually started to focus again on my writing and my projects rather than tinkering with a wheel that&amp;rsquo;s been built a thousand times (photo gallery scripts, php and perl cgi trickery for mundane templating etc). So while I will probably end up spending time on this at some point I really just want to find something that &amp;ldquo;just works&amp;rdquo; for showing code in blog posts. More to come I&amp;rsquo;m sure.&lt;/p&gt;</description></item><item><title>Microsoft's add-in framework and the need for diligence</title><link>https://chriswhitmore.com/2008/07/17/microsofts-add-in-framework-and-the-need-for-diligence/</link><pubDate>Thu, 17 Jul 2008 21:21:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/07/17/microsofts-add-in-framework-and-the-need-for-diligence/</guid><description>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;We've recently put Microsoft's &lt;a href="http://msdn.microsoft.com/en-us/library/bb384200.aspx"&gt;managed add-in framework&lt;/a&gt; (part of .NET 3.5) into very effective use building a plug-in system for a large asp.net application at work. Essentially the framework in place allows other developers (and our own team for out of stream releases) to develop new functionality for our platform that runs the entire life-cycle for a given widget. In our case for this particular widget we're talking about plugins being responsible for up to 4 asp.net controls in different contexts (for example data collection and reporting as two separate controls) as well as a script injection point where plug-ins are able to extend the scriptability of our platform.&amp;nbsp; &lt;/div&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;/div&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;For us going with the framework gave us a few things we didn't have with our original design for the add-ins.&amp;nbsp;&lt;/div&gt;&lt;ol&gt;&lt;li&gt;Tools to help enforce the pattern&lt;/li&gt;&lt;li&gt;An extra layer of versioning over the somewhat naive approach we started with&lt;/li&gt;&lt;li&gt;Built in discovery, provisioning, and a communication pipeline for serializing types and calls across the contracts that make up the interface between host and plugin&lt;/li&gt;&lt;li&gt;And last but not least support from Microsoft. This is somewhat more minor than the points above, but it helps legitimize our design when we are following the best practices laid out by Microsoft and used by others in similar situations. The documentation and training available also make getting other developers up to speed on the framework that much easier.&lt;/li&gt;&lt;/ol&gt;There have been numerous challenges in using the framework, but perhaps the most surprising of all for me was the human element and how simple it became over the life of the project to break the pattern by coupling components across or outside the pipeline.&lt;br /&gt;&lt;br /&gt;Examples :&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Referencing an assembly from both the addin and the host that shared code that should have been passed across the pipeline.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Bypassing the pipeline completely by calling web services from the addin code (client side or server side calling code)&amp;nbsp;&lt;/li&gt;&lt;li&gt;Conditional code in the host making decisions based on the type of the addin &lt;br /&gt;&lt;/li&gt;&lt;li&gt;Loose coupling based on common knowledge (that shouldn't be common)&amp;nbsp;&lt;/li&gt;&lt;/ol&gt;These all basically come down to a breach of contract or an absence of contract for various operations that we needed addins to handle. On some level all of these things can be excused and safely done without compromising the framework if they are done right. It's a slippery slope though and requires a commitment to not be lazy to avoid the temptation to sidestep the pipeline.&lt;br /&gt;&lt;br /&gt;In the case of #1 above the shared assembly started off very benign. Essentially some shared utility code for handling urls and some common resource tasks. Why rewrite when that code already existing the main project? Break it off from the project so that it has no dependencies then drop it in. Except that slowly the terrible pain of building contracts, views and adapters for every little interface or interface change drives you towards shortcuts. "Oh I'll just put this code here to test and then fix it later"&amp;nbsp; Even worse are those cases where you've chosen the path of least resistence in dealing with a bug resulting from unexpected behavior with serialization across the pipeline. It only took a few weeks of not being completely on top of this before I discovered our project was littered with types that were being shared directly between host and addin. Any change meant a recompilation of both projects, completely defeating the purpose.&lt;br /&gt;&lt;br /&gt;#2 is a legitimate need in our scenario, and we've found ourselves needing to creating proxy services that wrap our own services just to protect against the inevitable change that will follow. Given that third party developers may be writing code for the platform we have to make an effort to protect from change in all of our interfaces, web service or otherwise. In retrospect I think it would have made more sense to strictly enforce a team division so that no one writing addin code was also writing host code.This probably would have gone a long way to preventing these types of problems. &lt;br /&gt;&lt;br /&gt;#3 and #4 are a little more insidious and harder to spot without strict code review. #3 for us isn't technically breaking anything in terms of the interface or future versioning, but adds cruft and generally points to a missing method or property on the interface. The last thing you need as the host is to have case statements littered throughout your code looking for addins. #4 took many forms, and in some cases it's fine. An ok example might be sharing enums, which provided they are defined in the contracts or slightly worse something like a utility class is ok. A not ok example for me was code like this :&amp;nbsp; &lt;span style="font-family: courier new,monospace;"&gt;extension.GetSetting("Menu_Text");&lt;/span&gt;&amp;nbsp; which in this case has two errors. One "GetSetting" shouldn't really exist because how an addin chooses to configure itself should be transparent to the host. Second this code depends on the addin having a value defined in it's config file for the key "Menu_Text". This is next to impossible to enforce and can of course easily break. &lt;br /&gt;&lt;br /&gt;Replacing this with &lt;span style="font-family: courier new,monospace;"&gt;extension.MenuText; &lt;/span&gt;should be trivial, and a no-brainer. When we started using the framework back in December we were rolling the supporting code by hand. To give you a sense of what this entails, this is how you would define an extension who's only job is to return MenuText as in the code above :&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;IExtensionContract.cs&lt;/u&gt;&lt;/b&gt; &lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;using System.AddIn.Pipeline;&lt;br /&gt;using System.AddIn.Contract;&lt;br /&gt;&lt;br /&gt;namespace SimpleExtensionContracts&lt;br /&gt;{&lt;br /&gt; [AddInContract]&lt;br /&gt; public interface ExtensionContract : IContract&lt;br /&gt; {&lt;br /&gt; string MenuText { get; set; }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;IExtension.cs&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;namespace SimpleExtensionContracts.AddInViews&lt;br /&gt;{&lt;br /&gt; &lt;br /&gt; [System.AddIn.Pipeline.AddInBaseAttribute()]&lt;br /&gt; public interface IExtension&lt;br /&gt; {&lt;br /&gt; string MenuText&lt;br /&gt; {&lt;br /&gt; get;&lt;br /&gt; set;&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;IExtension.cs&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;namespace SimpleExtensionContracts.HostViews&lt;br /&gt;{&lt;br /&gt; &lt;br /&gt; public interface IExtension&lt;br /&gt; {&lt;br /&gt; string MenuText&lt;br /&gt; {&lt;br /&gt; get;&lt;br /&gt; set;&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;IExtensionContractToViewHostAdapter.cs&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;namespace SimpleExtensionContracts.HostSideAdapters&lt;br /&gt;{&lt;br /&gt; &lt;br /&gt; [System.AddIn.Pipeline.HostAdapterAttribute()]&lt;br /&gt; public class IExtensionContractToViewHostAdapter : SimpleExtensionContracts.HostViews.IExtension&lt;br /&gt; {&lt;br /&gt; private SimpleExtensionContracts.ExtensionContract _contract;&lt;br /&gt; private System.AddIn.Pipeline.ContractHandle _handle;&lt;br /&gt; static IExtensionContractToViewHostAdapter()&lt;br /&gt; {&lt;br /&gt; }&lt;br /&gt; public IExtensionContractToViewHostAdapter(SimpleExtensionContracts.ExtensionContract contract)&lt;br /&gt; {&lt;br /&gt; _contract = contract;&lt;br /&gt; _handle = new System.AddIn.Pipeline.ContractHandle(contract);&lt;br /&gt; }&lt;br /&gt; public string MenuText&lt;br /&gt; {&lt;br /&gt; get&lt;br /&gt; {&lt;br /&gt; return _contract.MenuText;&lt;br /&gt; }&lt;br /&gt; set&lt;br /&gt; {&lt;br /&gt; _contract.MenuText = value;&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt; internal SimpleExtensionContracts.ExtensionContract GetSourceContract()&lt;br /&gt; {&lt;br /&gt; return _contract;&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;IExtensionHostAdapter.cs&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;namespace SimpleExtensionContracts.HostSideAdapters&lt;br /&gt;{&lt;br /&gt; &lt;br /&gt; public class IExtensionHostAdapter&lt;br /&gt; {&lt;br /&gt; internal static SimpleExtensionContracts.HostViews.IExtension ContractToViewAdapter(SimpleExtensionContracts.ExtensionContract contract)&lt;br /&gt; {&lt;br /&gt; if (((System.Runtime.Remoting.RemotingServices.IsObjectOutOfAppDomain(contract) != true) &lt;br /&gt; &amp;&amp; contract.GetType().Equals(typeof(IExtensionViewToContractHostAdapter))))&lt;br /&gt; {&lt;br /&gt; return ((IExtensionViewToContractHostAdapter)(contract)).GetSourceView();&lt;br /&gt; }&lt;br /&gt; else&lt;br /&gt; {&lt;br /&gt; return new IExtensionContractToViewHostAdapter(contract);&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt; internal static SimpleExtensionContracts.ExtensionContract ViewToContractAdapter(SimpleExtensionContracts.HostViews.IExtension view)&lt;br /&gt; {&lt;br /&gt; if (view.GetType().Equals(typeof(IExtensionContractToViewHostAdapter)))&lt;br /&gt; {&lt;br /&gt; return ((IExtensionContractToViewHostAdapter)(view)).GetSourceContract();&lt;br /&gt; }&lt;br /&gt; else&lt;br /&gt; {&lt;br /&gt; return new IExtensionViewToContractHostAdapter(view);&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;IExtensionViewToContractHostAdapter.cs&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;namespace SimpleExtensionContracts.HostSideAdapters&lt;br /&gt;{&lt;br /&gt; &lt;br /&gt; public class IExtensionViewToContractHostAdapter : System.AddIn.Pipeline.ContractBase, SimpleExtensionContracts.ExtensionContract&lt;br /&gt; {&lt;br /&gt; private SimpleExtensionContracts.HostViews.IExtension _view;&lt;br /&gt; public IExtensionViewToContractHostAdapter(SimpleExtensionContracts.HostViews.IExtension view)&lt;br /&gt; {&lt;br /&gt; _view = view;&lt;br /&gt; }&lt;br /&gt; public string MenuText&lt;br /&gt; {&lt;br /&gt; get&lt;br /&gt; {&lt;br /&gt; return _view.MenuText;&lt;br /&gt; }&lt;br /&gt; set&lt;br /&gt; {&lt;br /&gt; _view.MenuText = value;&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt; internal SimpleExtensionContracts.HostViews.IExtension GetSourceView()&lt;br /&gt; {&lt;br /&gt; return _view;&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;IExtensionAddInAdapter.cs&lt;/u&gt;&lt;/b&gt; &lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;namespace SimpleExtensionContracts.AddInSideAdapters&lt;br /&gt;{&lt;br /&gt; &lt;br /&gt; public class IExtensionAddInAdapter&lt;br /&gt; {&lt;br /&gt; internal static SimpleExtensionContracts.AddInViews.IExtension ContractToViewAdapter(SimpleExtensionContracts.ExtensionContract contract)&lt;br /&gt; {&lt;br /&gt; if (((System.Runtime.Remoting.RemotingServices.IsObjectOutOfAppDomain(contract) != true) &lt;br /&gt; &amp;&amp; contract.GetType().Equals(typeof(IExtensionViewToContractAddInAdapter))))&lt;br /&gt; {&lt;br /&gt; return ((IExtensionViewToContractAddInAdapter)(contract)).GetSourceView();&lt;br /&gt; }&lt;br /&gt; else&lt;br /&gt; {&lt;br /&gt; return new IExtensionContractToViewAddInAdapter(contract);&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt; internal static SimpleExtensionContracts.ExtensionContract ViewToContractAdapter(SimpleExtensionContracts.AddInViews.IExtension view)&lt;br /&gt; {&lt;br /&gt; if (view.GetType().Equals(typeof(IExtensionContractToViewAddInAdapter)))&lt;br /&gt; {&lt;br /&gt; return ((IExtensionContractToViewAddInAdapter)(view)).GetSourceContract();&lt;br /&gt; }&lt;br /&gt; else&lt;br /&gt; {&lt;br /&gt; return new IExtensionViewToContractAddInAdapter(view);&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;IExtensionContractToViewAddInAdapter.cs &lt;/u&gt;&lt;/b&gt;&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;namespace SimpleExtensionContracts.AddInSideAdapters&lt;br /&gt;{&lt;br /&gt; &lt;br /&gt; public class IExtensionContractToViewAddInAdapter : SimpleExtensionContracts.AddInViews.IExtension&lt;br /&gt; {&lt;br /&gt; private SimpleExtensionContracts.ExtensionContract _contract;&lt;br /&gt; private System.AddIn.Pipeline.ContractHandle _handle;&lt;br /&gt; static IExtensionContractToViewAddInAdapter()&lt;br /&gt; {&lt;br /&gt; }&lt;br /&gt; public IExtensionContractToViewAddInAdapter(SimpleExtensionContracts.ExtensionContract contract)&lt;br /&gt; {&lt;br /&gt; _contract = contract;&lt;br /&gt; _handle = new System.AddIn.Pipeline.ContractHandle(contract);&lt;br /&gt; }&lt;br /&gt; public string MenuText&lt;br /&gt; {&lt;br /&gt; get&lt;br /&gt; {&lt;br /&gt; return _contract.MenuText;&lt;br /&gt; }&lt;br /&gt; set&lt;br /&gt; {&lt;br /&gt; _contract.MenuText = value;&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt; internal SimpleExtensionContracts.ExtensionContract GetSourceContract()&lt;br /&gt; {&lt;br /&gt; return _contract;&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;&lt;u&gt;IExtensionViewToContractAddInAdapter.cs&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;&lt;pre name="code" class="c-sharp"&gt;namespace SimpleExtensionContracts.AddInSideAdapters&lt;br /&gt;{&lt;br /&gt; &lt;br /&gt; [System.AddIn.Pipeline.AddInAdapterAttribute()]&lt;br /&gt; public class IExtensionViewToContractAddInAdapter : System.AddIn.Pipeline.ContractBase, SimpleExtensionContracts.ExtensionContract&lt;br /&gt; {&lt;br /&gt; private SimpleExtensionContracts.AddInViews.IExtension _view;&lt;br /&gt; public IExtensionViewToContractAddInAdapter(SimpleExtensionContracts.AddInViews.IExtension view)&lt;br /&gt; {&lt;br /&gt; _view = view;&lt;br /&gt; }&lt;br /&gt; public string MenuText&lt;br /&gt; {&lt;br /&gt; get&lt;br /&gt; {&lt;br /&gt; return _view.MenuText;&lt;br /&gt; }&lt;br /&gt; set&lt;br /&gt; {&lt;br /&gt; _view.MenuText = value;&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt; internal SimpleExtensionContracts.AddInViews.IExtension GetSourceView()&lt;br /&gt; {&lt;br /&gt; return _view;&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;Yeah, seriously. One interface and one string accessor requires nine class/interfaces and over 200 lines of code (which obviously could be made less with formatting etc).&amp;nbsp; It's also possible to share the views between addin and host but then you lose part of the more compelling robustness of the framework. If you are interested in where these classes come into play and how the add-in framework actually works &lt;a href="http://msdn.microsoft.com/en-us/magazine/cc163460.aspx"&gt;check out this link for a good description&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;Anyway, I can sympathize with the developers in wanting to speed up the process a bit, but the answer is not to bypass the pipeline. The answer is code generation! Thankfully by the time we realized our mistake Microsoft had released a &lt;a href="http://blogs.msdn.com/clraddins/archive/2008/02/11/feb-ctp-of-add-in-pipeline-generator-is-released-on-codeplex.aspx"&gt;CTP of their pipeline generator&lt;/a&gt; which is a nifty little visual studio addin which picks up the output of the Contracts project and uses reflection to find all of the contracts and generate the necessary projects and files for the pipeline. It literally saved us tons of hours and made the addin framework actually usable. Of couse the code generation is only going to work until we version one side or the other, but at that point we should have solidified those interfaces considerably so it will matter a lot less.&lt;br /&gt;&lt;br /&gt;Anyway, long story short, the add-in framework is great, but it's really important for the entire team to understand the goal and be diligent in ensuring that all that extra framework code isn't just being wasted by introducing dependencies.</description></item><item><title>Bill C61 notes</title><link>https://chriswhitmore.com/2008/06/26/bill-c61-notes/</link><pubDate>Thu, 26 Jun 2008 23:59:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/06/26/bill-c61-notes/</guid><description>&lt;p&gt;So I have a great personal distrust and disgust in the way copyright law has continually degraded and been abused by large corporations over the past 30 or 40 years . (&lt;a href="http://en.wikipedia.org/wiki/Sonny_Bono_Copyright_Term_Extension_Act"&gt;Thanks Mickey!&lt;/a&gt;) I cringe at the idea of the RIAA sueing people to protect their broken business model and laugh my ass off when bands like &lt;a href="http://www.youtube.com/watch?v=VIuR5TNyL8Y"&gt;Metallica&lt;/a&gt; &lt;a href="http://news.cnet.com/8301-13506_3-9965792-17.html"&gt;(2)&lt;/a&gt; and &lt;a href="http://news.cnet.com/8301-13506_3-9973662-17.html"&gt;Kiss&lt;/a&gt; make total asses of themselves while those artists that are still relevant embrace new ways of engaging their fans. Anyway, that&amp;rsquo;s the context for this post. I am legitimately interested in seeing how Canada will follow other countries in protecting artists, content producers and consumers.&lt;br /&gt;&lt;br /&gt;As much as I abhor the record industry I do think the law should reflect the reality of the new digital landscape. Content creators need to be protected, and consumers should get their money&amp;rsquo;s worth when buying or consuming copyrighted material. &lt;br /&gt;&lt;br /&gt;Anyway I watched these videos about the new Bill C61, and as painful as it is to listen to Jim Prentice repeat the same meaningless quip over and over in response to these questions, I did find it interesting. I&amp;rsquo;ve been really concerned about Canada following in the steps of the DMCA, and I imagine that under the covers this is largely similar, particularly where &amp;ldquo;digital locks&amp;rdquo; are concerned but I&amp;rsquo;ve so far not heard anything really terrible. &lt;br /&gt;&lt;a href="http://draft.blogger.com/tr_1214970788033"&gt;&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.digital-copyright.ca/node/4761"&gt;&lt;a href="http://www.digital-copyright.ca/node/4761"&gt;http://www.digital-copyright.ca/node/4761&lt;/a&gt;&lt;/a&gt;  (videos)&lt;br /&gt;&lt;br /&gt;Some highlights from the videos &lt;br /&gt;&lt;ul&gt;&lt;li&gt;Need for international cooperation, if it lets me watch more movies online for cheaper then going to the video store then yeah let&amp;rsquo;s go. How long has that been possible in the US?&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&amp;ldquo;and of course &lt;i&gt;new&lt;/i&gt; technologies such as mp3 players and &lt;i&gt;memory sticks&amp;rdquo;&lt;/i&gt; I just included that because it struck me as funny. &lt;br /&gt;&lt;/li&gt;&lt;li&gt;Time shifting and format shifting is preserved &lt;/li&gt;&lt;li&gt;BUT &amp;ldquo;digital locks&amp;rdquo; which are chosen by businesses (ie stopping format shifting) will be legally enforceable and will allow those time shifting and format shifting rights to be circumvented&lt;/li&gt;&lt;li&gt;Having personally already rented videos on iTunes I can see some benefit to these locks and some of the new models they enable (&lt;a href="http://www.theonion.com/content/video/historic_blockbuster_store_offers"&gt;death to blockbuster&lt;/a&gt;) &lt;br /&gt;&lt;/li&gt;&lt;li&gt;Also though owning a bunch of iTunes tracks I can&amp;rsquo;t use on other devices makes me hate the locks. But ultimately this is my decision on what to buy so I can&amp;rsquo;t complain too much. It&amp;rsquo;s important to let the market decide on some of these issues I think. Although how much of a market is it really when there are only a handful of really big labels and studios producing all the content?&lt;br /&gt;&lt;/li&gt;&lt;li&gt;no liabilities for ISP&amp;rsquo;s is great I think&lt;br /&gt;&lt;/li&gt;&lt;li&gt; New limits on the liability for &amp;ldquo;personal use&amp;rdquo; of copyrighted material to $500 PER INFRINGED WORK  (they kept playing up $500 limit as a good thing for consumers but it sounds like downloading 4 movies is still a $2000 hit)We all know how quickly this would completely sink most households.  In Prentice&amp;rsquo;s example this goes from five videos at $20,000 each  = $100,000 to $500 total&amp;hellip; he didn&amp;rsquo;t seem to really have that part down and I&amp;rsquo;m still not sure if it&amp;rsquo;s $500 per work or per incident or whatever? &lt;/li&gt;&lt;li&gt;Not that that matters as this is totally unenforceable, the law will enable companies to more confidently invest in delivery mechanisms that rely on locks and have a clearer understanding of rights, but none of it will help anyone actually enforce it. (Unless the companies do it themselves ala the RIAA sueings) &lt;br /&gt;&lt;/li&gt;&lt;li&gt;This whole bill was rammed through right at the end of summer with little consultation, seems ugly&lt;br /&gt;&lt;/li&gt;&lt;li&gt;When timshifting you can&amp;rsquo;t store those as a library of recordings, again very vague and would seemingly limit PVR software quite a bit. &lt;br /&gt;&lt;/li&gt;&lt;li&gt;You can&amp;rsquo;t import devices into Canada that enable bypassing locks (vague, could encompass a lot of devices )&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Teenagers seem to be the &amp;ldquo;they&amp;rdquo; in all these videos. Makes the questioners and the lawmakers seem out of touch. I understand teenagers are big offenders but they are by far not the only ones. &lt;/li&gt;&lt;li&gt;What are the whitewood treaties Mr Prentice brings up? I&amp;rsquo;m assuming I didn&amp;rsquo;t hear him because I didn&amp;rsquo;t see anything on my initial Googling of it. &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;The business network video is the best video of the bunch, if you want a summary just scroll down and watch that one. &lt;br /&gt;&lt;br /&gt;One of the things I was most surprised to hear was from Mr. Sookman saying that time shifting and format shifting is currently NOT legal? Really? I had always been under the impression that this was actually legal in Canada. &lt;br /&gt;&lt;br /&gt;Check out this website for more information on Bill C61&lt;br /&gt;&lt;a href="http://www.digital-copyright.ca/"&gt;&lt;a href="http://www.digital-copyright.ca/"&gt;http://www.digital-copyright.ca/&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Enough rope to hang yourself (C# Extension Methods)</title><link>https://chriswhitmore.com/2008/06/26/enough-rope-to-hang-yourself-c%23-extension-methods/</link><pubDate>Thu, 26 Jun 2008 11:16:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/06/26/enough-rope-to-hang-yourself-c%23-extension-methods/</guid><description>&lt;p&gt;So I ran into an interesting &amp;ldquo;gotchya&amp;rdquo; with C# extension methods tonight. And of course it happens at the 11th hour on a project that is being demoed at 9:00am tomorrow morning. Of course.&lt;br /&gt;&lt;br /&gt;&lt;h2 id="doqa"&gt;&lt;b id="doqa0"&gt;Extension Methods&lt;/b&gt;&lt;/h2&gt;&lt;a title="Extension methods" href="http://msdn.microsoft.com/en-us/library/bb383977.aspx" id="p58c"&gt;Extension methods&lt;/a&gt; are a really cool new feature of C# that were introduced in version 3.0 of the language. Essentially they are static methods that act like instance methods, allowing you to extend objects you don&amp;rsquo;t own. Ok, seeing those words on screen makes me think this is a terrible idea, but it really does have it&amp;rsquo;s place. (LINQ relies heavily on it)&lt;br /&gt;&lt;br /&gt;When I first saw these I got quite excited because we had a number of scenarios where they would make our code much much cleaner and easier to maintain. I can name a couple examples in our own project where this has the potential to make the API cleaner.&lt;br /&gt;&lt;br /&gt;&lt;h3 id="oiab1"&gt;Example 1: Helper/Utility/Static Methods&lt;/h3&gt;Try as they might, the .NET framework guys will not anticipate every piece of code that ends up repeated hundreds of times across your project to get around a common case. Before the framework added &lt;span id="du93" style="font-family:Courier New;"&gt;String.IsNullOrEmpty()&lt;/span&gt; in 2.0 we had &lt;span id="du930" style="font-family:Courier New;"&gt;StringHelper.IsNullOrEmpty(string arg)&lt;span id="d4.o" style="font-family:Verdana;"&gt;in our code base along with about half a dozen other methods. Now string may not be the best example, because in my mind I think it&amp;rsquo;s a bad idea to write extensions to framework types, but it does illustrate the problem well.&lt;br /&gt;&lt;br /&gt;In our project we have maybe a dozen of these Helper classes full of static methods (&lt;a title="utility pattern" href="http://en.wikipedia.org/wiki/Utility_pattern" id="nt8a"&gt;utility pattern&lt;/a&gt;). They are useful, but the biggest problem is the team&amp;rsquo;s ability to consistently discover those methods. Emails and other forms of communication helps, code review helps but ultimately you end up with repeated code fragments where helpers could have been used or even worse you end up with competing helpers in different namespaces that need to be consolidated once discovered.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;h3 id="mr3."&gt;&lt;span id="du930" style="font-family:Courier New;"&gt;&lt;span id="d4.o" style="font-family:Verdana;"&gt;Example 2: Enhancing Functionality Based on Context&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;Another useful place for extension methods in our project is to have our domain model be extended differently based on the area of the application and what rights the users executing that code have. Essentially what we have is two sets of functionality that are implemented very differently based on the context. For example in one context our object model is mapped using an ORM to the database directly, where as in another context that same object model is used with pre-populated data sets that are cached and completely scriptable by our end users. We still have code that needs to understand these objects across this context however, leading us to create interfaces for every single object in that domain that needs to work across these two contexts. I&amp;rsquo;m a fan of interfaces, but I think in this scenario we&amp;rsquo;ve clearly lost something in terms of the DRY principle and code readability.&lt;br /&gt;&lt;br /&gt;I&amp;rsquo;ve yet to really map out what this will look like for our project, but I see what&amp;rsquo;s been done with Linq and am excited about how simple it could be for example to include the &amp;ldquo;.Scripting&amp;rdquo; namespace to attach methods to our domain model that are exposed to end users. Similarly an &amp;ldquo;.API&amp;rdquo; namespace for our internal privileged code base with everyone sharing the same core objects.&lt;br /&gt;&lt;span id="du930" style="font-family:Courier New;"&gt;&lt;span id="d4.o" style="font-family:Verdana;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;h2 id="e6qo2"&gt;&lt;span id="du930" style="font-family:Courier New;"&gt;&lt;span id="d4.o" style="font-family:Verdana;"&gt;The Gotchya that kept me at work an extra hour&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;&lt;u id="s_os"&gt;&lt;b id="s_os0"&gt;Symptoms&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul id="ndde"&gt;&lt;li id="ndde0"&gt;Your extension method is no longer ever being executed&lt;/li&gt;&lt;/ul&gt;&lt;ul id="ndde1"&gt;&lt;li id="ndde2"&gt;Intellisense shows the correct method signature, reports no problems&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id="ndde4"&gt;&lt;li id="ndde5"&gt;Right click &amp;ldquo;go to definition&amp;rdquo; takes you to the method you think will be hit&lt;/li&gt;&lt;/ul&gt;&lt;ul id="ndde6"&gt;&lt;li id="ndde7"&gt;Stepping through the code shows you never reach your extension method&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;I&amp;rsquo;ve created some fake code to illustrate the problem. Imagine we have a simple factory class providing some useful functions like so :&lt;br /&gt;&lt;br /&gt;&lt;blockquote id="nxx1"&gt;&lt;span id="q:op" style="font-family:Courier New;"&gt;namespace ExtensionMethodsTest&lt;/span&gt;&lt;br /&gt;&lt;span id="q:op0" style="font-family:Courier New;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span id="q:op1" style="font-family:Courier New;"&gt; public class FactoryA&lt;/span&gt;&lt;br /&gt;&lt;span id="q:op2" style="font-family:Courier New;"&gt; {&lt;/span&gt;&lt;br /&gt;&lt;span id="q:op3" style="font-family:Courier New;"&gt; public ObjectA GetInstance()&lt;br /&gt; {&lt;br /&gt; return new ObjectA(&amp;ldquo;empty object&amp;rdquo;, -1);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public ObjectA GetInstance(string name)&lt;br /&gt; {&lt;br /&gt; return new ObjectA(name, 0);&lt;br /&gt; }&lt;/span&gt;&lt;br /&gt;&lt;span id="q:op13" style="font-family:Courier New;"&gt; }&lt;/span&gt;&lt;br /&gt;&lt;span id="q:op14" style="font-family:Courier New;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;But then we decide that we actually need to grab instances of ObjectA using an int id, so we add that using an extension method like so :&lt;br /&gt;&lt;br /&gt;&lt;blockquote id="oc90"&gt;&lt;span id="oc900" style="font-family:Courier New;"&gt;using ExtensionMethodsTest;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="oc903" style="font-family:Courier New;"&gt;namespace MyExtendingNamespace&lt;/span&gt;&lt;br /&gt;&lt;span id="oc905" style="font-family:Courier New;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span id="oc907" style="font-family:Courier New;"&gt; // a container for my extensions&lt;/span&gt;&lt;br /&gt;&lt;span id="oc909" style="font-family:Courier New;"&gt; public static class ExtendFactoryA&lt;/span&gt;&lt;br /&gt;&lt;span id="oc9011" style="font-family:Courier New;"&gt; {&lt;/span&gt;&lt;br /&gt;&lt;span id="oc9013" style="font-family:Courier New;"&gt; // Extend our factory to look objects up by id&lt;/span&gt;&lt;br /&gt;&lt;span id="oc9015" style="font-family:Courier New;"&gt; public static ObjectA GetInstance(this FactoryA factory, int id)&lt;/span&gt;&lt;br /&gt;&lt;span id="oc9017" style="font-family:Courier New;"&gt; {&lt;/span&gt;&lt;br /&gt;&lt;span id="oc9019" style="font-family:Courier New;"&gt; return new ObjectA(&amp;ldquo;got by id&amp;rdquo;, id);&lt;/span&gt;&lt;br /&gt;&lt;span id="oc9023" style="font-family:Courier New;"&gt; }&lt;/span&gt;&lt;br /&gt;&lt;span id="oc9025" style="font-family:Courier New;"&gt; }&lt;/span&gt;&lt;br /&gt;&lt;span id="oc9027" style="font-family:Courier New;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Blamo! Now anytime we&amp;rsquo;re using the &amp;ldquo;MyExtendingNamespace&amp;rdquo; our FactoryA includes the third way to grab an instance of ObjectA.&lt;br /&gt;&lt;br /&gt;&lt;blockquote id="gana0"&gt;&lt;div id="ts9t" style="padding: 1em 0pt; text-align: left;"&gt;&lt;img id="gana1" style="width: 405px; height: 84px;" src="http://docs.google.com/File?id=dd2p7twj_65cftmsm2s_b" /&gt;&lt;/div&gt;&lt;/blockquote&gt;Here is how I am calling both of these :&lt;br /&gt;&lt;br /&gt;&lt;blockquote id="z38t1" style="font-family: Courier New;"&gt; private void ByIdButton_Click(object sender, EventArgs e)&lt;br /&gt; {&lt;br /&gt; FactoryA fa = new FactoryA();&lt;br /&gt; ObjectA a = fa.GetInstance(42); // call extension method with int&lt;br /&gt; this.label1.Text = a.ToString();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private void ByNameButton_Click(object sender, EventArgs e)&lt;br /&gt; {&lt;br /&gt; FactoryA fa = new FactoryA();&lt;br /&gt; ObjectA a = fa.GetInstance(&amp;ldquo;gotten by name&amp;rdquo;); // call instance method with string&lt;br /&gt; this.label1.Text = a.ToString();&lt;br /&gt; }&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;This seems ok, our calls to GetInstance are consistent and we have everything working. Now transplant yourself a couple months into the future when the original owner of the FactoryA class has a need to alter the behavior to allow for more scenarios for retrieving instances of ObjectA.&lt;br /&gt;&lt;br /&gt;&lt;blockquote id="fuwu"&gt;&lt;span id="fuwu0" style="font-family:Courier New;"&gt; public ObjectA GetInstance(object proxyObj)&lt;/span&gt;&lt;br /&gt;&lt;span id="fuwu2" style="font-family:Courier New;"&gt; {&lt;/span&gt;&lt;br /&gt;&lt;span id="fuwu4" style="font-family:Courier New;"&gt; return new ObjectA(proxyObj.GetType().Name, 0);&lt;/span&gt;&lt;br /&gt;&lt;span id="fuwu6" style="font-family:Courier New;"&gt; }&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Now from the calling code everything still appears to work fine, intellisense continues to show the &amp;ldquo;int&amp;rdquo; signature that you think you are calling, and in fact if you right click the GetInstance call and say &amp;ldquo;Go to Definition&amp;rdquo; it takes you to the MyExtendingNamespace version of GetInstance.&lt;br /&gt;&lt;br /&gt;At &lt;b id="ih-h1"&gt;runtime&lt;/b&gt; however the CLR looks first for something that matches your call to fa.GetInstance(42); within the main namespace/class before looking at any extensions. Because our int gets automatically boxed we actually match &amp;ldquo;object proxyObject&amp;rdquo; and will never reach the extension method. Depending on the specific implementation in your code this can be a particularly insidious error or it may fail outright. Either way on a large project it can be a real annoyance to track down.&lt;br /&gt;&lt;br /&gt;To me there are a few mistakes here. 1) Why use an extension method here at all? 2) In general I think extension methods as overrides make little sense given how the CLR matches these and 3) GetInstance(object proxyObject) should probably be something more specific like ProxyBase or something else that is not an object. (Akin to catching System.Exception, bad&amp;hellip; be specific)&lt;br /&gt;&lt;br /&gt;Fixing this issue is as simple as renaming the extension method to GetInstanceById, or moving the method onto the Factory itself, or fixing the factory method to not use object. Personally I say drop the extension method.&lt;br /&gt;My example is over simplified, and in our scenario at work there was a little more justification for not changing the class that defined the original functionality. To me though this seems like the tip of an iceberg of problems.&lt;br /&gt;&lt;br /&gt;&lt;ul id="uo7t0"&gt;&lt;li id="uo7t1"&gt;Why negotiate with a module maintainer when I can just add functionality right here right now from my own code?&lt;br /&gt;&lt;/li&gt;&lt;li id="uo7t3"&gt;Why stop to understand that class and how it&amp;rsquo;s been constructed when I can just impose my view of how it should work overtop?&lt;/li&gt;&lt;li id="uo7t4"&gt;Intellisense makes it easy to find the method, so I don&amp;rsquo;t have to worry about how I organize this code.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Terrifying.&lt;/p&gt;</description></item><item><title>here here - use var sparingly</title><link>https://chriswhitmore.com/2008/06/21/here-here-use-var-sparingly/</link><pubDate>Sat, 21 Jun 2008 21:21:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/06/21/here-here-use-var-sparingly/</guid><description>&lt;p&gt;When I first read Jeff Atwood&amp;rsquo;s latest post on his love of C#&amp;rsquo;s new &amp;ldquo;var&amp;rdquo; keyword I was deeply bothered that my co-workers would find the article and latch on to the argument as a justification for laziness. While I do understand his point of view I was bothered by the idea of var statements littered throughout the code base making things more difficult to read for the next developer.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Saving key strokes is never justification for obscuring the code base. If you want to save keystrokes improve your environment, don&amp;rsquo;t sacrifice your code.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I came across this post on reddit tonight that very nicely counter&amp;rsquo;s the post on coding horror. Thanks Richard for a voice of reason.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://richarddingwall.name/2008/06/21/csharps-var-keyword-jeff-atwood-gets-it-all-wrong/"&gt;&lt;a href="http://richarddingwall.name/2008/06/21/csharps-var-"&gt;http://richarddingwall.name/2008/06/21/csharps-var-&lt;/a&gt; keyword-jeff-atwood-gets-it-all-wrong&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Dynamic vs Static... no wait make that DBC!</title><link>https://chriswhitmore.com/2008/06/14/dynamic-vs-static...-no-wait-make-that-dbc/</link><pubDate>Sat, 14 Jun 2008 21:14:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/06/14/dynamic-vs-static...-no-wait-make-that-dbc/</guid><description>&lt;p&gt;I need to blog this basically to toss it in my archive. There have been some interesting posts on the religious debate of static vs dynamic languages. I don&amp;rsquo;t know why I always get drawn into these lines of thought, but I do. (in fact I just added a &amp;ldquo;versus&amp;rdquo; label) &lt;br /&gt;&lt;br /&gt;I say drawn in because my underlying philosophy in all of these things is to choose the right tool for the job and leave it at that. I know, hardly original thinking, but despite the mantra and the collective nod that this is true we still get very heated on issues that are not actually at odds with each other.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;I&amp;rsquo;m NOT arguing that with you. I&amp;rsquo;m not arguing that with YOU. I&amp;rsquo;m not ARGUING that with you. I&amp;rsquo;m not ARGUING that with you Harry! Harry&amp;hellip; Harry&amp;hellip; Yeah Harry&amp;hellip; but can he DO the job. I know he can GET the job but can he do the job?&lt;br /&gt;&lt;div style="text-align: right;"&gt;Mr. Waturi, Joe vs the Volcano&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;Still there is fun to be had in the whole exercise. For the record I tend towards the static languages. Despite my recent fun with Python I have spent the last four years neck deep in C# and really am loving it. Our application uses over 75,000 lines of JavaScript, and every opportunity I have to decrease that number I will take. (Part of my excitement about Silverlight is just not having to write as much JavaScript anymore) I see the power in dynamic, I&amp;rsquo;ve done some really cool things with JavaScript and I&amp;rsquo;ve really enjoyed working in Python again&amp;hellip;. but I believe there is less of a ceiling for static languages then there is for dynamic in terms of tool set, performance and the ability to handle large projects with large teams.&lt;br /&gt;&lt;br /&gt;Anyway, Mat Podwsocki presents a great summary of the debate with links to a few bloggers here :&lt;br /&gt;&lt;br /&gt;&lt;a href="http://codebetter.com/blogs/matthew.podwysocki/archive/2008/05/28/static-versus-dynamic-languages-attack-of-the-clones.aspx"&gt;&lt;a href="http://codebetter.com/blogs/matthew.podwysocki/archive/2008/05/28/static-versus-dynamic-languages-attack-of-the-clones.aspx"&gt;http://codebetter.com/blogs/matthew.podwysocki/archive/2008/05/28/static-versus-dynamic-languages-attack-of-the-clones.aspx&lt;/a&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The original Steve Yegge presentation is here :&lt;br /&gt;&lt;br /&gt;&lt;a href="http://steve-yegge.blogspot.com/2008/05/dynamic-languages-strike-back.html"&gt;&lt;a href="http://steve-yegge.blogspot.com/2008/05/dynamic-languages-strike-back.html"&gt;http://steve-yegge.blogspot.com/2008/05/dynamic-languages-strike-back.html&lt;/a&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;And the response that I enjoyed the most is here :&lt;br /&gt;&lt;br /&gt;&lt;a href="http://codebetter.com/blogs/gregyoung/archive/2008/05/18/revenge-of-the-statically-typed-languages.aspx"&gt;&lt;a href="http://codebetter.com/blogs/gregyoung/archive/2008/05/18/revenge-of-the-statically-typed-languages.aspx"&gt;http://codebetter.com/blogs/gregyoung/archive/2008/05/18/revenge-of-the-statically-typed-languages.aspx&lt;/a&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I enjoyed Greg&amp;rsquo;s response because it just really got me thinking. I honestly know nothing about the design by contract research that&amp;rsquo;s going on, but it just feels like something that makes sense. I got excited just imagining seeing errors like the ones described showing up in our project at compile time. I believe that if we were using such a system we would see a real improvement in quality. I can see how some would see this as an unnecessary burden on the developer, but these are probably the same crowd not writing their unit tests.&lt;br /&gt;&lt;br /&gt;Design by contract is really a great example of what I mean when I&amp;rsquo;m thinking about the potential for statically typed languages in tool sets.&lt;/p&gt;</description></item><item><title>Gadgets in Blogger</title><link>https://chriswhitmore.com/2008/06/13/gadgets-in-blogger/</link><pubDate>Fri, 13 Jun 2008 22:30:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/06/13/gadgets-in-blogger/</guid><description>&lt;p&gt;So I&amp;rsquo;ve actually started my &lt;a href="http://blogquotes.appspot.com/"&gt;blogquotes&lt;/a&gt; project which was intended as a widget style provider for random quotes (from a personal library) to appear somewhere on my site. I&amp;rsquo;m using the new Google app engine for this project and so far I have to say it&amp;rsquo;s pretty damn easy. From barely knowing python to having a &lt;a href="http://djangoproject.com/"&gt;django&lt;/a&gt; templated, gql driven tiny quote engine. Granted it&amp;rsquo;s the &amp;ldquo;hello world&amp;rdquo; of web apps, but still considering I have an application running on Google, with built-in authentication and datastore &amp;hellip;. I&amp;rsquo;m pretty impressed.&lt;br /&gt;&lt;br /&gt;I&amp;rsquo;ve played with ruby on rails before, but so far I&amp;rsquo;m far more comfortable with what I&amp;rsquo;m building here than I ever was with Ruby. (I don&amp;rsquo;t think I&amp;rsquo;ll start detailing that here and now as this post is more about my gadget plans and I don&amp;rsquo;t care)&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_doSNwQwU8XA/SFNgB5BrkwI/AAAAAAAAA_o/SjiOTgpCWqE/s1600-h/gadgetcount.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="https://chriswhitmore.com/assets/gadgetcount.jpg" alt="" id="BLOGGER_PHOTO_ID_5211614779401802498" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;So I have my application, and I have the beginnings of the backend for my quote providers. I just went to &lt;a href="http://draft.blogger.com/"&gt;draft.blogger.com&lt;/a&gt; where google tests out new features and clicked &amp;ldquo;add gadget&amp;rdquo; from the layout view of the blog. I actually thought that what I was looking at was a mistake. 43,000 page elements and gadgets? How is that useful to anyone? How am I not just making the problem worse by adding another one that no one will find and no one but me will use? This is just insane.&lt;br /&gt;&lt;br /&gt;I did a search for quote on that page and it returned 13, thankfully none of them are what I have in mind. They are all basically syndication style &amp;ldquo;[fill in topic] quote of the day&amp;rdquo; style widgets. There actually seem to be a surprising number of gadgets like that. Things that just don&amp;rsquo;t really allow the user to add anything meaningful or contextual to the web. I suppose a lot of people use their blogs as their home page, but for me having the weather and a stock ticker on my blog just doesn&amp;rsquo;t make sense. My Google home page sure, but on millions of public blogs not so much.&lt;br /&gt;&lt;br /&gt;There also seems to be too many thinly disguised marketing devices and cheap looking ad-style nothing widgets. Personally I would like to see more of the types of gadgets that Google themselves are creating, where user generated content is the focus (my youtube videos, my picasa albums, my google docs etc) as opposed to content that is one size fits all for millions of blogs. At least it gives me some hope that what I&amp;rsquo;m doing is not a complete right off.&lt;br /&gt;&lt;br /&gt;The data won&amp;rsquo;t stick, but if you have a google account you can log in and add a quote to the pre-alpha-hello-world-version of blog quotes at &lt;a href="http://blogquotes.appspot.com"&gt;&lt;a href="http://blogquotes.appspot.com"&gt;http://blogquotes.appspot.com&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Google's changing the rules again (appspot)</title><link>https://chriswhitmore.com/2008/06/10/googles-changing-the-rules-again-appspot/</link><pubDate>Tue, 10 Jun 2008 22:38:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/06/10/googles-changing-the-rules-again-appspot/</guid><description>&lt;p&gt;I am super excited about Google&amp;rsquo;s recent foray into cloud computing, &lt;a href="http://appspot.com"&gt;the app engine&lt;/a&gt;. They are not first, I realize Amazon has been doing some pretty cool things with the &lt;a href="http://www.amazon.com/gp/browse.html?node=16427261"&gt;S3 services &lt;/a&gt;and their computing services but the ability to simply and easily have an application that can leverage &lt;a href="http://labs.google.com/papers/bigtable.html"&gt;BigTable&lt;/a&gt; and &lt;a href="http://code.google.com/appengine/docs/datastore/gqlreference.html"&gt;GQL&lt;/a&gt;, &lt;a href="http://code.google.com/appengine/docs/users/"&gt;google account authentication&lt;/a&gt;, &lt;a href="http://code.google.com/appengine/docs/images/"&gt;image manipulation&lt;/a&gt;, &lt;a href="http://code.google.com/appengine/docs/memcache/"&gt;memcache &lt;/a&gt;and having that all live within the seemingly infinite scalability of the &lt;a href="http://en.wikipedia.org/wiki/Google_platform"&gt;google platform&lt;/a&gt; is extremely exciting for me. In fact it&amp;rsquo;s the whole reason for my recent resurgent interest in python. App engine out of the gate is a python runtime environment which is robust enough even to run frameworks like Django for your web apps.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://arstechnica.com/news.ars/post/20080408-analysis-google-app-engine-alluring-will-be-hard-to-escape.html"&gt;ArsTechnica had some good comments on the service&lt;/a&gt; and one of their cheif concerns was being locked into the platform. I think this is not an invalid concern, but that the tools will be written to make migration from one platform to another a relatively trivial matter. From what I understand of GQL it is a subset of normal SQL with limitations like no joins which should make data/code migration easy, but scalability and hosting maybe not so much. There are open source implementations such as &lt;a href="http://www.hypertable.org/"&gt;HyperTable&lt;/a&gt; which is modeled after Google&amp;rsquo;s data platform, but ultimately the article is right. Personally I don&amp;rsquo;t see myself writing large scale applications on this platform though, I see this much more as a utility model for small useful services. &lt;br /&gt;&lt;br /&gt;I registered for the preview of app engine on the same day it was announced but not early enough to be one of the lucky first 10,000. When I did get my invite a couple weeks ago I immediately started to create applications. It&amp;rsquo;s clear this is exactly what everyone else did and I&amp;rsquo;m glad Google has capped usage at three applications per developer. Already it&amp;rsquo;s almost as bad as trying to register a domain. For each of my three applications I had to try a series of names before getting a clear one. In other words none of my ideas are at all unique. :-) On a positive note when I checked the names I was looking for there were also no uploaded applications for any of them. I predict Google may have to have an expiry date on these - I can see myself taking weeks or months to finally get anything uploaded.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;a href="http://silitrader.appspot.com"&gt;http://silitrader.appspot.com&lt;/a&gt;&lt;/span&gt; (silverlight port of the old game OilBaron)&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;a href="http://wherediditallgo.appspot.com"&gt;http://wherediditallgo.appspot.com&lt;/a&gt; &lt;/span&gt; (personal spending tracker)&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;a href="http://blogquotes.appspot.com"&gt;http://blogquotes.appspot.com&lt;/a&gt; &lt;/span&gt; &lt;br /&gt;&lt;br /&gt;I actually created that last application as I was trying to find a simple means of having a rotating list of hand picked quotes show up in the header of my blog. Back when somatose.com was hosted with &lt;a href="http://lunarpages.com"&gt;LunarPages&lt;/a&gt; this would have been trivial, throw the quotes into a textfile, write a script to randomly choose and insert one as I was building the page. I moved from a hosted environment to using blogger so that I would stop tinkering and focus on actual content. I spent most of tonight tinkering though, building up to actually building blogquotes. (By the way I am sure there are other blog quote like tools out there, but this is a rare case where I don&amp;rsquo;t mind reinventing the wheel somewhat)&lt;br /&gt;&lt;br /&gt;Now the nature of the tinkering has just changed. Rather than write a small shell script that spits out random lines I will actually build something of a small application/service. The quotes will be stored using the datastore api (GQL), and will be publicly visible. Other users will be able to authenticate and store their quotes in a similar manner. A widget will be built and hosted from that application that enables anyone to paste in a snippet of html to add random quotes from their personal db. I as a user can subscribe to my friend&amp;rsquo;s quotes. It&amp;rsquo;s remarkable really, the differences and yet familiarity of this new ecosystem. And while I do miss the control of simply writing a little shell script I have to say I love the idea of the internet being populated by these little widgets of functionality. The emergence of ajax and increasing power on the client means that millions of non-technical users who blog on platforms like blogger and wordpress can very easily use my quote engine. How cool is that?&lt;br /&gt;&lt;br /&gt;Google&amp;rsquo;s API&amp;rsquo;s (and Amazon&amp;rsquo;s) are proving to be the next Win32. Massively widespread and base functionality that anyone can build on. The plumbing is there for us to be able to chain together these small tools/widgets in much the same way a clever unix user could within their shell. And once the honeymoon wears off and I actually give some though to hosting data in the US and dealing with popularity should one of my apps get hammered and I end up having to pay Google usage fees&amp;hellip; well until all those little issues I can just be excited again about the changing landscape.&lt;/p&gt;</description></item><item><title>Moving to the interior</title><link>https://chriswhitmore.com/2008/06/10/moving-to-the-interior/</link><pubDate>Tue, 10 Jun 2008 08:13:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/06/10/moving-to-the-interior/</guid><description>&lt;p&gt;&lt;img id="bb9i" style="margin: 1em 1em 0pt 0pt; float: left;" src="http://docs.google.com/File?id=dd2p7twj_57ctq3jdfv_b" height="208" width="155"&gt;&lt;br id="j2:e1"&gt;The promise of the electronic office has been so damn close for so damn long now. I know there are thousands and thousands of people out there who now work primarily from home, but I remain on the outside looking in. (or inside looking out?) Visions of a city like &lt;a title="You can live in a castle in the mountains!" href="http://ilovenelson.com/about-city/" id="gs6g"&gt;Nelson&lt;/a&gt; or maybe Prince Rupert dance in my head, with me in my large solitary office overlooking the lake, hardwood everywhere, the distant sound of my daughter playing outside. &amp;lt;deep virtual breath&amp;gt; My neural implants connect me to the office at &amp;ldquo;ludicrous speed&amp;rdquo; and my Neo-like abilities make distance immaterial. &lt;br id="j2:e2"&gt;&lt;br id="j2:e3"&gt;Reading &lt;a title="reddit" href="http://reddit.com" id="e:kp"&gt;reddit&lt;/a&gt; too much can make you paranoid (and slightly dysfunctional, and unproductive, and slightly dumber) and these days I&amp;rsquo;m thinking too much about the impending collapse of our society and my desire to get the hell out of dodge before it happens. Preferably a nice small mountain town on a lake here in BC. Somewhere I can grow and fish/hunt food if the shit hits the fan. Somewhere where I&amp;rsquo;m not spending 40% of my income on housing. Of course, the idea of me hunting is almost enough to make me cry with laughter&amp;hellip; I am so not a hunter. &lt;br id="j2:e4"&gt;&lt;br id="j2:e5"&gt;Anyway, this post is about robots not the apocalypse. There are a few robots now intended to make the awkward ritual of sitting around in a board room and talking to a TV a little more awkward by having the TV come see you! Wonderful wonderful idea, and I&amp;rsquo;m sure extremely fun for the remote worker. A little less fun for the nervous employee constantly watching their backs for this thing to roll up behind them. &lt;br id="j2:e6"&gt;&lt;img id="l29j" style="margin: 1em 0pt 0pt 1em; width: 130px; height: 180px; float: right;" src="http://docs.google.com/File?id=dd2p7twj_59gqk8d9hq_b"&gt;&lt;br id="j2:e7"&gt;I can&amp;rsquo;t imagine this thing not having kick-me signs and other paraphernalia hanging from it within minutes in mockery of the whole process. I also can&amp;rsquo;t imagine being the remote worker and resisting the urge to roll around the office all day looking for interesting things to see. I think an episode of the office where Michael gets one of these would be brilliant and the comedic geniuses on that show could have some fun. &lt;br id="j2:e8"&gt;&lt;br id="j2:e9"&gt;This isn&amp;rsquo;t what I normally consider a robot because it&amp;rsquo;s not autonomous, but it&amp;rsquo;s still cool, and if it helps me unplug from the city while staying connected to work I love it. &lt;br id="j2:e13"&gt; &lt;br id="ynh20"&gt;&lt;a id="j2:e10" href="http://www.engadget.com/2007/03/07/giraffe-video-conferencing-robot-to-weird-employees-out/"&gt;Giraffe video conferencing robot to weird employees out - Engadget&lt;/a&gt;&lt;br id="r2-j0"&gt;&lt;br id="hiuj0"&gt;&lt;a title="HeadThere - the maker of the Giraffe" href="http://www.headthere.com/" id="dv-m"&gt;HeadThere - the maker of the Giraffe&lt;/a&gt; &lt;br id="evp90"&gt;&lt;br id="cu3r0"&gt;&lt;br id="v5_50"&gt;&lt;/p&gt;</description></item><item><title>Do I really need to embrace C++?</title><link>https://chriswhitmore.com/2008/06/07/do-i-really-need-to-embrace-c/</link><pubDate>Sat, 07 Jun 2008 13:21:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/06/07/do-i-really-need-to-embrace-c/</guid><description>&lt;p&gt;My internal debate rages on&amp;hellip; I have some C++ courses in the pipeline so I will definitely learn more than the basic understanding/grasp I have now&amp;hellip; &lt;br /&gt;&lt;br /&gt;Still though. Currently I associate C++ proponents with old-school attitudes on the need for absolute control and a fear of newer levels of abstraction that are allowing increasing complex and large projects. Garbage collection, the .NET framework etc, are all grouped together into a category of tools that only &amp;ldquo;weak&amp;rdquo; programmers need. I recoil pretty hard from this line of thinking and associate it with a dangerous cowboy like attitude towards engineering. &lt;br /&gt;&lt;br /&gt;There is a lure there, to join the elite, to be one of those cowboys who don&amp;rsquo;t need frameworks or garbage collection and who&amp;rsquo;s code can scream past yours with sheer force of will by the programmer. So I&amp;rsquo;m constantly torn between mockery and envy. I will say that I think it&amp;rsquo;s important to learn and think in C++ because the deeper our understanding of the systems we develop for the better off we are. I&amp;rsquo;d say the same thing about assembly though and would be just inclined to write large systems in C++ as I would in assembly. &lt;br /&gt;&lt;br /&gt;My own line of thinking is that these abstraction layers we&amp;rsquo;ve invented are more akin to compilers and file systems and OS API&amp;rsquo;s. Why should we all re-invent the wheel (and poorly) when these problems can be solved in a generic way? &lt;br /&gt;&lt;br /&gt;Anyway C/C++ are probably not going anywhere and have their niche, but I thought I would post this article to preserve it in my memory bank. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.mistybeach.com/articles/WhyIDontLikeCPlusPlusForLargeProjects.html"&gt;&lt;a href="http://www.mistybeach.com/articles/WhyIDontLikeCPlusPlusForLargeProjects.html"&gt;http://www.mistybeach.com/articles/WhyIDontLikeCPlusPlusForLargeProjects.html&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Power Consumption</title><link>https://chriswhitmore.com/2008/06/06/power-consumption/</link><pubDate>Fri, 06 Jun 2008 20:47:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/06/06/power-consumption/</guid><description>&lt;p&gt;I&amp;rsquo;m a graphing junkie, I have to admit it. So I was pretty pleased to discover that my power company (&lt;a title="BC Hydro" href="http://bchydro.ca" id="rh1a"&gt;BC Hydro&lt;/a&gt; ) provides some interesting consumption graphs for month to month kilowatts per hour usage. I&amp;rsquo;m pretty sure my meter is only read every two months so some of the resolution is lost in this, but still it&amp;rsquo;s helpful. &lt;br id="rb6o2"&gt;&lt;br id="rb6o3"&gt;One of the more striking trends I&amp;rsquo;ve seen in the data has been the birth of my daughter. Late nights, tons more laundry, cooking and heating bottles and leaving fans on so she can sleep. Power consciousness kinda goes out the window while we&amp;rsquo;re dealing with an unhappy Maggie. &lt;br id="rb6o4"&gt;&lt;br id="rb6o5"&gt;&lt;div id="yazf" style="padding: 1em 0pt; text-align: left;"&gt;&lt;img id="rb6o6" style="width: 516px; height: 418px;" src="http://docs.google.com/File?id=dd2p7twj_56gh3srwgs_b"&gt;&lt;/div&gt;&lt;br id="rb6o8"&gt;Summer should see the trend reverse and then I think we&amp;rsquo;ll have to get creative in terms of keeping it down. &lt;br id="rb6o9"&gt;&lt;br id="rb6o10"&gt; &lt;br id="k1-:0"&gt;&lt;/p&gt;</description></item><item><title>Vampires in Space</title><link>https://chriswhitmore.com/2008/05/31/vampires-in-space/</link><pubDate>Sat, 31 May 2008 22:27:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/05/31/vampires-in-space/</guid><description>&lt;p&gt;I read a very fun book on my holiday in Manitoba this last few weeks. It&amp;rsquo;s written by a biologist who has turned to fiction with an eye to producing some good hard core science based fiction. I would compare his work to William Gibson and Arthur C. Clarke.&lt;br /&gt;&lt;br /&gt;The book is called &amp;ldquo;BlindSight&amp;rdquo; by Peter Watts, and I&amp;rsquo;ve added it to my LibraryThing, there is a link to my full review below.&lt;br /&gt;&lt;a href="http://www.librarything.com/work/1333265/reviews/31302401"&gt;&lt;br /&gt;&lt;a href="http://www.librarything.com/work/1333265/reviews/31302401"&gt;http://www.librarything.com/work/1333265/reviews/31302401&lt;/a&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As an added bonus (I discovered this after buying the book) the author has published it under a &lt;a href="http://creativecommons.org"&gt;creative commons&lt;/a&gt; license and you can read the entire book online for free. How cool is that? (&lt;a href="http://www.rifters.com/real/Blindsight.htm"&gt;Read it here&lt;/a&gt;) &lt;br /&gt;&lt;br /&gt;There is a lot to chew on in this book, but my post subject says it all. Seriously though, don&amp;rsquo;t judge based on that, it&amp;rsquo;s a good book. No really&amp;hellip;&lt;br /&gt;&lt;table border="0"&gt;&lt;br /&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td align="center" valign="top"&gt;&lt;br /&gt;&lt;b&gt;No&lt;/b&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_doSNwQwU8XA/SEI0ZIEuC0I/AAAAAAAAA9U/TJMiu5FLbsU/s1600-h/cyoa071.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; cursor: pointer; width: 199px; height: 329px;" src="https://chriswhitmore.com/assets/cyoa071.jpg" alt="" id="BLOGGER_PHOTO_ID_5206781725462367042" border="0" /&gt;&lt;br /&gt;&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;&lt;td align="center" valign="top"&gt;&lt;br /&gt;&lt;i&gt;Yes&lt;/i&gt;&lt;br /&gt;&lt;img style="width: 221px; height: 330px;" alt="The image “http://images.amazon.com/images/P/0765312182.01._SX140_SCLZZZZZZZ_.jpg” cannot be displayed, because it contains errors." src="https://chriswhitmore.com/assets/0765312182.01._SX140_SCLZZZZZZZ_.jpg" /&gt;&lt;br /&gt;&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;</description></item><item><title>Javascript session hacking</title><link>https://chriswhitmore.com/2008/05/13/javascript-session-hacking/</link><pubDate>Tue, 13 May 2008 01:08:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/05/13/javascript-session-hacking/</guid><description>&lt;div&gt;I had to blog this, and yeah I'm going to be the billionth person to do so, but that's ok because no one reads my blog and it's basically just my personal public archive. (ppa?) &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This guy &lt;a href="http://www.thomasfrank.se/sessionvars.html"&gt;http://www.thomasfrank.se/sessionvars.html&lt;/a&gt; has managed to find a very clever place to store data within the browser without resorting to cookies, flash or anything beyond basic cross browser javascript. Apparently "&lt;span class="Apple-style-span" style="font-family:'courier new';"&gt;window.name"&lt;/span&gt; which lost it's usefulness when the spammers started making popups obsolete can contain arbitrarily long strings that persist as long as that window is open (equivalent to a session cookie) &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This is damn cool, and while a part of me twinges at the hack-ish nature of overloading a window property with a bunch of json strings, well this is javascript we're talking about here so what the hell.  You're already standing out in the rain trying to build a fire with soggy sticks and no pants so why not use what you've been given. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This is just one of those things I know I'll want to come back to one day for one of my pet projects so I thought I'd blog it. &lt;/div&gt;</description></item><item><title>Saturday night science link (DNA Visualization)</title><link>https://chriswhitmore.com/2008/05/11/saturday-night-science-link-dna-visualization/</link><pubDate>Sun, 11 May 2008 02:45:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/05/11/saturday-night-science-link-dna-visualization/</guid><description>&lt;p&gt;Fantastic molecular visualization of how dna, rna and ribosomes work&amp;hellip; where was this kind of stuff when I was going to school?&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;object width="425" height="355"&gt;&lt;param name="movie" value="http://www.youtube.com/v/4PKjF7OumYo&amp;amp;hl=en"&gt;&lt;param name="wmode" value="transparent"&gt;&lt;embed src="http://www.youtube.com/v/4PKjF7OumYo&amp;amp;hl=en" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;/div&gt;&lt;/p&gt;</description></item><item><title>ASP.NET Ajax Pendulum</title><link>https://chriswhitmore.com/2008/05/11/asp.net-ajax-pendulum/</link><pubDate>Sun, 11 May 2008 00:53:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/05/11/asp.net-ajax-pendulum/</guid><description>&lt;p&gt;I&amp;rsquo;m currently working on moving a web application from using some ad-hoc javascript and iframes to a full fledged &lt;a href="http://asp.net/ajax/"&gt;ASP.NET Ajax&lt;/a&gt; implementation based around &lt;a href="http://telerik.com/"&gt;Telerik&amp;rsquo;s RadControls&lt;/a&gt; and a suite of our own controls. This is the third application we&amp;rsquo;ve given the ajax treatment to and each time we&amp;rsquo;ve taken a slightly different approach.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Approach 1 &amp;hellip;   &amp;ldquo;Javascript + Web Services&amp;rdquo; &lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Full view manager/page controller implementation on the client side to handle events thrown by all the components on the page&lt;/li&gt;&lt;li&gt;Homegrown &amp;ldquo;ServiceManager&amp;rdquo; to handle brokering calls to the server &lt;ul&gt; &lt;li&gt;Centralized error handling&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Shared message contract base class to allow &amp;ldquo;sub-messaging&amp;rdquo; for the server to send information to the view controller on the client&lt;/li&gt;&lt;li&gt;Blocking calls when things needed to be &amp;ldquo;modal&amp;rdquo; or serialized&lt;/li&gt;&lt;li&gt;&amp;hellip; we had intentions of also building in grouping of calls&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&amp;hellip; we had intentions of canceling redundant calls when the user was asking for something that made a previous call unnecessary&lt;br /&gt;&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Chatty - many calls, small amounts of data (largely json)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Javascript controls that render almost strictly client side based on data delivered over web services&lt;/li&gt;&lt;li&gt;Zero postbacks / Very fast&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li style=""&gt;&lt;span class="Apple-style-span" style="color: rgb(255, 0, 0);"&gt;Expensive/Complex development and maintenance&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li style=""&gt;&lt;span class="Apple-style-span" style="color: rgb(255, 0, 0);"&gt;Prone to memory leaks&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=""&gt;&lt;span class="Apple-style-span" style="color: rgb(255, 0, 0);"&gt;More difficult to leverage third party controls &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(255, 0, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Approach 2 &amp;hellip;    &amp;ldquo;Update Panels&amp;rdquo;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Traditional ASP.NET development with a sprinkling of update panels where it made sense&lt;/li&gt;&lt;li&gt;Chunky communication&amp;hellip; partial postbacks, but still heavy&lt;/li&gt;&lt;li&gt;&amp;ldquo;Simple&amp;rdquo; development - UpdatePanels were spotty at the time, there were quite a few workarounds hacked in to this interface&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Medium reliance on third party controls&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="color: rgb(255, 0, 0);"&gt;Less performance than &amp;ldquo;Javascript + Webservices&amp;rdquo;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="color: rgb(255, 0, 0);"&gt;Less transparency and control to developers&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Approach 3 &amp;hellip;   &amp;ldquo;Javascript + Web Services + Update Panels&amp;rdquo;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;A view controller/ page manager approach similar to Approach 1 except that in this iteration we are relying on the ScriptManager and it&amp;rsquo;s events to handle a lot of what we were previously rolling on our own.&lt;/li&gt;&lt;li&gt;A heavy usage of Telerik&amp;rsquo;s &lt;a href="http://www.telerik.com/products/aspnet-ajax/what-is-radcontrols-prometheus.aspx"&gt;Prometheus&lt;/a&gt; suite of controls, which in turn is built against the Microsoft Ajax Framework&lt;/li&gt;&lt;li&gt;Webservice layer for a class of managed actions where we control the control flow via our view controller&lt;/li&gt;&lt;li&gt;Partial updates for more complex control interactions/workflows &lt;ul&gt;&lt;li&gt;These are sometimes triggered by the controls themselves in which case we are dealing with &amp;ldquo;chunky&amp;rdquo; transactions&lt;/li&gt;&lt;li&gt;Othertimes triggered by the page manager in which case we have small requests and potentially heavy responses&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Good use of third party controls&lt;/li&gt;&lt;li&gt;Chunky or Chatty based on need&lt;/li&gt;&lt;li&gt;Medium development complexity&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="color: rgb(255, 0, 0);"&gt;Less transparency/control for developers&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="color: rgb(255, 0, 0);"&gt;High development complexity&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="color: rgb(255, 0, 0);"&gt;Better performance than Approach 2) but less than 1) &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="color: rgb(255, 0, 0);"&gt;Still prone to memory leaks&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So you can see across these three different applications we&amp;rsquo;re dealing with a swinging pendulum of ajax development methodologies and philosophies. My hope with our most recent approach was that we would have the strength of increased reliance on Microsoft&amp;rsquo;s framework + Telerik&amp;rsquo;s suite of controls combined with hooks and web services to eek out that extra level of performance whenever needed. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Of course in this latest iteration we also have the added complexity of having to port legacy controls on a very difficult timeline. So we have a collection of editors, some of which are doing chunky partial post-backs whereas some of our newer type editors are using a more&amp;hellip; let&amp;rsquo;s say finely tuned approach where only the necessary data is sent and only limited page updates are performed. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The third option still has some proving out to do. Rather then being the perfect blend of complexity vs performance vs reuse vs transparency is instead turning out to be not especially good at any of these.  I&amp;rsquo;m frankly a bit frustrated by the whole exercise right now an am increasingly eyeing the glorious promises of &lt;a href="http://silverlight.net/"&gt;Silverlight&lt;/a&gt;. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Really I don&amp;rsquo;t see this stuff getting any easier until we&amp;rsquo;re either seeing browsers that have equivalent capabilities in supporting Html 5 and all the exciting new javascript features of the future or a widespread installed base of Silverlight 2. haha&amp;hellip; right. &lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_doSNwQwU8XA/SCeAiYgT64I/AAAAAAAAA8U/7ah9x9RnVzo/s1600-h/AjaxComplexity.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="https://chriswhitmore.com/assets/AjaxComplexity.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5199265623004408706" /&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>poetic words = exciters of nearby symbols</title><link>https://chriswhitmore.com/2008/05/07/poetic-words-exciters-of-nearby-symbols/</link><pubDate>Wed, 07 May 2008 00:07:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/05/07/poetic-words-exciters-of-nearby-symbols/</guid><description>&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://images.amazon.com/images/P/0465026567.01._SX140_SCLZZZZZZZ_.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 200px;" src="https://chriswhitmore.com/assets/0465026567.01._SX140_SCLZZZZZZZ_.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;In &lt;a href="http://www.librarything.com/work/5619/30253646"&gt;GEB&lt;/a&gt; Hofstadter mentions the complexity in building an isomorphism between two poems written in two languages. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&amp;ldquo;In ordinary language, the task of translation is more straightforward, since to each word or phrase in the original language, there can usually be found a corresponding word or phrase in the new language. By contrast, in a poem of this type, [Jabberwocky, Lewis Carroll] &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;many &amp;ldquo;words&amp;rdquo; do not carry ordinary meaning, but act purely as exciters of nearby symbols&lt;/span&gt;. However what is nearby in one language may be remote in another.&amp;quot;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;Reading that acted as an exciter for my own interest in poetry. I immediately think about some of the poetry I have read which had the most impact for me and it did exactly this. The ability of a good poet to draw scenes by exciting patterns of shared experience and perception is really amazing. Choosing those &amp;ldquo;words that excite nearby symbols&amp;rdquo; is a bit of a game and for me what makes trying to write poetry enjoyable. It becomes almost technical or like solving a problem. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I am often cynical that poetry can be really widely appealing if only because the most poignant and effective poems I&amp;rsquo;ve read require a familiarity with the writer and a shared experience that allows compact transfer of imagery. Then again, some of the power in the compression and lossy nature of these poetic images is that there is room for interpretation in the eye of the beholder.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style=""&gt;&lt;span class="Apple-style-span" style="color: rgb(102, 102, 0);"&gt;In a field at dusk, trees made short by distance, a line of black on blacker at a horizon pulled ever closer by night&amp;hellip;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/p&gt;</description></item><item><title>I've forgotten how much I enjoy Unix</title><link>https://chriswhitmore.com/2008/05/05/ive-forgotten-how-much-i-enjoy-unix/</link><pubDate>Mon, 05 May 2008 23:35:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/05/05/ive-forgotten-how-much-i-enjoy-unix/</guid><description>&lt;p&gt;I just finished reading &lt;a href="http://www.librarything.com/work/2051/reviews/29736813"&gt;&amp;ldquo;The Dream Machine&amp;rdquo;&lt;/a&gt; and getting a very cool look at some early history of computing including the birth of Multics and it&amp;rsquo;s spin off and almost more interesting the birth of tools like email and ftp as a way to actually do something with the ARPANET that was being built. A great read for anyone interested in how we collectively have arrived at where we are today in computing. And as it happens, I&amp;rsquo;m also currently challenging a course on Unix which as part of the challenge requires that I complete a project before I can write the final exam.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The project itself is great fun actually. I&amp;rsquo;ve been in the world of Microsoft for so long at work that I&amp;rsquo;ve completely forgotten about the old days of living in vi on Solaris as part of my 9-5 work. (CATI programming back then) More than anything about Unix I love the power and flexibility of combining these small well written tools like awk, sed, grep etc. These are incredible tools and it&amp;rsquo;s easy to forget how powerful a fully text driven system really  is.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I remember being completely stoked about Microsoft&amp;rsquo;s &lt;a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx"&gt;powershell&lt;/a&gt; project a few years ago. On the surface it seemed to take everything exciting about a Unix environment and add a layer of object orientation across it so that not only could you fully embracing piping and redirection with the help of some impressive shell programming capabilities but you also had the full .net framework at your fingertips and the ability to use reflection to &amp;ldquo;discover&amp;rdquo; a system at run time. This discover-ability aspect is key, and the importance of &amp;ldquo;man&amp;rdquo; to rusty or newbie Unix users can let you appreciate the value in being able to query objects to ask what they can do. The simplest example of where powershell is so powerful is to just imagine good ole &lt;span class="Apple-style-span" style="font-family:'courier new';"&gt;ls&lt;/span&gt;, but where each element output from ls was an actual file or directory object. If you do nothing then those are simply iterated by ls and essentially .FileName.ToString() gets called for each&amp;hellip; but if you pipe that output to your own iterator you can all of a sudden do some really amazing things with very little effort. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Having said that though I never truly fell into powershell like I have unix in the past. In my opinion it&amp;rsquo;s about the eco-system. The set of utilities in unix work because everything in unix plain old text, meaning the same tools can be strung together to do any countless numbers of tasks without additional support. Compare this to powershell which really loses it&amp;rsquo;s value where .NET doesn&amp;rsquo;t exist. True, there are some amazing providers that bridge gaps into SQL Server, WMI, etc etc. But just the fact that you are now talking about .NET development to create those new bridges means we&amp;rsquo;re half a step behind the accessibility and simplicity of a text file. I do think that powershell will only get better with age, but for now unix as a whole is still king for me even if powershell is sexier. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Anyway, this project I&amp;rsquo;m working on is just a series of clever questions that force you to construct chains of tools to elegantly (or inelegantly) solve a problem. It&amp;rsquo;s extremely fun and in the course of a couple weeks I&amp;rsquo;ve reinstalled cygwin at work, gotten ssh access to my mac at home and have had terminal open for pretty much a week straight on my iMac. It&amp;rsquo;s hard to keep this up without an actual task - and considering I&amp;rsquo;m still doing 95% .NET development i don&amp;rsquo;t expect this will continue for too long but it&amp;rsquo;s a good reminder. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/p&gt;</description></item><item><title>Patches on a centralized VCS in a small team</title><link>https://chriswhitmore.com/2008/04/30/patches-on-a-centralized-vcs-in-a-small-team/</link><pubDate>Wed, 30 Apr 2008 21:52:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/04/30/patches-on-a-centralized-vcs-in-a-small-team/</guid><description>&lt;div&gt; My team is always looking for ways to improve on quality and one of the proposed ideas this year was to follow a model similar to large open source projects where basically every checkin is first proposed as a diff/patch and then vetted into the code base AFTER review.&lt;br /&gt;&lt;br /&gt;Our current setup is a single large subversion repository where our team (~14 developers) all checkout the entire mainline branch we're working on and make commits to mainline as desired. Bugfixes are typically checked into mainline, then merged as requested by QA into the appropriate build. Once checked in the bug is updated in our bugtracker and handed over to another developer for code review.&lt;br /&gt;&lt;br /&gt;But of course, the code is now already checked in, and we're in a state of flux until the second developer gets around to reviewing the code. If problems are found (more often than you might expect) then subsequent checkins are made and not only is mainline in a state of flux (what happens if QA branches here?) but we also have lost the nice clean atomic nature of a single checkin. Merges get harder and tracking the code associated with a bug is just a tiny bit more overhead.&lt;br /&gt;&lt;br /&gt;I also believe that knowing a checkin has already been committed does something mentally to the reviewer. It's no longer as easy to request changes that might seem superficial or strictly style based. In the back of your mind as the reviewer you know that your comments will introduce a messy string of commits that you unconsciously weigh against the importance of your review.&lt;br /&gt;&lt;br /&gt;Our QA lead has often suggested a solution to this problem where code reviews must be done in person and before the checkin. As much as I can see the improvement this would have on quality I personally have issues with the frequent interruptions and delays this would add to the process. Not to mention the challenge of working from home and/or late. Not a good idea.&lt;br /&gt;&lt;br /&gt;So patches it is. I managed to convince my team leads that this was worthy of an experiment and so we chose three people out of a hat and for two weeks it was patches and only patches for all bug fixes. For those two weeks we would use TortoiseSVN to create patches of our changes and attach those patches to bugs in BugTracker. A reviewer would examine the diff rather than a subversion commit log and the process would repeat until the developer got it right.&lt;br /&gt;&lt;br /&gt;I liked the process, but overall it just didn't really fly with the test group. Here are a sampling of some of the reasons :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Complexity in managing multiple ongoing bugs at once&lt;/li&gt;&lt;li&gt;Reviewing via diff lacked enough context, whereas reviewing a subversion log using TortoiseSVN actually let you see the entire files with highlighted differences&lt;/li&gt;&lt;li&gt;Adding binary files seemingly couldn't be done in a patch (rare but annoying)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Extra steps required are often slow on our repository because of size&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;What's interesting is that in retrospect I am having a hard time seeing what the real issue here was. I believe that with diff being as standard as it is and the tool support available out there that almost all of these issues can be solved with some infrastructure and automation around the process. As it is the resistance to the idea and my unwillingness to force unnecessary process has killed this effort for now.&lt;br /&gt;&lt;br /&gt;Given the size of our team and the fact we are all working with fast direct access to subversion it's hard to justify needing to work with patch files. Particularly since "revert changes from this revision" is so easy to do.&lt;br /&gt;&lt;br /&gt;I do think this is one of those things worth pushing again, I may just have to do the legwork to smooth the process and prove the utility before getting everyone on board.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;</description></item><item><title>Terrible ad campaign (seal hunt)</title><link>https://chriswhitmore.com/2008/04/12/terrible-ad-campaign-seal-hunt/</link><pubDate>Sat, 12 Apr 2008 09:27:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/04/12/terrible-ad-campaign-seal-hunt/</guid><description>&lt;p&gt;So when I started this blog I wanted to make a point of not posting one angry rant after another. Essentially trying to follow the sage advice of bloggers like Scott Hansleman who says amongst other advice to: &lt;a href="http://www.hanselman.com/blog/BlogInteresting32WaysToKeepYourBlogFromSucking.aspx"&gt;&amp;ldquo;stick to a topic&amp;rdquo;, &amp;ldquo;avoid politics&amp;rdquo;, &amp;ldquo;don&amp;rsquo;t blog bile&amp;rdquo;&lt;/a&gt; &amp;hellip;&lt;br /&gt;&lt;br /&gt;Well I&amp;rsquo;ll break all those rules now by pointing out my extreme distaste for a series of ads being run by the international fund for animal welfare (IFAW). You can see the ads at &lt;a href="http://www.stopthesealhunt.ca/"&gt;stopthesealhunt.ca &lt;/a&gt;which basically attempt to use guilt and self perceived shallowness to make people act.&lt;br /&gt;&lt;br /&gt;Here are some examples of the ads being run at bus stops in my city :&lt;br /&gt;&lt;br /&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;&amp;lt;img style=&amp;ldquo;cursor:pointer; cursor:hand;&amp;rdquo; src=&amp;quot;/assets/seal_ad1.jpg&amp;quot; border=&amp;ldquo;0&amp;rdquo; alt=&amp;ldquo;&amp;ldquo;id=&amp;ldquo;BLOGGER_PHOTO_ID_5212148087871400082&amp;rdquo; /&amp;gt;&lt;/td&gt;&lt;td&gt;&amp;lt;img style=&amp;ldquo;cursor:pointer; cursor:hand;&amp;rdquo; src=&amp;quot;/assets/seal_ad2.jpg&amp;rdquo; border=&amp;ldquo;0&amp;rdquo; alt=&amp;ldquo;&amp;ldquo;id=&amp;ldquo;BLOGGER_PHOTO_ID_5212148235305695874&amp;rdquo; /&amp;gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Let&amp;rsquo;s put aside the actual question of whether or not hunting seals is immoral or wrong. The point I want to make is that these ads are based on the idea that somehow local/personal concerns should be trumped by global concerns. That any problems that we have in our day to day lives do not justify anger or action because there are bigger problems in the world we should be solving.&lt;br /&gt;&lt;br /&gt;If we as humans actually worked like this we&amp;rsquo;d be frozen by indecision in simply trying to prioritize our actions in the global context. I believe we just do not work like that. We must continue to act locally, as our communities and our daily interactions with each other are the foundation for everything else we can accomplish. Trivializing one issue because a larger one exists does not nullify the original issue. The bus is late, ok fine that&amp;rsquo;s a problem. Seals are dying, that is a problem. People are starving, that is a problem. Apparently by IFAW&amp;rsquo;s logic we would be selfish fools to worry about dying seals knowing that humans are dying.&lt;br /&gt;&lt;br /&gt;Check out this TED talk on prioritizing the world&amp;rsquo;s problems :&lt;br /&gt;&lt;a href="http://www.ted.com/index.php/talks/view/id/62"&gt;http://www.ted.com/index.php/talks/view/id/62&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here&amp;rsquo;s a laundry list of some issues I&amp;rsquo;d rather put effort towards before worrying about seals. (these are from the video above)&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;800 000 million&lt;/span&gt; are starving&lt;/li&gt;&lt;li&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;one billion&lt;/span&gt; lack clean drinking water&lt;/li&gt;&lt;li&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;two billion&lt;/span&gt; lack sanitation&lt;/li&gt;&lt;li&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;two million&lt;/span&gt; dying from aids&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;img style=&amp;ldquo;cursor:pointer; cursor:hand;&amp;rdquo; src=&amp;quot;/assets/seal_myad.jpg&amp;rdquo; border=&amp;ldquo;0&amp;rdquo; alt=&amp;ldquo;&amp;ldquo;id=&amp;ldquo;BLOGGER_PHOTO_ID_5212148345682661666&amp;rdquo; /&amp;gt;&lt;br /&gt;&lt;br /&gt;Anyway, the point is that these issues are not mutually exclusive. I think cruelty to animals is important, but I&amp;rsquo;m offended when this type of marketing uses negative appeals to our emotions with flawed logic.&lt;/p&gt;</description></item><item><title>On the need for re-architecting</title><link>https://chriswhitmore.com/2008/03/30/on-the-need-for-re-architecting/</link><pubDate>Sun, 30 Mar 2008 00:53:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/03/30/on-the-need-for-re-architecting/</guid><description>&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_doSNwQwU8XA/SFVH-KvcH2I/AAAAAAAABBA/2BSSqQ91PaE/s1600-h/escher-relativity.jpg"&gt;&lt;img style="cursor: pointer;" src="https://chriswhitmore.com/assets/escher-relativity.jpg" alt="" id="BLOGGER_PHOTO_ID_5212151277112008546" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I have been grappling with the concept of a rewrite of a relatively successful software product that I&amp;rsquo;ve been involved with since start-up mode. In truth I was googling for compelling stories about why NOT to disappear for a year to do a complete re-engineering of your product (ala Netscape). Mostly because I&amp;rsquo;m concerned about the size of the effort and the resources we have to pull it off. Instead came across this article, espousing the need to fire all your developers!&lt;br /&gt;&lt;br /&gt;&lt;a href="http://mikemason.ca/blog/?p=19"&gt;&lt;a href="http://mikemason.ca/blog/?p=19"&gt;http://mikemason.ca/blog/?p=19&lt;/a&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Well &lt;span&gt;I&amp;rsquo;m&lt;/span&gt; the guy who&amp;rsquo;s been promoted to a more senior developer role (not architect, our group shares that responsibility) but still by Mike&amp;rsquo;s logic the guy who should be fired (?!). I&amp;rsquo;m the guy who now is learning the ropes in management and who happens to really know the product and the business but now swimming in very exciting waters when it comes to our rearchitecting plans.&lt;br /&gt;&lt;br /&gt;What I do have going for me is an incredibly strong team to work with. I&amp;rsquo;m undecided yet as to whether we actually need an ivory tower architect or if our guys can work this with the guidance of our CTO. We&amp;rsquo;ll see, as it&amp;rsquo;s still not too late to change course.&lt;br /&gt;&lt;br /&gt;In any case I think I&amp;rsquo;ll keep an eye on more perspectives like Mike&amp;rsquo;s&amp;hellip;&lt;/p&gt;</description></item><item><title>University Bureaucracy</title><link>https://chriswhitmore.com/2008/03/30/university-bureaucracy/</link><pubDate>Sun, 30 Mar 2008 00:53:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/03/30/university-bureaucracy/</guid><description>&lt;p&gt;Depending on how I choose to count I am now dealing with my fifth or sixth post-secondary institution in my odyssey to finish my computer science degree. One thing that all of the schools I&amp;rsquo;ve dealt with have had in common is a slow and inflexible bureaucracy.&lt;br /&gt;&lt;br /&gt;Of course as a younger man I blamed a lot of my own failings on what I perceived then to be a completely fucked up system (University of Manitoba) that was screwing me over. I paid them for a service and yet the treat me as if I should feel lucky to be there! (Can you imagine dealing with thousands of similar minded young punks who couldn&amp;rsquo;t be bothered to actually read the calendar??)&lt;br /&gt;&lt;br /&gt;&lt;img style="margin: 0px auto 10px; cursor: pointer;" align="right" src="https://chriswhitmore.com/assets/UM_logo.jpg" alt="" id="BLOGGER_PHOTO_ID_5212142124099374338" border="0" /&gt;In retrospect though I can see that most of what was going wrong for me was based on my own mistakes and a failure to read the fine print. I did terribly in my first year of university (terrible = D average) and was put on probation at the UofM. In my frustration I simply packed up and took my business down the road to the University of Winnipeg. (Which also happened to be much closer to where I was working and living) &lt;br /&gt;&lt;br /&gt;Ahh&amp;hellip; I remember being so excited about this fresh start, getting away from the inept and massive machinations at the UofM and getting a much more familiar and friendly experience with the UofW (which was about 1/6 the size of UofM at that time). It only took registration to completely rid me of my naivety. I had gone from a large university with an annoying but efficient phone registration system to one where I was actually standing in lines and dealing with a slow human process full of uncertainty and questions. Worse, my crappy year of courses of course comes along with me; I&amp;rsquo;m still on probation and not every course I passed at UofM is even transferable to my new program.&lt;br /&gt;&lt;br /&gt;It wasn&amp;rsquo;t long before I was grumbling and complaining about the inept staff at UofW. I was a little more on top of things this time around though and was able to get through two solid years of course work having properly navigated the probationary process and meeting requirements from the transfer. It was just as I was settling in that I accepted a transfer with work and moved to Vancouver.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_doSNwQwU8XA/SFU_mCG1suI/AAAAAAAABAQ/fwXOiK-zpz4/s1600-h/schoolmap.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="https://chriswhitmore.com/assets/schoolmap.jpg" alt="" id="BLOGGER_PHOTO_ID_5212142066384351970" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;By this time I was much better at being a student, having learned my lessons the hard way and I had a certain expectation that future navigation of the university bureaucracy would be much easier. Had I been starting over that might have been the case, but instead I was now dealing with inter-provincial transfer rules and a struggle to get credit for the years I had already put in. I messed around for a few months trying to get into UBC and finally had someone recommend that I try Langara college as it would give me a simpler route into the BC system and transferring from there to UBC or SFU would become much easier.&lt;br /&gt;&lt;br /&gt;Langara was great, and because I wasn&amp;rsquo;t seeking credit with Langara for past work it was basically just a matter of signing up and attending. It all might have worked but ultimately I could no longer afford the time involved in getting to and from school during the work day. And for reasons that are totally beyond me, computer science is still one of those subjects that just does not seem to offer consistent night time access, at least not the universities I&amp;rsquo;ve been attending at the times I was there.&lt;br /&gt;&lt;br /&gt;Which finally has led me to the wonderful world of distance education. For the last two years or so I&amp;rsquo;ve been attending Athabasca University which is based in Alberta and at the time of my starting was the only fully accredited post secondary institution in Canada to offer a computer science degree.&lt;br /&gt;&lt;br /&gt;I should say now that I have been pretty happy with my experience with this school for the last couple years. My transfer process was smooth, the course selection/planning process was easy thanks to some good help from an adviser via email and about my only concern right now is how much respect this degree will actually get once I&amp;rsquo;m done all this work.&lt;br /&gt;&lt;br /&gt;Of course anytime you want to do something just a little different then that&amp;rsquo;s when you run into the beuracracy and this school was no different. Here&amp;rsquo;s a timeline of what was involved in challenging a course for credit :&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Feb 24&lt;/span&gt; - Email to exam unit to get the professor&amp;rsquo;s contact info to gain permission to challenge&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Feb 25 &lt;/span&gt;- Reply with professor name&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Feb 26&lt;/span&gt; - Email to professor with short summary and request&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Mar 12&lt;/span&gt; - Email the exam unit again asking for a different contact (still no reply)&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Mar 13&lt;/span&gt; - Reply requesting I try again and get back to the exam unit if no reply in 3 or 4 days&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Mar 17&lt;/span&gt; - Email to professor again&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Mar 16&lt;/span&gt; - Professor reply! (need more background for permission)&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Mar 20&lt;/span&gt; - Email professor with a customized resume&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Mar 20&lt;/span&gt; - Approval! Please contact the exam unit again to arrange&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Mar 20&lt;/span&gt; - Email to exam unit asking for next step&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Mar 25&lt;/span&gt; - Reply all from exam unit &amp;ldquo;can someone help Chris?&amp;quot;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Mar 31&lt;/span&gt; - Still no reply from anyone so I submit what I assume is the right form and notify the exam unit that I didn&amp;rsquo;t want to continue waiting, let me know if I need to do anything else&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Apr 5&lt;/span&gt; - the request is approved! course materials are in the mail.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Wow, 42 days from start to finish just to process my request to challenge an exam. That doesn&amp;rsquo;t include shipping time, or the time it will take to schedule and take the actual exam etc.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_doSNwQwU8XA/SFU_RZ-AWrI/AAAAAAAABAA/vhb4K7lk-7g/s1600-h/brazil_beuracracy.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="https://chriswhitmore.com/assets/brazil_beuracracy.JPG" alt="" id="BLOGGER_PHOTO_ID_5212141712012499634" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I think the big difference between this experience and previous more frustrating challenges with getting things done was that on two separate occasions in this one transaction I had to reach out again in order to get the process moving again. At eighteen I probably would have just written this off as no longer on my plate and waited. If nothing happened it wasn&amp;rsquo;t my fault. I no longer have murderous thoughts at other&amp;rsquo;s ineptitude when deadlines pass and I&amp;rsquo;m stuck in the lurch, I think I just accept that when humans are involved things get slow and error prone. Treat your education like your job and always assume responsibility.&lt;br /&gt;&lt;br /&gt;Still, no one enjoys dealing with this kind of crap do they?&lt;/p&gt;</description></item><item><title>Maggie!</title><link>https://chriswhitmore.com/2008/03/29/maggie/</link><pubDate>Sat, 29 Mar 2008 17:12:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/03/29/maggie/</guid><description>&lt;p&gt;This is one of my favorite pictures of my daughter Maggie. She&amp;rsquo;s not usually this sweet ;-) but at least a few times a day we get a few moments when she&amp;rsquo;s active, smiley and interactive. I took this picture last weekend, so she&amp;rsquo;s about nine weeks old here.&lt;br /&gt;&lt;br /&gt;A lot of Maggie pictures tend to really distort her, and while often cute they don&amp;rsquo;t all equally capture that part of her that really defines her personality (in my eyes). The grin here is very recognizable and actually looks a lot like her cousin Josh. I rarely get any sense of what she will eventually look like, but I can see this smile lasting a few years at least.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_doSNwQwU8XA/SFVGXWPWdPI/AAAAAAAABA4/FxCu6WoWhDA/s1600-h/IMG_3250.JPG-710389.jpg"&gt;&lt;img style="cursor: pointer;" src="https://chriswhitmore.com/assets/IMG_3250.JPG-710389.jpg" alt="" id="BLOGGER_PHOTO_ID_5212149510672119026" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>clever youtube covers</title><link>https://chriswhitmore.com/2008/03/28/clever-youtube-covers/</link><pubDate>Fri, 28 Mar 2008 17:14:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/03/28/clever-youtube-covers/</guid><description>&lt;p&gt;In the spirit of using the blog as a personal online searchable storage medium here is a playlist of some covers on youtube that I totally get a kick out of&amp;hellip; most of these are songs I came across in the past year and am now just logging so I don&amp;rsquo;t forget them.&lt;br /&gt;&lt;br /&gt;Youtube is absolutely full of crap song covers by amateur artists in their basements. I think that&amp;rsquo;s cool and all, I can imagine myself posting something like that when I was first learning guitar but it&amp;rsquo;s not something I want to watch (does anyone?). These are a little different and with the exception of the first cover, which just rocks because it&amp;rsquo;s a wicked song, all do something a little different with the original song. &lt;br /&gt;&lt;ol&gt;&lt;li&gt; &lt;span&gt;&lt;span style="font-weight: bold;"&gt;Fairytale of New York (The Pogues) - The Mahones With Damhnait Doyle&lt;/span&gt;&lt;span style="font-style: italic;"&gt; (a lot like the original, very good)&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span style="font-weight: bold;"&gt;Hey Ya (Outkast) - Matt Weddle of Obadiah Parker&lt;/span&gt; &lt;span style="font-style: italic;"&gt;(very different, I had no idea the lyrics to this song were good. Matt has an amazing voice, wait for the end when he really belts it out)&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;&lt;span style="font-weight: bold;"&gt;I might be wrong (Radiohead) - Amnesiac Quartet&lt;/span&gt; &lt;span style="font-style: italic;"&gt;(jazzy instrumental)&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Idioteque (Radiohead) - &lt;/span&gt;&lt;span&gt;&lt;span style="font-weight: bold;"&gt;Matt Weddle of Obadiah Parker&lt;/span&gt; &lt;span style="font-style: italic;"&gt;(not as good as hey ya, but I happened it across it while looking at the others so here you go)&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Who is it (Bjork) - &lt;/span&gt;&lt;span&gt;&lt;span style="font-weight: bold;"&gt;Matt Weddle of Obadiah Parker&lt;/span&gt; &lt;span style="font-style: italic;"&gt;(it&amp;rsquo;s a Matt Weddle playlist, this song is much more mellow than Bjork&amp;rsquo;s version, doesn&amp;rsquo;t really get good until about half way through)&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt; &lt;br /&gt; &lt;object width="530" height="370"&gt;&lt;param name="movie" value="http://www.youtube.com/p/B0438C58FC11559E"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/p/B0438C58FC11559E" type="application/x-shockwave-flash" width="530" height="370"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;</description></item><item><title>robots are your friends</title><link>https://chriswhitmore.com/2008/03/28/robots-are-your-friends/</link><pubDate>Fri, 28 Mar 2008 13:25:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/03/28/robots-are-your-friends/</guid><description>&lt;p&gt;OMG, I so love this freaky dog robot thing&amp;hellip; we need more like this! Truly exciting the kinds of things that are going on, I can&amp;rsquo;t wait to have a robot servant.&lt;br /&gt;&lt;br /&gt;Watch these all the way through, in the following order. The second one is f&amp;rsquo;n hilarious after you watch the first.&lt;br /&gt;&lt;br /&gt;&lt;p class="MsoNormal"&gt;The original&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;a href="http://gizmodo.com/368651/new-video-of-bigdog-quadruped-robot-is-so-stunning-its-spooky"&gt;Quadruped Robot Dog Thing&lt;/a&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&amp;lt;o:p&amp;gt; &amp;lt;/o:p&amp;gt;&lt;br /&gt;the spoof&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;a href="http://gizmodo.com/372272/video-of-bigdog-beta-quadruped-robot-is-so-stupid-its-hilarious"&gt;Spoof of Quadruped&lt;/a&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&amp;lt;o:p&amp;gt; &amp;lt;/o:p&amp;gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;and just for fun&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;a href="http://gizmodo.com/368979/tennis-ball-cannon-is-a-dogs-best-robotic-friend"&gt;Tennis Ball Cannon&lt;/a&gt;&lt;/p&gt;&lt;/p&gt;</description></item><item><title>I have some reading to do!</title><link>https://chriswhitmore.com/2008/03/27/i-have-some-reading-to-do/</link><pubDate>Thu, 27 Mar 2008 21:55:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/03/27/i-have-some-reading-to-do/</guid><description>&lt;p&gt;&lt;a href="http://listverse.com/literature/top-15-science-fiction-book-series"&gt;&lt;a href="http://listverse.com/literature/top-15-science-fiction-book-series"&gt;http://listverse.com/literature/top-15-science-fiction-book-series&lt;/a&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I came across this list of the best 15 science fiction series ever written. The reason I love seeing this is 1) it contains a bunch of science fiction series I&amp;rsquo;ve already read and thought very highly of and 2) contains some series I&amp;rsquo;ve never even heard of, which of course is exciting since it means I have some reading to do.&lt;br /&gt;&lt;br /&gt;For all I know the guy who wrote the list is totally unqualified and preying on people&amp;rsquo;s ego by throwing familiar items on a list with a bunch of obscure ones, but I&amp;rsquo;m gonna go with it.&lt;br /&gt;&lt;br /&gt;The series I&amp;rsquo;ve read so far :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Space Odyssey&lt;/li&gt;&lt;ul&gt;&lt;li&gt;I&amp;rsquo;ve only read 2001 so far, and only just recently. I had a total Aha! moment reading that book and finally getting bits of the movie that were totally nonsensical to me at the time. The book was great, the movie is overrated.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Rama series&lt;br /&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;My introduction to Arthur C. Clarke (RIP) and definitely my favorite work of his so far. I loved the matter of fact nature with which Clarke wrote, it helped make everything so believable. That and his respect for actual real science which is a total joy to read. &lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Hitch hikers guide to the galaxy&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Douglas Adams is my hero. He is insanely brilliant in the same way George Bush aren&amp;rsquo;t.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Ender&amp;rsquo;s Game&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Honestly I&amp;rsquo;ve lost track of all the Ender books, so I may not have read all of them, but I&amp;rsquo;ve read three or four and loved them all. For straight pure entertainment value I don&amp;rsquo;t know that I&amp;rsquo;ve ever enjoyed a sci-fi book as much as the original Ender&amp;rsquo;s game. I recently got &lt;a href="http://caitlinspencer.com"&gt;Caitlin&lt;/a&gt; to read it and she loved it (she&amp;rsquo;s not exactly a hard core sci-fi fan)&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Foundation Series&lt;/li&gt;&lt;ul&gt;&lt;li&gt;I got through all of these and I think all of the robot books as well. Very quick fun reads that had really nice tie in across books. I&amp;rsquo;m not sure these deserve the top ranking unless we&amp;rsquo;re just talking pure volume. They were enjoyable but not life changing enjoyable like Douglas Adams or Arthur C Clarke though.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;First books on the list I&amp;rsquo;ll go for will probably be ringworld. This is probably the third or fourth time in the last year where I thought to myself I should read it.&lt;/p&gt;</description></item><item><title>eighth first post</title><link>https://chriswhitmore.com/2008/03/27/eighth-first-post/</link><pubDate>Thu, 27 Mar 2008 21:50:00 UTC</pubDate><author>Chris Whitmore</author><guid>https://chriswhitmore.com/2008/03/27/eighth-first-post/</guid><description>&lt;p&gt;Testing blogger hooked up to my own domain&amp;hellip;. we&amp;rsquo;ll see&amp;hellip;.&lt;/p&gt;</description></item></channel></rss>