<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ZephyrBlog</title>
	<atom:link href="http://www.zephyros-systems.co.uk/blog/index.php?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.zephyros-systems.co.uk/blog</link>
	<description>A decade of Delphi, a little less .NET</description>
	<lastBuildDate>Wed, 27 Jan 2010 17:43:34 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>NHibernate Profiler&#8217;s Named Sessions</title>
		<link>http://www.zephyros-systems.co.uk/blog/?p=82</link>
		<comments>http://www.zephyros-systems.co.uk/blog/?p=82#comments</comments>
		<pubDate>Wed, 27 Jan 2010 15:52:29 +0000</pubDate>
		<dc:creator>Russ</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[nhibernate]]></category>
		<category><![CDATA[nhprof]]></category>

		<guid isPermaLink="false">http://www.zephyros-systems.co.uk/blog/?p=82</guid>
		<description><![CDATA[A typical DBA concern in larger shops is that once stored procedures no longer figure (or at least, are used where they are genuinely needed rather than as a mandate), they have no way of knowing what kind of NH-generated SQL might cause problems in production.  A while ago I bought Ayende&#8217;s NHibernate Profiler [...]]]></description>
			<content:encoded><![CDATA[<p>A typical DBA concern in larger shops is that once stored procedures no longer figure (or at least, are used where they are genuinely needed rather than as a mandate), they have no way of knowing what kind of NH-generated SQL might cause problems in production.  A while ago I bought Ayende&#8217;s NHibernate Profiler (hereafter NHProf) as part of a way to try to alleviate these concerns.  </p>
<p>As I&#8217;m sure everyone knows by now, NHProf is a nice tool which helps you spot when you&#8217;re doing something boneheaded when using NHibernate and gives you handy suggestions on what to do to fix it.  It&#8217;ll also show you a every SQL statement you&#8217;re throwing at your database, nicely formatted for your convenience.  It groups these statements into individual <code>ISession</code>s.  So if I have three integration tests based on Northwind that look like this (<code>InTransactionalSession</code> is just shorthand for <code>using(ISession) ... using(ITransaction)</code>):</p>
<pre class="brush: csharp;">
 [Test]
public void CanLoadCustomer()
{
    InTransactionalSession(session =&gt;
    {
         var v = session.Load&lt;Customer&gt;(&quot;ALFKI&quot;);
         Assert.That(v.CompanyName, Is.Not.Null &amp; Is.Not.Empty);
    });
}

[Test]
public void CanGetCustomersByRegion()
{
    InTransactionalSession(session =&gt;
     {
         IList&lt;Customer&gt; customers = session.CreateQuery(&quot;from Customer c where c.Region = 'OR'&quot;)
             .List&lt;Customer&gt;();
         Assert.That(customers.Count, Is.GreaterThan(0));
     });
}

private const string TestCustomerId = &quot;FLURB&quot;;
[Test]
public void CanDoRoundTripPersistenceTest()
{
    InTransactionalSession(session =&gt;
        session.Delete(
            string.Format(&quot;from Customer c where c.CustomerId = '{0}'&quot;,
                TestCustomerId)));

    InTransactionalSession(session =&gt;
        new PersistenceSpecification&lt;Customer&gt;(session)
            .CheckProperty(c =&gt; c.CustomerId, TestCustomerId)
            .CheckProperty(c =&gt; c.CompanyName, &quot;Flurb's Jelly&quot;)
            .CheckProperty(c =&gt; c.ContactName, &quot;Mr. Flurby&quot;)
            .CheckProperty(c =&gt; c.Region, &quot;OR&quot;)
            .VerifyTheMappings());
}
</pre>
<p>I can see four <code>InTransactionalSession</code> calls in those three tests, and the output from NHProf gives us what we might expect:</p>
<div id="attachment_89" class="wp-caption aligncenter" style="width: 169px"><img src="/blog/wp-content/uploads/2010/01/NHNumberedSessions.gif" alt="NHProf Numbered Sessions" title="NHNumberedSessions" width="159" height="151" class="size-full wp-image-89" /><p class="wp-caption-text">NHProf Numbered Sessions</p></div>
<p>Perfectly accurate, but if I had a hundred tests I&#8217;d struggle to notice which test had caused a problem and I&#8217;d lose time tying a session back to a test (ok, not <strong>too</strong> much time &#8211; NHProf has a stack trace tab which lets you double-click jump back to your code, after all, but I like &#8220;at-a-glance&#8221;).  Post-NHProf v1.0, Ayende <a href="http://ayende.com/Blog/archive/2009/09/13/nh-prof-post-v1.0-ideas.aspx#35467">asked for feedback</a> on what should go into future releases.  Since he&#8217;d already covered showing DB plans, I thought I&#8217;d <a href="http://ayende.com/Blog/archive/2009/09/13/nh-prof-post-v1.0-ideas.aspx#35467">take a punt</a> on named sessions.</p>
<p>A week or two back Ayende mailed me to say he&#8217;d added support (great customer service!).  Now all you&#8217;ve got to do is call
<pre class="brush: csharp;">NHibernateProfiler.RenameSessionInProfiler(session, sessionName);</pre>
<p> and the next session that NHProf hears about will take that name.  Combining this with a stack trace gives me exactly what I wanted in just a couple of overloads:</p>
<pre class="brush: csharp;">
        private string lastTestMethodName;
        private int sameMethodCount;

        protected void InTransactionalSession(Action&lt;ISession&gt; action)
        {
            string currentTestMethodName = new StackTrace().GetFrames()[1].GetMethod().Name;
            sameMethodCount = currentTestMethodName == lastTestMethodName ? sameMethodCount + 1 : 1;

            string methodName = string.Format(&quot;{0} #{1}&quot;, currentTestMethodName, sameMethodCount);
            InTransactionalSession(methodName, action);

            lastTestMethodName = currentTestMethodName;
        }

        protected void InTransactionalSession(string sessionName, Action&lt;ISession&gt; doDataAccess)
        {
            using(ISession session = SessionFactory.OpenSession())
            using(ITransaction tx = session.BeginTransaction())
            {
                NHibernateProfiler.RenameSessionInProfiler(session, sessionName);
                doDataAccess(session);
                if(session.Transaction.IsActive)
                    tx.Commit();
            }
        }
</pre>
<p>This results in something that lets me tie sessions to methods at a glance:</p>
<p><img src="http://www.zephyros-systems.co.uk/blog/wp-content/uploads/2010/01/NHProfNamedSessions.gif" alt="NHProf Named Sessions" title="NHProf Named Sessions" width="311" height="158" class="alignleft size-full wp-image-95" /></p>
<p>At the moment, this is great for people new to NH who want a quick way of demonstrating concepts, but it&#8217;s also great as a quick way of running a few tests at once and getting an idea of where your problem areas are.  Cheers Ayende.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zephyros-systems.co.uk/blog/?feed=rss2&amp;p=82</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OpenRasta &#8211; a really ReSTful alternative to WCF</title>
		<link>http://www.zephyros-systems.co.uk/blog/?p=45</link>
		<comments>http://www.zephyros-systems.co.uk/blog/?p=45#comments</comments>
		<pubDate>Mon, 25 Jan 2010 15:18:10 +0000</pubDate>
		<dc:creator>Russ</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[OpenRasta]]></category>
		<category><![CDATA[ReST]]></category>
		<category><![CDATA[WCF]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.zephyros-systems.co.uk/blog/?p=45</guid>
		<description><![CDATA[In my last post, I bemoaned the fact that WCF and ReST are still strange bedfellows and that the ReST starter kit, while promising, was still in no way ready for prime time.  Although a new preview release was uploaded last October, the license is still for preview software and requires that you upgrade [...]]]></description>
			<content:encoded><![CDATA[<p>In my last post, I bemoaned the fact that WCF and ReST are still strange bedfellows and that the ReST starter kit, while promising, was still in no way ready for prime time.  Although a <a href="http://aspnet.codeplex.com/wikipage?title=WCF%20REST&#038;referringTitle=Home">new preview release</a> was uploaded last October, the <a href="http://aspnet.codeplex.com/license">license</a> is still for preview software and requires that you upgrade to a commercial version at the time such a thing might be released. In any case, this post is mostly about why I ended up <strong>not</strong> using it (way back in July last year), and why I ended up going with a relative unknown that turned out to be so much more suitable &#8211; <a href="http://www.openrasta.com/">OpenRasta</a>.</p>
<h3>WCF&#8217;s support for ReST</h3>
<p>WCF is designed as a transport-agnostic support framework for services based on Operations (which have a natural mapping to methods) and Contracts (which have a natural mapping to behaviour-free data transfer objects). This means that your design is inherently RPC in nature.  Initially, we thought this&#8217;d be a good fit.  We knew we needed ReST (or at least, POX over HTTP).   This being the Syndication arm of <a href="http://www.nhs.uk/">NHS Choices</a>, we also thought that in order to conform to government standards we might need SOAP as well.  WCF seemed to fit the bill &#8211; we could write our operations as needed and just host a couple of endpoints: one SOAP, one ReST.  To start with, the development model also seemed simple and familiar.</p>
<p>Well, we had articles to syndicate, we had images, we had some videos and audio clips.  And it&#8217;s at this point that WCF started to let us down.  We also knew we needed various representations of each thing we were syndicating (JSON for digital set-tops and handset consumers, XHTML for a discovery channel), and WCF out of the box didn&#8217;t support multiple representations.  </p>
<p>For a while we used the open source library <a href="http://wcfrestcontrib.codeplex.com/">WcfRestContrib</a>, which goes a long way to providing some kind of content negotiation for WCF.  Based on the HTTP <code>Accept</code> header, WcfRestContrib will switch content type according to its own formatters.  Even this has a limitation, though.  For example, a JSON representation of a video makes almost no sense, and yet we could only supply a fixed set of representations which had to apply to all URIs.  At this point it started to become clear that we were asking too much of a service-based technology with strong <a href="http://en.wikipedia.org/wiki/Remote_procedure_call">RPC</a> overtones.  While we could have extended WCF, the learning curve was steep and unpalatable.  In addition, because we were primarily focussed on the usability of our ReST URI set, our &#8220;Operations&#8221; had become so ReST-centric we wouldn&#8217;t really even have had the mooted &#8220;SOAP-in-parallel&#8221; benefit anyway.</p>
<h3>Stumbling across OpenRasta</h3>
<p>The comments in <a href="http://stackoverflow.com/questions/1006309/is-the-wcf-rest-starter-kit-dead-in-the-water">this StackOverflow post</a> put me onto OpenRasta.  Two things put me off in the middle of last year, though: there wasn&#8217;t much documentation and there appeared to be only a single committer.  However, a number of things encouraged and intrigued.  The <a href="http://trac.caffeine-it.com/openrasta/wiki/Doc/Configuration/HowTos">fluent configuration</a> gave me warm fuzzies immediately, both from the point of view of meeting our conneg requirements instantly and also being vastly easier to read than the WCF XML configuration:</p>
<pre class="brush: csharp;">
        public void Configure()
        {
            using (OpenRastaConfiguration.Manual)
            {
                ResourceSpace.Has.ResourcesOfType&lt;Customer&gt;()
                    .AtUri(&quot;/customer/{customerId}&quot;)
                    .HandledBy&lt;CustomerHandler&gt;()
                    .AsXmlDataContract()
                    .And.AsJsonDataContract();
            }
        }
</pre>
<p>Score! Two representations that are attached specifically to that URI, with some class called <code>CustomerHandler</code> providing some kind of output.  Wondering what kind of output that could be, I was won over by the absolute simplicity in the handlers:</p>
<pre class="brush: csharp;">
    public class CustomersHandler
    {
        public Customer Get(int customerId)
        {
              return CustomerRepository.Get(customerId);
        }
    }
</pre>
<p>This simplicity is entirely brought about by OpenRasta&#8217;s built in, convention-based <a href="http://trac.caffeine-it.com/openrasta/wiki/Doc/Handlers/MethodSelection">approach to method matching</a>.  No configuration files were harmed during the mapping of this URI to its method; OpenRasta simply looks for a method starting with &#8220;Get&#8221; and with a parameter called the same thing as you put in the squiggly braces in the URI, and ends up returning a POCO <code>Customer</code> object.  Another beautiful thing was that no handlers need to inherit from any special type of object, leaving your one shot at inheritance still available to you.</p>
<p><em>Note: this attention to preserving individual developer productivity appears again and again in OpenRasta.  You&#8217;ll go to do something that you thought you might have to write (creating URIs for other resources, or HTTP digest authentication, for example) and you&#8217;ll find it baked into the framework.</em></p>
<p>So if that handler could return a straightforward POCO, what was responsible for wrapping that up in the format that the HTTP GET had asked for with its <code>Accept</code> header?  The answer lies with <a href="http://trac.caffeine-it.com/openrasta/wiki/Doc/Tutorials/ImplementingACodec">codecs</a>, and while OpenRasta ships with most that you&#8217;d need (for (X)HTML, XML and JSON), again the extensibility model wins with its simplicity &#8211; you simply implement a couple of interfaces with one method each to handle encoding and decoding.</p>
<p>I&#8217;ve stated many things I like about OpenRasta but I&#8217;ve barely scratched the surface.  I&#8217;ve not mentioned extending the pipeline (which meant we were able to bolt API key-based resource governance right in) or even the core developmental nicety that is OpenRasta&#8217;s built in support for IoC containers.  Windsor and Ninject support are there out of the box, though there&#8217;s a basic implementation that&#8217;ll serve 80% of small to medium-sized projects anyway.  When you start to put together HTML pages, you can do that with the familiar ASPX markup model &#8211; though even that has had a spruce-up and has extended the ASP.NET build provider in some useful ways.</p>
<h3>In Summary</h3>
<h4>Why we found WCF isn&#8217;t a great fit for ReST</h4>
<ul>
<li>WCF is designed as a transport-agnostic support framework for services based on Operations and Contracts. This means that your design is inherently RPC in nature. For simple cases, this might be enough.</li>
<li>ReST is an afterthought in WCF (hey, we *can* do this quite easily and we&#8217;ll service the needs of 80% of developers and they can continue to think about methods in services as the One True Way). However, given that it&#8217;s so different to, say, SOAP, it requires that you structure your WCF app in such a way that it can barely reap any of the rewards of transport agnosticism anyway</li>
<li>Content negotiation is not a given in WCF. It requires use of third party extensions such as WcfRestContrib, and even then you cannot negotiate content on a per-URI basis.  For example, I can&#8217;t say that at /videos/1 I will have a text/html representation and at /conditions/cancer/introduction I will have text/html and application/json.  Even with WcfRestContrib you will only have a fixed set of representations which will have to apply to all URIs.</li>
</ul>
<h4>Why we found that OpenRasta is</h4>
<ul>
<li>OpenRasta &#8211; like HTTP since the mid 90&#8217;s &#8211; focuses on resources and their representations, not RPC.</li>
<li>A resource is just a POCO which is addressable by one or more URIs</li>
<li>A representation is just an encoding of the resource (JSON, XML, byte stream) negotiated on what you said you&#8217;d <code>Accept</code> in your HTTP headers</li>
<li>A URI can have as many or as few representations available as it requires.</li>
</ul>
<p>WCF is designed around the concepts of Services and Contracts.  HTTP, and by extension ReST are not &#8211; they are about resources and representations of those resources.  OpenRasta understands this and has been designed from the ground up to support ReST-based architectures simply and elegantly &#8211; it&#8217;s a natural fit with HTTP whereas WCF is a slightly incompatible mismatch.  </p>
<p>I needed two WCF books from Safari Online and WcfRestContrib to even begin to implement what we needed in WCF and it still fell short of what we wanted to achieve and compromised the design at the same time.  OpenRasta not only freed us from WCF&#8217;s overbearing and config-heavy complexity &#8211; its elegant MVC model (with IoC at the core) made our code easy to write, easy to read, and above all a pleasure to maintain.</p>
<p>And if a project is only to have a single committer, better it be a &#8220;<a href="http://serialseb.blogspot.com/">self-proclaimed, egotistical doofus</a>&#8221; who also happens to be a borderline genius.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zephyros-systems.co.uk/blog/?feed=rss2&amp;p=45</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>WCF REST Starter Kit (Preview 2)</title>
		<link>http://www.zephyros-systems.co.uk/blog/?p=44</link>
		<comments>http://www.zephyros-systems.co.uk/blog/?p=44#comments</comments>
		<pubDate>Mon, 22 Jun 2009 16:36:05 +0000</pubDate>
		<dc:creator>Russ</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[WCF]]></category>
		<category><![CDATA[ReST]]></category>

		<guid isPermaLink="false">http://www.zephyros-systems.co.uk/blog/?p=44</guid>
		<description><![CDATA[I&#8217;ve been wanting to work with WCF for a fairly long time.  I suppose I could have flirted with burnout and done it on top of my daily paying activities, but I like to think my health&#8217;s improved with not doing this kind of thing.  In any case, suddenly a paying client has [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been wanting to work with WCF for a fairly long time.  I suppose I could have flirted with burnout and done it on top of my daily paying activities, but I like to think my health&#8217;s improved with not doing this kind of thing.  In any case, suddenly a paying client has a requirement for a REST-based set of services, and I thought it&#8217;d be nice to try this with WCF for a couple of reasons:<br />
<img src="http://www.zephyros.co.uk/images/hammock.jpg" alt="Hammock" align="right" style="margin: 20px" /></p>
<ol>
<li>I always liked REST <em>(die, SOAP, die)</em> and have rolled my own more times than I&#8217;d care to mention</li>
<li>WCF has an almost shiny, nearly-new <a href="http://msdn.microsoft.com/en-us/netframework/dd547388.aspx">REST Starter Kit</a></li>
</ol>
<p>I&#8217;ve seen enough about WCF to know that I like the separation of contract from implementation and I thought I&#8217;d be able to get a good idea of whether it did enough of the following to make the effort invested in a &#8220;starter kit&#8221; with no <a href="http://forums.asp.net/t/1400833.aspx">go-live license</a> worthwhile: -</p>
<ul>
<li>Authorization / API key implementation <em>(check &#8211; one sample project has an interceptor-based solution)</em></li>
<li>Serialization to XML and JSON <em>(check &#8211; it&#8217;s baked right into the kit when you implement a collection service base)</em></li>
<li>Error handling and presentation <em>(half a check &#8211; nice and RESTful, with a nice <code>WebProtocolException</code> that lets you tailor what just happened to the most appropriate HTTP status code, but I would like more control over what gets rendered back)</em></li>
<li>Documentation/discoverability <em>(half a check &#8211; there&#8217;s a nice <code>.../help</code> URL based on standard WCF contract/member attributes but there&#8217;s no WADL.  Did we need it <a href="http://bitworking.org/news/193/Do-we-need-WADL">anyway</a>?)</em></li>
<li>General syndication support <em>(check, thank you <code>SyndicationItem</code></em>)</li>
</ul>
<p>In any case it all looks terribly promising.  The templates are good, the screencasts are good &#8230; hang on, wait &#8211; Aaron Skonnard&#8217;s <a href="http://www.pluralsight.com/main/screencasts/default.aspx">screencasts</a> are mucking about with a <code>Service.svc.base.cs</code> file I don&#8217;t have, and that&#8217;s how he&#8217;s customising the output XML.  That&#8217;s not in Preview 2.  Suddenly I find that this stuff&#8217;s moved into <code>Microsoft.ServiceModel.Web</code> and I can&#8217;t edit it any more.  So the customisation story must have moved.  Then I discover that the way to customise is apparently to move the source code into your project and <a href="http://forums.asp.net/t/1428862.aspx">change the namespace so it doesn&#8217;t conflict with the existing ServiceModel</a>.  Woah.  That&#8217;s not even as nice an &#8220;extensibility point&#8221; as we had in Preview 1&#8230; oh well.  So I&#8217;m stuck with <code>ItemInfoList</code> and <code>ItemInfo</code> in my output XML.  Suddenly the lack of the aforementioned <a href="http://forums.asp.net/t/1400833.aspx">go-live license</a> doesn&#8217;t seem so bad.  I wouldn&#8217;t be able to use this as it is now.</p>
<p>So this leaves me in quite an odd place &#8211; clamouring for half of a very promising toolkit that just isn&#8217;t quite finished and which I wouldn&#8217;t be legally allowed to use anyway.  However, the source code appears to be all there.  And we need a REST strategy <strong>really</strong> soon.  Not to denigrate the excellent effort from the MS REST team, but it&#8217;s at times like this you wish the effort you&#8217;d just put in had been directed at an open source project &#8211; at least you&#8217;d have somewhere to go, even if you had to pedal that last mile yourself.  I&#8217;ve been titillated and subsequently frustrated &#8211; I&#8217;m not allowed to touch, as the chaperone&#8217;s an army of lawyers.</p>
<p>Looks like I&#8217;ll be rolling my own again.</p>
<p>EDIT: Hmm, I might have been a bit hasty &#8211; there&#8217;s plenty in WCF 3.5 as it stands to build REST services.  Just not quite as easily.  I&#8217;ll miss <code>WebProtocolException</code> and I&#8217;ll miss having the zero-config approach.  I might also miss the interceptor-based auth and the in-built help generation.  But it&#8217;s still <b>doable</b>, if just somewhat harder&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zephyros-systems.co.uk/blog/?feed=rss2&amp;p=44</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A cheap solution to a developer&#8217;s multi monitor lust</title>
		<link>http://www.zephyros-systems.co.uk/blog/?p=40</link>
		<comments>http://www.zephyros-systems.co.uk/blog/?p=40#comments</comments>
		<pubDate>Sun, 21 Jun 2009 16:37:53 +0000</pubDate>
		<dc:creator>Russ</dc:creator>
				<category><![CDATA[Hardware]]></category>
		<category><![CDATA[monitor]]></category>

		<guid isPermaLink="false">http://www.zephyros-systems.co.uk/blog/?p=40</guid>
		<description><![CDATA[NB &#8211; this has sat in my &#8220;you didn&#8217;t publish this, doofus&#8221; folder for some time now.  It still seems relevant, so here &#8211; for the benefit of my three readers &#8211; it is:
A confession &#8211; I&#8217;ve come to the multi monitor thing rather late.  For five years or so I&#8217;ve been getting [...]]]></description>
			<content:encoded><![CDATA[<p><em>NB &#8211; this has sat in my &#8220;you didn&#8217;t publish this, doofus&#8221; folder for some time now.  It still seems relevant, so here &#8211; for the benefit of my three readers &#8211; it is:</em></p>
<p>A confession &#8211; I&#8217;ve come to the multi monitor thing rather late.  For five years or so I&#8217;ve been getting by on a 1280&#215;1024 LCD like everyone else, and since I&#8217;m freelance I work in a lot of places where you&#8217;re lucky if you get that.  Most of the time you can expect an old 17&#8243; monitor that looks like it was smeared in fruit-based conserve (or worse, the core dump of a baboon &#8211; I&#8217;ll spare that particular company a mention, though I do hope their erstwhile IT Guy has discovered his shower &#8211; or at least toilet paper &#8211; by now).  As a result, given the usual small constellation of developer apps you&#8217;ll have open at any one time and their natural predilection for consuming what the entire software development industry has, irony-free, come to call &#8220;real estate&#8221;, I&#8217;ve become deft with ALT-TAB, CTRL-TAB, CTRL-F6, SHIFT-CTRL-F6 and ALT-CTRL-SHIFT-FN-pasa doblé-reverse triple somersault with pike.  Quite a lot of people (alright, one that I know of) will state their preference for some other kind of window manager shoehorned into XP at this point, and probably with good reason, but the aforementioned freelance status means it behoves you to learn to cope with default tools before coming to rely on yet another thing you&#8217;ll just have to set up at the start of your next gig.</p>
<p>Anyway, just recently I&#8217;ve been working at a place where multi-monitor setups are the norm and despite my previous reluctance to come to rely on something that may not be there at that next gig, I&#8217;ve rather taken to it.  In a limited sort of way, at any rate &#8211; I might only use the second monitor for having a browser open for reference, or a query window, or perhaps a Terminal Services session (though this last one is less likely since the TS client&#8217;s support for multiple monitors, especially when those monitors are of a different resolution and/or aspect ratio is, to put it charitably, absent).</p>
<p>The thing that really struck me is that my cognitive load is immediately lightened.  Those with a background in psychology (and even those with only a passing interest) will no doubt be acquainted with George A. Miller&#8217;s magical number <a href="http://en.wikipedia.org/wiki/The_Magical_Number_Seven,_Plus_or_Minus_Two">seven, plus or minus two</a> &#8211; the idea that we have between 5 and 9 short term memory &#8220;slots&#8221; available to us.  Not having to ALT-TAB or task switch using the task bar frees me from needing to remember where I left a program I haven&#8217;t used for a minute or nine.  </p>
<p>As a developer, anything that gives you back one of your 7 +/-2 short term memory items is invaluable.  Software development is a constant assailment of our limited mental faculties by almost overwhelming detail, and we constantly have a little &#8220;stack&#8221; of our own: can&#8217;t do <em>x</em> until <em>y</em> is complete, can&#8217;t do <em>y</em> until <em>z</em> and <em>b</em> are complete, <em>b</em> is awaiting consent from Harry in ops and we can&#8217;t do <em>z</em> right now because it&#8217;s lunchtime.  And multiple monitors really do help with this (although they can&#8217;t nip out and get you a chilli beef ramen).  I&#8217;ve seen it <a href="http://www.hanselman.com/blog/NewJobNewHouseNewBabyAndDesigningATotallyNewHomeOffice.aspx">said</a> by Scott Hanselman that: -</p>
<blockquote><p>You just can&#8217;t have enough screen space. Any space in front of your face that isn&#8217;t a working monitor but is still in your field of view is a waste if it&#8217;s not conveying information.</p></blockquote>
<p>I&#8217;d hesitate to go that far &#8211; the biggest benefit in terms of order of magnitude for me has come with going from one to two.  I suspect three would increase that benefit, but not to the extent that going from one to two did, and anyway, you do have to remember not to hit DEL indiscriminately when your cursor is on a physically different monitor.</p>
<p>So, given that we have a Very Small Brain and Very Large Problems which require Looking At Lots Of Stuff at once, may I suggest a trusted old tool which has been available for a good number of years now and which provides a handy way of viewing lots of pertinent information in a persistent, multipage readable form and which will be available at any modern desk at which you might find yourself sat?  It&#8217;s the good old pencil and paper (or pen and paper, should you be the kind of super being who never makes mistakes).  This all leads nicely on to the next article I&#8217;ll never write, in which I take to task every single developer who doesn&#8217;t use them -<em> Less Coding, More Thinking</em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zephyros-systems.co.uk/blog/?feed=rss2&amp;p=40</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NHS Choices site search for Ubiquity</title>
		<link>http://www.zephyros-systems.co.uk/blog/?p=43</link>
		<comments>http://www.zephyros-systems.co.uk/blog/?p=43#comments</comments>
		<pubDate>Sat, 07 Feb 2009 17:11:54 +0000</pubDate>
		<dc:creator>Russ</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[choices]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[nhs]]></category>
		<category><![CDATA[ubiquity]]></category>

		<guid isPermaLink="false">http://www.zephyros-systems.co.uk/blog/?p=43</guid>
		<description><![CDATA[I&#8217;ve been having a play with Ubiquity today. It shows a lot of promise and is a nice thing to use &#8211; both from a command user point of view and the point of view of a command author.  It&#8217;s great that they&#8217;ve baked jQuery right in too.  That should keep me coming [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been having a play with <a href="http://labs.mozilla.com/2008/08/introducing-ubiquity/">Ubiquity</a> today. It shows a lot of promise and is a nice thing to use &#8211; both from a command user point of view <em>and</em> the point of view of a command author.  It&#8217;s great that they&#8217;ve baked jQuery right in too.  That should keep me coming back.</p>
<p>As a small learning exercise, I&#8217;ve made a search command for the site that I currently work on &#8211; <a href="http://www.nhs.uk/">NHS Choices</a>.  Visit the <a href="http://www.zephyros-systems.co.uk/blog/?page_id=42">Ubiquity Commands</a> page to subscribe to the command (you&#8217;ll need to have previously installed Ubiquity).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zephyros-systems.co.uk/blog/?feed=rss2&amp;p=43</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MacBook Pro for Windows developers</title>
		<link>http://www.zephyros-systems.co.uk/blog/?p=41</link>
		<comments>http://www.zephyros-systems.co.uk/blog/?p=41#comments</comments>
		<pubDate>Sat, 07 Feb 2009 10:59:14 +0000</pubDate>
		<dc:creator>Russ</dc:creator>
				<category><![CDATA[Hardware]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[macbook]]></category>
		<category><![CDATA[vmware]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://www.zephyros-systems.co.uk/blog/?p=41</guid>
		<description><![CDATA[Andres wrote a nice summary of his experiences with a MacBook Pro as a Windows development machine.  I agree with everything he&#8217;s got to say, really &#8211; it&#8217;s a lovely machine but it&#8217;s not really suited to Windows development (I set aside only a 60GB partition for Windows XP, but hey, that was all [...]]]></description>
			<content:encoded><![CDATA[<p>Andres wrote a <a href="http://weblogs.asp.net/aaguiar/archive/2009/02/06/macbookpro-for-windows-developers.aspx">nice summary</a> of his experiences with a MacBook Pro as a Windows development machine.  I agree with everything he&#8217;s got to say, really &#8211; it&#8217;s a lovely machine but it&#8217;s not really suited to Windows development (I set aside only a 60GB partition for Windows XP, but hey, that was all of my &#8220;old&#8221; laptop) for a number of reasons: -</p>
<ol>
<li><strong>The heat:</strong> actually, I suffer from this less than Andres does but it&#8217;s about freezing in the UK at the moment.  There are two graphics cards in the MBP &#8211; a GeForce 9400M and a 9600M.  Windows can only use the 9600M, which is great for gaming but not a deal of use for development, because of&#8230;</li>
<li><strong>&#8230; The battery life:</strong> again, I&#8217;m pointing the finger squarely at the graphics card usage here. OS/X uses the 9400M to get as much as 4-5 hours light use out of the machine.  You&#8217;ll struggle to get an hour and a half out of Windows XP.</li>
<li><strong>The keyboard:</strong> As Andres notes, it&#8217;s missing a delete key (which is &#8220;simulated&#8221; with FN+BACKSPACE.  This is probably the biggest downside for me.  There are other annoyances in the UK too &#8211; the MBP does not come with a traditional keyboard layout.  Backslash and tilde are in the wrong places, there&#8217;s an odd §/± key in the corner, and &#8211; crucially for me, particularly when editing CSS or using regions in C#, or even <strong>saying</strong> C# &#8211; there&#8217;s no &#8216;#&#8217; key (though see below for a fix).  CTRL and FN are the &#8220;wrong&#8221; way round &#8211; your muscle memory is severely hampered for the first two or three weeks.</li>
<li><strong>The trackpad:</strong> it&#8217;s a thing of beauty in OS/X, but BootCamp down to XP and you&#8217;ll be tearing your hair out.  It&#8217;s almost as if they went out of their way to deliberately cripple the driver so that you&#8217;d hurry back to your new &#8220;favourite&#8221; OS/X.  The &#8220;two-finger tap&#8221; right-click method I use in OSX is cruelly transformed into a &#8220;three-finger-claw click&#8221; (even though I&#8217;ve told the driver I&#8217;d like to tap to click, which it does for left clicks and not for rights). The sensitivity seems off and the tap-drag threshold for window dragging is insanely large.</li>
</ol>
<p>The above sounds like a fairly exhaustive list of why you <strong>wouldn&#8217;t</strong> want a MacBook.  Apple have done what they probably wanted: to make Windows usable but make it so irritating that you&#8217;ll long to be back in OS/X just to use multitouch properly.  Oddly, though, I love it.  This is probably because development isn&#8217;t the main thing I do on it.  So what is it I love?</p>
<ul>
<li><strong>The keyboard:</strong> Yes, the very thing I&#8217;m maligning above.  The travel is small, the feedback (to me) seems excellent, and typing this post I&#8217;m struck by the speed at which my thoughts are hitting the page.  Also, I can regain my &#8216;#&#8217; key (in OS/X) and shift the other keys back where I&#8217;m used to having them with the excellent (and mis-spelt) <a href="http://www.macupdate.com/info.php/id/14495">Ukelele</a>. The only thing I still can&#8217;t do is swap FN and CTRL or jury-rig a DELETE key on the EJECT button&#8230;</li>
<li><strong>The touchpad</strong> feels lovely once you&#8217;ve set it up to taste. The poor Windows drivers are inexcusable when you know how good the pad can be.</li>
<li><strong>VMWare Fusion:</strong> Weirdly, when running my BootCamp installation through Fusion, the trackpad works exactly as I expect it.  This is probably the best way to develop on it.  I boot into Windows only when I want to play Fallout 3.  Which I&#8217;ve finished.  So I never boot into Windows.</li>
<li><strong>The construction:</strong> The unibody construction, the LED backlighting of both screen and keys &#8230; it&#8217;s got heft and there&#8217;s no give or play in any of it.  The only downside is that the body is so cold first thing in the morning in this <a href="http://news.bbc.co.uk/1/hi/uk/7876195.stm">freezing weather</a> we&#8217;re having.</li>
<li><strong>OS/X:</strong> There&#8217;s plenty to like.  Exposé is as good as everyone says.  iTunes and <a href="http://iscrobbler.sourceforge.net/">iScrobbler</a> are a joy compared to the Windows equivalents and it all integrates beautifully with the dedicated player keys on the keyboard.  Safari is fast and usable (once you&#8217;ve installed the excellent <a href="http://www.macupdate.com/info.php/id/27708/glims">Glims</a>).  iCal integrates with my Google Calendar well using the excellent <a href="http://code.google.com/p/calaboration/">Calaboration</a>.  I can check my GMail from the great desktop widgets (which knock Vista&#8217;s sidebar into a cocked hat).  The typography is excellent (especially in the excellent and ubiquitous Dictionary), even if <a href="http://www.macobserver.com/columns/devilsadvocate/2003/20030523.shtml">Quartz doesn&#8217;t quite come up to ClearType standards</a> at small font sizes.  &#8220;Spaces&#8221; is the first &#8220;multiple desktop&#8221; solution I&#8217;ve ever wanted to continue using.  The Unix underpinnings are solid, packed with open source gems and don&#8217;t require the amount of tinkering that my last dalliance with Linux (admittedly over a decade ago) did.</li>
</ul>
<p>It&#8217;s a shame that Apple haven&#8217;t put as much effort into their Windows drivers as they have the rest of the overall experience.  Really, the big two things that the drivers need are: <strong>the ability to select the graphics card</strong> and <strong>the same trackpad driver capabilities as OS/X has.</strong>  As Andres has already said, this means it&#8217;s not the best choice for Windows development &#8211; though if you&#8217;re close to a power outlet it&#8217;s all do-able.  However, for personal use and even just as an exercise to see how digital life is through a non-Microsoft prism, I&#8217;ve found it to be a thoroughly useful and enjoyable experience.  </p>
<p>I&#8217;d buy it again, but knowing that I&#8217;d only use it for digital photo manipulation, surfing and music.  I am trying other languages with it (Python and vim ship with the system and I&#8217;ve dipped my toes), but it&#8217;s not quite the full ticket for Windows-based .NET development and the keyboard issues, while not insurmountable, do mean that (for me, anyway) it&#8217;s better suited for general writing than source file editing.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zephyros-systems.co.uk/blog/?feed=rss2&amp;p=41</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Learn to find stuff first</title>
		<link>http://www.zephyros-systems.co.uk/blog/?p=38</link>
		<comments>http://www.zephyros-systems.co.uk/blog/?p=38#comments</comments>
		<pubDate>Mon, 28 May 2007 09:20:43 +0000</pubDate>
		<dc:creator>Russ</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[search]]></category>

		<guid isPermaLink="false">http://www.zephyros-systems.co.uk/blog/?p=38</guid>
		<description><![CDATA[Giles Bowkett turned up in my Reddit feed today with a thought-provoking article:  Programmer Interviews: Two Warning Signs.  He says:
&#8220;But the ability to locate reference materials isn&#8217;t an important criterion in hiring programmers; it&#8217;s an important criterion in hiring librarians.&#8221;
As I commented over there about a nanosecond before I realised it&#8217;d make a [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://gilesbowkett.blogspot.com/">Giles Bowkett</a> turned up in my Reddit feed today with a thought-provoking article:  <a href="http://gilesbowkett.blogspot.com/2007/05/programmer-interviews-two-warning-signs.html">Programmer Interviews: Two Warning Signs</a>.  He says:</p>
<blockquote><p>&#8220;But the ability to locate reference materials isn&#8217;t an important criterion in hiring programmers; it&#8217;s an important criterion in hiring librarians.&#8221;</p></blockquote>
<p>As I commented over there about a nanosecond before I realised it&#8217;d make a decent post for the first time in about ten months:</p>
<blockquote><p>Au contraire <img src='http://www.zephyros-systems.co.uk/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  I feel that the ability to locate the right kind of reference materials in the right situation is something that is sadly lacking in even some otherwise wonderful coders. In fact, one of my interview questions in the late 90s was &#8220;What do you <em>read</em>?&#8221;</p>
<p>Even today, it seems that many coders think themselves too busy to actually read up on the right ways to deal with certain challenges, preferring instead to use their &#8216;initiative&#8217; and fudge around the problem rather than seeking out prior art.</p></blockquote>
<p>I know, I know &#8211; I&#8217;m quoting <em>myself</em>, on a comment I made on someone else&#8217;s blog.  I&#8217;m pretty certain this contravenes some basic blogger&#8217;s code of conduct that I&#8217;d have read if only I&#8217;d have found the time (hey, I&#8217;m too <em>busy</em>.  See above).  But my point remains &#8211; too many coders struggle for way too long by themselves before reaching for the great white google search box in the sky.  And when they do reach for that search box, they use it poorly.  Very poorly.  I see too few people even use double quotes to indicate that words should occur in sequence, and many give up after one or two searches, whereas I&#8217;ll try up to a dozen rephrasings before I&#8217;m satisfied that I&#8217;ve exhausted the possibilities.</p>
<p>So really all I&#8217;m saying is this: the world&#8217;s full of people who are cleverer than you and who post to their blogs more often than you do.  Use their effort, not yours, since the chances are good that whatever you&#8217;re doing is a solved problem.  The next interview I perform, I&#8217;m going to confront the hapless code monkey in front of me with an obscure ADO.NET issue and a laptop running Firefox and see how long he takes to winkle out the solution.  <em>Then</em> I might show him some code and ask him what&#8217;s wrong with it, and finally I&#8217;ll ask him what flavour doughnut filling he takes (custard is a no-hire).</p>
<p>And Mr. Bowkett, I&#8217;d never dream of posting something as potentially career-threatening as <a href="http://gilesbowkett.blogspot.com/2007/05/shouldnt-conference-schedules-match.html">this</a> (scroll down to the blue photo, which is probably SFW but not for small children), but props to you for having the brass knackers to so do.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zephyros-systems.co.uk/blog/?feed=rss2&amp;p=38</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>LINQ&#8217;s &#8220;var&#8221; keyword &#8211; the new obfuscation method of choice</title>
		<link>http://www.zephyros-systems.co.uk/blog/?p=36</link>
		<comments>http://www.zephyros-systems.co.uk/blog/?p=36#comments</comments>
		<pubDate>Wed, 13 Sep 2006 16:50:58 +0000</pubDate>
		<dc:creator>Russ</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Languages]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[linq]]></category>
		<category><![CDATA[var]]></category>

		<guid isPermaLink="false">http://www.zephyros-systems.co.uk/blog/?p=36</guid>
		<description><![CDATA[Does anyone else think that C# 3.0&#8217;s var keyword and its concomitant type inference (see the LINQ Preview if you&#8217;ve no idea what I&#8217;m rattling on about) is in some circumstances pointlessly clever syntactic sugar?  Yes, it&#8217;s a necessary keyword for ad-hoc projections of data for which you have no class definition (and can&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>Does anyone else think that C# 3.0&#8217;s <code>var</code> keyword and its concomitant type inference (see the <a href="http://msdn.microsoft.com/data/ref/linq/">LINQ Preview</a> if you&#8217;ve no idea what I&#8217;m rattling on about) is in some circumstances pointlessly clever syntactic sugar?  Yes, it&#8217;s a necessary keyword for ad-hoc projections of data for which you have no class definition (and can&#8217;t be bothered to create one), but elsewhere it&#8217;s likely to become a lazy shortcut which reduces readability.  One of the first LINQ preview&#8217;s hands-on labs has this piece of code:</p>
<pre>
static void ObjectQuery()
{
    var people = new List<Person>() {
        new Person { Age=12, Name="Bob" },
        new Person { Age=18, Name="Cindy" },
        new Person { Age=13 }
    };

    var teenagers =
        from p in people
        where p.Age &gt; 12 &#038;&#038; p.Age &lt; 20
        select p;

    Console.WriteLine("Result:");
    foreach(var val in teenagers)
    {
        Console.WriteLine("> Name = {0}, Age = {1}", val.Name, val.Age);
    }
}
</pre>
<p>It&#8217;s the <code>foreach(var val in teenagers)</code> that gets me &#8211; what&#8217;s wrong with <code>foreach(Person teenager in teenagers)</code>? Ok, so it&#8217;s a trivial example, but it seems to me that since <code>var</code> will be used as a lazy way of avoiding thinking about what kind of object you&#8217;re really instantiating under the covers, it&#8217;ll become an easy shortcut, and it&#8217;s just less readable than the former.</p>
<p>And how about this (From the C# 3.0 Language Enhancements Guide, also in the LINQ May preview)?</p>
<pre>
var x = 7;
var s = "This is a string.";
var d = 99.99;
var numbers = new int[] { 0, 1, 2, 3, 4, 5, 6 };

Console.WriteLine("x: " + x);
Console.WriteLine("s: " + s);
Console.WriteLine("d: " + d);
Console.WriteLine("numbers: ");
foreach (int n in numbers) Console.WriteLine(n);
</pre>
<p>Of course, no-one in their right mind would write <code>var x=7</code> unless they had no idea that C# was a strongly-typed language and could confer certain compile-time benefits (a particularly insular JavaScript programmer, perhaps).  So why allow it?  It&#8217;s perfectly reasonable to allow <code>var</code> in the case where it&#8217;s required: i.e. when the compiler has constructed an anonymous class to deal with a projection of data.  In nearly all other circumstances, however, this lazy shortcut will allow mediocre programmers to believe that they need to think even less about data typing than they did before, and in the process add an extra barrier to maintenance.  Perhaps the compiler (or FxCop) could be set to enforce readability where the type of <code>var</code> is expressible?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zephyros-systems.co.uk/blog/?feed=rss2&amp;p=36</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The crowning jewel in XLinq</title>
		<link>http://www.zephyros-systems.co.uk/blog/?p=37</link>
		<comments>http://www.zephyros-systems.co.uk/blog/?p=37#comments</comments>
		<pubDate>Wed, 13 Sep 2006 16:16:02 +0000</pubDate>
		<dc:creator>Russ</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[linq]]></category>
		<category><![CDATA[xlinq]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://www.zephyros-systems.co.uk/blog/?p=37</guid>
		<description><![CDATA[It&#8217;s not the fact that you can query XML documents in-memory using a SQL-like syntax (hey, I already had XPath, thanks all the same).
It&#8217;s the fact that you can now create an XML document, for use in an example, where the C# code structure used to create the document mirrors almost exactly that of the [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s not the fact that you can query XML documents in-memory using a SQL-like syntax (hey, I already had XPath, thanks all the same).</p>
<p>It&#8217;s the fact that you can now create an XML document, for use in an example, where the C# code structure used to create the document <em>mirrors almost exactly that of the resulting output document</em>.</p>
<p>This is brought about by the ancient magic of variable parameter lists and well thought-out constructor overloads, and whoever&#8217;s responsible, I&#8217;d like to buy him a drink and look after his cat while he&#8217;s on holiday.  This technique sits right between ugly raw DOM hacking (of which, I confess, I have done much) and beautifully-generated but hard-to-keep-in-sync <a href="http://en.wikipedia.org/wiki/XML_Data_Binding">XML Data Binding</a>.  </p>
<p>This is from the LINQ hands-on labs:</p>
<pre>
public static XDocument CreateDocument()
{
   // create the document all at once
   return new XDocument(
      new XDeclaration("1.0", null, null),
          new XElement("organizer",
             new XElement("contacts",
                 new XElement("contact", new XAttribute("category", "home"),
                 new XElement("name", "John Smith")),
                 new XElement("contact", new XAttribute("category", "home"),
                 new XElement("name", "Sally Peters")),
                 new XElement("contact", new XAttribute("category", "work"),
                 new XElement("name", "Jim Anderson")))));
}
</pre>
<p>Wonderful, n&#8217;est pas?  The only shame is that the &#8220;X&#8221; classes are a little divorced from the rest of the XML namespaces; their primary purpose is to provide something for LINQ to talk to.  So if I do want to use XPath, I&#8217;ll have to <code>.Save</code> this doc into a memory stream and reload it.  Sigh&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zephyros-systems.co.uk/blog/?feed=rss2&amp;p=37</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>My longest-standing VS.NET RegEx question, answered</title>
		<link>http://www.zephyros-systems.co.uk/blog/?p=35</link>
		<comments>http://www.zephyros-systems.co.uk/blog/?p=35#comments</comments>
		<pubDate>Sat, 15 Jul 2006 10:10:20 +0000</pubDate>
		<dc:creator>Russ</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[regex]]></category>
		<category><![CDATA[visual studio]]></category>

		<guid isPermaLink="false">http://www.zephyros-systems.co.uk/blog/?p=35</guid>
		<description><![CDATA[I&#8217;ve got Jeff Atwood to thank for an awful lot of things he posts over at Coding Horror, but this post in particular has made my day.  I&#8217;ve often wondered why it is that the Find/Replace RegEx engine built into the VS.NET IDE uses a wilfully different RegEx flavour to the .NET framework classes. [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve got Jeff Atwood to thank for an awful lot of things he posts over at Coding Horror, but <a href="http://www.codinghorror.com/blog/archives/000633.html">this post</a> in particular has made my day.  I&#8217;ve often wondered why it is that the Find/Replace RegEx engine built into the VS.NET IDE uses a wilfully different RegEx flavour to the .NET framework classes.   I use <a href="http://tools.osherove.com/CoolTools/Regulator/tabid/185/Default.aspx">The Regulator</a> for my regular expression building/testing, but I&#8217;ve always found it confusing and irritating that I can&#8217;t take a regex from The Regulator and plug it into a standard VS.NET IDE Find/Replace.</p>
<p>Now at least I know why, as it seems the VS.NET Lead Program Manager thinks enough of Jeff&#8217;s blog to shed some light on the matter:</p>
<blockquote><p>It is a very oddball regex syntax, and as best we can tell it comes from Visual C++ 2.0. We did want to add additional support for .NET 2.0-style regular expressions in the Visual Studio 2005 release, but unfortunately due to time pressures it didn&#8217;t make the final list of features. We were able to make a number of bug fixes to the existing engine though, to give some improvement over VS 2003.</p>
<p>We do keep this on our list of things we want to fix. Ideally at some point we&#8217;ll actually build in a nifty little extensibility point so you can wire up any regex engine you want for searches.</p></blockquote>
<p>Extensibility point schmextensibility point.  Just plug in the regular framework classes (but leave the great shortcuts like :q).  Thanks <img src='http://www.zephyros-systems.co.uk/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.zephyros-systems.co.uk/blog/?feed=rss2&amp;p=35</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
