tag:blogger.com,1999:blog-109262452024-03-13T00:49:09.005+01:00Burnt Out CoderRuminations of an old burnt out programmer.dshttp://www.blogger.com/profile/03787168975353835632noreply@blogger.comBlogger18125tag:blogger.com,1999:blog-10926245.post-59037856727712117192009-05-10T15:35:00.009+02:002009-05-10T22:08:05.592+02:00An (F) Sharp Pain in the Butt<div>Recently we did a major refactoring at work, which involved extending System.Data.DataSet. As we were still using the version 3 framework, we decided to extend DataSet rather than use an extension method. After finishing the refactoring, we were asking ourselves if the refactoring was useful or not.<br /></div><div><br /></div><div>This brought up the subject of how we could find all the locations in our program where we used DataSet and all the locations where we used our new derived class. No problem I said, "I think we can use FxCop to scan the assemblies and locate all our problems". This post is about how I got from that statement to where I am now.</div><div><br /></div><div>First, while I had heard that you could easily write rules for FxCop, I had never really investigated as to how you might go about doing this. Fortunally I found a great tutorial at <a href="http://www.binarycoder.net/fxcop/index.html">binary coder</a> . So after a quick peruse of this document, I thought it might be useful to write a rule that would show me all my methods that are never called. The tutorial showed how to do this very easy task and within a few minutes I had something that was spitting out rule violations left, right and center. Here is my code:</div><div><br /></div><div><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;">using System;<br /></span></span></span></div><div><div><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;">using Microsoft.FxCop.Sdk;</span></span></span></div><div><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;">sealed class MethodCalledRule : BaseIntrospectionRule {</span></span></span></div><div><span class="Apple-tab-span" style="white-space: pre; "><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;"> </span></span></span></span><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;">public MethodCalledRule ()</span></span></span></div><div><span class="Apple-tab-span" style="white-space: pre; "><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;"> </span></span></span></span><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;">: base ("MethodCalledRule", "Vigis.Fxcop.Rules", typeof (MethodCalledRule).Assembly) {</span></span></span></div><div><span class="Apple-tab-span" style="white-space: pre; "><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;"> </span></span></span></span><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;">}</span></span></span></div><div><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;"><br /></span></span></span></div><div><span class="Apple-tab-span" style="white-space: pre; "><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;"> </span></span></span></span><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;">public override TargetVisibilities TargetVisibility {</span></span></span></div><div><span class="Apple-tab-span" style="white-space: pre; "><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;"> </span></span></span></span><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;">get {</span></span></span></div><div><span class="Apple-tab-span" style="white-space: pre; "><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;"> </span></span></span></span><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;">return TargetVisibilities.All;</span></span></span></div><div><span class="Apple-tab-span" style="white-space: pre; "><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;"> </span></span></span></span><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;">}</span></span></span></div><div><span class="Apple-tab-span" style="white-space: pre; "><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;"> </span></span></span></span><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;">}</span></span></span></div><div><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;"><br /></span></span></span></div><div><span class="Apple-tab-span" style="white-space: pre; "><span class="Apple-style-span" style=" ;"><span class="Apple-style-span" style=" ;"><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;"> </span></span></span></span></span></span><span class="Apple-style-span" style=" ;"><span class="Apple-style-span" style=" ;"><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;">public override ProblemCollection Check (Member member) {</span></span></span></span></span><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;"><br /></span></span></div><div><span class="Apple-tab-span" style="white-space: pre; "><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;"> </span></span></span></span><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;">Method m = member as Method;</span></span></span></div><div><span class="Apple-tab-span" style="white-space: pre; "><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;"> </span></span></span></span><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;">if (m != null) {</span></span></span></div><div><span class="Apple-tab-span" style="white-space: pre; "><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;"> </span></span></span></span><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;">MethodCollection mc = CallGraph.CallersFor (m);</span></span></span></div><div><span class="Apple-tab-span" style="white-space: pre; "><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;"> </span></span></span></span><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;">if (mc == null || mc.Count <></span></span></span></div><div><span class="Apple-tab-span" style="white-space: pre; "><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;"> </span></span></span></span><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;">if (!m.Name.Name.Contains ("_") && !("Main".Equals (m.Name.Name)) && !("Dispose".Equals (m.Name.Name))) {</span></span></span></div><div><span class="Apple-tab-span" style="white-space: pre; "><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;"> </span></span></span></span><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;">this.Problems.Add (new Problem (this.GetNamedResolution ("DeleteMethod", m.Name.Name)));</span></span></span></div><div><span class="Apple-tab-span" style="white-space: pre; "><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;"> </span></span></span></span><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;">}</span></span></span></div><div><span class="Apple-tab-span" style="white-space: pre; "><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;"> </span></span></span></span><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;">}</span></span></span></div><div><span class="Apple-tab-span" style="white-space: pre; "><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;"> </span></span></span></span><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;">}</span></span></span></div><div><span class="Apple-tab-span" style="white-space: pre; "><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;"> </span></span></span></span><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;">return this.Problems;</span></span></span></div><div><span class="Apple-tab-span" style="white-space: pre; "><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;"> </span></span></span></span><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;">}</span></span></span></div><div><span class="Apple-style-span" style=""><span class="Apple-style-span" style="font-family: arial;"><span class="Apple-style-span" style="font-size: small;">}</span></span></span></div></div><div><blockquote></blockquote><span class="Apple-style-span" style="font-family: arial;">Basically, we walk through all the members of all the classes. When we find a method, we ask the </span><span class="Apple-style-span" style="font-style: italic;">CallGraph </span>for all the methods that call it (the callers). If there are none, then I have a method that is potentially never called (I am not writing API code). Basically I found that the <span class="Apple-style-span" style="font-style: italic;">Main </span>and <span class="Apple-style-span" style="font-style: italic;">Dispose </span>methods of this (a WinForms application) were never explicitely called, so I decided to explicitely ignore them. I also determined that methods that implement event logic, while reference by the event, were never called either. Note, I decided not to check for method referenced by events, but rather to just ignore all methods with an underscore in there name (a standard for WinForms event handlers).</div><div><br /></div><div>This was all well and good and I was happy with the result. My total investement in this affair was about an hour at this time (including reading the tutorial).</div><div><br /></div><div>Now, I have being investigating the use of F# as an alternative language to C# for about a year now. Have read "Expert F#" about twice and I had twiddled with the compiler, but never really written anything with a purpose. I decided that this was a project that I could write in F# (only 30 lines of C# code and it does something). Now, I must say that I am hesitant about F#. I don't think that it has tool support (compiler and Visual Studio integration) sufficient for commercial software development. I have strong reservations about the syntax, because I don't believe that a competant C# programmer can even read the code without a significant amount of training. Thus, in the near term, I don't think that F# is an appropriate choice for commercial software develepment. However, with the prevalence of multi-core architectures, it is clear that multi-processing must become part of our everyday way of writing programs, and I do believe that functional languages and F# in particular have their place in this world. Maybe not today, but soon. For this reason, I think an investement in learning F# is justified.</div><div><br /></div><div>So, armed with my book and a good internet connection for googling any problem, I set out to write my FxCop rule in F#. First I have to say that the assembly created worked perfectly and so hats off to microsoft. There is nothing strange about an F# assembly at the byte code level. My problem is the source code level.</div><div><br /></div><div>In truth, I took me about 4 hours to implement my simple FxCop rule:</div><div><br /></div><div><div><span class="Apple-style-span" style="font-style: italic;"><span class="Apple-style-span" style="font-size: small;">namespace Vigis.Fxcop.FSharp</span></span></div><div><span class="Apple-style-span" style="font-style: italic;"><span class="Apple-style-span" style="font-size: small;"><br /></span></span></div><div><span class="Apple-style-span" style="font-style: italic;"><span class="Apple-style-span" style="font-size: small;"> open System</span></span></div><div><span class="Apple-style-span" style="font-style: italic;"><span class="Apple-style-span" style="font-size: small;"> open Microsoft.FxCop.Sdk</span></span></div><div><span class="Apple-style-span" style="font-style: italic;"><span class="Apple-style-span" style="font-size: small;"><br /></span></span></div><div><span class="Apple-style-span" style="font-style: italic;"><span class="Apple-style-span" style="font-size: small;"> type MethodCalledRule () = </span></span></div><div><span class="Apple-style-span" style="font-style: italic;"><span class="Apple-style-span" style="font-size: small;"> inherit BaseIntrospectionRule ("MethodCalledRule", "Vigis.Fxcop.FSharp.Rules", typeof</span><methodcalledrule><span class="Apple-style-span" style="font-size: small;">.Assembly)</span></methodcalledrule></span></div><div><span class="Apple-style-span" style="font-style: italic;"><span class="Apple-style-span" style="font-size: small;"> </span></span></div><div><span class="Apple-style-span" style="font-style: italic;"><span class="Apple-style-span" style="font-size: small;"> override this.TargetVisibility with get() = TargetVisibilities.All</span></span></div><div><span class="Apple-style-span" style="font-style: italic;"><span class="Apple-style-span" style="font-size: small;"> </span></span></div><div><span class="Apple-style-span" style="font-style: italic;"><span class="Apple-style-span" style="font-size: small;"> override this.Check(m : Member) = </span></span></div><div><span class="Apple-style-span" style="font-style: italic;"><span class="Apple-style-span" style="font-size: small;"> match m with</span></span></div><div><span class="Apple-style-span" style="font-style: italic;"><span class="Apple-style-span" style="font-size: small;"> | :? Method as me -> </span></span></div><div><span class="Apple-style-span" style="font-style: italic;"><span class="Apple-style-span" style="font-size: small;"> match CallGraph.CallersFor me with</span></span></div><div><span class="Apple-style-span" style="font-style: italic;"><span class="Apple-style-span" style="font-size: small;"> | v when v.Count <> 0 -> this.Problems</span></span></div><div><span class="Apple-style-span" style="font-style: italic;"><span class="Apple-style-span" style="font-size: small;"> | _ -></span></span></div><div><span class="Apple-style-span" style="font-style: italic;"><span class="Apple-style-span" style="font-size: small;"> | "Main" | "Dispose" -> this.Problems</span></span></div><div><span class="Apple-style-span" style="font-style: italic;"><span class="Apple-style-span" style="font-size: small;"> | n when n.Contains ("_") -> this.Problems</span></span></div><div><span class="Apple-style-span" style="font-style: italic;"><span class="Apple-style-span" style="font-size: small;"> | e -></span></span></div><div><span class="Apple-style-span" style="font-style: italic;"><span class="Apple-style-span" style="font-size: small;"> this.Problems.Add (new Problem (this.GetNamedResolution ("DeleteMethod", [| box e |] )))</span></span></div><div><span class="Apple-style-span" style="font-style: italic;"><span class="Apple-style-span" style="font-size: small;"> this.Problems</span></span></div><div><span class="Apple-style-span" style="font-style: italic;"><span class="Apple-style-span" style="font-size: small;"> | _ -> this.Problems</span></span></div><div><span class="Apple-style-span" style="font-size:small;"><span class="Apple-style-span" style="font-style: italic;"> </span></span></div><div>Now, in the unlikely event that someone ever reads this article and in the even more unlikely event that person knows something about F#, please don't laugh at my code. The FxCop rule in C# is standard code, we are basically extending a base class and overriding a couple of do nothing methods. This is not the way F# is typically implemented. It took me a long time to find the right override syntax and I have the impression that there are several ways the simple extend and override object might be implemented. If we are going to use F# in an OO world, we will have to have real idioms for doing OO operations and these will have to be explained in the standard documentation. I don't believe that this is the case today. I suffered leafing through books and googling useless sites before coming up with this implementation. If it is not good, its not for lack of trying.</div><div><br /></div><div>Next, once I had the basic skeleton of what I wanted to implement, I still ran into problems at every turn. First, and this is nothing against F# or other functional languages, is that I am a OO programmer. Before that I was a procedural programmer. My functional programming is limited to a couple of exercises in university about twenty years ago (lisp and prolog). So, as you can imaging the idea that I always have to return the right value at the end of an expression cames hard (but the compiler eventually quit complaining).</div><div><br /></div><div>I still don't know the correct idiom to use when implementing these things. An FxCop rule basically means you have to override a <span class="Apple-style-span" style="font-style: italic;">Check </span>method that returns a <span class="Apple-style-span" style="font-style: italic;">ProblemCollection</span> specifically <span class="Apple-style-span" style="font-style: italic;">this.Problems</span>. So, we have a <span class="Apple-style-span" style="font-style: italic;">Check </span>where the last line has to read <span class="Apple-style-span" style="font-style: italic;">this.Problems</span> in all cases. Now, I kind'a like the match pattern expression, especially when we have to try object casts. I do this a lot in real life (<span class="Apple-style-span" style="font-style: italic;">Describe </span>for those of you in the club). Seeing language support pleases me. But, how do you finish with all groups emiting the same result. My implementation does not please me. Maybe I will go back and change it later, once I know what I am doing.</div><div><br /></div><div>The worst thing was when I had to add a problem. This basically involves giving the name of a resolution resource (that was defined in an XML file) and then passing an array of objects which will be applied to the resource string (using something like a <span class="Apple-style-span" style="font-style: italic;">string.Format</span>). After much head shaking and grinding of teeth, I came up with this concoction.</div><div><span class="Apple-style-span" style="font-size: small;"><span class="Apple-style-span" style="font-style: italic;"></span></span></div><blockquote><div><span class="Apple-style-span" style="font-size: small;"><span class="Apple-style-span" style="font-style: italic;"><br /></span></span></div><div><span class="Apple-style-span" style="font-size: small;"><span class="Apple-style-span" style="font-style: italic;">[| box e |]<br /></span></span></div><div><span class="Apple-style-span" style="font-size: small;"><span class="Apple-style-span" style="font-style: italic;"><br /></span></span></div><div></div></blockquote><div>Basically <span class="Apple-style-span" style="font-style: italic;">e</span> is a string and<span class="Apple-style-span" style="font-style: italic;"> [| somthing; something-else |]</span> says create an array with the arguments. The problem is that when you create an array with a string, it creates a string array. I tried a number of hack arounds, but I did not come across the correct incantation. Thus I finshed by saying, box the string as an object, then create an object array. I was unable to cast a string array to an object array and I don't know why. I consider this to be hard, because .NET programming is full of passing arguments as object arrays so we need a good idiom to get this done. I probably spent more than an hour on this issue, and I didn't find anything better than this.</div><div><br /></div><div>Now, the standard analysis, done by F# affectionados is "look how few lines of code I used". In this case F# is clearly better - 18 lines against 28 for C#. If we don't count lines containing a single curly braces, the contest turns out to be 18 to 18. Note, I used a match structure in F# to do what was done in a single if test in C#, so I don't think that number of lines is really meaningful. Obviously I wrote the C# much more quickly than the F#. I will likely to continue to write C# must more quickly than F# for sometime to come, so this is really not a good measure either. </div><div><br /></div><div>In the end, I don't need no stinking measures to justify this experiment. I think this was a useful exercise and I am very pleased to have done it. And I think this is what is important. I should really be competent in both OO and functional development so that I can bring either tool to bear if the situation arises.</div></div>dshttp://www.blogger.com/profile/03787168975353835632noreply@blogger.com0tag:blogger.com,1999:blog-10926245.post-91471642867539733482009-03-07T22:51:00.003+01:002009-03-07T23:12:09.950+01:00I Must Have Dosed Off for a YearWow... what just happened. I think I must have dosed off for a year there... Just kidding. I have been a bit busy and I recently thought I might start blogging again. First an update. I looked at my last post... it was a depressing entry about writing our license server with Xheo. Well, just as a way of update date here is how the story plays out.<div><br /></div><div>In fact, in the end I did get my license server working. Basically it allows us to install a single application that manages all licenses. When a customer buys a product we give him a license server that he uses on his site to manage all his applications. A license administation client uploads licenses to the server which stores them in a secure way. The license server also talks to my local license activation server every once in a while so I can have an idea of how many purchased licenses are actually being deployed. Licenced applications don't have to worry about installing licenses. They simply ask my server for a license by user name and machine id. If they own a license, they are authorized, otherwise they will aquire a license if one is available. If none are available, the application stops. </div><div><br /></div><div>In the comming weeks we will be running a beta test with a new product. The product uses a project server hosted on our site that licenses our remote beta testers by accessing a local license server (the product is a desktop application). The beta tester don't even know that they are using a licensed product.</div><div><br /></div><div>Overall, the licensing system works pretty well. I don't think I understand everything about Xheo and sometime trying to resolve problems is like playing baseball in the dark (a swing and a miss) but Xheo does provide a lot of features and it can be coerced into working.</div><div><br /></div><div>Funning thing is, a year after I implemented and tested this, I was forced to reactivate a licence service. Unfortunatly someone had changed the network setting of my server (we have an internet facing project server accessing a license server behind the firewall. It took us almost a week to unravel the network mess before finally figuring out what was wrong. The only thing we knew was the we didn't have a valid license...<br /><div><br /></div><div><br /></div></div>dshttp://www.blogger.com/profile/03787168975353835632noreply@blogger.com0tag:blogger.com,1999:blog-10926245.post-29395101325631817822008-01-10T22:42:00.000+01:002008-01-10T22:49:17.309+01:00Xheo-duWell, I think I have enough Xheo to get me started working on other aspects of my license server. It was not easy and the documentation did not really help. In the end I had to show the license registration dialog or the registration information just was not sent to the server (even though there were default values and the registration method was called). I don't pretend to understand everything about DeployX, but I have enough continue.<br /><br />I think this underscores the problem with Microsoft's help format. Help is cut up into a hierarchical collection of factoids and it is very difficult to read linearly (i.e. there is no start and there is no end, so in general you can only read a snippet of the available documentation). Why can't someone produce a nice PDF from an existing VS2005 help file (or maybe somebody can?...).dshttp://www.blogger.com/profile/03787168975353835632noreply@blogger.com0tag:blogger.com,1999:blog-10926245.post-69916239466374170172008-01-09T21:02:00.000+01:002008-01-09T21:17:03.022+01:00Xheo ShmeoI have found a name for my pain. I call it <a href="http://www.xheo.com/">Xheo DeployX .</a> I have been working on a new license server for about the past month and I am really at my wits end. It is rare that I come to such a point in a project, but I would like to give up.<br /><br />For those of you who don't know Deployx is a software license package for .NET. It is very complete with a lot of features and is also very expensive. We would like to use it to write our own centralize licensing server so that corporate users could simplify deployment (and we could get paid for what we are doing - a big change). Unfortunately it is a black box and a brick sXXt house. I don't know how it works, I don't know how it is supposed to work if it did work. I don't know when it is working and when it is not working. All I know is that is it not doing what I hoped it would do. <br /><br />The documentation is minimal and the support staff surly (when they answer at all). If there were any other product that might be able to do my job I would have bought it.<br /><br />Depression... depression... depression.dshttp://www.blogger.com/profile/03787168975353835632noreply@blogger.com1tag:blogger.com,1999:blog-10926245.post-1158694435536016002006-09-19T21:09:00.000+02:002006-09-19T22:01:49.566+02:00What about AOP?I have read a lot of stuff on AOP recently. In the past couple years both the CACM and IEEE Software dedicated entire issues to AOP. However, after reading both of these and a host of other stuff I remained largely unconvinced.<br /><br />However, when coding tricky projects we have been faced with times when we wished that we could inject code compiler at compile time - a typical thing that AOP will allow. In addition, I can see the utility of AOP for a lot of developer tools, for example, TypeMock - a C# mock object framework, uses AOP extensively. This brought me back to AOP.<br /><br />I decided I would try (again) to do something with AspectJ. It seems to be one of the big guns of the AOP world (in CACM and IEEE Software, there were articles that originated with this project). In addition, there are very good AspectJ tools for Eclipse. This time, to help me I bought the Addison Wesley book on AspectJ with Eclipse (I forget the name just now). And decided I would try to read it over the summer holidays.<br /><br />To my surprise, the book offered a new picture of AspectJ. In its introductory chapter it actually solved a real problem (serialization of objects) with something that seemed to be an AOP application (not a just a developer tool) that was useful. Much of the authors claims made sense. That is, use aspects to modualize objects that are in different inheritance hierachies. The serialization example was very convincing.<br /><br />The idea is that a lot of busness objects should not mix thier busness logic with there "book keeping" code (for example how the object is stored). The result was similar code that cut across a number of unrelated objects could be treated in a unified way.<br /><br />The more I looked at the examples presented by the author and the more I thought of it, the less excited I became. I am, however convinced that if used as another programming tool, AOP can be useful, but if you abuse the AOP hammer, I think you will end of with a big, complex, distributed mess. Here are my main beefs,<br /><br /><ol><li>In Holub's Pattern book he makes a convincing pitch that objects should be able to save themselves in context. According to Holub, getter and setter (or properties if you come from C# land) are evil. I believe Holub in this case. The serialization aspect can not just save everyone by looking set and get methods and use them to serialize the object. Object serialization is a task the object must participate in. This is made clear in Holub's book. Otherwise, we trade modularity of the serialization code for a tangle of aspect and object code, with the guts of the objects exposed in the wild, rather than carefully concealed.</li><li>I note that in AspectJ you can write point cuts on private join points. For example, we could execute a bit of code every time the program accessed a private field. Is this really a good idea. Is it not really fragile to use a private point cut? The implementing private method has made no contract to exist and may be changed at anytime. This type of aspects might be good to hack to do something like unit testing with mocks, but we can not write application code like this.</li><li>Aspect interpretation is hard... too hard. When I read my first paper on AspectJ the authors emphasized that tool support would be required if the framework was to be adopted. I think that tool support is good, but tool requirement is bad. That is, if when I write a point cut I need a tool to show me which objects (might be affected), then I am in trouble. I think that writing point cuts is like writing regular expression. Seems easy until you have to do something really hard. Sometimes you ge more hits tht you think you will and it is very difficult to see the difference. With this, the advantage of AOP (localized code for dispersed object) becomes a disadvantage. You never know which objects will be hid by an AOP bug and the object and aspect code are dispersed, so you might have a hard time locating the bad line of code.</li><li>Your object can not count on aspects (usually). Here is a philosphical point. Should the object know there will be an aspect attached to it. If not, why does it not implement all the code required to do its business (rather that stuffing some code in a aspect). If it does know, why is it not more specific about its contract with the aspect. I think this is where I am now. I would like to use aspects, but I would like my objects to expose a public point cut interface that could be used by the aspect for stuff the object would have had to do. Then and only then can the object remove "non-business" code. Otherwise, the only thing we have done is created a dependance between the object and the aspect that is implicit, required but very weak (can you ship the object without the aspect - AspectJ say - go ahead).</li></ol><p>So there is my 2 cents worth on AOP. I think when we do AOP the objects would do well to define a set of exposed point cuts. I don't think we should bend over backwards looking for aspects - aspects are suppose to deal with cross-cutting issues. If there are no cross-cutting issues using an aspect (or inventing an abstract cross-cutting issue) is just making things more difficult than it needs to be (I had the impression to read an article like this in IEEE Software). Finally, I don't think that an aspect should ever point cut a private or protected or package join point. Maybe for a developer tool, but not for a application. An OO programmer would not use reflection to execute a private method just because he could after all, so an aspect should not do the same thing.</p>dshttp://www.blogger.com/profile/03787168975353835632noreply@blogger.com0tag:blogger.com,1999:blog-10926245.post-1144349398970406182006-04-06T20:47:00.000+02:002006-04-06T21:52:23.413+02:00On 10 Things Jim Mischel Hates About C#The other day a read Jim Mischel expound on the 10 things he hates about C#. I was a bit disappointed because most of the things he didn't like about C# he wouldn't like about C or any of its decendants. I think he missed all the meat. Take a look here before I add my two cents worth.<br /><br /><a href="http://www.informit.com/guides/content.asp?g=dotnet&seqNum=481&rl=1">Jim's Top Ten</a><br /><br />1. No Anonymous Inner Classes<br /><br />Anyone who says they don't like the syntax of anonymous inner classes misses the point of C-like languages. That is, minimizing the amount of text minimizes the amount of errors and using common idioms eliminates common errors. No anonymous inner classes ensure that there is always a large amount of boilerplate infrastructure to hack up everytime you ever want to implement a class that will only ever be created in one place (does IEnumerable and IEnumerator mean anything to you). I hate creating private named IEnumerables when I could easily do the same thing with an anonymous class. The syntax might be something pascal programmers are not use to, but we are after all highly paid programmers. Besides, putting the code right beside where it is used rather than in some dusty corner *always* makes it easier to maintain. I can not see why anyone would prefer not to use anaymous inner classes at every opportunity... must be a hold over from our BASIC days.<br /><br />2. Interfaces Can't have Inner Objects<br /><br />How many times do you implement an exception that is only thrown by an interface method, or an enum that is only used in an interface. Why can not these be inner classes and enums on the interface itself. This allows the internals to be encapsulated within the interface and it reduces namespace pollution by seldom used items.<br /><br />3. Enums aren't Objects<br /><br />Enums can not have any body. But this is not the way they are used. Enums often have services they have to perform, like showing as a translated string, saving themselves in a persistence framework or just display themselves in the UI (as a drop down menu for example). These are real needs (google whack "enum C# ToString" and you will see what I mean). Enums should not be just a short list of ints. In an object oriented language they should be full class objects.<br /><br />4. I Don't Like Delegates (and I like Events even less).<br /><br />The syntax of delagates still confuses me, their place in the object hierachy confuses me (e.g. what is "this" when you are in a delegate method). I don't think there is a need for a function wrapper in an object oriented language. An no, there is nothing object-oriented about a delegate.<br />I can say the same for events, except the syntax is even worse and more confusing. How can this:<br /><br />button.Click -= new Event (myEvent);<br /><br />remove an event listener when I just created a new delegate. I think the entire event system in .NET was made so that the people who implemented VisualStudio had an easier time (and to hell with the people who have to use the generated code).<br /><br />I don't think I have to go to 10. I am disapointed Jim just came up with the same "don't like C conditionals" ... blah, blah, blah. C is about minimizing typing, using standard implementation idioms and putting the code near to where the action is taking place. I think if you don't like these ideas, then, effectively, you won't like C or any of its decendants (no sweat). Having said that, there is lots of things about C# that we don't have to like (assuming we like C). I listed a few. I think if you have not felt the same need, you aren't really trying. Almost every day I code C# I miss anonymous inner classes and inner classes on interfaces.dshttp://www.blogger.com/profile/03787168975353835632noreply@blogger.com0tag:blogger.com,1999:blog-10926245.post-1142789720247426922006-03-19T18:25:00.000+01:002006-03-19T18:55:41.176+01:00XML, Strings and "Simple" Text ProcessingLast friday I was hacking up a simple system for maintaining a presistent local parameter store. I did not want to waste a lot time on it, so I decided I would persist my parameters in an XML file and store the file everytime a parameter was added or changed. After finishing the implementation, the first thing I wanted to do was persist an XML document, represented as a string (a log4net configuration document). No problem I thought, its just text - I had a key node with the parameter key and a value node where I persisted the XML document.<br /><br />When I went to implement a simple parameter editor, I thought... after editing, maybe my XML document is non-conforming. I think I will reload it into an XML document after editing to test its validity. Much to my disappointment, when I did this everything broke. All my XML elements were XML encoded as <node-name> and when I reloaded the document I got lots of errors. What went wrong.<br /><br />In fact, when I loaded the document into the XML document and later stored the document inner XML (in .NET C#) the new text contained an node giving the encoding of the document. Since this was being stored as an XML node in my parameters document, the XML framework thought it must be text and encoded it for me. This show why XML sucks. You can not just blindly add text to a document. If I would have added XML that was not well-formed in a single node, this could break my containing document.<br /><br />To counter this I decided to base64 encode the xml text and push it into a CDATA section of my parameters document. Okay, the text of my parameters document would not be as easy to hack, but I could guarantee that any parameter could be put in the document without breaking the container. This is the source of today's rant. I find the C# API for such a task is crappy.<br /><br />First, what I expected to do was to create a string object that was the base64 representation of my initial string object. But the Convert method for creating a base64 string takes a byte array (okay that is logical), but to create a byte array from a string you have to get text encoding object and call the GetBytes method. One would expect that string could expose a constructor that takes and encoding and a byte array and a GetBytes method that could create a byte array. I spent 1/2 hour looking though the crappy .NET documentation trying to find the objects collaborating in the string to byte array sequence before stumbling upon the correct incantation. Then I spent another 1/2 hour doing the same thing for converting a byte array back to a string.<br /><br />The basic problem here is that you should be able to say, "string, give me a byte array representation of yourself - here is my encoding scheme" - I think this is the Java strategy and I think it is the logical one. What .NET has is "encoding, here is a string, take a peak inside its current implementation and representation and give me a byte array represetation of it". I think it breaks encapsulation and you really have to have a lot of experience working in domains where character encodings are important (i.e. where 99% of all north american programmers like myself don't work) before you even guess where the solution might be located.<br /><br />The second problem is that all the .NET documentation (no... make that all Microsoft documentation) is broken in the 1/2 screen factoids with circular references between every three pages. Examples are designed to make people quit trying. For example, I recently looked at the documenation for getting directory information and an example program was presented showing how to print out the various parts of a file path without showing what the various method calls should return... I suppose they expect you to create a project, copy and paste the example code and run the example if you are really interested in knowing what the method calls do, rather than just clearly explaining it in the description of the methods.dshttp://www.blogger.com/profile/03787168975353835632noreply@blogger.com0tag:blogger.com,1999:blog-10926245.post-1142537749874998772006-03-16T20:25:00.000+01:002006-03-16T20:45:01.693+01:00Review Your CodeThe other day one of my little boys was sick at home, so as I had to spend the day with him. I decided to write a presentation document - using OpenOffice Impress - describing the technical details of an iteration release of one of our products. The idea was that we produce some much code, for so many different products that, first we don't remember what we did or how we solved the problems a month later and second, people who were not sitting in on the coding session don't have a good idea of how the code works. I thought an Impress presentation would allow us all to quickly review what we did on a release, and the developers who did the code could give insight to the implementation strategies.<br /><br />We have not really had a review meeting (but this will happen), but I found the process of writing the code review presentation to be very informative for me. First, I am the worst when it comes to forgetting what I did two weeks ago (I am the burnt out coder after all). Second when we isolate code sections for a simple presentation, we see inconsistencies and omissions that are not appearent when you are busy hacking code. In one section of the presentations I talk about the major interfaces that we implemented. I show a UML class diagram of the interface on the left with a description on the right. That's it... one interface per slide. Under this presentation you notice things about the interface design the you don't when it is all mungied-up with other classes and interfaces.<br /><br />In the end, on one hand I could see that some interface members may have been asymetrically or inconsistently implemented, but on the other hand we don't add things to interfaces lightly and everything is the subject to quite a bit of debate. Also we have a strict rule about not adding stuff we don't need. Currently the interfaces work (warts and all) and that is the most important thing. I am happy with the review and I am happy with the structure of the interfaces. I find the time spent writing the review was not wasted.dshttp://www.blogger.com/profile/03787168975353835632noreply@blogger.com0tag:blogger.com,1999:blog-10926245.post-1141421891816321872006-03-03T22:37:00.000+01:002006-03-03T22:53:46.886+01:00I am backI have not been blogging very often, but I have been working hard. We have created a lot of code and I have a lot of cool projects on the go. Version 4 of our principal product is progressing in fits and starts. We are implementing the foundation using some of the most incomprehensible code that I have ever written.<br /><br />We corrected a major problem with the PTI (ProjectTypeIndexer) today. This is an object that is repsonsible for finding other addressable objects at runtime, from "nearby" dl'ls, validating the rules associated with them and allowing them to be integrated into the project as first class citizens. The bug had to do with how the change manager rebuilt this object so that once one user identified and integrated a type, it could be distributed to to other user using a commit/synch workflow.<br /><br />Rarely have we written such simple code that has such a contorted runtime trace.<br /><br />With this bug fix we are on target to finish implemented basic change management for graphic objects. This project has put such an emphasis on change management (using local and distributed workflows) that I don't think we will ever look at implemented an undo/redo facility in the same way. We learned lots of stuff and when everything starts working it is super cool....dshttp://www.blogger.com/profile/03787168975353835632noreply@blogger.com0tag:blogger.com,1999:blog-10926245.post-1118082662141547952005-06-06T20:21:00.000+02:002005-06-06T20:31:02.146+02:00Docbook on OxygenI have not been blogging much lately - too much job depression in the air I guess. I have started a new home project - trying to get a good transform for my docbook documention. My idea is to use fop (ouch) and saxon to generate PDF output of professional quality. Given the complexity of our documents and the proliferation of different features (vector and raster graphics, multi-language and a bit of math thrown in) I think this will be very difficult. I did look at the docbook to latex transformation project and it looks very interesting. I will try that when fop does not work (I suppose that would mean starting to hack eps files again...).<br /><br />I got the docbook xslt book, so I think I have a chance. Unforturnately my documents are all written with epic 4.x, so I have the added adventure of using the arbortext flavor of the docbook dtd. I am slowly but surely getting started. Once I have a good xslt/fop build, I will start hacking the stylesheets to see if I can produce some presentable copy. I am early in the process, so I am still optimistic.<br /><br />I have been using the latest Oxygen XML editor (on the one month trial) and I must say I love it (but I don't know why). There are certainly some rough edges, but for xslt I find it to be pretty darn good (and yes it does let me transform docbook into pdf with minimum fuss). I would like to buy it, but I don't dare ask the boss for another toy... maybe I will buy a home license..dshttp://www.blogger.com/profile/03787168975353835632noreply@blogger.com0tag:blogger.com,1999:blog-10926245.post-1114975809065711272005-05-01T21:21:00.000+02:002005-05-01T21:30:09.066+02:00GOC programmingI did something I had not done in a couple of years this week, some good-old C programming (GOC). You might find this odd, but it is true. And me, a confirmed C hacker for years. Recently I had be obliged to do Java (which I like), C# which I like considerably less and lots and lots of JavaScript. You might laugh at my JavaScript hacking, but I did construct a large OO JavaScript scaffold that served me very well for a couple of years. There are cool things about JavaScript that you don't get with anything else (I like expando classes where you can just add a method to an existing object and everything works...<br /><br />Anyway this is about C programming. I have done a lot of C programming in my life and it is the one language where I consider that I could figure out what the compiler would do by looking at the source code. Imagine my embarassement when I wasted 15 minutes trying to figure out why my close() wasn't working (Compiler was really expecting fclose()). Oh well, it took me a while to get back into the swing of things, but I new I arrived when I coded:<br /><br />(*mylist)[(*nbmylist)++]->name = strdup(myname);<br /><br />It was here I rediscovered why I love C and I challenge python weenie to prove me wrong.dshttp://www.blogger.com/profile/03787168975353835632noreply@blogger.com0tag:blogger.com,1999:blog-10926245.post-1114112935236601482005-04-21T21:30:00.000+02:002005-04-21T21:54:44.673+02:00The Utility of UMLI think that any software developer likes to see the design of his system in UML just as any engineer might like to see the schematics of a system that he has designed (as opposed to just seeing the final package). For that last few years UML has been put forward as <em>the</em> way of expressing software design. Unfortunately, in the harried trenches, most people can not even understand UML, and often its utility is questioned. Personally I like UML, but mostly because a UML tool will give you a way to diagram a system without forcing you into the endless tweeking of diagrams that you often have to do when making them in word or visio.<br /><br />So you see, I like UML (and I have spent a lot of time and effort trying to apply it to my everyday work), but even I find it difficult to justify. And I have made zero effort trying to force my co-workers to understand it. Why is this? Is it because secretly I question its utility also. In fact I do question its utility for developing software systems. This week we were trying to come to grips with implementing in new and rather complex system. In terms of our normal project size, this is a good one - not so big that it can not be done, not so small as to be trivial. This for me is where UML comes in. Recently in <a href="http://www.acmqueue.com">Queue</a> there have been a series of articles on <em>UML fever</em> and how to get cured of it. The most profound statement of this set of articles for me was that you can use UML to explore the design space (and while doing so, learn how the software should be implemented), but you are still developing software, not UML diagrams. I must say I find this to be a revolutionary way of approaching a problem.<br /><br />I find that creating a quick UML project (I am using <a href="http://www.sparxsystems.com/">Enterprise Architect</a>) where I can define a set of requirements, hack up a few simple use cases with a scenario or two and then do a simple activity diagram or two allows us to have a concrete base to discuss the design. After this I will (rarely) hack up a few simple class diagrams, but more often than not, I just discuss the ideas with co-workers and we can then start the developement from notes on scraps of paper. The UML diagrams and notes are referenced but are never followed in detail. The thing is that the UML diagrams are just tools to explore the design space. I really don't think UML should be used to over-specify systems where the architechs create every object and every method and the developers just add the boilerplate. This is the way most tool venders feel that you should be using the tool. <br /><br />But then, have you ever <em>reverse engineered</em> class diagrams from existing code? The result, while it may be pretty and it may impress the boss, is actually <em>almost</em> useless.dshttp://www.blogger.com/profile/03787168975353835632noreply@blogger.com1tag:blogger.com,1999:blog-10926245.post-1112549531877533552005-04-03T19:14:00.000+02:002005-04-03T19:32:11.880+02:00Software QualityLast week I finished reading the QA issue of Queue magazine (for those of you who are ACM members or live in the US or Canada this is a great magazine and it's free - go to <a href="http://www.acmqueue.com">ACM Queue</a> and check it out). Anyway, the quality issue got me thinking about software quality. For me the main downside of having crappy software (and I have that) is that I have to spend more time in maintenance and on the phone with customers that I do hacking new code.<br /><br />Anyway reading the QA issue made me think of three main issues to investigate. First, is code coverage. We already try to do unit testing (and even unit testing before implementing the tested code) but I am affraid our test don't really address the real issues. I think code coverage would help us focus our testing effort. I went to the Clover .NET home page to check out a demo and was quite impressed (see the report screen shots at <a href="http://www.cenqua.com/clover.net/">Cenqua</a>). I have not had time to try it on our code, but I indend to do this my first free moment (I am writing some overdue system proposals right now - yuck).<br /><br />The next thing that I think is cool is code reviews. We are a small group so a code review is someone else reading code and signaling parts that suck. I have a good plugin for eclipse ( <a href="http://csdl.ics.hawaii.edu/Tools/Jupiter/">Jupiter</a>) but I need something for .NET. I found <a href="http://www.macadamian.com/products/codereview/">CodeReview</a> and it seems quite cool. I have a project where we have manditory code review, and I will be trying it out. I would just like something where we could annotate lines and have someone respond to the annotations. I think it will really improve the quality of the code.<br /><br />There is one final area that I think we can address quality issues. That is using the P4 report tool. This allows us to see the files and project in the SCM that have had the most activity. This should allow us to look at these places for bugs first. I think I have to move all my DHTML to P4 (from PVCS) as soon as possible...dshttp://www.blogger.com/profile/03787168975353835632noreply@blogger.com0tag:blogger.com,1999:blog-10926245.post-1111179991497916332005-03-18T21:45:00.000+01:002005-03-18T22:06:31.500+01:00C# Express and other stuffI downloaded and installed the C# express beta on my home development machine. First thing to note is that even on my old 400MHz hp (with 256M ram) I get acceptable performance from C# express. I was also able to install service pack 4 for win2k even though I am not connected to the internet. I did it with my 128MB USB key and the new winzip 9 where I can easily partition a big file into 128 MB chunks. The sneaker net lives!<br /><br />Unfortunately I was a bit disappointed with C# express. I tried to install the SQL server and even though I (think) it installed correctly I was unable to connect or create a new database... I did notice an error in the event log, but at is was just a long string of numbers, so I decided to ignore it. This was annoying, but the thing I found really disappointing is really the lack of features of C# express itself.<br /><br />My context is someone who uses eclipse quite a bit and netbeans a little. These are free products with what I consider to be very good features for the professional programmer. The best things are continuous compiling with clickable correction hints, refactoring and history. Since these products have captured a large portion of the developer mindshare, I was more or less convinced that the next version of VS was going to have to attempt to include these new features. My experiance with VS.NET 2003, had been mixed. It has a good debugger and adequant code completion, but thats where the list of features ends. The class "wizards" can barely be called that and there is not even support for managing translation resources (this is the first thing that made us question whether or not we could even use VS). Add to this, a brain-dead builder and you have an IDE that is "mostly useless", expensive and that can trash a machine just by installing it.<br /><br />With this in mind I approached C# express with hope. Perhaps they would have to mimic other popular IDE's and provide some real features. After using it for a couple of days I see why it is called a beta. No doc and I can't even find MSBUILD. This was the feature I installed the product for. Result, I don't think we will be upgrading the 2005 version of VS any time soon and certainly not for this price.dshttp://www.blogger.com/profile/03787168975353835632noreply@blogger.com0tag:blogger.com,1999:blog-10926245.post-1110472121445479642005-03-10T16:58:00.000+01:002005-03-10T17:28:41.453+01:00A Quiet Day at HomeThere is a big public service strike in France today. I was "forced" to take the day off and stay with this kids. Of course it is a crisis at work, so I was in (almost) constant touch with the office via phone and email. The boys were a bit wild this morning, but in the afternoon I exchanged a little boy for a girl and everything is much more quiet (even tib has found new maners since Valetine is here).<br /><br />Checked out some cool stuff today. I downloaded the .NET framework beta 2 and installed it on my development machine. No problems. I see there is the new MSBUILD delivered with it. This seems to be quite interesting. I would like to hack up a build script to build our current release (just to see if it is going to be good enough to replace our Nant builds). I don't mind Nant (and I like Ant), but it is a bit rough around the edges sometimes and I don't know how actively it is being developed. I have the impression that it is hard to gain any mindshare in the Microsoft world, because if people start to use your product Microsoft will deliver a clone of it just to wipe you off the face of the earth. I fear that MSBUILD is going to do this to Nant. On the other hand, Nant exists because VS.2003's build infrastructure basically sucks. I think it is completely, totally, 100% useless (and I mean that in the nicest way possible).<br /><br />I was hoping for anoymous inner classes in the .NET framework version 2, but I notice they just have anoymous methods. These methods would be able to be used anywhere a delegate would be used. I find this sucks a bit, since I don't really think delegate are such a good idea. When will Microsoft enter the Object Oriented world and give up on function pointers! I was planning on using anoymous inner classes to implement interfaces, but this seems to not be possible (I will have to look further and perhaps think a bit).<br /><br />I might try to install VS C# express to see if it is as good as VS 2003 (which I think sucks). This would allow me to get rid of VS from my work machine.<br /><br />I spent a good part of the afternoon writing a proposal using arbortext's Epic editor. Maybe I just hate Microsoft, but I do find this editor to be sweet. I wrote my last two proposals with MS word and I planted far too often (I even sent the client a crashed version of some installation documentation, that was missing the last 3 pages - after this event, which resulted in a 2 day misunderstanding on how to install the product - I vowed never to use word again). As an aside, I have installed open office on my development machine and it seemed to handle my word documents okay. It even gives me our custom styles, I was quite surprised. I did use OO on linux about 6 months ago - and I did have a few problems, so I am not really ready to switch to OO yet. I have epic and it is a great editor, so I don't really need to look further.<br /><br />Finally, I had another problem with XML encoding. This is got to be the most annoying problem we have ever had. That is the '&', '>' and '<' characters in XML streams. I think the current problem was that we have an encoded xml stream that is read by a filter that is suppose to extract some information and re-stream the xml. Unfortunately it removes the encoding and streams the pure text. Will we ever get this right? Between that and the character encoding (i.e. iso-8859-1, UTF-8 and unicode) I don't think that XML is that easy after all!dshttp://www.blogger.com/profile/03787168975353835632noreply@blogger.com0tag:blogger.com,1999:blog-10926245.post-1109958028556431652005-03-04T18:28:00.000+01:002005-03-04T18:40:28.556+01:00End of another weekWell, this has been an eventful week, even if I did not get many lines of code done. Five days in Prague was a bit much. It is a beautiful city and I drank my share of beer and I love the food, but after only 3 days of conference, I'm all bentleyed out. Not much interesting at the conference (which is a bit of a surprise when you consider that 4 months ago they were talking about a looming MS pre-release in Feb/March).<br /><br />The other big news is the weather. In Prague everything was good, -7 to -12, a bit of snow and everyone knows how to live with it (it was a bit cool for a stroll on the bridge in my little jacket, but like any canadian - I'm tough, I can take it). But getting back to Paris, was a mess. Snow, slush, crappy roads, slick summer tires and bozos everywhere. In the end, I left my car at the office and came home on the train. Then I did the two ways to the in-laws to pick up the boys (a seven hour stroll across half of france).<br /><br />In business, we talked seriously to two groups. First the holland group that manages the web application. I can see they are going to suffer with this "what do we do for clients who want to use linux/firefox or macintosh/safari" question. I am not dedicated to serving these clients, but if we abandon them, I would prefer to do it with our eyes wide open.<br /><br />The second group was a german organization that we may be able to cooperate with. Given the size of our two companies, a shared source solution might make a lot of sense. I don't know if we have the technical and legal savey to pull it off however.dshttp://www.blogger.com/profile/03787168975353835632noreply@blogger.com0tag:blogger.com,1999:blog-10926245.post-1109363383437812922005-02-25T21:09:00.000+01:002005-02-25T21:29:43.440+01:00Good week for codingLots of interesting stuff seems to have happened this week for coding. First we (basically) finished two major product releases. This allowed us to implement a couple of really neat tools. First, I have worked out a way of creating a CHM out of an XML extraction from the issue tracking system. This cuts a lot of time off creating release notes and the results are pretty good. I would like to be able to create a PDF from the CHM, but the products I have previewed seem to mostly suck. Maybe if I create a chunked HTML document we could use Acrobat to create the equivalent document, hmmm...<br /><br />Started using the new SCM to manage the code lines. This is a vast improvement over the previous system (which produced branch lines that were entirely imposible to manage). Yesterday I created a major product release branch without a hitch. This will revolutionize the way be maintain our code. I can hardly wait to use it for our other my web product. It should allow me to reorganize the code base as well as making it a lot easier to rebuild and fix released versions. Up until now it had be a task only for the few gurus who would bother... mostly we would just try to install the lastest version and fix bugs there.<br /><br />Got Eclipse 3.1M5 yesterday. I am very excited about the improved SWT drawing methods. This was the only thing that was missing to replacing my existing fat web client with an Eclipse RPC application. I see only advantages. I will have to try a code spike of drawing a VVF file to see if the performance is up to snuff or not (normally it should be, since it is a thin wrapper over the windows API, performance should not be a problem).<br /><br />Did a lot of C# hacking today. Tried to apply some of the principals that I have been reading about in Holub. The more we think about what he has to say, the more (I think) it revolutionizes our coding practices. The only question is, will our code be better or worse... I suppose only time will tell. I think the idea of putting the Describe method in the IStorable interface will really change the way we think about interacting with our objects. This is the smartest thing that we have done on this code iteration (and we have done a lot of thinking about how to clean up our implementations). We hacked out a lot of lines of code today. I feel good about it for a change (even if it was C#).<br /><br />Have to leave to the geo user conf tomorrow in Prague. It will be nice to visit the city (and drink a bit of beer), but I wonder what I am going to do there...dshttp://www.blogger.com/profile/03787168975353835632noreply@blogger.com0tag:blogger.com,1999:blog-10926245.post-1108755652905624002005-02-18T20:39:00.000+01:002005-02-18T20:40:52.906+01:00First Blog EntryWell I think I am going to start to publish a blog. This is only a test entry. I hope someday I will have something useful to say.dshttp://www.blogger.com/profile/03787168975353835632noreply@blogger.com0