<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="en" xml:base="http://kalebpederson.com/wp-atom.php">
	<title type="text">Kaleb Pederson's Blog</title>
	<subtitle type="text">Growing together on bits of Software Craftsmanship, Entrepreneurship, and Life.</subtitle>

	<updated>2012-01-18T17:37:37Z</updated>

	<link rel="alternate" type="text/html" href="http://kalebpederson.com" />
	<id>http://kalebpederson.com/index.php/feed/atom</id>
	

	<generator uri="http://wordpress.org/" version="3.3.1">WordPress</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/KalebPederson" /><feedburner:info uri="kalebpederson" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2FKalebPederson" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FKalebPederson" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/KalebPederson" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FKalebPederson" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FKalebPederson" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FKalebPederson" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://www.plusmo.com/add?url=http%3A%2F%2Ffeeds.feedburner.com%2FKalebPederson" src="http://plusmo.com/res/graphics/fbplusmo.gif">Subscribe with Plusmo</feedburner:feedFlare><feedburner:feedFlare href="http://www.thefreedictionary.com/_/hp/AddRSS.aspx?http%3A%2F%2Ffeeds.feedburner.com%2FKalebPederson" src="http://img.tfd.com/hp/addToTheFreeDictionary.gif">Subscribe with The Free Dictionary</feedburner:feedFlare><feedburner:feedFlare href="http://www.bitty.com/manual/?contenttype=rssfeed&amp;contentvalue=http%3A%2F%2Ffeeds.feedburner.com%2FKalebPederson" src="http://www.bitty.com/img/bittychicklet_91x17.gif">Subscribe with Bitty Browser</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsalloy.com/?rss=http%3A%2F%2Ffeeds.feedburner.com%2FKalebPederson" src="http://www.newsalloy.com/subrss3.gif">Subscribe with NewsAlloy</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2FKalebPederson" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><feedburner:feedFlare href="http://mix.excite.eu/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FKalebPederson" src="http://image.excite.co.uk/mix/addtomix.gif">Subscribe with Excite MIX</feedburner:feedFlare><feedburner:feedFlare href="http://download.attensa.com/app/get_attensa.html?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FKalebPederson" src="http://www.attensa.com/blogs/attensa/WindowsLiveWriter/BadgeredintoBadges_10C02/attensa_feed_button5.gif">Subscribe with Attensa for Outlook</feedburner:feedFlare><feedburner:feedFlare href="http://www.webwag.com/wwgthis.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FKalebPederson" src="http://www.webwag.com/images/wwgthis.gif">Subscribe with Webwag</feedburner:feedFlare><feedburner:feedFlare href="http://www.podcastready.com/oneclick_bookmark.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FKalebPederson" src="http://www.podcastready.com/images/podcastready_button.gif">Subscribe with Podcast Ready</feedburner:feedFlare><feedburner:feedFlare href="http://www.flurry.com/pushRssFeed.do?r=fb&amp;url=http%3A%2F%2Ffeeds.feedburner.com%2FKalebPederson" src="http://www.flurry.com/images/flurry_rss_logo2.gif">Subscribe with Flurry</feedburner:feedFlare><feedburner:feedFlare href="http://www.wikio.com/subscribe?url=http%3A%2F%2Ffeeds.feedburner.com%2FKalebPederson" src="http://www.wikio.com/shared/img/add2wikio.gif">Subscribe with Wikio</feedburner:feedFlare><feedburner:feedFlare href="http://www.dailyrotation.com/index.php?feed=http%3A%2F%2Ffeeds.feedburner.com%2FKalebPederson" src="http://www.dailyrotation.com/rss-dr2.gif">Subscribe with Daily Rotation</feedburner:feedFlare><entry>
		<author>
			<name>Kaleb Pederson</name>
						<uri>http://kalebpederson.com</uri>
					</author>
		<title type="html"><![CDATA[Nant Error: &#8220;The type or namespace does not exist&#8221;]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/KalebPederson/~3/VSXaJRHCU90/nant-error-the-type-or-namespace-does-not-exist" />
		<id>http://kalebpederson.com/?p=180</id>
		<updated>2012-01-18T17:37:37Z</updated>
		<published>2012-01-18T17:37:37Z</published>
		<category scheme="http://kalebpederson.com" term="bugs" /><category scheme="http://kalebpederson.com" term="c#" /><category scheme="http://kalebpederson.com" term="nant" />		<summary type="html"><![CDATA[I was trying to run a nant task on a new project this morning but received the following error: error CS0234: The type or namespace name 'RegularExpressions' does not exist in the namespace 'System.Text' (are you missing an assembly reference?) The RegularExpressions namespace definitely exists as it has been around since .NET 1.1. The code looked [...]]]></summary>
		<content type="html" xml:base="http://kalebpederson.com/index.php/2012/01/nant-error-the-type-or-namespace-does-not-exist">&lt;p&gt;I was trying to run a nant task on a new project this morning but received the following error:&lt;/p&gt;
&lt;p&gt;&lt;tt&gt;error CS0234: The type or namespace name 'RegularExpressions' does not exist in the namespace 'System.Text' (are you missing an assembly reference?)&lt;/tt&gt;&lt;/p&gt;
&lt;p&gt;The &lt;a href="http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regex.aspx"&gt;RegularExpressions&lt;/a&gt; namespace definitely exists as it has been around since .NET 1.1.&lt;/p&gt;
&lt;p&gt;The code looked something like this:&lt;/p&gt;
&lt;pre class="brush: xml; html-script: true;"&gt;&amp;lt;target name="DoReplace"&amp;gt;
  &amp;lt;script language="C#" &amp;gt;
   &amp;lt;code&amp;gt;
     &amp;lt;![CDATA[
       public static void ScriptMain(Project project)
       {
         var rx = System.Text.RegularExpressions.Regex();
         // ...
       }
     ]]&amp;gt;
   &amp;lt;/code&amp;gt;
  &amp;lt;/script&amp;gt;
&amp;lt;/target&amp;gt;&lt;/pre&gt;
&lt;p&gt;The solution was quite simple, add a reference block:&lt;/p&gt;
&lt;pre class="brush: xml; html-script: true;"&gt;&amp;lt;target name="DoReplace"&amp;gt;
  &amp;lt;script language="C#" &amp;gt;
    &amp;lt;references&amp;gt;
      &amp;lt;lib&amp;gt;
        &amp;lt;include name="System.dll" /&amp;gt;
     &amp;lt;/lib&amp;gt;
   &amp;lt;/references&amp;gt;
   &amp;lt;code&amp;gt;
     // as before
   &amp;lt;/code&amp;gt;
  &amp;lt;/script&amp;gt;
&amp;lt;/target&amp;gt;&lt;/pre&gt;
&lt;p&gt;I don&amp;#8217;t know &lt;strong&gt;why&lt;/strong&gt; it would be necessary to reference a basic system assembly, but it was for me.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=VSXaJRHCU90:AcleWDdUwss:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=VSXaJRHCU90:AcleWDdUwss:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=VSXaJRHCU90:AcleWDdUwss:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=VSXaJRHCU90:AcleWDdUwss:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=VSXaJRHCU90:AcleWDdUwss:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=VSXaJRHCU90:AcleWDdUwss:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/KalebPederson/~4/VSXaJRHCU90" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://kalebpederson.com/index.php/2012/01/nant-error-the-type-or-namespace-does-not-exist#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://kalebpederson.com/index.php/2012/01/nant-error-the-type-or-namespace-does-not-exist/feed/atom" thr:count="0" />
		<thr:total>0</thr:total>
	<feedburner:origLink>http://kalebpederson.com/index.php/2012/01/nant-error-the-type-or-namespace-does-not-exist</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Kaleb Pederson</name>
						<uri>http://kalebpederson.com</uri>
					</author>
		<title type="html"><![CDATA[Fiddler won&#8217;t capture Safari traffic?]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/KalebPederson/~3/c8HdmXNVBXc/fiddler-wont-capture-safari-traffic" />
		<id>http://kalebpederson.com/?p=170</id>
		<updated>2012-01-06T04:52:56Z</updated>
		<published>2012-01-06T04:50:23Z</published>
		<category scheme="http://kalebpederson.com" term="bugs" /><category scheme="http://kalebpederson.com" term="web programming" /><category scheme="http://kalebpederson.com" term="fiddler" /><category scheme="http://kalebpederson.com" term="safari" />		<summary type="html"><![CDATA[Ok. Laugh now, but I expected Safari would &#8220;just work&#8221; with my application as Chrome did. I wasn&#8217;t using any fancy HTML-5 or anything, so why wouldn&#8217;t it? But it didn&#8217;t work, so I jumped to Fiddler (which is absolutely great, BTW!). Try as I may, I couldn&#8217;t get Fiddler wouldn&#8217;t capture Safari&#8217;s traffic to my [...]]]></summary>
		<content type="html" xml:base="http://kalebpederson.com/index.php/2012/01/fiddler-wont-capture-safari-traffic">&lt;p&gt;Ok. Laugh now, but I expected Safari would &amp;#8220;just work&amp;#8221; with my application as Chrome did. I wasn&amp;#8217;t using any fancy HTML-5 or anything, so why wouldn&amp;#8217;t it? But it didn&amp;#8217;t work, so I jumped to &lt;a href="http://www.fiddler2.com/fiddler2/"&gt;Fiddler &lt;/a&gt;(which is absolutely great, BTW!).&lt;/p&gt;
&lt;p&gt;Try as I may, I couldn&amp;#8217;t get Fiddler wouldn&amp;#8217;t capture Safari&amp;#8217;s traffic to my site so I could debug my web application. I had the relevant settings:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://kalebpederson.com/wp-content/uploads/2012/01/fiddler_settings.png"&gt;&lt;img class="aligncenter size-medium wp-image-172" title="Fiddler setup as a proxy to capture all traffic" src="http://kalebpederson.com/wp-content/uploads/2012/01/fiddler_settings-300x196.png" alt="" width="300" height="196" /&gt;&lt;/a&gt;I ran through the quick checklist:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fiddler running as a proxy&lt;/li&gt;
&lt;li&gt;Safari setup to use the proxy&lt;/li&gt;
&lt;li&gt;Safari started after Fiddler&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;None of it helped.  I investigated a bit further.  &lt;strong&gt;All&lt;/strong&gt; traffic to other sites would show up, but not to mine&amp;#8230; and I wasn&amp;#8217;t even hitting localhost, I was hitting my IIS instance using its hostname on the externally visible IP.&lt;/p&gt;
&lt;p&gt;Then I had a strange thought, &amp;#8220;&lt;strong&gt;maybe it&amp;#8217;s because I&amp;#8217;m referencing it as an intranet site?&amp;#8221;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So, I appended the domain name to my machine name (e.g. my-machine.mydomain). Fiddler instantly picked up all the traffic&amp;#8230; and my application worked perfectly. I&amp;#8217;m not yet sure what Safari does differently when it&amp;#8217;s referencing the server locally, but the behavior&amp;#8217;s consistent at least.&lt;/p&gt;
&lt;p&gt;Today&amp;#8217;s moral &amp;#8211; if you&amp;#8217;re running a web application and the host would be considered an intranet site, it may be worth checking with the fully qualified domain name.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=c8HdmXNVBXc:XRGOt6C9Jtc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=c8HdmXNVBXc:XRGOt6C9Jtc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=c8HdmXNVBXc:XRGOt6C9Jtc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=c8HdmXNVBXc:XRGOt6C9Jtc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=c8HdmXNVBXc:XRGOt6C9Jtc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=c8HdmXNVBXc:XRGOt6C9Jtc:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/KalebPederson/~4/c8HdmXNVBXc" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://kalebpederson.com/index.php/2012/01/fiddler-wont-capture-safari-traffic#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://kalebpederson.com/index.php/2012/01/fiddler-wont-capture-safari-traffic/feed/atom" thr:count="0" />
		<thr:total>0</thr:total>
	<feedburner:origLink>http://kalebpederson.com/index.php/2012/01/fiddler-wont-capture-safari-traffic</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Kaleb Pederson</name>
						<uri>http://kalebpederson.com</uri>
					</author>
		<title type="html"><![CDATA[Splitting documents vertically in Visual Studio 2010]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/KalebPederson/~3/aONyZobHkB8/splitting-documents-vertically-in-visual-studio-2010" />
		<id>http://kalebpederson.com/?p=150</id>
		<updated>2011-12-20T20:16:52Z</updated>
		<published>2011-12-16T21:10:18Z</published>
		<category scheme="http://kalebpederson.com" term="software" /><category scheme="http://kalebpederson.com" term="productivity power tools" /><category scheme="http://kalebpederson.com" term="vs2010" />		<summary type="html"><![CDATA[Apparently it&#8217;s not common knowledge that you can split documents vertically in Visual Studio 2010. You&#8217;ll need to do two things to enable this functionality: NOTE: It turns out I was wrong about where this functionality comes from. Although &#8220;Document Well 2010 Plus&#8221; (a.k.a &#8220;Document Tab Well&#8221;) does add quite a bit if nice functionality, [...]]]></summary>
		<content type="html" xml:base="http://kalebpederson.com/index.php/2011/12/splitting-documents-vertically-in-visual-studio-2010">&lt;p&gt;Apparently it&amp;#8217;s not common knowledge that you can split documents vertically in Visual Studio 2010. You&amp;#8217;ll need to do two things to enable this functionality:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE: &lt;/strong&gt;It turns out I was wrong about where this functionality comes from. Although &amp;#8220;Document Well 2010 Plus&amp;#8221; (a.k.a &amp;#8220;Document Tab Well&amp;#8221;) does add quite a bit if nice functionality, &lt;strong&gt;it&amp;#8217;s not necessary. &lt;/strong&gt;&lt;em&gt;You may entirely skip the Productivity Power Tools steps listed below&lt;/em&gt;.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Download the &lt;a href="http://visualstudiogallery.msdn.microsoft.com/d0d33361-18e2-46c0-8ff2-4adea1e34fef/"&gt;Productivity Power Tools&lt;/a&gt; extension, and&lt;/li&gt;
&lt;li&gt;Enable &amp;#8220;Document Well 2010 Plus&amp;#8221; under &lt;strong&gt;&lt;strong&gt;Tools -&amp;gt; Options -&amp;gt; Productivity Power Tools&lt;/strong&gt;&lt;/strong&gt;  &lt;a href="http://kalebpederson.com/wp-content/uploads/2011/12/ppt_document_tab_well.png"&gt;&lt;img class="aligncenter size-medium wp-image-155" title="Configure Document Well 2010 Plus" src="http://kalebpederson.com/wp-content/uploads/2011/12/ppt_document_tab_well-300x175.png" alt="" width="300" height="175" /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[Optional] Configure the &amp;#8220;Document Tab Well&amp;#8221; extension under &lt;strong&gt;Tools -&amp;gt; Options -&amp;gt; Productivity Power Tools -&amp;gt; Document Tab Well -&amp;gt; General&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now to split vertically, open a couple of files, then click and drag one of the tabs towards the center of the document.  Once you&amp;#8217;ve dragged it sufficiently far a drop target will appear in the center of the screen:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://kalebpederson.com/wp-content/uploads/2011/12/drag_to_split_vertically.png"&gt;&lt;img class="aligncenter size-medium wp-image-156" title="Drag tab towards center to see drop target" src="http://kalebpederson.com/wp-content/uploads/2011/12/drag_to_split_vertically-300x254.png" alt="" width="300" height="254" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;And congratulations, you can now split documents vertically!&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=aONyZobHkB8:8bxJ_B0PTLM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=aONyZobHkB8:8bxJ_B0PTLM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=aONyZobHkB8:8bxJ_B0PTLM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=aONyZobHkB8:8bxJ_B0PTLM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=aONyZobHkB8:8bxJ_B0PTLM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=aONyZobHkB8:8bxJ_B0PTLM:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/KalebPederson/~4/aONyZobHkB8" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://kalebpederson.com/index.php/2011/12/splitting-documents-vertically-in-visual-studio-2010#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://kalebpederson.com/index.php/2011/12/splitting-documents-vertically-in-visual-studio-2010/feed/atom" thr:count="0" />
		<thr:total>0</thr:total>
	<feedburner:origLink>http://kalebpederson.com/index.php/2011/12/splitting-documents-vertically-in-visual-studio-2010</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Kaleb Pederson</name>
						<uri>http://kalebpederson.com</uri>
					</author>
		<title type="html"><![CDATA[The Tight Three: SRP, OCP, and IoC]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/KalebPederson/~3/PD5h0byGm8c/the-tight-three-srp-ocp-and-ioc" />
		<id>http://kalebpederson.com/?p=110</id>
		<updated>2011-03-14T19:30:35Z</updated>
		<published>2011-03-14T19:30:35Z</published>
		<category scheme="http://kalebpederson.com" term="design" /><category scheme="http://kalebpederson.com" term="design-patterns" /><category scheme="http://kalebpederson.com" term="inversion of control" /><category scheme="http://kalebpederson.com" term="open-closed principle" /><category scheme="http://kalebpederson.com" term="single-responsibility principle" />		<summary type="html"><![CDATA[Today I&#8217;m going to elaborate on a statement I made in my Inversion of Control (IoC) post: &#8230;inversion of control falls naturally out of writing cohesive units that adhere to the single-responsibility principle (pdf) and the open-closed principle (pdf). Inversion of control is about responsibility placement. That is, to use IoC is to consider an object&#8217;s [...]]]></summary>
		<content type="html" xml:base="http://kalebpederson.com/index.php/2011/03/the-tight-three-srp-ocp-and-ioc">&lt;p&gt;Today I&amp;#8217;m going to elaborate on a statement I made in my &lt;a href="http://kalebpederson.com/index.php/2011/02/inversion-of-control-ioc-and-dependency-injection-di"&gt;Inversion of Control (IoC) post&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&amp;#8230;inversion of control falls naturally out of writing cohesive units that adhere to the single-responsibility principle (&lt;a href="http://www.objectmentor.com/resources/articles/srp.pdf"&gt;pdf&lt;/a&gt;) and the open-closed principle (&lt;a href="http://www.objectmentor.com/resources/articles/ocp.pdf"&gt;pdf&lt;/a&gt;).&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Inversion of control is about responsibility placement. That is, to use IoC is to consider an object&amp;#8217;s variant (or changeable) behaviors and then &amp;#8220;invert&amp;#8221; those behaviors making them controllable by the appropriate party, often the callee.  In this statement we see a number of different considerations:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Identifying variant and invariant behaviors&lt;/li&gt;
&lt;li&gt;Determining whether variant behaviors, which we could also call responsibilities, should be &amp;#8220;inverted&amp;#8221; or controllable by some callee.&lt;/li&gt;
&lt;li&gt;Allowing those behaviors to be controlled independent of the object&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These three considerations are directly related to inversion of control, the single responsibility principle, and the open-closed principle:&lt;/p&gt;
&lt;div id="attachment_118" class="wp-caption aligncenter" style="width: 295px"&gt;&lt;a href="http://kalebpederson.com/wp-content/uploads/2011/03/Requirements_SRP_OCP.png"&gt;&lt;img class="size-medium wp-image-118" title="Reqs_to_IoC_to_SRP_to_OCP" src="http://kalebpederson.com/wp-content/uploads/2011/03/Requirements_SRP_OCP-285x300.png" alt="Relationship between IoC, SRP, and OCP" width="285" height="300" /&gt;&lt;/a&gt;&lt;p class="wp-caption-text"&gt;Relationship between IoC, SRP, and OCP&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;I&amp;#8217;ll now talk more about each of these considerations.&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size: 20px; font-weight: bold;"&gt;Identifying Variant and Invariant Behaviors&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The single responsibility principle (SRP) says that an object should have only one reason to change. It&amp;#8217;s actually fairly important to note that it does &lt;strong&gt;not&lt;/strong&gt; say that an object only has one responsibility.  Let me restate that so it can make it through my thick skull:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;An object may have multiple responsibilities but must only ever have one reason to change.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;To be honest, I completely missed that point until writing this post. Although I&amp;#8217;ve learned how (which may be arguable to some) to define objects that have only a single responsibility and compose well, to structure my application as such at all times is the smell of Needless Complexity. Bob and Micah Martin put it this way in &lt;a href="http://www.amazon.com/Agile-Principles-Patterns-Practices-C/dp/0131857258/ref=sr_1_1?ie=UTF8&amp;amp;qid=1300130719&amp;amp;sr=8-1"&gt;Agile Principles, Patterns, and Practices in C#&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;em&gt;An axis of change is an axis of change only if the changes occur.&lt;/em&gt; It is wise not to apply SRP &amp;#8212; or any other principle, for that matter &amp;#8212; if there is no symptom.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;If a behavior is truly invariant and never going to change, then the best implementation is likely the quickest as it will cost the business the least. Quick, of course, is not the same as messy. Although we can do our best to make informed decisions about an axis of change, we&amp;#8217;re likely going to be wrong much of the time.&lt;/p&gt;
&lt;h2&gt;Controllable Behavior &amp;amp; Behavior Placement&lt;/h2&gt;
&lt;p&gt;The Single Responsibility Principle (SRP) guides us to separate out behaviors based on axis of change. Understanding an axis of change allows us to design the software in a way that makes it easy to change in the expected manner. The Open/Closed Principle (OCP) guides us to package components in a way that makes them open to extension but closed for extension. Once again, here&amp;#8217;s OCP defined:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Software entities should be open for extension but closed for modifications.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;That means that given a class C, C must be extendable in the way intended without a change to its source code or package (e.g. dll, assembly, jar). When components aren&amp;#8217;t packaged in a way that allows an axis of change to adhere to OCP, then the best bet may be to ignore that axis of change until the change actually happens&amp;#8230; if it happens at all.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s assume, for a moment, that we expect a change in some area. SRP says we should isolate that area of change, or area of responsibility, into a single component. One of the most fundamental ways that we tackle SRP and OCP is through the use of design patterns. The strategy, template method, and visitor patterns all aim to make at least one behavior variant while fixing others. Dependency injection is another way to allow a behavior to vary. Each of these is a form of inversion of control.&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size: 20px;"&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;To summarize briefly, when designing software we must consider areas or axis of change. Some of those should be considered implicitly as we consider testability, ideally using some sort of test-driven development. Then, for those areas where it&amp;#8217;s highly anticipated that changes will occur, we use inversion of control so that the appropriate party has responsibility over that area of change.  But, that&amp;#8217;s really what SRP says in the first place &amp;#8211; an object should have only one reason to change, so move that behavior out.  And lastly, OCP defines, to some extent, how different components that adhere to the SRP should be packaged. That is, they should be packaged in some way that allows the behavior to be extended (i.e. changed) without the corresponding source code or package needing to change. Thus, considering axis of change drives one to invert control, or apply SRP, in a way that can be maintained according to OCP. I&amp;#8217;m not even sure it&amp;#8217;s even possible to correctly use SRP without using IoC in one form or another &amp;#8212; what do you think?&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=PD5h0byGm8c:1I6K39PxStA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=PD5h0byGm8c:1I6K39PxStA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=PD5h0byGm8c:1I6K39PxStA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=PD5h0byGm8c:1I6K39PxStA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=PD5h0byGm8c:1I6K39PxStA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=PD5h0byGm8c:1I6K39PxStA:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/KalebPederson/~4/PD5h0byGm8c" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://kalebpederson.com/index.php/2011/03/the-tight-three-srp-ocp-and-ioc#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://kalebpederson.com/index.php/2011/03/the-tight-three-srp-ocp-and-ioc/feed/atom" thr:count="0" />
		<thr:total>0</thr:total>
	<feedburner:origLink>http://kalebpederson.com/index.php/2011/03/the-tight-three-srp-ocp-and-ioc</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Kaleb Pederson</name>
						<uri>http://kalebpederson.com</uri>
					</author>
		<title type="html"><![CDATA[Inversion of Control (IoC) and Dependency Injection (DI)]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/KalebPederson/~3/xSJ-qJU-_Z4/inversion-of-control-ioc-and-dependency-injection-di" />
		<id>http://kalebpederson.com/?p=89</id>
		<updated>2011-03-15T15:27:35Z</updated>
		<published>2011-02-28T20:35:57Z</published>
		<category scheme="http://kalebpederson.com" term="architecture" /><category scheme="http://kalebpederson.com" term="design-patterns" /><category scheme="http://kalebpederson.com" term="testing" /><category scheme="http://kalebpederson.com" term="dependency injection" /><category scheme="http://kalebpederson.com" term="inversion of control" /><category scheme="http://kalebpederson.com" term="open-closed principle" /><category scheme="http://kalebpederson.com" term="single-responsibility principle" /><category scheme="http://kalebpederson.com" term="testability" />		<summary type="html"><![CDATA[What is Inversion of Control (IoC)? Inversion of Control (IoC) is a generic term for changing (i.e. inverting) which of at least two sites controls a specific behavior. In other words, inversion of control is a simple statement about where the responsibility or control over some behavior belongs.  Thus, inversion of control falls naturally out [...]]]></summary>
		<content type="html" xml:base="http://kalebpederson.com/index.php/2011/02/inversion-of-control-ioc-and-dependency-injection-di">&lt;h2&gt;What is Inversion of Control (IoC)?&lt;/h2&gt;
&lt;div&gt;Inversion of Control (IoC) is a generic term for changing (i.e. inverting) which of at least two sites controls a specific behavior. In other words, inversion of control is a simple statement about where the responsibility or control over some behavior belongs.  Thus, inversion of control falls naturally out of writing cohesive units that adhere to the single-responsibility principle (&lt;a href="http://www.objectmentor.com/resources/articles/srp.pdf"&gt;pdf&lt;/a&gt;) and the open-closed principle (&lt;a href="http://www.objectmentor.com/resources/articles/ocp.pdf"&gt;pdf&lt;/a&gt;).  As inversion of control is really about the control over behavior, IoC can be implemented in many different ways. For example, control may be inverted from callee to caller through:&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Function pointers and function objects in C/C++&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Callbacks&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Lambda methods and delegates in C#&lt;/li&gt;
&lt;li&gt;Dependency Injection&lt;/li&gt;
&lt;li&gt;Event Dispatching&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The term inversion of control is quite generic, enough so that Martin Fowler has said:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Inversion of Control is too generic a term, and thus people find it confusing. As a result with a lot of discussion with various IoC advocates we settled on the name &lt;em&gt;Dependency Injection&lt;/em&gt;.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;When related to dependency injection (DI), inversion of control is to move the control and the creation and wiring of dependencies to outside the usage site. This often involves changing from procedural code to a declarative style wherein the connections between dependencies are configured separately from usage.&lt;/p&gt;
&lt;p&gt;For example, it&amp;#8217;s common to see code like the following:&lt;/p&gt;
&lt;pre&gt;
&lt;pre&gt;
public class QueryService {
    public QueryService() {
        this.db = new SqlServerDBConnectionWrapper(/*...*/)
    }
    // ...
}
&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;For one-off software, the above may be perfectly acceptable, but in typical enterprise software better change control points are needed.  For example, the above will fail to compile if the SqlServerDBConnectionWrapper constructor is changed. The problem with the above in any large-scale software is that the dependencies are hard coded. If a change request comes along requiring that an Oracle Database be supported the code must change because the dependency has been hard-wired. Or, to tie it back to the open-closed principle (OCP), the above code is not closed with respect to the database connection wrapper.&lt;/p&gt;
&lt;pre&gt;
&lt;pre&gt;
// somewhere in the configuration code
public void SetupBindings() {
    iocConfiguration.Bind&amp;lt;SqlServerDBConnectionWrapper&amp;gt;().To&amp;lt;IDBConnectionWrapper&amp;gt;();
}

// elsewhere
public class QueryService {
    public QueryService(IDBConnectionWrapper db) {
        this.db = db;
    }
    // ...
}
&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;Although some IoC containers are nothing more than DI containers, others aim to be a general purpose IoC container and support facets of IoC beyond dependency injection. DI and IoC containers allow concrete implementations to be bound to abstract components, such as interfaces. When we use dependency injection we move from procedurally defining dependencies to declaratively defining those dependencies. This allows for dependencies to be easily changed later, as in the above example.  Using a little logic, it becomes possible to use a different database connection wrapper whenever needed.&lt;/p&gt;
&lt;h2&gt;Benefits of IoC&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Encourages proper placement of behaviors and responsibilities.&lt;/em&gt; As you consider which parts of the code might need to be inverted it becomes more obvious where the lines of responsibility fall and, with that clarity, a better design becomes more likely.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Provides better configurability and testability.&lt;/em&gt; Proper use of an IoC container encourages the separation of component wiring from use which makes the application more configurable and more easily tested.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Centralizes configuration management.&lt;/em&gt; When the configuration of components happens in one place it becomes easier to spot duplication and make changes that affect the configuration as a whole.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Handles deeply nested object hierarchies. &lt;/em&gt;Computers are good handling the repetitive and mundane.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;IoC Container Features&lt;/h2&gt;
&lt;p&gt;The following items should be considered when choosing and working with an IoC/DI container:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Registration (e.g. binding a concrete implementation to an abstract type)&lt;/li&gt;
&lt;li&gt;Resolution – runtime creation of requested types&lt;/li&gt;
&lt;li&gt;Lifecycle Management – control of when objects are disposed or garbage collected&lt;/li&gt;
&lt;li&gt;Configuration Management (e.g. passing settings into necessary objects)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I&amp;#8217;m not going to go into details on the above features in this post, but there are many benefits to using an IoC/DI container. It&amp;#8217;s very possible to write good software without an IoC container. In some cases, not using an IoC container will allow problems to be spotted and fixed earlier. Of course, poorly used, IoC containers can exacerbate existing problems. But, that said, you should consider the &lt;a href="http://stackoverflow.com/questions/871405/why-do-i-need-an-ioc-container-as-opposed-to-straightforward-di-code"&gt;benefits of using an IoC container over using straightforward DI code&lt;/a&gt;.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=xSJ-qJU-_Z4:cM40ryJkq88:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=xSJ-qJU-_Z4:cM40ryJkq88:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=xSJ-qJU-_Z4:cM40ryJkq88:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=xSJ-qJU-_Z4:cM40ryJkq88:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=xSJ-qJU-_Z4:cM40ryJkq88:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=xSJ-qJU-_Z4:cM40ryJkq88:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/KalebPederson/~4/xSJ-qJU-_Z4" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://kalebpederson.com/index.php/2011/02/inversion-of-control-ioc-and-dependency-injection-di#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://kalebpederson.com/index.php/2011/02/inversion-of-control-ioc-and-dependency-injection-di/feed/atom" thr:count="0" />
		<thr:total>0</thr:total>
	<feedburner:origLink>http://kalebpederson.com/index.php/2011/02/inversion-of-control-ioc-and-dependency-injection-di</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Kaleb Pederson</name>
						<uri>http://kalebpederson.com</uri>
					</author>
		<title type="html"><![CDATA[Accessing Linux File Systems from within Windows]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/KalebPederson/~3/-dGVxn5ES5o/accessing-linux-file-systems-from-within-windows" />
		<id>http://kibab.kalebpederson.com/index.php/2010/09/accessing-linux-file-systems-from-within-windows</id>
		<updated>2011-01-02T06:30:32Z</updated>
		<published>2010-09-04T05:08:00Z</published>
		<category scheme="http://kalebpederson.com" term="linux" /><category scheme="http://kalebpederson.com" term="networking" /><category scheme="http://kalebpederson.com" term="virtualbox" /><category scheme="http://kalebpederson.com" term="windows" /><category scheme="http://kalebpederson.com" term="xfs" />		<summary type="html"><![CDATA[This post was imported from blogger, to see the original, likely better-formatted post see kalebpederson.blogspot.com. Near the end of 2009 I ask a question on superuser.com about accessing a Linux XFS filesystem from within Windows. After investigating coLinux I decided to try the VirtualBox route &#8212; and it worked beautifully! I can now access my [...]]]></summary>
		<content type="html" xml:base="http://kalebpederson.com/index.php/2010/09/accessing-linux-file-systems-from-within-windows">&lt;div class="attention"&gt;
&lt;p&gt;This post was imported from blogger, to see the original, likely better-formatted post see &lt;a href="http://kalebpederson.blogspot.com"&gt;kalebpederson.blogspot.com&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Near the end of 2009 I ask a question on superuser.com about &lt;a href="http://superuser.com/questions/93664/how-can-i-access-a-linux-xfs-partition-from-windows"&gt;accessing a Linux XFS filesystem from within Windows&lt;/a&gt;. After investigating &lt;a href="http://www.colinux.org/"&gt;coLinux&lt;/a&gt; I decided to try the VirtualBox route &amp;#8212; and it worked beautifully! I can now access my standard Linux install (which I dual boot into) from within Windows on those few days where I need to be in Windows.&lt;/p&gt;
&lt;p&gt;&lt;span id="more-74"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h1&gt;System Configuration&lt;/h1&gt;
&lt;p&gt;Machine: Windows 7 and Gentoo Linux.  Windows is acting as the boot loader. Here&amp;#8217;s my drive layout:&lt;/p&gt;
&lt;pre&gt;/dev/sda1 - NTFS - Windows 7&lt;/pre&gt;
&lt;pre&gt;/dev/sda2 - Extended Partition&lt;/pre&gt;
&lt;pre&gt;/dev/sda5 - Boot Partition (EXT3)&lt;/pre&gt;
&lt;pre&gt;/dev/sda6 - Swap/dev/sda7 - LVM&lt;/pre&gt;
&lt;pre&gt;/dev/sda8 - LVM&lt;/pre&gt;
&lt;p&gt;The Windows boot loader needs a copy of the boot record to be used.  In my case, I had installed grub into /dev/sda5, my boot partition.  I copied the boot loader out of &lt;tt&gt;/dev/sda5&lt;/tt&gt; using &lt;tt&gt;dd&lt;/tt&gt; which makes it possible to copy the first 512 bytes of the partition:&lt;/p&gt;
&lt;pre&gt;dd if=/dev/sda5 of=/root/sda5_mbr bs=512 count=1&lt;/pre&gt;
&lt;p&gt;I then copied &lt;tt&gt;/root/sda5_mbr&lt;/tt&gt; over to a thumb drive so it was available on Windows. We will need this file not only for the Windows boot loader, but also for VirtualBox as you&amp;#8217;ll see shortly.&lt;/p&gt;
&lt;p&gt;My Linux machine is publicly accessible on the internet and I have, as a requirement, that it still be accessible on the internet when I&amp;#8217;m in Windows with VirtualBox running. Given that requirement, here&amp;#8217;s my networking configuration:&lt;/p&gt;
&lt;pre&gt;Windows 7 Host- 192.168.1.20 - static IP
Linux Host:- 192.168.1.10 - static IP
Router:- 192.168.1.1 - primary gateway, forwards desirable ports to 192.168.1.10&lt;/pre&gt;
&lt;p&gt;I&amp;#8217;ve purposefully given Windows and Linux different static IP&amp;#8217;s so each is accessible and they don&amp;#8217;t run into any IP address conflicts.&lt;/p&gt;
&lt;h1&gt;Install VirtualBox&lt;/h1&gt;
&lt;p&gt;First, I installed VirtualBox in Windows. Most application installs are pretty much the same in Windows, and &lt;a href="http://www.virtualbox.org/"&gt;VirtualBox&lt;/a&gt; was no different, so I&amp;#8217;m not going to document installing VirtualBox.  If you&amp;#8217;re reading this, I&amp;#8217;m sure you&amp;#8217;re more than capable.&lt;/p&gt;
&lt;h1&gt;Configure VirtualBox Hard Drive Access&lt;/h1&gt;
&lt;p&gt;Like many applications, VirtualBox has some standard directories that it uses:&lt;/p&gt;
&lt;pre&gt;%USERDIR%\%USERNAME%\.VirtualBox\HardDisks%USERDIR%\%USERNAME%\.VirtualBox\Machines&lt;/pre&gt;
&lt;p&gt;&lt;tt&gt;%USERDIR%&lt;/tt&gt; is likely &lt;tt&gt;C:\Users&lt;/tt&gt; and &lt;tt&gt;%USERNAME%&lt;/tt&gt; is the username of the account that you typically log in as.&lt;/p&gt;
&lt;p&gt;You can create the above directories by hand if you like, but I&amp;#8217;m going to assume they exist. With those directories in hand, we now need to tell VirtualBox about the raw partitions that we want it to use. Since Windows is our host, we do not want to accidentally access it from within Linux as that could cause corruption.  Furthermore, we want to use the grub boot loader so we don&amp;#8217;t have to bother with the standard Windows MBR.  Since we&amp;#8217;re giving VirtualBox access to the physical drive, we need to be a full administrator. So, run &lt;tt&gt;cmd&lt;/tt&gt; as an administrator. Now let&amp;#8217;s make VirtualBox aware of the rest of our partitions:&lt;/p&gt;
&lt;pre&gt;C:\&amp;gt;cd \users\kpederson\.virtualbox\harddisks&lt;/pre&gt;
&lt;pre&gt;C:\Users\kpederson\.VirtualBox\HardDisks&amp;gt;"\Program Files\Oracle\VirtualBox\VBoxManage" \&lt;/pre&gt;
&lt;pre&gt;  internalcommands createrawvmdk -filename rawdisk.vmdk -rawdisk \\.\PhysicalDrive0 \&lt;/pre&gt;
&lt;pre&gt;  -partitions 5,6,7,8 -mbr f:\sda5_mbr -register&lt;/pre&gt;
&lt;p&gt;The above creates two files, rawdisk.vmdk and rawdisk-pt.vmdk:&lt;/p&gt;
&lt;pre&gt;-r-------- 2 root root     161280 Sep  1 22:19 rawdisk-pt.vmdk&lt;/pre&gt;
&lt;pre&gt;-r-------- 2 root root        994 Sep  2 00:16 rawdisk.vmdk&lt;/pre&gt;
&lt;p&gt;The files aren&amp;#8217;t particularly big. They do little more than tell VirtualBox about the partitions that it can access and embed the MBR. Here&amp;#8217;s some details about the command:&lt;/p&gt;
&lt;pre&gt;&lt;em&gt;"\Program Files\Oracle\VirtualBox\VBoxManage"&lt;/em&gt; - the command we're calling&lt;/pre&gt;
&lt;pre&gt;&lt;em&gt;internalcommands&lt;/em&gt; - the main command we're calling&lt;/pre&gt;
&lt;pre&gt;&lt;em&gt;createrawvmdk&lt;/em&gt; - the sub command - create a raw virtual disk file&lt;/pre&gt;
&lt;pre&gt;&lt;em&gt;-filename rawdisk.vmdk&lt;/em&gt; - specify name of the virtual disk to be created&lt;/pre&gt;
&lt;pre&gt;&lt;em&gt;-&lt;/em&gt;&lt;em&gt;rawdisk \\.\PhysicalDrive0&lt;/em&gt; - creating a raw disk and using the main physical drive&lt;/pre&gt;
&lt;pre&gt;&lt;em&gt;-partitions 5,6,7,8&lt;/em&gt; - only give VirtualBox access to the Linux partitions&lt;/pre&gt;
&lt;pre&gt;&lt;em&gt;-mbr f:\sda5_mbr&lt;/em&gt; - install a new MBR, the one I copied onto my thumb drive (f:\)&lt;/pre&gt;
&lt;pre&gt;&lt;em&gt;-register&lt;/em&gt; - add the drive virtual media manager&lt;/pre&gt;
&lt;p&gt;If the above command worked successfully, we should see output similar to the following:&lt;/p&gt;
&lt;pre&gt;Oracle VM VirtualBox Command Line Management Interface Version 3.2.8(C) 2005-2010 Oracle CorporationAll rights reserved.

RAW host disk access VMDK file rawdisk.vmdk created successfully.&lt;/pre&gt;
&lt;h1&gt;Create your Virtual Machine&lt;/h1&gt;
&lt;p&gt;Now that VirtualBox knows about my raw Linux partitions and is setup to use the MBR containing grub, I can now configure a Virtual Machine within VirtualBox. Here&amp;#8217;s the basic steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Choose a name and the correct version (note 64-bit option)&lt;/li&gt;
&lt;li&gt;Select the amount of available RAM to dedicate to the VM&lt;/li&gt;
&lt;li&gt;Make sure &amp;#8220;Boot Hard Disk&amp;#8221; is checked and select use existing hard disk: FIXME: insert image here&lt;/li&gt;
&lt;li&gt;Review settings and select Finish&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The system should now boot up when choose start.  Hopefully you&amp;#8217;ll be greeted by a the grub startup screen:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/41Fwf-9AA1VWrjeRI6HjXufFcIpgBVMyR7HxjMFMStE?feat=embedwebsite"&gt;&lt;img src="http://lh6.ggpht.com/_9KeH89IzttQ/TIHbwjX6HvI/AAAAAAAAARw/wuyFLoivbKI/s400/grub_running.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;Configure Networking&lt;/h1&gt;
&lt;p&gt;Most of the configuration is pretty straightforward, but my networking requirements will take a little effort to get right.  First, let me show you the &lt;del&gt;obvious&lt;/del&gt; correct answer and my first attempt &amp;#8212; bridged networking. Bridge networking should allow the virtual network card presented to Linux by VirtualBox to send out any data it wants on the physical device as if the computer was assigned both IP addresses (192.168.1.10 and 192.168.1.20):&lt;/p&gt;
&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/N-iwgZKqNY6ylITduXF7xefFcIpgBVMyR7HxjMFMStE?feat=embedwebsite"&gt;&lt;img src="http://lh4.ggpht.com/_9KeH89IzttQ/TIHbwc5NfSI/AAAAAAAAARk/uQTh8qUyoew/s400/bridged_network_connection.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Unfortunately, that didn&amp;#8217;t work &amp;#8212; I had network access, but it was only local. Windows 7 could communicate with my virtual machine and my virtual machine could communicate with Windows but my virtual machine didn&amp;#8217;t have internet access and couldn&amp;#8217;t resolve DNS. I tried for quite a while and couldn&amp;#8217;t figure out the problem in a reasonable time (I assume it&amp;#8217;s a bug).  However, I found a work around thanks to a post that on the VirtualBox forum that I can no longer find. Instead of letting VirtualBox create the bridge, use Windows to bridge the connections. To do this, we have to configure our virtual machine to use host-only networking:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/H2UdoALF0I59PhnLwGpFgefFcIpgBVMyR7HxjMFMStE?feat=embedwebsite"&gt;&lt;img src="http://lh5.ggpht.com/_9KeH89IzttQ/TIHbwoXRKfI/AAAAAAAAARo/YpBLbgYVBlM/s400/host_only_networking.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;With host-only networking configured, we&amp;#8217;ll now boot into Linux.  Once up and running, lets bridge the networks.  Pull up the network interfaces dialog and select your standard network adapter and the host-only network adapter, then right click and bridge the connection as illustrated below:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/H7CWyYMChCYSDlwtgSlESufFcIpgBVMyR7HxjMFMStE?feat=embedwebsite"&gt;&lt;img src="http://lh6.ggpht.com/_9KeH89IzttQ/TIHbww5ZDrI/AAAAAAAAAR0/FwUx4cxlvbM/s800/bridge_network_connections.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;That does bring some slight complications, namely, I have to disable the bridge in order to retain internet access when my virtual machine isn&amp;#8217;t running.&lt;/p&gt;
&lt;p&gt;Since the new bridge is in place, you should now be able to resolve network addresses.  Here&amp;#8217;s a quick test using &lt;tt&gt;dig&lt;/tt&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/Ef6Kt1o5vE9AyU2DrU48bufFcIpgBVMyR7HxjMFMStE?feat=embedwebsite"&gt;&lt;img src="http://lh4.ggpht.com/_9KeH89IzttQ/TIHeEPAaJ_I/AAAAAAAAAR4/6SgJ_InfM2I/s400/fullscreen_network_access.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;Configure Samba&lt;/h1&gt;
&lt;p&gt;Assuming your Linux distribution installs a working samba, the only thing you should need to do is to edit &lt;tt&gt;smb.conf&lt;/tt&gt; to include a share.  Here&amp;#8217;s my most frequently used share definition:&lt;/p&gt;
&lt;pre&gt;[shared]   comment = Shared Documents   path = /home/shared   force group = smb_users   guest ok = no   writable = yes&lt;/pre&gt;
&lt;p&gt;With that share in place you can restart samba (or have it re-read the configuration file using &lt;tt&gt;smbcontrol&lt;/tt&gt;) to enable the share.  And with that, you should be able to access that share from within Windows using your ip address or netbios name.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=-dGVxn5ES5o:g18124RbVKE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=-dGVxn5ES5o:g18124RbVKE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=-dGVxn5ES5o:g18124RbVKE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=-dGVxn5ES5o:g18124RbVKE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=-dGVxn5ES5o:g18124RbVKE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=-dGVxn5ES5o:g18124RbVKE:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/KalebPederson/~4/-dGVxn5ES5o" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://kalebpederson.com/index.php/2010/09/accessing-linux-file-systems-from-within-windows#comments" thr:count="2" />
		<link rel="replies" type="application/atom+xml" href="http://kalebpederson.com/index.php/2010/09/accessing-linux-file-systems-from-within-windows/feed/atom" thr:count="2" />
		<thr:total>2</thr:total>
	<feedburner:origLink>http://kalebpederson.com/index.php/2010/09/accessing-linux-file-systems-from-within-windows</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Kaleb Pederson</name>
						<uri>http://kalebpederson.com</uri>
					</author>
		<title type="html"><![CDATA[QMetaEnum Magic &#8211; Serializing C++ Enums &#8211; Take 2]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/KalebPederson/~3/G7h7vpsK6TA/qmetaenum-magic-serializing-c-enums-take-2" />
		<id>http://kibab.kalebpederson.com/index.php/2010/08/qmetaenum-magic-serializing-c-enums-take-2</id>
		<updated>2010-08-21T03:52:00Z</updated>
		<published>2010-08-21T03:52:00Z</published>
		<category scheme="http://kalebpederson.com" term="qmetaenum" /><category scheme="http://kalebpederson.com" term="qt" /><category scheme="http://kalebpederson.com" term="serialization" />		<summary type="html"><![CDATA[This post was imported from blogger, to see the original, likely better-formatted post see kalebpederson.blogspot.com. > A few posts ago I described two methods of serializing C++ enums. Of these, method 2 serialized the Qt::Key enum. The approach, however, relied on some behind the scenes magic that I wasn&#8217;t fully aware of nor did I [...]]]></summary>
		<content type="html" xml:base="http://kalebpederson.com/index.php/2010/08/qmetaenum-magic-serializing-c-enums-take-2">&lt;div class="attention"&gt;
&lt;p&gt;This post was imported from blogger, to see the original, likely better-formatted post see &lt;a href="http://kalebpederson.blogspot.com"&gt;kalebpederson.blogspot.com&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&gt;
&lt;p&gt;&lt;a href="http://www.kalebpederson.com/2010/07/qmetaenum-magic-serializing-c-enums.html"&gt;A few posts ago&lt;/a&gt; I described two methods of serializing C++ enums. Of these, method 2 serialized the &lt;tt&gt;Qt::Key&lt;/tt&gt; enum. The approach, however, relied on some behind the scenes magic that I wasn&amp;#8217;t fully aware of nor did I fully document.  This approach remedies that and describes in full the requirements for serializing C++ enums.&lt;/p&gt;
&lt;h2&gt;Method 2 &amp;#8211; Reevaluated&lt;/h2&gt;
&lt;p&gt;The goal for this method is to take an enum called &lt;tt&gt;MyKey&lt;/tt&gt; in the &lt;tt&gt;MyNS&lt;/tt&gt; namespace and serialize it.  In brief, the code for that looks like the following:&lt;/p&gt;
&lt;pre&gt;namespace MyNS{    enum MyKey {        MyKey_Return = 0,        MyKey_Enter = 1        };}&lt;/pre&gt;
&lt;p&gt;Since we want Qt to be able to serialize the above enum, it needs to know about the enum, so we&amp;#8217;re going to need &lt;tt&gt;Q_ENUMS(MyKey)&lt;/tt&gt;. But unless moc sees a &lt;tt&gt;Q_OBJECT&lt;/tt&gt; or &lt;tt&gt;Q_GADGET&lt;/tt&gt; macro, our &lt;tt&gt;Q_ENUMS&lt;/tt&gt; macro will result in a compilation error. To get around this, we need to convince moc to process the file as if it were a class.  We can do that by adding some preprocessor defines:&lt;/p&gt;
&lt;pre&gt;#ifndef Q_MOC_RUNnamespace MyNS#elseclass MyNS#endif{#if defined(Q_MOC_RUN)    Q_GADGET    Q_ENUMS(MyKey)public:#endif    enum MyKey {        MyKey_Return = 0,        MyKey_Enter = 1    };}&lt;/pre&gt;
&lt;p&gt;At this point we&amp;#8217;ve convinced moc to look at and process the file, but that alone isn&amp;#8217;t enough. The code that moc generates assumes that a &lt;tt&gt;const staticMetaObject&lt;/tt&gt; has been declared, but at this point one hasn&amp;#8217;t been declared. Although some compilers will let us get away with this, we&amp;#8217;ll declare it as follows:&lt;/p&gt;
&lt;pre&gt;    // ... continuing at the enum    enum MyKey {        MyKey_Return = 0,        MyKey_Enter = 1    };    extern const QMetaObject staticMetaObject;}&lt;/pre&gt;
&lt;p&gt;With that in place, we&amp;#8217;re ready to serialize the enum.  The first step is to get a copy of the &lt;tt&gt;QMetaEnum&lt;/tt&gt; object.  We do so by accessing the static reference directly and then calling &lt;tt&gt;indexOfEnumerator&lt;/tt&gt; to get the appropriate index:&lt;/p&gt;
&lt;pre&gt;    // get the QMetaEnum object    const QMetaObject &amp;#038;mo = MyNS::staticMetaObject;    int enum_index = mo.indexOfEnumerator("MyKey");    QMetaEnum metaEnum = mo.enumerator(enum_index);&lt;/pre&gt;
&lt;p&gt;With the &lt;tt&gt;QMetaEnum&lt;/tt&gt; instance in hand, we can now serialize the enum as demonstrated in my prior post:&lt;/p&gt;
&lt;pre&gt;    // convert to a string    MyNS::MyKey key = MyNS::MyKey_Return;    QByteArray str = metaEnum.valueToKey(key);    qDebug() &lt;&lt; "Value as str:" &lt;&lt; str;

    // convert from a string    int value = metaEnum.keyToValue("MyKey_Enter");    key = static_cast&lt;myNS::MyKey&gt;(value);    qDebug() &lt;&lt; "key is MyKey_Enter? : " &lt;&lt; (key == MyNS::MyKey_Enter);&lt;/pre&gt;
&lt;p&gt;With all the above in place, we&amp;#8217;ve used a bit of magic to trick moc into thinking &lt;tt&gt;MyNS&lt;/tt&gt; was a class. This causes moc to generate a &lt;tt&gt;MyNS::staticMetaObject&lt;/tt&gt; instance and store the necessary serialization meta data. With everything in place, we get the following output:&lt;/p&gt;
&lt;pre&gt;Value as str: "MyKey_Return" key is MyKey_Enter? :  true &lt;/pre&gt;
&lt;p&gt;References:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;#8220;&lt;a href="http://labs.trolltech.com/page/Projects/DevDays/DevDays2007"&gt;Secrets of Qt Full&lt;/a&gt;&amp;#8221; developer days presentation&lt;/li&gt;
&lt;li&gt;&lt;a href="http://qt.gitorious.org/qt/qt/blobs/4.7/src/tools/moc/generator.cpp#line340"&gt;src/tools/moc/generator.cpp:340&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://qt.gitorious.org/qt/qt/blobs/4.7/src/corelib/global/qnamespace.h#line53"&gt;src/corelib/global/qnamespace.h:53,80&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=G7h7vpsK6TA:f7rbjrXlHvE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=G7h7vpsK6TA:f7rbjrXlHvE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=G7h7vpsK6TA:f7rbjrXlHvE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=G7h7vpsK6TA:f7rbjrXlHvE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=G7h7vpsK6TA:f7rbjrXlHvE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=G7h7vpsK6TA:f7rbjrXlHvE:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/KalebPederson/~4/G7h7vpsK6TA" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://kalebpederson.com/index.php/2010/08/qmetaenum-magic-serializing-c-enums-take-2#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://kalebpederson.com/index.php/2010/08/qmetaenum-magic-serializing-c-enums-take-2/feed/atom" thr:count="0" />
		<thr:total>0</thr:total>
	<feedburner:origLink>http://kalebpederson.com/index.php/2010/08/qmetaenum-magic-serializing-c-enums-take-2</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Kaleb Pederson</name>
						<uri>http://kalebpederson.com</uri>
					</author>
		<title type="html"><![CDATA[Learning Ruby Symbols]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/KalebPederson/~3/Drzc6c7Vzeg/learning-ruby-symbols" />
		<id>http://kibab.kalebpederson.com/index.php/2010/08/learning-ruby-symbols</id>
		<updated>2010-08-15T05:34:00Z</updated>
		<published>2010-08-15T05:34:00Z</published>
		<category scheme="http://kalebpederson.com" term="Uncategorized" />		<summary type="html"><![CDATA[This post was imported from blogger, to see the original, likely better-formatted post see kalebpederson.blogspot.com. > Ruby has at least a couple of different ways of referencing variables. Class instance variables can be created with the @ prefix, like @my_var = "test", there&#8217;s also an @@ prefix for class-level variables. For the first few days [...]]]></summary>
		<content type="html" xml:base="http://kalebpederson.com/index.php/2010/08/learning-ruby-symbols">&lt;div class="attention"&gt;
&lt;p&gt;This post was imported from blogger, to see the original, likely better-formatted post see &lt;a href="http://kalebpederson.blogspot.com"&gt;kalebpederson.blogspot.com&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&gt;
&lt;p&gt;Ruby has at least a couple of different ways of referencing variables.  Class instance variables can be created with the &lt;tt&gt;@&lt;/tt&gt; prefix, like &lt;tt&gt;@my_var = "test"&lt;/tt&gt;, there&amp;#8217;s also an &lt;tt&gt;@@&lt;/tt&gt; prefix for class-level variables.&lt;/p&gt;
&lt;p&gt;For the first few days I was learning Ruby and Ruby on Rails, I kept stumbling upon &amp;#8220;variables&amp;#8221; like &lt;tt&gt;:name&lt;/tt&gt;. But when I tried to assign one, I quickly discovered that it wasn&amp;#8217;t a variable &amp;#8212; &lt;em&gt;it was a symbol&lt;/em&gt;.  My attempt resulted in a failure:&lt;/p&gt;
&lt;pre&gt;irb(main):001:0&gt; :test = 4SyntaxError: compile error(irb):1: syntax error, unexpected '=', expecting $end:test = 4       ^        from (irb):1&lt;/pre&gt;
&lt;p&gt;The ruby compiler didn&amp;#8217;t expect anything after the &amp;#8216;&lt;tt&gt;=&lt;/tt&gt;&amp;#8216;, and it complains.&lt;/p&gt;
&lt;h2&gt;What are Symbols?&lt;/h2&gt;
&lt;p&gt;According to the &lt;a href="http://ruby-doc.org/core/classes/Symbol.html"&gt;Symbol documentation&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;tt&gt;Symbol&lt;/tt&gt; objects represent names and some strings inside the Ruby interpreter. They are generated using the &lt;tt&gt;:name&lt;/tt&gt; and &lt;tt&gt;:"string"&lt;/tt&gt; literals syntax, and by the various &lt;tt&gt;to_sym&lt;/tt&gt; methods. The same Symbol object will be created for a given name or string for the duration of a program&amp;#8217;s execution, regardless of the context or meaning of that name. Thus if Fred is a constant in one context, a method in another, and a class in a third, the &lt;tt&gt;Symbol&lt;/tt&gt; &lt;tt&gt;:Fred&lt;/tt&gt; will be the same object in all three contexts.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;A symbol acts as an alias to a name such as a variable, class, or method. As a simple example, consider the following two hashes:&lt;/p&gt;
&lt;pre&gt;u1 = { "name" =&gt; "Kaleb", "phone" =&gt; "private" }u2 = { "name" =&gt; "Larry", "phone" =&gt; "private" }&lt;/pre&gt;
&lt;p&gt;And here&amp;#8217;s a similarly structured hash using symbols:&lt;/p&gt;
&lt;pre&gt;u1 = { :name =&gt; "Kaleb", :phone =&gt; "private" }u2 = { :name =&gt; "Larry", :phone =&gt; "private" }&lt;/pre&gt;
&lt;p&gt;For each hash the compiler keeps copies of the keys &lt;tt&gt;"name"&lt;/tt&gt; and &lt;tt&gt;"phone"&lt;/tt&gt;. For a couple of values this doesn&amp;#8217;t matter, but for thousands of records it adds up to a lot of duplication and wasted memory. A &lt;a href="http://glu.ttono.us/articles/2005/08/19/understanding-ruby-symbols"&gt;post on glu.ttono.us&lt;/a&gt; provides more concrete details on both symbols and memory usage differences.&lt;/p&gt;
&lt;h2&gt;Other Resources on Symbols&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.randomhacks.net/articles/2007/01/20/13-ways-of-looking-at-a-ruby-symbol"&gt;13 Ways of Looking at a Ruby Symbol&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://ruby-doc.org/core/classes/Symbol.html"&gt;The Symbol Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.google.com?q=ruby+symbols"&gt;Google&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=Drzc6c7Vzeg:jfs36X92mNk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=Drzc6c7Vzeg:jfs36X92mNk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=Drzc6c7Vzeg:jfs36X92mNk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=Drzc6c7Vzeg:jfs36X92mNk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=Drzc6c7Vzeg:jfs36X92mNk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=Drzc6c7Vzeg:jfs36X92mNk:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/KalebPederson/~4/Drzc6c7Vzeg" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://kalebpederson.com/index.php/2010/08/learning-ruby-symbols#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://kalebpederson.com/index.php/2010/08/learning-ruby-symbols/feed/atom" thr:count="0" />
		<thr:total>0</thr:total>
	<feedburner:origLink>http://kalebpederson.com/index.php/2010/08/learning-ruby-symbols</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Kaleb Pederson</name>
						<uri>http://kalebpederson.com</uri>
					</author>
		<title type="html"><![CDATA[rspec: undefined method route_for error]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/KalebPederson/~3/cw08c6YEi9o/rspec-undefined-method-route_for-error" />
		<id>http://kibab.kalebpederson.com/index.php/2010/08/rspec-undefined-method-route_for-error</id>
		<updated>2010-08-13T04:04:00Z</updated>
		<published>2010-08-13T04:04:00Z</published>
		<category scheme="http://kalebpederson.com" term="errors" /><category scheme="http://kalebpederson.com" term="rspec" /><category scheme="http://kalebpederson.com" term="ruby-on-rails" />		<summary type="html"><![CDATA[This post was imported from blogger, to see the original, likely better-formatted post see kalebpederson.blogspot.com. > I&#8217;m now in the process of learning Ruby on Rails and its friends, like rspec. Firmly believing in TDD, I jumped on the rpsec bandwagon as soon as I could. The second thing I started to test was my [...]]]></summary>
		<content type="html" xml:base="http://kalebpederson.com/index.php/2010/08/rspec-undefined-method-route_for-error">&lt;div class="attention"&gt;
&lt;p&gt;This post was imported from blogger, to see the original, likely better-formatted post see &lt;a href="http://kalebpederson.blogspot.com"&gt;kalebpederson.blogspot.com&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&gt;
&lt;p&gt;I&amp;#8217;m now in the process of learning Ruby on Rails and its friends, like rspec. Firmly believing in TDD, I jumped on the rpsec bandwagon as soon as I could. The second thing I started to test was my routes. My test looked something like this:&lt;/p&gt;
&lt;pre&gt;  describe "should create :page param for / url" do    route_for(:controller =&gt; 'pages', :action =&gt; 'index').should == "/"  end&lt;/pre&gt;
&lt;p&gt;But sadly this resulted in the following error:&lt;/p&gt;
&lt;pre&gt;pages_controller_routing_spec.rb:14: undefined method `route_for' for #&lt;class:0x7f679e912b40&gt; (NoMethodError)&lt;/pre&gt;
&lt;p&gt;After some googling I found a &lt;a href="http://groups.google.com/group/rspec/browse_thread/thread/f73a3341b50ffd45"&gt;thread on the rspec mailing list&lt;/a&gt; that revealed a few different causes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;spec/controllers in their path (i.e. spec/controllers/foo_controller_spec)&lt;/li&gt;
&lt;li&gt;describe &amp;#8220;route generation&amp;#8221;, :type =&gt; :controller do&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;My spec class was a controller, so that wasn&amp;#8217;t the issue. The second option is only required when the controller test is not in &lt;tt&gt;spec/controllers&lt;/tt&gt;, so that wasn&amp;#8217;t the issue.  I had scoured the rspec docs, and everything I read said it should work.
&lt;p&gt;I had missed the most obvious thing of all &amp;#8212; I had said &lt;em&gt;describe&lt;/em&gt; when I meant &lt;em&gt;it&lt;/em&gt;:&lt;/p&gt;
&lt;pre&gt;  &lt;b&gt;it&lt;/b&gt; "should create :page param for / url" do    route_for(:controller =&gt; 'pages', :action =&gt; 'index').should == "/"  end&lt;/pre&gt;
&lt;p&gt;So, if you happen to encounter a similar error&amp;#8230; don&amp;#8217;t forget to check the obvious.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=cw08c6YEi9o:jv9HNVMbPrM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=cw08c6YEi9o:jv9HNVMbPrM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=cw08c6YEi9o:jv9HNVMbPrM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=cw08c6YEi9o:jv9HNVMbPrM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=cw08c6YEi9o:jv9HNVMbPrM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=cw08c6YEi9o:jv9HNVMbPrM:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/KalebPederson/~4/cw08c6YEi9o" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://kalebpederson.com/index.php/2010/08/rspec-undefined-method-route_for-error#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://kalebpederson.com/index.php/2010/08/rspec-undefined-method-route_for-error/feed/atom" thr:count="0" />
		<thr:total>0</thr:total>
	<feedburner:origLink>http://kalebpederson.com/index.php/2010/08/rspec-undefined-method-route_for-error</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Kaleb Pederson</name>
						<uri>http://kalebpederson.com</uri>
					</author>
		<title type="html"><![CDATA[QMetaEnum Magic &#8211; Serializing C++ enum&#8217;s]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/KalebPederson/~3/TWA67qXygxc/qmetaenum-magic-serializing-c-enums" />
		<id>http://kibab.kalebpederson.com/index.php/2010/07/qmetaenum-magic-serializing-c-enums</id>
		<updated>2010-07-29T04:46:00Z</updated>
		<published>2010-07-29T04:46:00Z</published>
		<category scheme="http://kalebpederson.com" term="qmetaenum" /><category scheme="http://kalebpederson.com" term="qt" /><category scheme="http://kalebpederson.com" term="serialization" />		<summary type="html"><![CDATA[This post was imported from blogger, to see the original, likely better-formatted post see kalebpederson.blogspot.com. > Qt has a number of useful classes and utilities; among these is QMetaEnum which provides the ability to serialize and deserialize C++ enumerations through the use of moc, the meta-object compiler. Method 1 &#8211; Enum&#8217;s within a QObject (fairly [...]]]></summary>
		<content type="html" xml:base="http://kalebpederson.com/index.php/2010/07/qmetaenum-magic-serializing-c-enums">&lt;div class="attention"&gt;
&lt;p&gt;This post was imported from blogger, to see the original, likely better-formatted post see &lt;a href="http://kalebpederson.blogspot.com"&gt;kalebpederson.blogspot.com&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&gt;
&lt;p&gt;Qt has a number of useful classes and utilities; among these is &lt;tt&gt;&lt;a href="http://doc.trolltech.com/4.6/qmetaenum.html"&gt;QMetaEnum&lt;/a&gt;&lt;/tt&gt; which provides the ability to serialize and deserialize C++ enumerations through the use of &lt;a href="http://doc.qt.nokia.com/4.6/moc.html"&gt;moc&lt;/a&gt;, the meta-object compiler.&lt;/p&gt;
&lt;h2&gt;Method 1 &amp;#8211; Enum&amp;#8217;s within a QObject (fairly common)&lt;/h2&gt;
&lt;p&gt;First, let&amp;#8217;s take a look at a common example of an &lt;tt&gt;enum&lt;/tt&gt; within a class as provided in the &amp;#8220;Secrets of Qt Full&amp;#8221; developer days presentation:&lt;/p&gt;
&lt;pre&gt;class Person : public QObject {    Q_OBJECT    enum  Qualification { Student, ... };    Q_ENUMS(Qualification)};&lt;/pre&gt;
&lt;p&gt;When &lt;tt&gt;moc&lt;/tt&gt; runs on the above and sees &lt;tt&gt;Q_OBJECT&lt;/tt&gt; it adds a &lt;tt&gt;staticMetaObject&lt;/tt&gt; member (that&amp;#8217;s static, big surprise) of type &lt;a href="http://doc.qt.nokia.com/4.6/qmetaobject.html"&gt;QMetaObject&lt;/a&gt;. This &lt;tt&gt;QMetaObject&lt;/tt&gt; instance has an &lt;a href="http://doc.qt.nokia.com/4.6/qmetaobject.html#indexOfEnumerator"&gt;indexOfEnumerator&lt;/a&gt; and an &lt;a href="http://doc.qt.nokia.com/4.6/qmetaobject.html#enumerator"&gt;enumerator&lt;/a&gt; member functions that make it possible to access the &lt;tt&gt;QMetaEnum&lt;/tt&gt; representing the &lt;tt&gt;Person::Qualification&lt;/tt&gt; enum.&lt;/p&gt;
&lt;p&gt;The code to access the &lt;tt&gt;QMetaEnum&lt;/tt&gt; member looks something like the following:
&lt;pre&gt;const QMetaObject &amp;#038;mo = Person::staticMetaObject;int index = mo.indexOfEnumerator("Qualification"); // watch out during refactoringsQMetaEnum metaEnum = mo.enumerator(index);&lt;/pre&gt;
&lt;p&gt;We can then use the &lt;tt&gt;QMetaEnum&lt;/tt&gt; object as follows:&lt;/p&gt;
&lt;pre&gt;// first, let's convert from an enum value to a stringQualification q = Person::Student;QByteArray str = metaEnum.valueToKey(q);// str now contains "Student"

// second, let's convert from a string to an enum value:int value = metaEnum.keyToValue("Student");Qualification q = static_cast
&lt;person::Qualification&gt;(value);&lt;/pre&gt;
&lt;h2&gt;Method 2 &amp;#8211; Without a QObject-based class (less common)&lt;/h2&gt;
&lt;p style="background: #cccccc; border: 2px; border: 1px solid black; padding: 4px;"&gt;&lt;strong&gt;UPDATE:&lt;/strong&gt; Based on Vladislaw&amp;#8217;s comment, I&amp;#8217;ve done further research and added an &lt;a href="http://www.kalebpederson.com/2010/08/qmetaenum-magic-serializing-c-enums.html"&gt;additional post&lt;/a&gt; which demonstrates how to accomplish this in namespaces other than Qt.&lt;/p&gt;
&lt;p&gt;Another less well-known feature is that with only minor effort you can use this same feature without needing a &lt;tt&gt;QObject&lt;/tt&gt;-based class as a container.  For this example, I&amp;#8217;ll use the &lt;tt&gt;Qt::Key&lt;/tt&gt; enum. Since we don&amp;#8217;t want a &lt;tt&gt;QObject&lt;/tt&gt; based class, rather than using &lt;tt&gt;Q_OBJECT&lt;/tt&gt; we&amp;#8217;ll use the &lt;tt&gt;Q_GADGET&lt;/tt&gt; macro within a container:&lt;/p&gt;
&lt;pre&gt;class Container { Q_GADGET Q_PROPERTY(Qt::Key key_enum);public: Qt::Key key_enum;};&lt;/pre&gt;
&lt;p&gt;Like &lt;tt&gt;Q_OBJECT&lt;/tt&gt;, &lt;tt&gt;Q_GADGET&lt;/tt&gt; creates a &lt;tt&gt;staticMetaObject&lt;/tt&gt; member that we&amp;#8217;ll need to use to access the &lt;tt&gt;QMetaEnum&lt;/tt&gt;:&lt;/p&gt;
&lt;pre&gt;const QMetaObject &amp;#038;mo = Container::staticMetaObject;int prop_index = mo.indexOfProperty("key_enum");QMetaProperty metaProperty = mo.property(prop_index);QMetaEnum metaEnum = metaProperty.enumerator();&lt;/pre&gt;
&lt;p&gt;Unlike the first example, in this example I referenced the &lt;tt&gt;Qt::Key&lt;/tt&gt; typed &lt;tt&gt;key_enum&lt;/tt&gt; property to get a hold on the &lt;tt&gt;QMetaEnum&lt;/tt&gt; object that I can now use exactly as before:&lt;/p&gt;
&lt;pre&gt;// convert to a stringQt::Key key = Qt::Key_Down;QByteArray str = metaEnum.valueToKey(key);qDebug() &lt;&lt; "Value as str:" &lt;&lt; str;

// convert from a stringint value = metaEnum.keyToValue("Key_Up");key = static_cast&lt;qt::Key&gt;(value);qDebug() &lt;&lt; "key is Key_Up: " &lt;&lt; (key == Qt::Key_Up);&lt;/pre&gt;
&lt;p&gt;Which results in the following output:&lt;/p&gt;
&lt;pre&gt;Value as str: "Key_Down" key is Key_Up:  true&lt;/pre&gt;
&lt;p&gt;And there you have it&amp;#8230; an easy way to leverage Qt to serialize C++ enums.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=TWA67qXygxc:nkq2aG_Cw9Q:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=TWA67qXygxc:nkq2aG_Cw9Q:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=TWA67qXygxc:nkq2aG_Cw9Q:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=TWA67qXygxc:nkq2aG_Cw9Q:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=TWA67qXygxc:nkq2aG_Cw9Q:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=TWA67qXygxc:nkq2aG_Cw9Q:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/KalebPederson/~4/TWA67qXygxc" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://kalebpederson.com/index.php/2010/07/qmetaenum-magic-serializing-c-enums#comments" thr:count="3" />
		<link rel="replies" type="application/atom+xml" href="http://kalebpederson.com/index.php/2010/07/qmetaenum-magic-serializing-c-enums/feed/atom" thr:count="3" />
		<thr:total>3</thr:total>
	<feedburner:origLink>http://kalebpederson.com/index.php/2010/07/qmetaenum-magic-serializing-c-enums</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Kaleb Pederson</name>
						<uri>http://kalebpederson.com</uri>
					</author>
		<title type="html"><![CDATA[The leak that wasn&#8217;t a bug (i.e. one reason programming is hard)]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/KalebPederson/~3/-dyRcYoO_Sk/the-leak-that-wasnt-a-bug-i-e-one-reason-programming-is-hard" />
		<id>http://kibab.kalebpederson.com/index.php/2010/04/the-leak-that-wasnt-a-bug-i-e-one-reason-programming-is-hard</id>
		<updated>2010-05-01T04:32:00Z</updated>
		<published>2010-05-01T04:32:00Z</published>
		<category scheme="http://kalebpederson.com" term="bugs" /><category scheme="http://kalebpederson.com" term="law of leaky abstractions" />		<summary type="html"><![CDATA[This post was imported from blogger, to see the original, likely better-formatted post see kalebpederson.blogspot.com. > Bugs are a pain, they eat time, destroy quality, and seem to almost always happen at inopportune times. What&#8217;s even worse is when the bug is in a 3rd party library or somebody else&#8217;s code. My application needed to [...]]]></summary>
		<content type="html" xml:base="http://kalebpederson.com/index.php/2010/04/the-leak-that-wasnt-a-bug-i-e-one-reason-programming-is-hard">&lt;div class="attention"&gt;
&lt;p&gt;This post was imported from blogger, to see the original, likely better-formatted post see &lt;a href="http://kalebpederson.blogspot.com"&gt;kalebpederson.blogspot.com&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&gt;
&lt;p&gt;Bugs are a pain, they eat time, destroy quality, and seem to almost always happen at inopportune times. What&amp;#8217;s even worse is when the bug is in a 3rd party library or somebody else&amp;#8217;s code.&lt;/p&gt;
&lt;p&gt;My application needed to monitor a directory for changes to files. Unfortunately, Java 6 doesn&amp;#8217;t yet have support for directory monitoring, so I started looking around for different libraries.  I found two that were good candidates, &lt;a href="http://jnotify.sourceforge.net/"&gt;JNotify&lt;/a&gt; and &lt;a href="http://jpoller.sourceforge.net/"&gt;JPoller&lt;/a&gt; but ultimately decided to use JPoller because it was a pure Java implementation and was fairly well documented.&lt;/p&gt;
&lt;p&gt;It didn&amp;#8217;t take long to integrate JPoller into my application.  Although it wasn&amp;#8217;t designed for testability in mind, I expected the tests to go fairly quickly, and they did.  Everything looked good. After some refactoring I started to implement my next feature. Something was wrong. &lt;em&gt;My file wasn&amp;#8217;t picked up.&lt;/em&gt; The first and second times I just assumed I placed the files in the wrong directory&amp;#8230; but I hadn&amp;#8217;t.&lt;/p&gt;
&lt;p&gt;I started looking through the JPoller source. I learned a few things, made some changes and continued the bug hunt. But, to no avail. Despite the logic looking perfectly sound it wasn&amp;#8217;t working right all the time. It was a &lt;a href="http://en.wikipedia.org/wiki/Race_condition"&gt;race condition&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As luck would have it, I had a startling insight.  &lt;b&gt;What if the timestamps were wrong?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;After &lt;a href="http://stackoverflow.com/questions/2717936/file-createnewfile-creates-files-with-last-modified-time-before-actual-creation"&gt;quite a bit of investigation&lt;/a&gt; I discovered the insight was correct. Despite the files having a timestamp in milliseconds, it was only accurate up to one second.  This allowed the file to be created at 850 milliseconds after some second and to have a timestamp of 850 milliseconds earlier.&lt;/p&gt;
&lt;h2&gt;The Law of Leaky Abstractions&lt;/h2&gt;
&lt;p&gt;I had just been struck by the &lt;a href="http://www.joelonsoftware.com/articles/LeakyAbstractions.html"&gt;Law of Leaky Abstractions&lt;/a&gt;.  On a Windows NTFS file system the resolution was accurate to 100 nanoseconds, but on Linux it was accurate to one second. And Windows FAT filesystems were only accurate to two seconds (for modification time).&lt;/p&gt;
&lt;p&gt;Despite the cross-platform nature of Java, I had to know and understand file system specifics in order to hunt down and kill this bug that wasn&amp;#8217;t a bug.  Instead, it was a leak, and one that had to be carefully worked around in order to maintain the cross-platform nature of Java.&lt;/p&gt;
&lt;p&gt;Programming is hard. It&amp;#8217;s never enough to know a single language or a single platform. Sooner or later a leaky abstraction forces you into other realms.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=-dyRcYoO_Sk:8sReD6KdT18:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=-dyRcYoO_Sk:8sReD6KdT18:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=-dyRcYoO_Sk:8sReD6KdT18:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=-dyRcYoO_Sk:8sReD6KdT18:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=-dyRcYoO_Sk:8sReD6KdT18:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=-dyRcYoO_Sk:8sReD6KdT18:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/KalebPederson/~4/-dyRcYoO_Sk" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://kalebpederson.com/index.php/2010/04/the-leak-that-wasnt-a-bug-i-e-one-reason-programming-is-hard#comments" thr:count="1" />
		<link rel="replies" type="application/atom+xml" href="http://kalebpederson.com/index.php/2010/04/the-leak-that-wasnt-a-bug-i-e-one-reason-programming-is-hard/feed/atom" thr:count="1" />
		<thr:total>1</thr:total>
	<feedburner:origLink>http://kalebpederson.com/index.php/2010/04/the-leak-that-wasnt-a-bug-i-e-one-reason-programming-is-hard</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Kaleb Pederson</name>
						<uri>http://kalebpederson.com</uri>
					</author>
		<title type="html"><![CDATA[The faller&#8217;s wedge &amp; ubiquitous language]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/KalebPederson/~3/2nDfrL9OFn8/the-fallers-wedge-ubiquitous-language" />
		<id>http://kibab.kalebpederson.com/index.php/2010/04/the-fallers-wedge-ubiquitous-language</id>
		<updated>2010-04-17T14:58:00Z</updated>
		<published>2010-04-17T14:58:00Z</published>
		<category scheme="http://kalebpederson.com" term="ddd" /><category scheme="http://kalebpederson.com" term="ubiquitous language" />		<summary type="html"><![CDATA[This post was imported from blogger, to see the original, likely better-formatted post see kalebpederson.blogspot.com. > I&#8217;ve recently been reading Domain-Driven Design, by Eric Evans. One of the foremost things Evans discusses is ubiquitous language, which he defines as: A language structured around the domain model and used by all team members to connect all [...]]]></summary>
		<content type="html" xml:base="http://kalebpederson.com/index.php/2010/04/the-fallers-wedge-ubiquitous-language">&lt;div class="attention"&gt;
&lt;p&gt;This post was imported from blogger, to see the original, likely better-formatted post see &lt;a href="http://kalebpederson.blogspot.com"&gt;kalebpederson.blogspot.com&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&gt;
&lt;p&gt;I&amp;#8217;ve recently been reading &lt;em&gt;&lt;a href="http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215/ref=sr_1_1?ie=UTF8&amp;#038;s=books&amp;#038;qid=1271519704&amp;#038;sr=8-1"&gt;Domain-Driven Design&lt;/a&gt;&lt;/em&gt;, by Eric Evans. One of the foremost things Evans discusses is &lt;span style="font-variant: small-caps;"&gt;ubiquitous language&lt;/span&gt;, which he defines as:&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;br /&gt;
&lt;blockquote&gt;
&lt;p&gt;A language structured around the domain model and used by all team members to connect all the activities of the team with the software.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;br/&gt;
&lt;p&gt;Without that shared language, problems ensue.  The following story, told by &lt;a href="http://www.lds.org/ldsorg/v/index.jsp?hideNav=1&amp;#038;locale=0&amp;#038;sourceId=468ce5e18be63110VgnVCM100000176f620a____&amp;#038;vgnextoid=2354fccf2b7db010VgnVCM1000004d82620aRCRD"&gt;Samuel T. Whitman&lt;/a&gt;, illustrates well what may happen without a common shared language:&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;br /&gt;
&lt;blockquote&gt;
&lt;p&gt;“The ice storm [that winter] wasn’t generally destructive. True, a few wires came down, and there was a sudden jump in accidents along the highway. … Normally, the big walnut tree could easily have borne the weight that formed on its spreading limbs. It was the iron wedge in its heart that caused the damage.&lt;br/&gt;&lt;br/&gt;“The story of the iron wedge began years ago when the white-haired farmer [who now inhabited the property on which the tree stood] was a lad on his father’s homestead. The sawmill had then only recently been moved from the valley, and the settlers were still finding tools and odd pieces of equipment scattered about. …&lt;br/&gt;&lt;br/&gt;“On this particular day, [the lad found] a faller’s wedge—wide, flat, and heavy, a foot or more long, and splayed from mighty poundings. [A faller’s wedge, used to help fell a tree, is inserted in a cut made by a saw and then struck with a sledgehammer to widen the cut.] … Because he was already late for dinner, the lad laid the wedge … between the limbs of the young walnut tree his father had planted near the front gate. He would take the wedge to the shed right after dinner, or sometime when he was going that way.&lt;br/&gt;&lt;br/&gt;“He truly meant to, but he never did. [The wedge] was there between the limbs, a little tight, when he attained his manhood. It was there, now firmly gripped, when he married and took over his father’s farm. It was half grown over on the day the threshing crew ate dinner under the tree. … Grown in and healed over, the wedge was still in the tree the winter the ice storm came.&lt;br/&gt;&lt;br/&gt;“In the chill silence of that wintry night, … one of the three major limbs split away from the trunk and crashed to the ground. This so unbalanced the remainder of the top that it, too, split apart and went down. When the storm was over, not a twig of the once-proud tree remained.&lt;br/&gt;&lt;br/&gt;“Early the next morning, the farmer went out to mourn his loss. …&lt;br/&gt;&lt;br/&gt;“Then, his eyes caught sight of something in the splintered ruin. ‘The wedge,’ he muttered reproachfully. ‘The wedge I found in the south pasture.’ A glance told him why the tree had fallen. Growing, edge-up in the trunk, the wedge had prevented the limb fibers from knitting together as they should.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;br/&gt;&lt;br /&gt;
&lt;h2&gt;The Communication Schism&lt;/h2&gt;
&lt;p&gt;A chasm, or at minimum a schism, often exists between domain experts and developers.  Domain experts often use terms that are inexact or ambiguous.  Developers use terms specific to themselves and that describe implementation details.  This leads to fracture in in both communication and the domain model.  This fracture happens at all levels of communication.  Without a &lt;span style="font-variant: small-caps;"&gt;ubiquitous language&lt;/span&gt; used by all team members and the domain experts who largely define the software, a gap between understanding and implementation grows.&lt;/p&gt;
&lt;p&gt;Domain experts often use terms that are inexact or ambiguous.  Developers use terms specific to programmers and describe implementation details.  This leads to fracture in in both communication and the domain model.  This fracture happens at all levels.  Sometimes it may be a small schism and other times it grows into a chasm.&lt;/p&gt;
&lt;p&gt;Without a solid base, a &lt;span style="font-variant: small-caps;"&gt;ubiquitous language&lt;/span&gt; to meld the domain expert&amp;#8217;s knowledge with implementation, it is as if there&amp;#8217;s a faller&amp;#8217;s wedge stuck in our limbs.  Our communication avoids certain aspects of the domain, circumvents necessary detail, and ignores relevant issues.&lt;/p&gt;
&lt;p&gt;As this happens time and time again, both developers and domain experts become hardened, they don&amp;#8217;t see the issues nor understand how to resolve the differences. Rather than build up knowledge, it is skirted and worked around.&lt;/p&gt;
&lt;p&gt;In &lt;em&gt;&lt;a href="http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215/ref=sr_1_1?ie=UTF8&amp;#038;s=books&amp;#038;qid=1271519704&amp;#038;sr=8-1"&gt;Domain-Driven Design&lt;/a&gt;&lt;/em&gt;, Eric teaches us how to overcome these problems.  I highly recommend it.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=2nDfrL9OFn8:xayd1q4OSrc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=2nDfrL9OFn8:xayd1q4OSrc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=2nDfrL9OFn8:xayd1q4OSrc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=2nDfrL9OFn8:xayd1q4OSrc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=2nDfrL9OFn8:xayd1q4OSrc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=2nDfrL9OFn8:xayd1q4OSrc:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/KalebPederson/~4/2nDfrL9OFn8" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://kalebpederson.com/index.php/2010/04/the-fallers-wedge-ubiquitous-language#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://kalebpederson.com/index.php/2010/04/the-fallers-wedge-ubiquitous-language/feed/atom" thr:count="0" />
		<thr:total>0</thr:total>
	<feedburner:origLink>http://kalebpederson.com/index.php/2010/04/the-fallers-wedge-ubiquitous-language</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Kaleb Pederson</name>
						<uri>http://kalebpederson.com</uri>
					</author>
		<title type="html"><![CDATA[Customer Support is about LOVE]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/KalebPederson/~3/5PBFDNQ9au4/customer-support-is-about-love" />
		<id>http://kibab.kalebpederson.com/index.php/2010/04/customer-support-is-about-love</id>
		<updated>2010-04-08T15:00:00Z</updated>
		<published>2010-04-08T15:00:00Z</published>
		<category scheme="http://kalebpederson.com" term="customer service" />		<summary type="html"><![CDATA[This post was imported from blogger, to see the original, likely better-formatted post see kalebpederson.blogspot.com. > Yes, customer support is about love! It&#8217;s about caring and doing something because you care. Here are some relevant definitions from Dictionary.com: Love --1. a profoundly tender, passionate affection for another person9. affectionate concern for the well-being of others: [...]]]></summary>
		<content type="html" xml:base="http://kalebpederson.com/index.php/2010/04/customer-support-is-about-love">&lt;div class="attention"&gt;
&lt;p&gt;This post was imported from blogger, to see the original, likely better-formatted post see &lt;a href="http://kalebpederson.blogspot.com"&gt;kalebpederson.blogspot.com&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&gt;
&lt;p&gt;Yes, customer support is about love! It&amp;#8217;s about caring and doing something because you care. Here are some relevant definitions from &lt;a href="http://dictionary.reference.com/browse/love"&gt;Dictionary.com&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;b&gt;Love&lt;/b&gt; --1. a profoundly tender, passionate affection for another person9. affectionate concern for the well-being of others: &lt;em&gt;the love of one's neighbor&lt;/em&gt;10. strong predilection, enthusiasm, or liking for anything: &lt;em&gt;her love of books&lt;/em&gt;11. the object or thing so liked: &lt;em&gt;The theater was her great love&lt;/em&gt;&lt;/pre&gt;
&lt;p&gt;And that&amp;#8217;s not it, there are other relevant definitions, but the above are sufficient to make my point:&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Customer support and business to customer relations should be about love.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve recently had a few customer support experiences that I&amp;#8217;d like to recount:&lt;/p&gt;
&lt;h2&gt;Pulsar Watches&lt;/h2&gt;
&lt;p&gt;The battery in my wife&amp;#8217;s &lt;a href="http://www.pulsarwatches.com/"&gt;Pulsar watch&lt;/a&gt; died years ago. Sometime after taking the battery out to get it replaced I lost the battery. Nothing on the watch helped us identify the correct battery. My wife, as organized as ever, knew exactly where the receipt was and I was able to look up the model number, but no online searches revealed the correct battery, so I e-mailed pulsar customer support.&lt;/p&gt;
&lt;p&gt;Even though the watch was over 10 years old, completely out of warranty, and I doubt they had many electronic records about the watch, they e-mailed me back and provided me with the exact battery type.&lt;/p&gt;
&lt;p&gt;To be honest, I wouldn&amp;#8217;t have minded at all if they had said they had no idea where they could find that information, but they answered my question when they could have easily disregarded it.  I could say they showed a &lt;em&gt; predilection for their customer&lt;/em&gt; referring back to definition 10. Pulsar watches loved their customer enough to go the extra mile.&lt;/p&gt;
&lt;h2&gt;The Unnamed Tech Company&lt;/h2&gt;
&lt;p&gt;The Unnamed Tech Company has a great product that many people love.  In addition to their main product they have another product that&amp;#8217;s quite esoteric but that happens to fill an exact need that I have at the time.  I e-mailed them, and then I waited&amp;#8230; and waited&amp;#8230; and waited. Nothing. I decided to e-mail them again, this time at a different e-mail address, explaining my previous e-mail, and clarifying my intention to purchase. And then I waited&amp;#8230; and waited.&lt;/p&gt;
&lt;p&gt;I did finally receive an e-mail back, but now I&amp;#8217;m waiting for a response.  Support has been lackluster, perhaps almost dismal.  In the spirit of full disclosure they admitted my first e-mail went into junk mail, but still.  I&amp;#8217;m a potential customer, or could have been an existing customer, and my e-mail was lost. They didn&amp;#8217;t answer all my questions and still haven&amp;#8217;t reached a satisfactory conclusion.&lt;/p&gt;
&lt;h2&gt;Netflix on Proactive Love&lt;/h2&gt;
&lt;p&gt;&lt;a href="" style="float: right;"&gt;&lt;img src="http://lh4.ggpht.com/_9KeH89IzttQ/S713ugncW0I/AAAAAAAAAPc/d14CxlyfH3c/netflix_small.jpg"&gt;&lt;/a&gt;&lt;a href="http://netflix.com"&gt;Netflix&lt;/a&gt; constantly amazes me.  Even their &lt;a href="http://www.slideshare.net/reed2001/culture-1798664"&gt;company culture&lt;/a&gt; is amazing. But, it goes far beyond that. They are passionate about their customers.  Yes, that&amp;#8217;s right. They &lt;em&gt;love&lt;/em&gt; their customers, or at least I think so&amp;#8230; and I doubt they&amp;#8217;d say otherwise.&lt;/p&gt;
&lt;p&gt;A few days ago, after having streamed a movie the night before, I received an e-mail asking me how the quality was. I was impressed. Not only were they proactive, but they really wanted to know. And, I&amp;#8217;m happy to say that the quality was superb. For a 10-15 year old movie, I can&amp;#8217;t imagine the picture being any better had it been on Blu-ray.&lt;/p&gt;
&lt;p&gt;But&amp;#8230; it doesn&amp;#8217;t stop there. Monday I sent back a DVD which they received early Tuesday morning.  Nice and quick. I was impressed. But, it gets better.  &lt;b&gt;They then asked me when I mailed it.&lt;/b&gt; They actually wanted to know how well their service was doing. Was it taking too long? Would they consider building a distribution center closer to me? I don&amp;#8217;t know, but I knew they cared. I knew &lt;em&gt;they loved their customer&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;Love Your Customer&lt;/h2&gt;
&lt;p&gt;If you and your business doesn&amp;#8217;t care about your customers, change jobs, or something.  As &lt;a href="http://garyvaynerchuk.com/post/107300929/crush-it-why-now-is-the-time-to-cash-in-on-your"&gt;Gary Vaynerchuk&lt;/a&gt; would say, follow your passion. Show your customers you care. Make a difference in their lives.  When you do, they&amp;#8217;ll become your earlyvangelists, your marketers, your best and most devoted customers.  And, perhaps most importantly, they&amp;#8217;ll love you back, and forgive you when you make mistakes.&lt;/p&gt;
&lt;p style="font-size: smaller"&gt;[Image Courtesy: &lt;a href="http://www.flickr.com/photos/66568868@N00/3078317546/"&gt;dolphinsdock on flickr&lt;/a&gt;]&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=5PBFDNQ9au4:l3UOf_Yo_Nc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=5PBFDNQ9au4:l3UOf_Yo_Nc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=5PBFDNQ9au4:l3UOf_Yo_Nc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=5PBFDNQ9au4:l3UOf_Yo_Nc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=5PBFDNQ9au4:l3UOf_Yo_Nc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=5PBFDNQ9au4:l3UOf_Yo_Nc:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/KalebPederson/~4/5PBFDNQ9au4" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://kalebpederson.com/index.php/2010/04/customer-support-is-about-love#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://kalebpederson.com/index.php/2010/04/customer-support-is-about-love/feed/atom" thr:count="0" />
		<thr:total>0</thr:total>
	<feedburner:origLink>http://kalebpederson.com/index.php/2010/04/customer-support-is-about-love</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Kaleb Pederson</name>
						<uri>http://kalebpederson.com</uri>
					</author>
		<title type="html"><![CDATA[Scripting Refactoring &#8212; Overthrowing the GUI (part 4)]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/KalebPederson/~3/0y-SXhTW8oE/scripting-refactoring-overthrowing-the-gui-part-4" />
		<id>http://kibab.kalebpederson.com/index.php/2010/03/scripting-refactoring-overthrowing-the-gui-part-4</id>
		<updated>2010-03-31T02:26:00Z</updated>
		<published>2010-03-31T02:26:00Z</published>
		<category scheme="http://kalebpederson.com" term="cli" /><category scheme="http://kalebpederson.com" term="refactoring" />		<summary type="html"><![CDATA[This post was imported from blogger, to see the original, likely better-formatted post see kalebpederson.blogspot.com. > Over the last few blog posts I&#8217;ve mentioned a number of different reasons why it would be nice to be able to script the application of refactorings. This post talks more about one possible scripting language that could be [...]]]></summary>
		<content type="html" xml:base="http://kalebpederson.com/index.php/2010/03/scripting-refactoring-overthrowing-the-gui-part-4">&lt;div class="attention"&gt;
&lt;p&gt;This post was imported from blogger, to see the original, likely better-formatted post see &lt;a href="http://kalebpederson.blogspot.com"&gt;kalebpederson.blogspot.com&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&gt;
&lt;p&gt;Over the last few blog posts I&amp;#8217;ve mentioned a number of different reasons why it would be nice to be able to script the application of refactorings.  This post talks more about one possible scripting language that could be used to script refactorings.&lt;/p&gt;
&lt;h2&gt;Interesting Cases&lt;/h2&gt;
&lt;p&gt;Although I could just provide the grammar and some sample input, it wouldn&amp;#8217;t be very instructive or helpful. Here are some more interesting cases and considerations.&lt;/p&gt;
&lt;h3&gt;Camel Case&lt;/h3&gt;
&lt;p&gt;Camel Case is a standard Java convention that uses capital letters to separate words that form an identifier.  For example, &lt;tt&gt;isTrue&lt;/tt&gt;, &lt;tt&gt;shouldValidate&lt;/tt&gt;, and &lt;tt&gt;eatsHotdogsOrHamburgers&lt;/tt&gt; are all camel case identifier names.  The  first letter is typically lower case with the first letter in each subsequent word in the identifier being upper case.&lt;/p&gt;
&lt;p&gt;Imagine that &lt;em&gt;Jr. Programmer&lt;/em&gt; comes along and creates a class named &lt;tt&gt;AbstractSyntaxNode&lt;/tt&gt; that contains methods called &lt;tt&gt;complexNode&lt;/tt&gt;, &lt;tt&gt;simpleNode&lt;/tt&gt; and 20 more similarly named methods.  When &lt;em&gt;Mr. Senior Programmer&lt;/em&gt; comes along he immediately notices that in order to follow standard Java programming conventions, these should instead be named &lt;tt&gt;getComplexNode&lt;/tt&gt;, &lt;tt&gt;getSimpleNode&lt;/tt&gt;, and so on. Although it would be painful to manually go through and invoke the rename refactoring on all 22 methods, this is a good case for scripted refactorings.  Consider the following rename refactoring script:&lt;/p&gt;
&lt;pre&gt;rename {    AbstractSyntaxNode{class}::(.*)Node{method},    AbstractSyntaxNode::get\1Node;}&lt;/pre&gt;
&lt;p&gt;This, however, would result in the  following method names:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;getcomplexNode&lt;/li&gt;
&lt;li&gt;getsimpleNode&lt;/li&gt;
&lt;li&gt;&amp;#8230;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the above case, we need an easy way to tell it that the first letter needs to be transformed to an upper case character.  Perl provides a &lt;tt&gt;&lt;a href="http://perldoc.perl.org/perlretut.html#More-on-characters%2c-strings%2c-and-character-classes"&gt;\u&lt;/a&gt;&lt;/tt&gt; regular expression escape sequence that capitalizes the following character.  Thus, to handle the camel case issue nicely, the substitution engine would need to support similar escape sequences.&lt;/p&gt;
&lt;h3&gt;Absolute and Relative Position&lt;/h3&gt;
&lt;p&gt;Absolute and relative position markers also make an interesting case. For example, I might want to rename the variable on the second line after the start of the method.  Or, I might have my cursor over a variable within an editor that has a keyboard shortcut for invoking a refactoring.  In these cases, I have both relative and absolute position information that is likely desirable in a refactoring scripting language.
&lt;p&gt;Assume for a moment that I want to do an &lt;tt&gt;Extract Method&lt;/tt&gt; refactoring of everything between line 40 and 60, inclusive.  I might write the following:&lt;/p&gt;
&lt;pre&gt;extractMethod {    40, 60, newMethodName;}&lt;/pre&gt;
&lt;p&gt;In this case, there&amp;#8217;s no need for column information, so using a basic integer for the line information is sufficient.  But, what if you wanted to inline the function referenced between column 20 and 30 on line 42?  Then I would need to write something like this:&lt;/p&gt;
&lt;pre&gt;inline {    42:20, 42:30;}&lt;/pre&gt;
&lt;p&gt;As many editors display the line and column information as &lt;tt&gt;line:column&lt;/tt&gt;, the above syntax is fairly familiar.  But, how could we go about identifying relative position indicators? Consider the following:&lt;/p&gt;
&lt;pre&gt;rename {    @(SomeClass::someMethod{method &amp;#038;&amp;#038; definition} + 2), newVariableName;}&lt;/pre&gt;
&lt;p&gt;This shows a couple of more interesting cases &amp;#8211; first, I need to be able to identify the the method definition which I do by restricting the results of my element query to definitions in my scope clause.  And, second, I needed to use the &lt;tt&gt;@&lt;/tt&gt; operator to make the element reference a position based reference.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Such a scripting language could easily grow unwieldy, but the &lt;a href="http://en.wikipedia.org/wiki/Pareto_principle"&gt;Pareto Principle&lt;/a&gt; suggests that there must be a fairly &amp;#8220;easy&amp;#8221; solution that will handle 80% of the cases. What would such a solution look like? It&amp;#8217;s really hard to say until somebody actually implements one and has some real-world users.  Nevertheless, my sample input and ANTLR based grammar are linked to below.&lt;/p&gt;
&lt;p&gt;Comments and thoughts? I&amp;#8217;d love to hear them! Thanks.&lt;/p&gt;
&lt;p&gt;A full set of &lt;a href="http://github.com/kalebpederson/scripting_refactoring/blob/master/SampleInput.txt"&gt;sample inputs&lt;/a&gt; is available on &lt;a href="http://github.com/kalebpederson/scripting_refactoring"&gt;GitHub&lt;/a&gt;.  Similarly, the &lt;a href="http://github.com/kalebpederson/scripting_refactoring/blob/master/ScriptableRefactorings.g"&gt;full grammar&lt;/a&gt; is also available.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=0y-SXhTW8oE:u_4dUyAw8r4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=0y-SXhTW8oE:u_4dUyAw8r4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=0y-SXhTW8oE:u_4dUyAw8r4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=0y-SXhTW8oE:u_4dUyAw8r4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=0y-SXhTW8oE:u_4dUyAw8r4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=0y-SXhTW8oE:u_4dUyAw8r4:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/KalebPederson/~4/0y-SXhTW8oE" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://kalebpederson.com/index.php/2010/03/scripting-refactoring-overthrowing-the-gui-part-4#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://kalebpederson.com/index.php/2010/03/scripting-refactoring-overthrowing-the-gui-part-4/feed/atom" thr:count="0" />
		<thr:total>0</thr:total>
	<feedburner:origLink>http://kalebpederson.com/index.php/2010/03/scripting-refactoring-overthrowing-the-gui-part-4</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Kaleb Pederson</name>
						<uri>http://kalebpederson.com</uri>
					</author>
		<title type="html"><![CDATA[Scripting Refactoring &#8212; Overthrowing the GUI (part 3)]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/KalebPederson/~3/scVZaj6LHgg/scripting-refactoring-overthrowing-the-gui-part-3" />
		<id>http://kibab.kalebpederson.com/index.php/2010/03/scripting-refactoring-overthrowing-the-gui-part-3</id>
		<updated>2010-03-09T07:16:00Z</updated>
		<published>2010-03-09T07:16:00Z</published>
		<category scheme="http://kalebpederson.com" term="cli" /><category scheme="http://kalebpederson.com" term="refactoring" />		<summary type="html"><![CDATA[This post was imported from blogger, to see the original, likely better-formatted post see kalebpederson.blogspot.com. > I&#8217;ve already mentioned why it might be useful to perform refactorings in bulk. Perhaps we&#8217;ve decided we followed a poor naming convention, or perhaps we&#8217;ve moved some classes into their own namespace, so part of the class name is [...]]]></summary>
		<content type="html" xml:base="http://kalebpederson.com/index.php/2010/03/scripting-refactoring-overthrowing-the-gui-part-3">&lt;div class="attention"&gt;
&lt;p&gt;This post was imported from blogger, to see the original, likely better-formatted post see &lt;a href="http://kalebpederson.blogspot.com"&gt;kalebpederson.blogspot.com&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&gt;
&lt;p&gt;I&amp;#8217;ve already mentioned why it might be useful to perform refactorings in bulk.  Perhaps we&amp;#8217;ve decided we followed a poor naming convention, or perhaps we&amp;#8217;ve moved some classes into their own namespace, so part of the class name is redundant and can be removed.&lt;/p&gt;
&lt;p&gt;Another point of textual element identification is to remove the necessity of the GUI.  Take, for example, Emacs and Vim.  Both are very capable editors and and lack (to the best of my knowledge) complete and capable refactoring support.  But, if an element can be identified in text, either through line and column information, or through an element reference, the editors like Vim, Emacs, and Textmate could have macros written for them that call out to a command line refactoring engine.&lt;/p&gt;
&lt;h2&gt;Two Syntaxes for Scripting Refactoring&lt;/h2&gt;
&lt;p&gt;Each refactoring could look like a function call as in the following:&lt;/p&gt;
&lt;pre&gt;rename(OldNamespace::OldClass, NewNamespace::NewClass);&lt;/pre&gt;
&lt;p&gt;In the above case, the rename refactoring takes in two different &lt;tt&gt;ElementReference&lt;/tt&gt; parameters.  In order to perform many rename refactorings, we&amp;#8217;d end up with a list of the above:&lt;/p&gt;
&lt;pre&gt;rename(OldNamespace::FirstClass, NewNamespace::FirstClass);rename(OldClass, NewClass);rename(OldClass::oldMethod, OldClass::newMethod);rename(globalFunction, newGlobalFunction);//...&lt;/pre&gt;
&lt;p&gt;Although the above is unreadable, it seemed a little repetitive, so I went with a block structure that allowed the refactoring to be specified once, with a list of parameter sequences:&lt;/p&gt;
&lt;pre&gt;rename {    // support named parameters    // and type restriction after name specifier    oldName = SomeNamespace{namespace}::/(.*)ElementName/,    newName = SomeNamespace::\1Node;

    // type restriction within regular expression    /SomeClass{class}::get(.*)Node/,    SomeClass::\1Node;

    ::memset, ::customMemSet;}&lt;/pre&gt;
&lt;p&gt;The block syntax above isn&amp;#8217;t as repetitive as the first example.  To help the case where an editor would invoke the refactoring, line and column information could be used to identify elements as well.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Although the above is a new syntax, it&amp;#8217;s built on many different syntaxes that are common to languages.  It uses a block syntax for overall structure.  Named parameters are supported in many different dynamic languages. It supports regular expressions for matching and backreferences for substitutions.  It also has C++ and Java style comments and uses the sometimes-despised semicolon as a terminator.&lt;/p&gt;
&lt;p&gt;Yeah, some people aren&amp;#8217;t going to like the syntax and may avoid it like the plague.  But, arguably, there are some very good reasons to to make refactorings scriptable to the average programmer, among which are the easy interface it would provide to editors and the ability to doing certain refactorings in bulk.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=scVZaj6LHgg:zaBMKfm5Bgg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=scVZaj6LHgg:zaBMKfm5Bgg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=scVZaj6LHgg:zaBMKfm5Bgg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=scVZaj6LHgg:zaBMKfm5Bgg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=scVZaj6LHgg:zaBMKfm5Bgg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=scVZaj6LHgg:zaBMKfm5Bgg:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/KalebPederson/~4/scVZaj6LHgg" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://kalebpederson.com/index.php/2010/03/scripting-refactoring-overthrowing-the-gui-part-3#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://kalebpederson.com/index.php/2010/03/scripting-refactoring-overthrowing-the-gui-part-3/feed/atom" thr:count="0" />
		<thr:total>0</thr:total>
	<feedburner:origLink>http://kalebpederson.com/index.php/2010/03/scripting-refactoring-overthrowing-the-gui-part-3</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Kaleb Pederson</name>
						<uri>http://kalebpederson.com</uri>
					</author>
		<title type="html"><![CDATA[Scripting Refactoring &#8212; Overthrowing the GUI (part 2)]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/KalebPederson/~3/L5-L2MJUGhE/scripting-refactoring-overthrowing-the-gui-part-2" />
		<id>http://kibab.kalebpederson.com/index.php/2010/03/scripting-refactoring-overthrowing-the-gui-part-2</id>
		<updated>2010-03-04T08:15:00Z</updated>
		<published>2010-03-04T08:15:00Z</published>
		<category scheme="http://kalebpederson.com" term="cli" /><category scheme="http://kalebpederson.com" term="refactoring" />		<summary type="html"><![CDATA[This post was imported from blogger, to see the original, likely better-formatted post see kalebpederson.blogspot.com. > Last week I introduced a hokey syntax that could be used to identify various elements that were going to be refactored in bulk. The syntax was ambiguous and incapable of expressing anything of even mild complexity. Now for something [...]]]></summary>
		<content type="html" xml:base="http://kalebpederson.com/index.php/2010/03/scripting-refactoring-overthrowing-the-gui-part-2">&lt;div class="attention"&gt;
&lt;p&gt;This post was imported from blogger, to see the original, likely better-formatted post see &lt;a href="http://kalebpederson.blogspot.com"&gt;kalebpederson.blogspot.com&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&gt;
&lt;p&gt;&lt;a href="http://www.kalebpederson.com/2010/02/scripting-refactoring-overthrowing-gui.html"&gt;Last week&lt;/a&gt; I introduced a hokey syntax that could be used to identify various elements that were going to be refactored in bulk. The syntax was ambiguous and incapable of expressing anything of even mild complexity.  Now for something better.&lt;/p&gt;
&lt;p&gt;The proposed syntax doesn&amp;#8217;t apply to every language. It would be both pointless and painful to attempt such a task.  Rather, the following syntax is intended to work with languages like Java, C/C++, and other similarly structured languages.&lt;/p&gt;
&lt;h2&gt;A Grammar Proposal&lt;/h2&gt;
&lt;p&gt;Consider the following grammar defined in EBNF, with non-terminals being lower-cased and terminals being upper-cased and left implicit:&lt;/p&gt;
&lt;pre&gt;query-element: pattern ( "::" pattern )*;

pattern: ( IDENTIFIER | "/" REGEXP-LITERAL "/" ) type-specifier?;

type-specifier: "{" TYPE-LITERAL "}";&lt;/pre&gt;
&lt;p&gt;Using the above EBNF, arbitrary elements can be queried and their type constrained when necessary.  Here&amp;#8217;s a few examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;All classes named MyClass in any namespace &amp;#8211; /.*/::MyClass&lt;/li&gt;
&lt;li&gt;Any class containing the word Node in the AST namespace &amp;#8211; AST::/.*Node.*/&lt;/li&gt;
&lt;li&gt;The second class containing the word Node in the AST namespace -AST::/.*Node.*/[1]&lt;/li&gt;
&lt;li&gt;All typedefs named subType contained in functions of the Node class &amp;#8211; Node::/.*/::subType{typedef}&lt;/li&gt;
&lt;li&gt;All variables named other contained in functions of the Node class &amp;#8211; Node::/.*/{function}::other{variable}&lt;/li&gt;
&lt;li&gt;Any function starting with test in the Temp namespace &amp;#8211; Temp::/test.*/{function}&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Admittedly, this query language does not support all the queries that one mightwant to make, but it should be noted that the above query language can be easilyextended. For example, instead of using a &lt;tt&gt;TYPE-LITERAL&lt;/tt&gt; terminal symbol, one coulduse a &lt;tt&gt;type-literal&lt;/tt&gt; production that allowed for negating conditions, alternations, and more.&lt;/p&gt;
&lt;p&gt;Function and operator overloading, as supported by C++, also complicate matters. Even though the fully qualified name of a function may be specified, it does notimply that only a single match exists. Any number of functions might exist.This language could be expanded to allow the types of the parameters to bespecified. By specifying the parameter types, any function could be fully resolved. Inaddition, anonymous namespaces and blocks could be identified by augmenting thelanguage to support empty names and array indexing.&lt;/p&gt;
&lt;h2&gt;Isn&amp;#8217;t It Complicated?&lt;/h2&gt;
&lt;p&gt;Yes, now we&amp;#8217;re starting to get complicated.  But honestly, most of those features wouldn&amp;#8217;t matter.  It&amp;#8217;s like the saying, &amp;#8220;20% of your code you handle 80% of the cases.&amp;#8221;  By starting out simple, and only augmenting the grammar when a real, arguable need is established, the grammar could be expanded little-by-little in useful ways. It really goes back to two principles: KISS and YAGNI. Start simple, design when necessary, refactor to your goal&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size: small;"&gt;Bonus points to the person who finds the grammar / example mismatch above.&lt;/span&gt;&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=L5-L2MJUGhE:K3-stxPxiDw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=L5-L2MJUGhE:K3-stxPxiDw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=L5-L2MJUGhE:K3-stxPxiDw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=L5-L2MJUGhE:K3-stxPxiDw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=L5-L2MJUGhE:K3-stxPxiDw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=L5-L2MJUGhE:K3-stxPxiDw:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/KalebPederson/~4/L5-L2MJUGhE" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://kalebpederson.com/index.php/2010/03/scripting-refactoring-overthrowing-the-gui-part-2#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://kalebpederson.com/index.php/2010/03/scripting-refactoring-overthrowing-the-gui-part-2/feed/atom" thr:count="0" />
		<thr:total>0</thr:total>
	<feedburner:origLink>http://kalebpederson.com/index.php/2010/03/scripting-refactoring-overthrowing-the-gui-part-2</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Kaleb Pederson</name>
						<uri>http://kalebpederson.com</uri>
					</author>
		<title type="html"><![CDATA[Scripting Refactoring &#8212; Overthrowing the GUI]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/KalebPederson/~3/HkOXAcaz2jM/scripting-refactoring-overthrowing-the-gui" />
		<id>http://kibab.kalebpederson.com/index.php/2010/02/scripting-refactoring-overthrowing-the-gui</id>
		<updated>2010-02-25T06:23:00Z</updated>
		<published>2010-02-25T06:23:00Z</published>
		<category scheme="http://kalebpederson.com" term="cli" /><category scheme="http://kalebpederson.com" term="refactoring" />		<summary type="html"><![CDATA[This post was imported from blogger, to see the original, likely better-formatted post see kalebpederson.blogspot.com. > The most basic and common refactoring in any language is Rename. Whether it&#8217;s Rename Variable, Rename Method, Rename Class, or Rename Namespace/Package, this simple refactoring helps improve code clarity and, when applied correctly, makes code easier to understand. As [...]]]></summary>
		<content type="html" xml:base="http://kalebpederson.com/index.php/2010/02/scripting-refactoring-overthrowing-the-gui">&lt;div class="attention"&gt;
&lt;p&gt;This post was imported from blogger, to see the original, likely better-formatted post see &lt;a href="http://kalebpederson.blogspot.com"&gt;kalebpederson.blogspot.com&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&gt;
&lt;p&gt;The most basic and common refactoring in any language is &lt;i&gt;Rename&lt;/i&gt;. Whether it&amp;#8217;s &lt;i&gt;Rename Variable&lt;/i&gt;, &lt;i&gt;Rename Method&lt;/i&gt;, &lt;i&gt;Rename Class&lt;/i&gt;, or &lt;i&gt;Rename Namespace/Package&lt;/i&gt;, this simple refactoring helps improve code clarity and, when applied correctly, makes code easier to understand. As reading code is the most frequent activity a programmer undertakes, this makes the &lt;i&gt;Rename&lt;/i&gt; refactoring one of the most powerful tools in a developers&amp;#8217; arsenal.&lt;/p&gt;
&lt;h2&gt;Introducing Element Identification&lt;/h2&gt;
&lt;p&gt;Consider now the &lt;i&gt;Rename&lt;/i&gt; refactoring when &lt;a href="http://www.kalebpederson.com/2010/02/enabling-bulk-refactorings.html"&gt;applied in a batch&lt;/a&gt;.  In order to apply the &lt;i&gt;Rename&lt;/i&gt; refactoring, I first need to be able to unambiguously identify the element being renamed, be it a class, method, variable, etc.  Let&amp;#8217;s entertain for a moment the following notation&lt;/p&gt;
&lt;pre&gt;[Member::[Member::[Member::...]]]Member&lt;/pre&gt;
&lt;p&gt;This notation could be used to identify:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a namespace at any level (e.g., MyNamespace, Namespace1::Namespace2)&lt;/li&gt;
&lt;li&gt;a class within a namespace (e.g., MyNamespace::MyClass, SomeClass)&lt;/li&gt;
&lt;li&gt;a member of a class (e.g., AClass::someVar, ANamespace::MyClass::a)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Although this syntax resembles the C++ scoping syntax, it is important to notethat it is ambiguous. Given the search query, &lt;tt&gt;Something::someMember&lt;/tt&gt;, determining whether &lt;tt&gt;Something&lt;/tt&gt; is a class, struct, or namespace is impossible.  Similarly, &lt;tt&gt;someMember&lt;/tt&gt; could be a class within a namespace, a class or struct within a namespace, or a member variable within a class or struct.&lt;/p&gt;
&lt;h2&gt;Overcoming Ambiguity&lt;/h2&gt;
&lt;p&gt;Since we need to constrain how we select elements, lets extend our syntax a bit by adding an optional &lt;tt&gt;{ TYPE_LITERAL }&lt;/tt&gt; constraint to each member:&lt;/p&gt;
&lt;pre&gt;[Member[{TYPE}]::...]Member[{TYPE}]&lt;/pre&gt;
&lt;p&gt;More cases can now be handled well:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Something{namespace}::someMember{class}&lt;/li&gt;
&lt;li&gt;Something{class}::someMember{method}&lt;/li&gt;
&lt;li&gt;Something{method}::someMember{variable}&lt;/li&gt;
&lt;li&gt;Something{namespace}::Something{class}::someMember{method}&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But&amp;#8230; we&amp;#8217;re still ambiguous.  Consider the following code:&lt;/p&gt;
&lt;pre&gt;void doSomething() {    for (int i=0; i&lt;10; ++i) { /* ... */ }    /* ... more code here ... */    for (int i=0; i&lt;15; ++i) { /* ... */ }}&lt;/pre&gt;
&lt;h2&gt;Staying Useful&lt;/h2&gt;
&lt;p&gt;In the above code we have two different counter variables with a name of &lt;tt&gt;i&lt;/tt&gt;.  Does that mean it&amp;#8217;s pointless to try to support batch refactorings or to try to constrain elements in a refactoring scripting language?  No.&lt;/p&gt;
&lt;p&gt;Regular expressions don&amp;#8217;t allow everything to be queried, yet they&amp;#8217;re still useful.  Even after adding positive or negative lookahead (or lookbehind) assertions, they&amp;#8217;re still limited.  Yet, at the same time, they handle a few more cases and become more generally useful.&lt;/p&gt;
&lt;p&gt;The same thing should be able to happen for (most) programming languages. It&amp;#8217;s possible to create a scripting language, or syntax, that will allow us to easily identify most syntactic elements within a programming language.  Perhaps this refactoring scripting language could leverage the BNF that defines the programming language, or perhaps there&amp;#8217;s even something better.  Either way, we&amp;#8217;re one step closer to overthrowing the GUI and enabling bulk and scriptable refactorings.&lt;/p&gt;
&lt;p&gt;Yet more excerpts and discussion from my thesis to come.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=HkOXAcaz2jM:1UQbIOGdG50:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=HkOXAcaz2jM:1UQbIOGdG50:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=HkOXAcaz2jM:1UQbIOGdG50:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=HkOXAcaz2jM:1UQbIOGdG50:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=HkOXAcaz2jM:1UQbIOGdG50:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=HkOXAcaz2jM:1UQbIOGdG50:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/KalebPederson/~4/HkOXAcaz2jM" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://kalebpederson.com/index.php/2010/02/scripting-refactoring-overthrowing-the-gui#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://kalebpederson.com/index.php/2010/02/scripting-refactoring-overthrowing-the-gui/feed/atom" thr:count="0" />
		<thr:total>0</thr:total>
	<feedburner:origLink>http://kalebpederson.com/index.php/2010/02/scripting-refactoring-overthrowing-the-gui</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Kaleb Pederson</name>
						<uri>http://kalebpederson.com</uri>
					</author>
		<title type="html"><![CDATA[Enabling Bulk Refactorings]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/KalebPederson/~3/PW0rSDLGiRA/enabling-bulk-refactorings" />
		<id>http://kibab.kalebpederson.com/index.php/2010/02/enabling-bulk-refactorings</id>
		<updated>2010-02-17T07:30:00Z</updated>
		<published>2010-02-17T07:30:00Z</published>
		<category scheme="http://kalebpederson.com" term="refactoring" />		<summary type="html"><![CDATA[This post was imported from blogger, to see the original, likely better-formatted post see kalebpederson.blogspot.com. > In my last post, I talked about some of the limitations of refactoring IDEs and enumerated three different cases that could better be handled by refactoring IDEs: Vendor Branches &#8211; can we make refactorings apply like patches? Universal Language [...]]]></summary>
		<content type="html" xml:base="http://kalebpederson.com/index.php/2010/02/enabling-bulk-refactorings">&lt;div class="attention"&gt;
&lt;p&gt;This post was imported from blogger, to see the original, likely better-formatted post see &lt;a href="http://kalebpederson.blogspot.com"&gt;kalebpederson.blogspot.com&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&gt;
&lt;p&gt;In my last post, I talked about some of the limitations of refactoring IDEs and enumerated three different cases that could better be handled by refactoring IDEs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Vendor Branches &amp;#8211; can we make refactorings apply like patches?&lt;/li&gt;
&lt;li&gt;Universal Language &amp;#8211; can we switch between vocabularies or languages?&lt;/li&gt;
&lt;li&gt;In Concrete &amp;#8211; can we overcome some of the small problems presented?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For this post, I&amp;#8217;m going to examine the small concrete cases presented in &lt;i&gt;In Concrete&lt;/i&gt;.&lt;/p&gt;
&lt;h3&gt;Bulk Renaming&lt;/h3&gt;
&lt;p&gt;My first case was to &amp;#8220;Rename all my &lt;tt&gt;*ElementName&lt;/tt&gt; classes in a given namespace to &lt;tt&gt;*Node&lt;/tt&gt; where the asterisk represents some wildcard.&lt;br /&gt;Consider over a 100 classes like the following, spread out over at least as many files. Each one might represent a different element in an XML or otherwise non-trivial file format:&lt;/p&gt;
&lt;pre&gt;package com.example.xml.schemas;

public class ComplexTypeElement { /* ... */ }public class CompoundTypeElement { /* ... */ }public class SimpleTypeElement { /* ... */ }public class AnyElement { /* ... */ }&lt;/pre&gt;
&lt;p&gt;Here&amp;#8217;s what the current Rename refactoring dialog looks like in Eclipse:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://2.bp.blogspot.com/_9KeH89IzttQ/S3uUYC90aXI/AAAAAAAAAH8/xdmlfBCBZPs/s1600-h/eclipse_rename_class_dialog.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_9KeH89IzttQ/S3uUYC90aXI/AAAAAAAAAH8/xdmlfBCBZPs/s320/eclipse_rename_class_dialog.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Augmenting the Rename UI&lt;/h3&gt;
&lt;p&gt;In this case, our goal is to bulk refactor the classes since our naming convention of &lt;tt&gt;*ElementName&lt;/tt&gt; ended up being a poor convention.  What we essentially need is a context sensitive, regex-based &lt;del&gt;find-and-replace&lt;/del&gt; refactoring engine.  So, let&amp;#8217;s augment the rename dialog with a couple of other elements that, left alone, wouldn&amp;#8217;t alter the rename behavior:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://4.bp.blogspot.com/_9KeH89IzttQ/S3uWbFGeAvI/AAAAAAAAAIE/v6c-th4ZWTI/s1600-h/enhanced_class_rename_dialog.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_9KeH89IzttQ/S3uWbFGeAvI/AAAAAAAAAIE/v6c-th4ZWTI/s320/enhanced_class_rename_dialog.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now, let me describe a couple of the elements. First, I introduced a checkbox that allows the programmer to specify whether the refactoring should indeed be a wildcard refactoring.  Second, I introduced an &amp;#8220;Old name&amp;#8221; field.  This field represents the entire fully qualified class name to which the refactoring should be applied when a wildcard refactoring is being performed.  When a standard (non-bulk or wildcard) refactoring is being performed, this field would display the original class name.  Third, I added support for backreferences in the &amp;#8220;New name&amp;#8221; field.  By allowing support for backreferences, the new class name can be based on and derived from the old class name, much like might be done with sed.&lt;/p&gt;
&lt;p&gt;To handle the second case presented in my previous blog post, I could now use the following in the &amp;#8220;Old name&amp;#8221; and &amp;#8220;New name&amp;#8221; input fields, respectively:&lt;/p&gt;
&lt;p&gt;Old name: &lt;tt&gt;DataNode::(.*)::get.*Instance&lt;/tt&gt;&lt;/p&gt;
&lt;p&gt;New name: &lt;tt&gt;DataNode::\1::instance&lt;/tt&gt;&lt;/p&gt;
&lt;p&gt;In this example, the backreference is used to identify the class but not needed for the member function.  Like &lt;tt&gt;sed&lt;/tt&gt; or &lt;tt&gt;awk&lt;/tt&gt;, the syntax and structure would take a bit of learning, but it could be learned far faster than it would likely take to rename over 100 different classes manually.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;The above syntax is, of course, not yet sufficient for everything that might need to happen.  For example, it might also match &lt;tt&gt;DataNode::NestedNamespace::AnotherNestedNamespace::getSomeInstance&lt;/tt&gt; even though only one  namespace should have been considered, but it&amp;#8217;s a start, and one that I&amp;#8217;ll elaborate on in later posts.&lt;/p&gt;
&lt;p&gt;The main point, however, is that it is possible to overcome many of the current limitations of refactoring engines.  Yes, it will take some work, but it will be worth it in the long run.  And, in the above cases at least, the implementation is trivial compared with the work already done to support a single rename refactoring.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=PW0rSDLGiRA:CXeerDa7JP4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=PW0rSDLGiRA:CXeerDa7JP4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=PW0rSDLGiRA:CXeerDa7JP4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=PW0rSDLGiRA:CXeerDa7JP4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=PW0rSDLGiRA:CXeerDa7JP4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=PW0rSDLGiRA:CXeerDa7JP4:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/KalebPederson/~4/PW0rSDLGiRA" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://kalebpederson.com/index.php/2010/02/enabling-bulk-refactorings#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://kalebpederson.com/index.php/2010/02/enabling-bulk-refactorings/feed/atom" thr:count="0" />
		<thr:total>0</thr:total>
	<feedburner:origLink>http://kalebpederson.com/index.php/2010/02/enabling-bulk-refactorings</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Kaleb Pederson</name>
						<uri>http://kalebpederson.com</uri>
					</author>
		<title type="html"><![CDATA[Limitations of Refactoring IDEs]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/KalebPederson/~3/c8lO382Ro-M/limitations-of-refactoring-ides" />
		<id>http://kibab.kalebpederson.com/index.php/2010/02/limitations-of-refactoring-ides</id>
		<updated>2010-02-10T06:17:00Z</updated>
		<published>2010-02-10T06:17:00Z</published>
		<category scheme="http://kalebpederson.com" term="cli" /><category scheme="http://kalebpederson.com" term="gui" /><category scheme="http://kalebpederson.com" term="refactoring" />		<summary type="html"><![CDATA[This post was imported from blogger, to see the original, likely better-formatted post see kalebpederson.blogspot.com. > Coupled with every strength is a weakness. Within an IDE, the ability to leverage the utility of a mouse is a strength. When trying to automate the selection of the next four characters, no matter where you may be [...]]]></summary>
		<content type="html" xml:base="http://kalebpederson.com/index.php/2010/02/limitations-of-refactoring-ides">&lt;div class="attention"&gt;
&lt;p&gt;This post was imported from blogger, to see the original, likely better-formatted post see &lt;a href="http://kalebpederson.blogspot.com"&gt;kalebpederson.blogspot.com&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&gt;
&lt;div style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em"&gt;&lt;img src="http://lh3.ggpht.com/_9KeH89IzttQ/S3JORm7K8SI/AAAAAAAAAH4/6eoJWQEjjJQ/refactoring_book_small.jpg" alt="Refactoring Book"/&gt;&lt;/div&gt;
&lt;p&gt;Coupled with every strength is a weakness. Within an IDE, the ability to leverage the utility of a mouse is a strength. When trying to automate the selection of the next four characters, no matter where you may be in a  file, requiring the same mouse-driven approach becomes a weakness. And so it is with refactoring tools today. The current mouse-driven approach to identifying parameters to refactorings has a number of weaknesses:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Other than through GUI automation tools, such as APIs and macros supported by IDEs, starting the refactoring process cannot be automated.&lt;/li&gt;
&lt;li&gt;It is impossible to apply the same refactoring to many elements at one time. Rather, each element must be selected one at a time and the refactoring applied.&lt;/li&gt;
&lt;li&gt;It is difficult or impossible to script refactoring operations.&lt;/li&gt;
&lt;li&gt;Elements being refactored are often identifi ed by line and column position within a fi le, which usually changes over time.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Although perhaps unseen and unrecognized, the weaknesses stated above are prevalent. The mainstay of element identi cation within existing refactoring tools is the mouse location and current cursor position. Although these function to identify the elements to which refactorings should be applied, they are not appropriate nor reasonable for every situation. Two use cases, detailed below, demonstrate an unmet need in the arena of refactoring tools.&lt;/p&gt;
&lt;h2&gt;Use Case 1 &amp;#8211; Vendor Braches&lt;/h2&gt;
&lt;h3&gt;Background&lt;/h3&gt;
&lt;p&gt;John is working with a vendor&amp;#8217;s source code and is maintaining a vendor branch. Unfortunately, the vendor&amp;#8217;s code has some unpatched bugs and often uses poorly named identi ers which make it hard to work with.&lt;/p&gt;
&lt;h3&gt;Problem&lt;/h3&gt;
&lt;p&gt;John has a set of patches which he applies using the standard vendor branch approach to patching. He has two sets of patches. The  first set of patches applies the Rename refactoring to many di fferent elements in order to make the code easier to work with. The second set of patches  fixes currently unpatched bugs.&lt;/p&gt;
&lt;p&gt;Following the vendor branch patching process, after each vendor update John loads the vendor&amp;#8217;s source code into the source control system and then applies the first and second set of patches. Unfortunately, the first set of patches often fails to compile because any new references to the variables being renamed are not included in the patch. Each new reference must be manually renamed and the patch updated. Once the first patch has been successfully applied, the second bug-fi xing patch usually applies successfully.&lt;/p&gt;
&lt;p&gt;Although this approach accomplishes what it needs to, it is less than ideal. With each new vendor release the Rename refactoring must be re-applied to the source code for every newly introduced reference to the variables being renamed.&lt;/p&gt;
&lt;h2&gt;Use Case 2 &amp;#8211; Universal Language&lt;/h2&gt;
&lt;h3&gt;Background&lt;/h3&gt;
&lt;p&gt;Beth is involved in an Open Source project whose primary developers are French. The source code is written and commented entirely in French, making it hard for Beth, who does not speak French. Although the developers have decided to change to English as their universal language, they have not yet made the change.&lt;/p&gt;
&lt;p&gt;Beth worked with the developers to understand the meaning of each variable but needs to work with the French code for quite a while before English becomes the universal language.&lt;/p&gt;
&lt;h3&gt;Problem&lt;/h3&gt;
&lt;p&gt;Although Beth could maintain a separate English branch of the source code, that would require that all code be modi ed or committed twice, once for English and once for French. She could convert the source code over once within a separate branch, but each new reference to an existing variable would need to be changed. No good solution exists.&lt;/p&gt;
&lt;h2&gt;Use Case 3 &amp;#8211; In Concrete&lt;/h2&gt;
&lt;p&gt;I would like to perform the following refactorings, but doing so through a GUI will be painful:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Rename all my &lt;tt&gt;*ElementName&lt;/tt&gt; classes in a given namespace to &lt;tt&gt;*Node&lt;/tt&gt; where the asterisk represents some wildcard.&lt;/li&gt;
&lt;li&gt;Rename all &lt;tt&gt;get*Instance&lt;/tt&gt; member functions to &lt;tt&gt;instance&lt;/tt&gt; for every class within the &lt;tt&gt;DataNode&lt;/tt&gt; namespace.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Perhaps the above seem meaningless, but I&amp;#8217;ve had to do almost those exact same things.  After a while, I discovered that some of the class names and methods that I was using weren&amp;#8217;t descriptive enough. I had to go rename over 50 classes even more files.&lt;br /&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Current refactoring tools are wonderful&amp;#8230; for what they were intended for.  They make the process of writing code, and cleaning up that code while you&amp;#8217;re working on it, far easier and more likely to happen that if the process were manual.  But, the GUI itself is also a weakness, one for which we need an alternative.  We need a way to handle these and other uses cases. We need a way to back-port refactorings, where possible, without forcing the programmer to take manual steps. We need wildcards and sed-like functionality in our refactoring tools.&lt;/p&gt;
&lt;p&gt;Much of the above content comes directly from my thesis.  I believe there&amp;#8217;s a solution and future posts will discuss pieces of that solution.  I don&amp;#8217;t believe my solution is complete or perfect, but I hope to further the work in this area.&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size: smaller"&gt;&lt;em&gt;Image courtesy &lt;a href="http://www.flickr.com/photos/zub/58278251/"&gt;seizethedave&lt;/a&gt; on Flickr&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=c8lO382Ro-M:dd1DQA8pvzU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=c8lO382Ro-M:dd1DQA8pvzU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=c8lO382Ro-M:dd1DQA8pvzU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=c8lO382Ro-M:dd1DQA8pvzU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=c8lO382Ro-M:dd1DQA8pvzU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=c8lO382Ro-M:dd1DQA8pvzU:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/KalebPederson/~4/c8lO382Ro-M" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://kalebpederson.com/index.php/2010/02/limitations-of-refactoring-ides#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://kalebpederson.com/index.php/2010/02/limitations-of-refactoring-ides/feed/atom" thr:count="0" />
		<thr:total>0</thr:total>
	<feedburner:origLink>http://kalebpederson.com/index.php/2010/02/limitations-of-refactoring-ides</feedburner:origLink></entry>
		<entry>
		<author>
			<name>Kaleb Pederson</name>
						<uri>http://kalebpederson.com</uri>
					</author>
		<title type="html"><![CDATA[Things I Wish I Knew&#8230;]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/KalebPederson/~3/9Z9JJTEJotI/things-i-wish-i-knew" />
		<id>http://kibab.kalebpederson.com/index.php/2010/01/things-i-wish-i-knew</id>
		<updated>2010-01-31T07:15:00Z</updated>
		<published>2010-01-31T07:15:00Z</published>
		<category scheme="http://kalebpederson.com" term="computer science" /><category scheme="http://kalebpederson.com" term="knowledge" /><category scheme="http://kalebpederson.com" term="university" />		<summary type="html"><![CDATA[This post was imported from blogger, to see the original, likely better-formatted post see kalebpederson.blogspot.com. > When I was a young child an adult friend of mine took me over to his house and showed me his Commodore 64 computer. From the moment I saw the music software and the other things that he could [...]]]></summary>
		<content type="html" xml:base="http://kalebpederson.com/index.php/2010/01/things-i-wish-i-knew">&lt;div class="attention"&gt;
&lt;p&gt;This post was imported from blogger, to see the original, likely better-formatted post see &lt;a href="http://kalebpederson.blogspot.com"&gt;kalebpederson.blogspot.com&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&gt;
&lt;div style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img height="213" src="http://lh5.ggpht.com/_9KeH89IzttQ/S2UsUqqZViI/AAAAAAAAAHU/UzQvhWxeDZQ/245624341_edc43a15b8.jpg" width="320" /&gt;&lt;/div&gt;
&lt;p&gt;When I was a young child an adult friend of mine took me over to his house and showed me his Commodore 64 computer. From the moment I saw the music software and the other things that he could do on his computer, I was hooked.&lt;/p&gt;
&lt;p&gt;From that moment on, I played with computers whenever the opportunity arose.  Before long, an uncle of mine, who was a computer programmer, sent me a Radio Shack TRS-80 computer.  My interested piqued, I started programming in BASIC, going to the library to get programming books, and saving my money for computer parts. My interest for computers never died.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Years Later&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Years later I found myself studying computer science (CS) at Eastern Washington University. I enjoyed it.  Aside from some occasional frustration at my inability to easily do a homework assignment, &lt;i&gt;I loved it!&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;Then, a bit of realization struck, which I didn&amp;#8217;t fully understand at the time:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I never heard version control systems mentioned&lt;/li&gt;
&lt;li&gt;The instructor&amp;#8217;s used &lt;tt&gt;#include &amp;lt;iostream.h&amp;gt;&lt;/tt&gt; instead of &lt;tt&gt;#include &amp;lt;iostream.h&amp;gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Unit tests were unheard of&lt;/li&gt;
&lt;li&gt;Test-driven development wasn&amp;#8217;t considered&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;I Wish I Knew&amp;#8230;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Having reflected on some of the insights I had earlier, I&amp;#8217;ve realized many different things that I wished I knew when I started in school.  I almost think they should have been obvious, but I had no mentor to ask and no prior knowledge to inform me. Here&amp;#8217;s a few of the things I wish I knew long ago:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Computer Science is not a programming degree.&lt;/b&gt; Although much of what is learned in computer science is useful when programming, knowing everything they teach in CS doesn&amp;#8217;t make you a good programmer.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Programming is an art&lt;/b&gt;. Programmers need a sense of aesthetics.  They need to see how different pieces fit together to form a beautiful and functional whole.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Good code is beautiful code.&lt;/b&gt; Just as a good writer&amp;#8217;s sentences are flowered with adjectives and adverbs that form vivid images in his readers&amp;#8217; minds, good code helps its reader understand and envisage the whole intent of the code.  Each variable and name is like an adjective or adverb that adds clarifying definition to the whole.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Programming is rarely engineering.&lt;/b&gt; Unfortunately perhaps, requirements are rarely what they seem. A good programmer communicates, questions, and suggests whatever might be the best for her customer; she doesn&amp;#8217;t assume the customer knows what she wants.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Universities can&amp;#8217;t teach you everything.&lt;/b&gt; And, they don&amp;#8217;t even try. A CS degree program doesn&amp;#8217;t try to teach you everything you&amp;#8217;ll need to know, because much of it can&amp;#8217;t be taught.  At best, the professors can encourage the student to go off and do research on their own. It takes hard work, and lots of practice to be a good programmer. Although you need not go through trial and error to make a test pass, it takes trial and error to perfect your skills, and there&amp;#8217;s nothing that you can do about it.  Put in your 10,000 hours. Do it fast, and do it right. Read, study and learn on your own.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Countless other details could be added to the list above.  I&amp;#8217;m sure there are many more which I have yet to consider, but I hope this will help some future student.&lt;/p&gt;
&lt;p&gt;What do you wish you had known?&lt;/p&gt;
&lt;p&gt;&lt;span&gt;[Image courtesy &lt;a href="http://www.flickr.com/photos/thedoctor856/245624341/"&gt;Guy with the Bolex&lt;/a&gt; on Flickr.]&lt;/span&gt;&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=9Z9JJTEJotI:FVVtf9VB-gc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=9Z9JJTEJotI:FVVtf9VB-gc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=9Z9JJTEJotI:FVVtf9VB-gc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=9Z9JJTEJotI:FVVtf9VB-gc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?i=9Z9JJTEJotI:FVVtf9VB-gc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/KalebPederson?a=9Z9JJTEJotI:FVVtf9VB-gc:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/KalebPederson?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/KalebPederson/~4/9Z9JJTEJotI" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://kalebpederson.com/index.php/2010/01/things-i-wish-i-knew#comments" thr:count="2" />
		<link rel="replies" type="application/atom+xml" href="http://kalebpederson.com/index.php/2010/01/things-i-wish-i-knew/feed/atom" thr:count="2" />
		<thr:total>2</thr:total>
	<feedburner:origLink>http://kalebpederson.com/index.php/2010/01/things-i-wish-i-knew</feedburner:origLink></entry>
	</feed><!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk
Page Caching using disk (enhanced) (Requested URI is rejected)

Served from: kalebpederson.com @ 2012-02-21 02:42:20 -->

