A seemingly futile discussion on considering XP

The reasons offered by the people for not switching to XP I talk to are so thin that they are practically transparent but yet they can't see thru them. e.g. Some points from a discussion yesterday with another person at work.

Even with auto testing (example here was NUnit) there is a "thin layer" that is never exercised i.e. the user moving the mouse to a particular menu item and clicking it.
I then showed him a test right there which directly called the eventhandler (Tim H. -search "UserInterrogator"- has done one step better by directly firing the event) but somehow it didn't quench his need for an "end-user" testing the app. I questioned his existing testing approach of using manual testing and how it attacks the thin layer but my rhetoric didn't get thru. His very thought of considering NUnit shows that his current approach is not doing the job as well as he liked. The thin layer is always present - i.e. tests not considered by the developer.

He had a customer found defect where he had a grid control which displayed a wrong value even though it's data store had the right value. This special grid is said to have no method to get the displayed value. Additionally he said that querying the grid for the cell value is delegated to the data store and hence NUnit would say that the test had passed. The solution was to refresh the grid after the calculation had modified the data store. I felt this falls in the weird UI control dept.

Next on his list, was that he already had a very huge code-base for a product that is already deployed and he doesn't have the time to write tests. I replied that in this case retrofitting tests is very difficult and not advisable. So what you should do .. the next time you have to make a change for a new defect.
1. Understand the area of the defect.
2. Write tests for that area first. Make all of em green.
3. Write a test for the defect.
4. Make that pass
5. Run all the tests from step 2 again and make sure you haven't broken anything.
6. Do your "Victory jig" (You have one right ? awww...)

After all this discussion, I lost an hour of my day and the person was still not convinced although he kept iterating that he wanted a bunch of tests that he could run at any given moment but no time, too diff... this n that and I hate this proj sustenance, and so on and so forth.
My brain kept yelling 'There's no free lunch dude. You want non-manual self-running test-base. GO WRITE IT!' As usual I muffled the noises in my head 8)

[Update Jan 26, 2008]
Looking back at this.. I realize Mary Poppedieck puts it as clearly as possible in the Google tech talks video. Look in Stuff I bookmarked on the blog home page.

Non-obvious XPath: Getting an element by specifying it's value

This one took around half - an - hour out of my working day.
Problem:
I needed to get a specific element from an XML document based on its value / element content.
[Root]
[SomeSection]
[path]C:\Diablo II\[/path]
[path]H.G.Wells[/path]
[/SomeSection]
[Section2]
[path]Morlocks[/path]
[/Section2]
[/Root]

So I need a query to get me the element which has the text H.G.Wells. I could find a whole lot of examples on the net to get me an element based on the value of one of it's attribute.
e.g. /root/SomeSection[@attr='value']
or based on one of its sub elements
e.g. /root/SomeSection[path='H.G.Wells']
I tried a whole of things but to no avail. Then I turned to pester one of my buddies Ranjeet here, who turned to a saved ref document.

The answer here is
/root/SomeSection/path[.='H.G.Wells']
the dot was my missing link to the solution. Oh well, what the hell...
Here's hoping the next guy finds it sooner

Simpleton pondering over Singletons

Are singletons bad ? (I won't call them evil - coz they don't want to take over the world)

http://blogs.msdn.com/scottdensmore/archive/2004/05/25/140827.aspx
Counterview
http://www.mattberther.com/2004/05/000481.html

Here's my example

public sealed class LicenseManager : IDisposable
{
///
/// The single instance in the entire app
///

private static LicenseManager m_obLicMgr;

///
/// Single point to access all LicenseManager members
///

public static LicenseManager Instance
{
get
{
if (null == m_obLicMgr)
{
m_obLicMgr = new LicenseManager();
}

return m_obLicMgr;
}
}

Here's one that I just used.. What would the benefit be in just moving the Factory method to anothe class as Scott suggests ? Hmmm... I'll poke around.

XML Comments bug in VS .NET 2003

It seems that no one is using XML Comments generation via the VS.Net 2003 IDE.
Recently I tried getting all projects to generate the Code Comment pages for all projects to a specific folder. I mean, how difficult could that be ?
  1. Get into Project Properties.
  2. Select Configuration Properties in the tree on the left side.
  3. Enter the relative path into the "XML Documentation File" property under the Outputs category.
Bada bing Bada boom.. you're done! Right ? Wrong !
If you try this out, you will see that the IDE is stubborn as a mule with this.
  • You enter a filename like "MyProj.xml" and everything is smooth. You'll get the page allright.
  • Now try something like [..\..\Comments\MyProj.xml] and click Apply. You'll find your setting being unceremoniously dumped by the IDE and reset to the last good value.
  • Tried the forward slash and still the same.
  • Now try the same with the quotes [""..\..\Comments\MyProj.xml"]. You'll find the IDE accepts it this time :o but still won't output the file there. It will give some weird path errors or file creation errors.
  • Next I just plained opened the .csproj file in Notepad and force set the property. Open the project again in IDE, it will again fail citing some inane reason and blank out the property (LGValue).

I spoke to my at-hand ref guru and he said that it might be due to command line issues since the IDE calls csc.exe with the /doc switch to generate these. But then the description for the 'XML Documentation File' property should not have stated 'Path must be relative to the proj directory (/doc)'

In the end I just gave up and downloaded NDoc. Will try to integrate that with my CI Server which is down with the flu. But I bet I can get that setup faster than I can get CodeComments (from the painfully entered XML Comments) via the VS .NET 2003 IDE.

Great Code: Microsoft gets TDD guidelines wrong.

Just read about the whole fiasco from Aniket's blog.
There is no question that the author got it wrong (and got torched).. he has proposed and delivered a speech on his deviation/derivation of TDD. The problem here is the title.. it should have been 'VS.NET 2005 tools for automated testing' not "Guidelines for TDD"
Seconding Ron Jeffries, I too hope that this is not an MS attempt to adopt, contort and pollute the XP stream with IDE-forced/induced deviations from the holy path shown by the "Rev." Kent Beck :) who has led so many like me across the deserts in search of the promised land (where quality code meets mutually accepted deadlines).

2 Books I think a doubter/newcomer should read are
• XP Xplained - Kent Beck
(First AND second editions to know where XP comes from and what it is)
• Extreme Programming Adventures in C# - Ron Jeffries
For a fun, hands-on, fly-on-the-wall look at how to practice XP.

Angst of an Automated Build Enthusiast leads to GetBOB

I am near the end of the rope with keeping my builds automated.
· NAnt failing to build my solution and breaking the back of my CI Server. I spent nearly a day on finding what the hell is going wrong! If the IDE can build it why can't you ? I get a stupid regasm error stating "RegAsm error: File or assembly name XXX, or one of its dependencies, was not found. External Program Failed: C:\WINNT\Microsoft.NET\Framework\v1.1.4322\regasm.exe (return code was 100)"
· CruiseControl.NET also has decided to out do NAnt by just timing out my SourceControl operation. It used to run perfectly till about 2 days ago. Now every build times out with Starteam operations timing out. I manually run a batch and that works :P

I have been trying so very hard to find the cause for it. It's a funny pickle I am in. I have spent too much time setting all this up. Now everything tumbling down like a pack of cards and I don't wanna go back to batch files (which still run as you tell them to. Day in Day out!).

I figured that maybe the NAnt issue was due to some things in the bin or obj folders. I have solved Intellisense lock ups by deleting the bin and obj folders under each project directory. I hunted around for some recursive dir delete switch in the DOS command line utilities. No luck. Next tried NAnt task. Fine help that is ... couldn't figure that one out -- assuming that it is possible. Finally I decided to write one myself - A Bin Obj Blaster - A recursive directory/folder delete utility
You can just paste into a .cs file and compile it as a 'GetBob Console App'. Then configure your PATH variable so that the exe is available everywhere.

>GetBOB.exe -t
(TestMode: lists out all bin and obj folders that would be deleted but does NOT delete it)
>GetBOB -v
(verbose: Lists and deletes all bin and obj folders)
>GetBOB
(silent mode - deletes all bin and obj folder directly)
>GetBOB temp*
(this should also work - haven't given it a try. Will delete all folder beginning with 'Temp' in the current folder or it's sub-directories.

It's pretty cool and something I needed for quite some time. Give it a whirl :) and let me know of any quick improvements!

I really need to learn how to post code in a blog. XML Comments and indentations are totally screwing up my blog layout. So please ignore...

using System;
using System.Collections;
using System.IO;
using System.Diagnostics;


namespace CallBOB
{
class BOB
{
private static bool bVerboseMode;
private static bool bTestMode;

[STAThread]
static void Main(string[] arrDirPatterns)
{
try
{
Console.WriteLine("BinObjBlaster (B.O.B.) - A recursive 'seek and destroy' folder utility");
Console.WriteLine("Created: Gishu Pillai Nov 17, 2005.");
Console.WriteLine("DISCLAIMER: I give everyone the right to copy/use! Use as you please and at your own risk and free will. The author is not responsible for any damages that may occur from using this.");

ArrayList alDirPatterns;
GetDirPatternsForDelete(arrDirPatterns, out alDirPatterns);

if (alDirPatterns.Count == 0)
{ alDirPatterns.Add("bin"); alDirPatterns.Add("obj"); }
else
{ // we have their number }

DirectoryInfo obDirInfo = new DirectoryInfo(Environment.CurrentDirectory);
SeekAndDestroy(obDirInfo, alDirPatterns);
}
catch(Exception obExcep)
{ Console.WriteLine(obExcep); }
}

private static void GetDirPatternsForDelete(String[] arrArguments, out ArrayList alDirPatterns)
{
alDirPatterns = new ArrayList();
try
{
foreach(string sLoop in arrArguments)
{
if (sLoop.StartsWith("-"))
{
string sTemp = sLoop.Replace("-", "").ToLower();
if (0 == sTemp.Length)
{ continue; }
switch (sTemp[0])
{
case 'v':
bVerboseMode = true;
break;
case 't':
bTestMode = true;
break;
case 'h':
Console.WriteLine("List of Available switches");
string sFormatString = "-{0} {1:15} {2}";
Console.WriteLine( sFormatString, "t", "Test Mode", "Prints a listing of directories that would be deleted but does NOT Delete them");
Console.WriteLine( sFormatString, "v", "Verbose Mode", "Prints the name of the deleted directories");
break;

default:
break;
}
}
else
{
alDirPatterns.Add( sLoop );
}
}
}
catch(Exception obExcep)
{ Console.WriteLine( obExcep ); }
}

private static void SeekAndDestroy(DirectoryInfo obCurDirInfo, ArrayList alDirPatterns)
{
try
{
foreach(string sDirPattern in alDirPatterns)
{
foreach(DirectoryInfo obDirForDelete in obCurDirInfo.GetDirectories(sDirPattern))
{
if (bVerboseMode || bTestMode)
Console.WriteLine( "Found " + obDirForDelete.FullName );
if (!bTestMode)
obDirForDelete.Delete(true);
}
}
foreach(DirectoryInfo obLivingDir in obCurDirInfo.GetDirectories())
{
SeekAndDestroy( obLivingDir, alDirPatterns );
}
}
catch(Exception obExcep)
{ Console.WriteLine(obExcep); }
return;
}
}
}

Playing with Mock Objects

We know that Agile Programming has arrived when the pointy haired boss has heard of it.
http://www.dilbert.com/comics/dilbert/archive/dilbert-20051116.html

On a more techie note, I was reading through some papers for the second time. I am in the process of creating Mock Objects to help me automate my testing. It again reiterates my belief that the most beautiful things are generally the simplest. A good short introduction read would be http://www.pragmaticprogrammer.com/articles/may_02_mock.pdf from Dave and Andy (the PPs).
An even better paper is mentioned on my links list to the left.

Try F.E.A.R.

The next frontier in FPS. The ambience is great :))
As is the trend nowadays, the demo takes 1 Gig on my HDD and then gives me about 2 hours of gameplay before the Demo-n arrives and tells you to buy the whole game.
Impressed I am but upgrade your computer you must. (Yoda style)...
I have almost given up on PC Games.. I think each game now should now come with a GFX card with which the game works. Buying a console like a PS is a more enjoyable option.

Overcome F.E.A.R. you'll need to give it your best shot. http://www.whatisfear.com/us

Neat Tip: Shortcut Keys VS.NET IDE

Jot it down. As the PP book said, it's important to know atleast one IDE very well.

  • Sometime back a 'fellow coder' asked me for a keyboard shortcut for moving to the next build error in the Visual Studio .NET 2003 IDE. Turns out it's as simple as F8. Now instead of moving to the task window and precision clicking on the next item in the list, Just press function key 8 and you are teleported to where you wanna be.
  • Another useful is one that takes you back and forth your function browse history. Lets say you click View definition from caller to be transported to callee. Now Press 'Ctrl & -' to simple waltz back to caller. (the reverse is 'Ctrl & Shift & -' ). No more remembering which file you come from and where you want to go.
For all the brickbats thrown, MS never ceases to amaze with some things of pure simplicity.

Resolving assembly references in a .NET solution

When Calvin proclaimed that "Life is a lot more fun if you are not responsible for your own actions", I think he missed this side of the coin where you don't know what the "heck" is going on..
I have a solution containing a "decidedly and dedicatedly rotten" project. This project references a 3rd Party component (v1.1) from a specific ExtLib directory. This directory is now embedded as the HintPath in the csproj file. Now the magic starts. I have a CI server (CCNet+ NAnt) running builds on the hour. This build machine has v1.0 and v1.1 of the component registered in the GAC. When I open the solution in the IDE, the rotten project gets the assembly from the GAC and the wrong one to boot (1.0).At runtime, it blows up saying that you do not have a license for 1.0. I have pleaded for a day that I don't want 1.0 take 1.1 it's right there you moron but no deal !

Things I found out today.

I don't know the assembly resolution process of Visual Studio. Here's my study notes though...

* When I add a reference to a project, it stores a relative path in the HintPath property (.csproj file). It then translates the relative path to an absolute path and stores it as a ReferencePath setting in the .csproj.user file.
* When I open the solution again, the IDE just picks up the assembly from the absolute path in the .csproj.user file.
* If I delete the .csproj.user file, the IDE seems to be getting the wrong version of the assembly from the GAC. This leads me to believe that the hintpath property is used only if the assembly is not found in the GAC. This time the .csproj.user file is not created, maybe because the reference was resolved from the GAC.

Now one way to resolve this was to add the ExtLib dir path to the ReferencePath property in Project Settings. This will create the .csproj.user file for you with the absolute path inside it. I don't check in .csproj.user files to SourceControl. So this is a workaround rather than a solution.

Another stunning piece of knowledge was on another machine, there is a dramatic difference. If I delete the .csproj.user file, I found that it automatically got the correct 1.1 DLL from the ExtLib (even though even that machine had 1.0 and 1.1 in the GAC) AND recreated the .csproj.user file automatically.


I'm a ignorant .NET programmer so HELP ME God !!

Ruby Sparkle: How to swap two numbers

Here's a perennial question how do you swap two numbers effectively ? Let's say a=5 and b=3 and you want to swap a and b so that a now holds 3 and b = 5.
So in the typical C way, common answer is use a temporary variable for swapping

temp = a
a = b
b = temp

Now for the stingy ones who don't wanna waste memory, here's another way

a = a + b;

b = a - b;
a = a - b;

If you are wondering what the hell have I been smoking, cover your eyes to keep you from being blinded by the brilliance of Ruby

a, b = b, a

This is like a gloved slap in the face. Touche !

Post Build events and NAnt build failures

Found a gotcha with NAnt and Visual Studio .NET 2003.
If you have specified a post-build event in the project properties (e.g. like a file copy operation - copy A.txt \executables) AND you have used the OutputDir attribute for the solution task in your NAnt build script (e.g. you want the built executables to go into another folder than the one specified in the proj properties) you'll run into build failures.


< solution configuration="${BuildConfig}" solutionfile="${ImportUtil_SlnPath}" outputDir="\executables" verbose="true">

The project will build correctly under the IDE but not under NAnt. This is because of the difference in current directories in both cases.


1. When run from the IDE, the path from which the postbuild batch is executed is [ProjectDir]\bin\debug (or release)
2. When run from NAnt, the path would be \executables (i.e. the OutputDir attribute value)
Hence the copy command can't find the source file and fails the build.

Lessons Learnt:

  • Post build events are not recommended - use NAnt build script as the single point where all such tasks are documented. Post build events are hidden inside property pages and hence are difficult for someone new to find out. This however means that the entire team makes a commitment to use Nant (bye bye IDE builds).
  • Do not use OutputDir attribute if you still use Pre/Post build events. :)

In the end I took option 2 to get my CI server back to Green

Finally my Pickaxe is here !!


As of this writing I have spent another 1.8K INR to get a techie book (The Pickaxe book) that I wanted to read. This because there is no Indian edition of this book available and I don't see anyone printing this here in the near future.I must confess I collect books that I like. I am just about to run out of space to keep em. Personally I hate reading online.. I normally don't go more than 4 pdf pages before my eyes hurt (although blogs are perfectly okay). There is something to holding a book in your hand and trying something out. Get stuck and automatically my hands reach for the book and I am already latching onto the relevant portion of the book. To do the same thing with a online book or html pages is pure pain (You need to know the particular html to initiate a Find on it.) Even with the plethora of online docs, I have old fashioned 'reference books' at arm's length.
But I find it very unsettling that I see very few people reading nowadays. In this field, where everything is on the move, the uncontrolled constant is change and the need is constant learning. There is a good chance that someone else has already been there and a book has been written. And if you procrastinate, there is a good chance that someone else isn't and you'd be picking up something like 'My Job went to India' (This is actually a book -
)
But here in Mumbai (commercial capital of the country) I need to wait for a month and pay thru my nose (no Amazon Discounts either) to get a book that was released in the US in 1999 i.e. six freaking years ago. At this rate, we'll always remain two steps behind and doing plumbing tasks with stone age tools. I'm of the opinion that the only way to learn something is to get your hands dirty. Nowadays thanks to the internet, the software requirements are easily met one way or the other :). But the books are turning out to be the real hurdles. As of today cb-india.com is the only option like freaking MTNL, a 'I'm the only one' 'take-it-or-leave-it' place.

But still, 2 chapters in, the book is making all this worthwhile. Thanks Dave, Andy and Chad for taking time out to help me find this gem of a language. Book Home Page

Next frontier in User Interfaces with Win Vista

Be afraid guys... very afraid. The following is claimed to be done by programmers who went from 0 experience to doing this in 6 weeks.
http://channel9.msdn.com/Showpost.aspx?postid=116327
This is not a canned video playing but an actual CSharp app.

Essential .NET (Don Box + Chris Sells)

A bit terse but a treasure trove of .NET internal knowledge nonetheless. I finished the book last weekend. (Okay I cheated in the last 2 chapters). Security just went over my head and my intense passion for building heterogenous (COM, unmanaged and managed ) social (every module goes across the boundaries where the dragons be) systems (and pulling my hair out) led me to surf right over the last Interop chapter.The other chapters were quite enjoyable and I would recommend it to almost anyone, who is commited enough to unboxing the occasionally cryptic text. Also sometimes (read in the last 2 chapters), I felt that they were running out of pages and tried to stuff in as much as they could.
Assembly resolution, Interception and the CLR type system were real eye-openers. The figures in the book really help the prose.
All in all a great book.

What next?? I got another "Essential" book ( I love pain !) - Essential XML I'm gonna frag you too !!

Building your own Continuous Integration Server

The benefits of setting up a CIS are just too obvious

Setting up a Continuous Integration Server This is more of a personal Note to myself than a tutorial. You will not leave this post feeling that you know all the tools. You will have to spend time with their docs and get a little frustrated at times, but hey you live you learn.. You will need the following things.

Step 1. This is easy. Ensure that you have a working build by opening the workspace/solution file in the IDE and doing a complete build. Now we use this as a base for Step 2.
Step 2:Making an NAnt build file. Please unzip and READ THE DOCS folder in the nant zip. I found the docs really cool - nothing that makes you read and read and read and zzz. You can keep skimming thru the docs when you hit a dead end. Find the solution and forge ahead. The core concept is simple. The build file has tasks like a batch file has commands. But the tasks are inherently more powerful and configurable or else they wouldn't exist. Take a print of the NAnt tasks list - quick reference at a glance. So here's what I came up with..

GC.build

G TIP

<?xml version="1.0"?>
<!-- NAnt build script for a VS.NET solution
Gishu Sep 14, 2005.
Email: gishu<dot>pillai<at>gmail<dot>com -->
<project name="GC" default="debugBuild">
<property name="ReleaseOutputDir" value="bin\release" />
<property name="SolutionFilePath" value="source\GC.sln" />
<target name="clean" description="Cleans binaries folder">
<delete dir="${OutputDir}" verbose="true" failonerror="false"/>
<mkdir dir="${OutputDir}" failonerror="false" />
</target>
<target name="debugBuild">
<property name="OutputDir" value="bin\debug" />
<property name="BuildConfig" value="Debug" />
<call target="clean" failonError="false"/>
<call target="build"/>
</target>
<target name="build">
<exec program="..\GC_CheckOut.bat" />
<echo message="Source Checkout complete" />
<solution configuration="${BuildConfig}" solutionfile="${SolutionFilePath}" verbose="true" > <assemblyfolders>
<includes name="C:\Windows\Microsoft.NET\Framework\v1.1.4322\**" fromPath="true" /> </assemblyfolders>
</solution> </target> </project>

  • The .NET solution has a pesky hintpath property for framework DLLs. Running the solution task looks up the hardcoded HintPath value and fails. To go around this, you need to add an AssemblyFolders element to the solution task, with the path to the Framework installation on the current machine. This can be a property/constant defined at the top of the build file.
  • Next, another thing that I overlooked in my exuberance is that NAnt.exe.config take framework 1.0 as the default. Change this is you are using Framework 1.1 or else meet Mr. Build Failure. When I found this, I felt specially stupid since I had done the same thing on my last attempt at home. This time I'm gonna DOCUMENT IT HERE!!!.
  • Use the new (and uber cool) solution task. It does not require the IDE and blah blah to be installed. What it does is that it parses the solution file and invokes csc ( long live the command line ) after resolving references. Now ain't that sweet ? It doesn't use devenv - less resources required and faster. I read this from DevX.

Step 3: Meet Cruise Control.NET CruiseControl is another Rad tool which will help complete our Continuous Integration Server. Configure your CruiseControl.NET Server: You need to make a ccnet.config file to make your server do something useful. Start with the \Doc\CCNET\CruiseControl.NET Server.html under the CC installed directory. You will need to write your specific sourcecontrol block, based on what you actually use. G TIP This tool will only detect an update to the SourceControl Server and then give you a callback. You have to write a script to check out the changes. CC won't do it for you. This was something I learned the hard way. So you need to write a script that will checkout the latest source. This will depend on exactly what you use - I have tried Subversion and StarTeam. Both would be different scripts - see their command line documentation for details. I have built myself a batch file. There I go putting my foot in my mouth. The Subversion block did not have this option but I now see that Starteam sourcecontrol block has a [autoGetSource]true[/autoGetSource] entry. I'll try that out later and update this post. For now I'll stick to my batch file (which I have verified works from the prompt).

Listing: Sample CC config file

<cruisecontrol>
<!-- My Second CruiseControl Config File
Gishu Sep 14, 2005.
Email: gishu<dot>pillai<at>gmail<dot>com -->
<project name="GC">
<sourcecontrol type="starteam">
<executable>c:\Program Files\Starbase\StarTeam 5.4\stcmd.exe</executable>
<project>GC.net/GC.net</project>

<username>buildGuy</username> <password>buildPwd</password>
<host>XX.XX.XX.XXX</host> <port>50000</port>
<path>/GC/Source</path>
<autoGetSource>false</autoGetSource>
</sourcecontrol>
<tasks>
<nant>
<baseDirectory>E:\GC\RootBuild</baseDirectory>
<buildFile>GC.build</buildFile>
<buildTimeoutSeconds>1200</buildTimeoutSeconds>
</nant> </tasks>
<triggers> <intervalTrigger seconds="1800" buildCondition="ForceBuild"/> </triggers> <publishers> <xmllogger><logDir>E:\Program Files\CruiseControl.NET\server\GCLogs</logDir></xmllogger> </publishers>
</project> </cruisecontrol>

Copy the ccnet.config file to your CruiseControl.Net\Server directory. Ensure that Nant is on your PATH EnvVar so that CC can find it. Now pray to your favourite God and double-click the ccnet.exe file in the server directory. This should start the CC Server. (SP2 might try to throw a spanner in the works. Click on Unblock).

G TIP

  • In case of people like me, this generally blows up. So what you do is start a command prompt and start the exe from within the command window. This gives you a chance to look at what blew up. Common things - incorrect paths, locked log files (Stop any running servers first), etc.Ok looks like I got my StarTeam folder project and view names wrong. Backspace Backspace Type Type. That’s it !

Now I can open my web dashboard http://localhost/ccnet to view a whole lot of things on a web page, totally FREE. Not an iota of effort put in. That’s the kinda of thing I like. I had a lotta fun doing this and this will help me have a lot of fun in the future rather than sit here verifying builds. I have got better things to do.. If you have any issues/suggestions or things that you feel I should know, post a comment here. I’ll try my best to get back.. Ciao!

KILLJOY FootNote

Source control servers across WANs rob you of most of the joy with a CIS. E.g. My experiment showed that a project which takes around 17 secs to build from the command prompt with an NAnt script, will take ~11 mins! What the @#%^!!! Allmost all the time is spent in network operations for the SourceControl app (Starteam here), even when checking out only the changes. Still I feel that the benefits justify the time spent even though you have to wait for some time to see the green light. Another excuse for a break :)

Update
Starteam is absolutely horrendous. If you have ST as the source control and it is also across a WAN, please stick with doing all this manually. Take this from me..


Machine Name : BABYBOX

Here it is the new one in my stable. I present my new second machine. This was a near impulse buy. Plan to buy time of under a week. My old machine is sick so I thought that there is no use flogging a dead horse.
Constraints = Money. I had decided that 10K INR is the max I would go. I ended just breaching the limit by a few hundreds.
The new hardware list
  • AMD Sempron 2500+
  • ASUS K8S-MX mobo (got onboard sound, video and LAN)
  • 256 MB 400MHz RAM 1200 INR
  • Sony DVD ROM drive 1500 INR
  • Mini Cabinet 1550 INR

The things I reused list

  • Monitor
  • Keyboard+Mouse
  • DialUp Modem
  • Floppy Drive
  • a 10 Gig HDD

The motherboard supports 6.1 sound and 8 usb ports (fine print - need to buy additional module for going above normal 2 spk sound and 4 USB ports). I have it on my home lan and it is a dream to work on.

The AMD Sempron 2500+ CPU 1.4 GHz has a x64 logo - is this a 64 bit CPU ??? Performance wise it's quite okay. Prior to installing Norton and Win2K, everything was fast :)) I had heard that AMDs run hotter than Intel in the past but this thing blows cold air out like an AC. I do not know the reason for this ... good ventilation - air not getting time to heat up ? nothing heating up ?

The cabinet is quite small at the cost of limiting any expansion (can only fit in 1 CD, floppy and HDD). But then this is my second machine that I wouldn't be using for gaming. So doesn't matter. It's kinda cute.

The ASUS Mobo is sweet. A good board with everything nicely color coded to prevent goofups. Nice manuals. I had to flash my BIOS to get it to recognize my CPU (seems it's a new release). Went in with all fingers crossed but it turned out okay due to the ASUS EZ update utility. Norton 2005 is bundled.



My Wish to own an AMD comes true.







MyMachines

Under the hood of BABYBOX



Essential Interception using Contexts in .NET

This chapter is a result of my tinkering with the Advanced methods chapter of Essential .NET (Don Box and Chris Sells). This chapter is one of my favourites in the book.
Task : Boost thread priority temporarily to a level (specified by the component type). Keep in mind that we want to provide this as an Aspect of the class. The class authors should not have to write any special code or use convoluted/arcane ways to instantiate objects.
This is the example taken in the book. We can intercept calls and provide any pre/post processing as needed. Some of it is not well-documented in .NET. But I loved it nonetheless. This post is to make sure I don't forget the entire load and an attempt to unbox Don Box ( had to let that out of my system).

Keep in mind that any method call can be represented as a Message. System.Runtime.Remoting.Messaging contains IMessage, IMethodMessage, IMethodCallMessage, IMethodReturnMessage, IConstructionCallMessage and IConstructionReturnMessage. (Look up MSDN for more on these classes :)

Option A: The simple but slightly tedious way is to define a proxy class and a Factory method in the required class. This can be seen in the source file Interception1.cs. The essence here is the System.Runtime.Remoting.Proxies.RealProxy class.

  1. So we derive from this class e.g. PriorityProxy to wrap our target class. The target class defines a factory (public static) method like CreateInstance() to have a chance to intercept creation. And obviously, hide the ctor. Now in this method, we create our ProxyObject with a new instance of our target class. We now return a transparent proxy ( a class that mocks everything in our target class ) by returning obProxyObj.GetTransparentProxy(). This is what the calling code gets back.. a devious imposter !
  2. Next: The prime method RealProxy.Invoke() takes and returns an IMessage implementation. Any method call to our transparent proxy is delegated to RealProxy.Invoke(). We can do nothing and call the method via RemotingServices.ExecuteMessage(target, IMethodCallMessage). But we did not jump thru all these hoops to do nothing. Before and After this call lie endless possibilities. E.g. Here we can bump the Thread Priority as Pre-Op and restore it after as Post-Op code.
    Note to call RemotingServices.ExecuteMessage, our target class must derive from MarshalByRef object. This looks restrictive but I do not know of another way to "Call a method" on a target class

So there we have it. But we don't wanna write factory methods (and raise suspicion) so there has to be a more transparent method. And it turns out there is, we can use a special attribute (System.Runtime.Remoting.Proxies.ProxyAttribute) to do this. See Attribute.cs
Derive an Attribute class from ProxyAttribute e.g. PriorityProxyAttribute.

  1. The magic here is that if a class derives from System.ContextBoundObject and it is decorated with a ProxyAttribute, then as Don Box says, the CLR does a dance for you to intercept creation. On a "new", The CLR will first create the ProxyAttribute and call ProxyAttribute.CreateInstance(Type). The default implementation creates the type for you. You cannot call new here as it will trigger the same thing all over again. So here we can create our PriorityProxy here and return the transparent proxy. This eliminates the need for a factory method. The client just does a simple new to instantiate!

So is that all ? Not at all. We're just getting warmed up. For more control (read control-freaky control), we have Contexts and sinks (not the kitchen variety but message sinks). Contexts are logical divisions within an Appdomain analogous to the relationship between AppDomains and Processes. Deriving from ContextBoundObject means that the object is attached to a specific Context i.e. not "Context-Agile". So let's dive into this. For Source, see Contexts.cs

  1. First we decorate our target class with an Attribute that implements IContextAttribute. System.Runtime.Remoting.Contexts.IContextAttribute defines two methods


    void GetPropertiesForNewContext(IConstructionCallMessage msg);
    bool IsContextOK(Context ctx, IConstructionCallMessage msg);


    On a new on our ContextBound type, The CLR will find all context attributes for this class and begin Pass 1. Here it will inquire IsContextOK for each attribute i.e. is the current context fine by you, O mighty context attribute? The context attribute can perform a check and say Nay by returning false. In my example, I call GetProperty on the context to check if the context has a property "ThreadPriority" AND it matches the requested priority. If any one fails, I return false.
    This lets the CLR know that a new context needs to be created. It does so and then begins Pass 2. This time it will call upon GetPropertiesForNewContext(). Each attribute is given a chance to add "context properties" to the new context. This is it's reason for existence. A context property implements System.Runtime.Remoting.Contexts.IContextProperty


    void Freeze(Context newContext);
    bool IsNewContextOK(Context newCtx);
    string Name { get; }


    The third member defines the name of the context property (e.g. "ThreadPriority"). The second member is there to handle conflicts. A type may have multiple context attributes, each adding properties that may have conflicting requirements. So a property can return false to cancel instantiation and throw an exception. Our amiable property return true.. it can get along with any one.
  2. Ok but where is the interception ? For that we now bring in the heavy artillery, Message Sinks. A context property has the ability to add sinks in the message chain. There are four types of sinks
    1. Server Context Sink
    2. Object Sink
    3. ClientContext Sink
    4. Envoy Sink
    All other types other than the Object Sink will be covered in a later post (all my constraints permitting). To add an Object Sink, the property needs to implement System.Runtime.Remoting.Contexts.IContributeObjectSink. This interface has a single method, which returns the MessageSink to be added. (We add our PrioritySink in our property PriorityContextProp). So there we have it, our control point.
    Our PrioritySink is a Message sink, why ? because it derives from IMessageSink.


    IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink);
    IMessage SyncProcessMessage(IMessage msg);
    IMessageSink NextSink { get; }


    Our focus here would be on SyncProcessMessage. On a (synchronous) method call, this method would be called on each sink (a chain may be present). Our implementation of this method would boost the thread priority before calling SyncProcessMessage on the next sink in the chain. Then it restores the old priority.

To use this aspect, we can define any class


[PriorityContext(ThreadPriority.AboveNormal)]
public class Amadeus : ContextBoundObject
{
public void ComposeAGermanOpera()
{
Logger.LogMessage(" Amadeus.ComposeAGermanOpera() ");
Console.WriteLine("Mozart goes to work!!!");
}
}


Object usage

Amadeus Mozart = new Amadeus();
Logger.LogMessage("Commission Mozart.");
Mozart.ComposeAGermanOpera();
Mozart.ComposeAGermanOpera();
Logger.LogMessage("Mozart - Out.");


Here is the output due to some logging code (mainly for inspection purposes)

Thread-2 Context-0 Priority-Normal : Commission Mozart.
Thread-2 Context-1 Priority-Normal : IContributeObjectSink.GetObjectSink()
PrioritySink.SyncProcessMessage (ObjectSink impl) Obe-wan boost my force!
Thread-2 Context-1 Priority-AboveNormal : Amadeus.ComposeAGermanOpera()
Mozart goes to work !!!
PrioritySink.SyncProcessMessage (ObjectSink impl) Obe-wan boost my force!
Thread-2 Context-1 Priority-AboveNormal : Amadeus.ComposeAGermanOpera()
Mozart goes to work !!!
Thread-2 Context-0 Priority-Normal : Mozart - Out.

Fantastic – excuse me while I pat myself on the back again ! From the object usage, do you suspect anything going on behind the scenes ?

Amadeus Mozart = new Amadeus();
Mozart.ComposeAGermanOpera();


Without the logging, everything would be like Magic. All method calls to Amadeus instances are on Nitro!! To quote The Ghost who walks ‘Everything’s simple when you know how’. There you have it. No more interfaces I promise..

References:
Essential .NET – Don Box and Chris Sells.
Msdn.microsoft.com/msdnmag/issues/03/03/contextsinnet/default.aspx – Juval Lowy

For the source file I am trying out a free hosting site - Hope this works! file name: Interception.zip file size: 12439 bytes File number: 00080238 file link: http://www.sendmefile.com/00080238
Everything written here is based on my understanding, which is nothing to write home about. Use your better judgment... FINE PRINT



Enabling AutoComplete at Win2K Command Prompt

I just copied the steps from http://www.activewin.com/tips/win2000/1/2000_tips_44.shtml. Thank you Venkat Sankar, u great surfer on office time !!!! http://venkkats.blogspot.com

I don't know why this is not turned on by default. Who in their right minds would rather type out complete paths ?

• Type Regedit and OK,
• Find HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor,
• In the right pane of Regedit, double click the 'CompletionChar' DWORD value,
• Type 9 click OK,
• Close Regedit,

My first non-frivolous program in Ruby !!!

It has been done. (on Suse Linux 9.1 so Win Users have to deal with the newline diff)

The problem was taken from Starter Problems
To find a way thru a maze from point s to e. I tweaked the problem to read the maze from a text file (say "Maze.txt". The PathFinder creates a Maze object from the file, finds a way thru it and outputs the maze with the solution to a new text file (e.g. named 'Solution to Maze.txt" as per the input filename). The PathFinder is able to deal with mazes of any height or width as long as it is rectangular.

To do a sample run,
p = PathFinder.new
p.findPath( "TestMaze.txt" )
This would create another text file named "Solution to TestMaze.txt" with the solution .

Under Influence of XP

Was simultaneously reading Ron Jeffries' book (see previous post) :). I did this the XP way, by which I mean I had a test store that I kept stashing test cases into as I went along.
TestPathFinder.rb - run this via
ruby -w TestPathFinder.rb
for a test run. I could not find a NUnit like testRunner, for the red, green, refactor steps. So I made something really basic myself.. which I feel is pretty neat and helped me a lot.
The entire process took about 3 hrs including the tests, which is not bad by my standards.
The code has minimal comments at the same time, I feel it is quite readable. The only places I used comments are
  • to blow my own trumpet in the file header
  • I could not find a way to represent characters other than by using ASCII codes (71 instead of 'G'). Found another solution where he overcame this by using "G"[0].. (eww..)
Now how do I put a zip online so that it is free for everyone to access. Any ideas anyone ? Till I find something, drop me a mail if you are interested at
gishu underscore pillai at yahoo dot com

Extreme Programming Adventures in C#

Ron Jeffries
ISBN 81-7853-088-0. 500 pgs / Indian edition available

I completed my run thru a couple of days back. Since I purchased this book, I feel I am entitled to a a review (which I am always). So here goes..
Ron's style of writing is nice... technique sprinkled with good humor. In this book, Ron is new to C# and needs an XML editor for his web site (Xprogramming.com - which is also good). The book is the result of these circumstances. So Ron places you on his ear and lets you peek while he goes about writing an XML editor, tailored to his needs while simultaneously practicing XP (okay so he cheats once in a while but who doesn't. As I found out, it's pretty tempting when you don't have a pair and you suffer from 'Let me see if this hack would work!'.
The sublime moral that Ron drops on you every now and then is that it is okay to not have a detailed design upfront, rather get a rough working model and keep chipping till you are done. (And you are done when all your tests run! XP Explained - 'XP Yoda' Kent Beck). This approach along with periodic reflection and refactoring gives much better results.
I tried this with a problem in Ruby (this should be my next post) and I am happy with my work.
As a chronic whiner, I felt that the "Undo" chapters don't seem right where Ron is faced with a design-breaking XP story. I'll have to re-read those once again.

All in all **** stars, pick this up - should have a lasting effect on the way you code.

Me  Posted by Picasa

Smotchkkiss blinded by Ruby Sparkle

I tired of making WinForms in .NET (how ironic that they named it .NET, is it bcoz u just need to type in . for intellisense and choose whatever appeals to you at that moment. Your only choice in life is the next method (I choose Door No. 3 - oh crap! My Forms don't paint anymore or I need to read 20pgs to find out all the intricacies of dispose/finalize. Help ! Help ! Aaaarghhhhh.... ) Ok maybe I'm exaggerating but Fact of the matter is I'm bored !!

So I started looking around and I even got a book on Perl. But then there I see it ... Ruby - a Japanese language by Yukihiro "Matz" Matsumoto. Look up the Wiki for more on this.

I started with THE (free) book from the PPs, but found my self side tracked after 4-5 chapters. I solemnly promise to get back :)

Meanwhile I hit a good link, which so far is making me smile amid all the mess that I am in... Take a look at http://poignantguide.net/ruby/chapter-1.html

Another link is on how to get started on new languages.. i.e. finding something to do that helps learn(R). The next baby-step (R) (Kent Beck - XP Explained) after Hello World, which is a one liner in Ruby.
http://blogs.pragprog.com/cgi-bin/pragdave.cgi/Practices/Kata by Dave Thomas

What the .... I just inquired about the "pickaxe book", the 2nd edition of the book. It costs about 1.7K INR. (I might end up buying this anyway.) But am I the only one in this country who is still reading from books, instead of pdfs, htmls and other electronic blobs ???

My Links List

A list of links that I liked for some reason

Newer links at the top...

http://blog.james-carr.org/2006/11/03/tdd-anti-patterns/ [Dec 2, 2008] James Carr lists down the usual suspects in TDD land... things you shouldn't do and should spot as soon as possible

http://martinfowler.com/articles/injection.html [Aug 26, 2008] Martin Fowler lays down the law w.r.t. Inversion of Control/Dependency Injection

http://www.martinfowler.com/articles/mocksArentStubs.html#TheDifferenceBetweenMocksAndStubs[Feb 22, 2008] Martin Fowler defines mocks, stubs, etc - When is it a mock and not a stub ?

http://video.google.com/videoplay?docid=-5105910452864283694 [Jan 25, 2008]
Mary Poppendieck speaks at Google Tech Talks on Lean Software development. Nice summary of the underlying principles.

http://blog.wolfman.com/articles/2006/05/26/howto-format-ruby-code-for-blogs [Jul 25, 2007]
This one helps you to format ruby code for blog posts so that it looks pretty! And it's written in ruby. Awesome.

http://www.yoda.arachsys.com/csharp/threads/ [Nov 22, 2005]
This is where i learnt about threading in .NET. Just came back looking for this. So jotting it down.

http://www.ccs.neu.edu/research/demeter/related-work/extreme-programming/MockObjectsFinal.PDF [July 16, 2005]

A very nice paper on how using Mock Objects simplifies testing, improves design and induces the law of Demeter.

http://gigabyte-usa.com/Motherboard/Products/Products_7VM400M-RZ.htm [Sep 8 2005]Had a real hard time looking for their homepage.

http://www.theserverside.net/blogs/showblog.tss?id=TheArchitect [Aug 4, 2005]
This is a nice satire of the neverending incoherent tirade of the Architect in the Matrix; except that the piece is written such that the Architect is Bill Gates and the Matrix is Longhorn.. Vista!

http://www.25hoursaday.com/CsharpVsJava.html [July 20, 2005 12:28PM]

Interesting lil project. This one compares C# and Java w.r.t. what is different. I found that explicit interface implementation is not supported in Java. Notch 1 more to C# then...

http://www.csc.calpoly.edu/~dbutler/tutorials/winter96/cvs/

This link is a tutorial to using CVS - a source control package.


GNU/Linux on a CD

I got a book called the Linux bible - what prompted me to get the book was the CD+DVD included inside, with a lot of distros.

I heard some good things about Knoppix - a distro on the DVD.
So I popped the DVD into a laptop, boot from the CD and voila !!
I have Knoppix - GNU/Linux running without touching my HDD ! No partitioning, no taking backups, nothing doing :) You can't get better than this.
What was even more surprising was that it detected almost everything without pestering me. I listened to an mp3 file on Linux for the first time ever and it sounded cool. Played a bit.. everything seemed ok.
I then reboot the machine. The OS politely ejects the CD and asks me to remove the disk and press Enter. I remove the disk and we have XP again.

I guess I'm gonna run it this way till I speak Penguin. The next distro in my scope is Debian "Sarge".. but that's later
That's my new thing for the week.. Ciao

The Imperial March

Over the past few weeks, I found that most of my posts on my other blog
www.-gishu-.blogspot.com were getting techier by the minute..
So I moved all those posts here. I now declare that this blog shall contain coderspeak
and nothing else.
Btw just got back from Star Wars III ! Bow down to Lucas n Gang. What have I done ...
I now re- declare that this blog shall contain coderspeak from now on...