Contents tagged with English
-
GhostDoc News
Development of GhostDoc is moving slowly, but steadily towards version 1.3.0, which will be the first release since October (wow, incredible how time flies by). So what has happened since the last GhostDoc News on this blog back in January? Looking from the outside, not much. If you remember the screenshot published back then, “all I did” was add the rule configuration tree to the configuration dialog and make all the buttons work:
Editing the settings of a rule looks something like this:
Behind the scenes, things have been far more complicated and time-consuming than expected. But the good news is that editing/exporting/importing the configuration (of rules and everything else) is pretty much finished.
So what’s the big deal about moving some configuration data around? I won’t go too much into detail, but simply imagine two computers A and B runnning GhostDoc (e.g. at home and at work) and you change some settings of a rule on A, change the priority of another (or maybe the same) rule on B. Then add some rules on A, remove some rules on B, and of course all these changes happened days after the last time you synced both computers. There are many opportunities to fry the user’s configuration data and while a fully automatic synchronization simply wasn’t possible, even just asking the user what to do (and then frying his/her data — nah, just kidding) already took a huge effort.
So what are the next steps? I’ll now write new text generation rules to solve some of the most often reported issues (e.g. “On…” methods) and the user defined rules mentioned in the January post. That will be pretty much the feature set for 1.3.0. Other ideas I have been playing around with will have to wait until 1.4.0 or later.
Visual Studio Beta 2
As people have been asking: Yes, I’ll look into releasing a version of 1.3.0 for Visual Studio 2005 Beta 2. There will not be a port of 1.2.1, though.
Other News
- I saw that GhostDoc is mentioned on the Microsoft Visual C# Developer Center — nice.
- There’s a new section on the GhostDoc home page, the “GhostDoc Hall of Shame” showing some of the more obscure results of the text generation. If you have weird/funny/sad/unexpected results, don’t hesitate to drop me a line.
-
My Copy of "Visual Studio Hacks" Has Arrived
I’ve received my free copy of Visual Studio Hacks by James Avery which I got for contributing hack #69 “Create comments faster” (page 280 – 285). These pages contain an introduction to – you may have guessed it – GhostDoc. After reading my part (of course ;-) I took a quick look at the rest of the book and I must say the first impression is really good. Obviously, after reading only a few pages, it’s too early for me to give a final verdict, so I’ll leave that for a later blog post.
A nice surprise for me is that my original text wasn’t edited that much (I wasn’t really sure what to expect, as English isn’t my primary language).
-
A GhostDoc Feature I Will Not Implement
I’ve received a number of requests for a new GhostDoc feature for documenting a whole source file at once. This feature is filed as item #45 in my issue tracking system, and its status is “rejected”.
The texts generated by GhostDoc are suggestions generated by some stupid code that breaks identifiers into separate words and juggles them around. Each and every text generated by GhostDoc has to be checked by the developer, and should be revised by the developer if necessary. Depending on your coding style, the time required for checking and revising the generated text usually is less than writing everything from scratch, i.e. using GhostDoc saves you time.
So that’s the idea: GhostDoc guesses some documentation text, you check the results, and in the end you’ve saved some time.
I’m pretty sure that many of us know at least one “motivationally challenged” developer who is very likely to skip the part where you actually have to use your own brain. If such a person has to document a class member by member, there’s at least a little chance that he/she will notice texts that are just too stupid (e.g. such classics like “Toes the string.” and “Ons the click”). But can you imagine the same person given the feature of running GhostDoc on a whole source file at once? DailyWTF, anyone?
-
Why throwing an exception should be the exception
Alex writes about the impact of throwing an exception on performance and that it may not be as bad as one may assume. In the comments, people write that using exceptions for flow control is not the Right Thing to do.
Here’s my #1 reason why throwing an exception for flow control is definitely not a good idea: Debugging. When I’m debugging and I’ve set the debugger to “break on CLR exceptions” (and no, I don’t want to get more specific when I switch that option on and off dozens of times per day), I don’t want code execution to halt over and over again until I get to the actual problem.
It’s bad enough if some exceptions in non-exceptional situations cannot be avoided — I don’t need to introduce them in my own code.
-
Sound Forge 8.0 Scripting
One of my other hobbies besides developing software is audio editing. Working with Sound Forge for a couple of years now, I just upgraded to Sound Forge 8.0. Scripting is one of the new features and while it has a certain “version 1.0” feeling to it, it’s nice to see the preferred choice of “scripting language”:
-
LastBoxStanding 0.9.1 (bugfix release)
-
LastBoxStanding 0.9.0
Summary: LastBoxStanding is a Windows service that pings a configurable list of machines in your LAN to determine whether at least one of them is still running. If no machine responds, the service performs a custom action, e.g. a shutdown.
Some time ago I built a server for my LAN from old parts (e.g. a P2B mainboard with a PII 400 and some RAM I had in a drawer). I use it for storing backup images and running SourceGear Vault (source control) and Dragnet (bug tracking) mainly used for my GhostDoc project. The server is not connected to a monitor and it’s really quiet (thanks to some hard-core silent modding), so it’s not uncommon that I simply forget to shut it down before going to bed. That usually means that the server keeps running until I come back from work the next evening – what a waste of electricity.
I solved the problem by writing a Windows service to shut down the server automatically when it’s no longer needed, which is defined as when no other potential client on the LAN is running. The current version of LastBoxStanding can be configured to call any executable when the computer running the service is “the last box standing”.
You can download the most recent version on the LastBoxStanding homepage.
Update: Unfortunately, a small issue with 0.9.0 was found. If you set the check interval on your server to say 5 minutes, (re)start the service and then switch off all other machines on the LAN, LastBoxStanding does not perform the shutdown (or any other action you have configured). This is because the service has to reach at least one of the configured clients once and – this is the problem – the first check is not performed when the service starts, but after the (timer) interval has elapsed. If at that time none of the machines can be reached, LastBoxStanding assumes that the server is running standalone (e.g. for maintenance) where you don’t want the automatic shutdown.
Even if this issue does not affect usage in “Real Life” that much, it’s a huge problem if people download LastBoxStanding and want to try it out. I’ll look into providing a fix this evening when I get back from work.
-
GhostDoc in Upcoming Book "Visual Studio Hacks" by James Avery
Ok, now that the book “Visual Studio Hacks” by James Avery has been announced officially, I’m finally allowed to talk about my (small) contribution to the book: My Visual Studio add-in GhostDoc is one of the “hacks”.
Shortly after GhostDoc won Roy Osherove’s Add-In contest in August 2004, James contacted me to write a quick run-down on using GhostDoc. He couldn’t offer any money (if you wonder why, you should read this), but hey – a few hours work for a free book isn’t too bad ;-)
Let’s see what the editors at O’Reilly thought of my English writing skills (or lack thereof?) and what’s left of my original text…
-
Raising C# events doesn't feel right (and seems to have problems too)
[This blog post was inspired by reading “Events, Delegate and Multithreading” by Brad Abrams.]
I'm pretty sure the language designers thought about the whole thing way longer than I did, but from the very beginning raising events simply didn't "feel right". I’m not talking about the pattern of using “On…” methods — while that was something I (with an extensive Javascript background) had to get used to, it was a typical case of “what? whose idea was that? hmm, that’s not so dumb after all… hey, good idea!”.
No, it’s the way of actually raising the event inside the “On…” method. In the blog post mention above Eric Gunnerson is quoted “We have talked about adding an Invoke() keyword to the language to make this easier, but after a fair bit of discussion, we decided that we couldn't do the right thing all the time, so we elected not to do anything”. Well, but that’s exactly what I’m missing: a keyword. While I don’t miss much from VB6 (ok, maybe the command window), I really miss the good ol’ RaiseEvent.
When you look at source code, keywords are something that catch your eye. While you are bombarded with lots and lots of words (names of classes, variables, methods, etc. ), keywords like “delegate”, “event”, “throw”, “override” (man, I’m thankful for that one!) stand out — not only because of the coloring inside the editor, but also because of the different syntax compared to lines and lines of “variable = Method(parameter)”.
For example throwing an exception:
throw new FooException("bar");
It says “throw” and you can virtually see some referees throwing a yellow flag.
If I declare a delegate “FooHandler” and an event "Foo"
public delegate void FooHandler(object sender, FooArgs e);
public event FooHandler Foo;then one can argue the overall approach (is it too complicated yes/no?), but nevertheless it’s quite clear what the code is trying to tell me: This is a delegate, and this is an event, and there seems to be some connection between those two (because FooHandler appears in both).
But then comes the big letdown: the code for raising the event. Until recently I would have used
protected virtual void OnFoo(FooArgs e)
{
if (Foo != null)
Foo(this, e);
}Now I’ve read the recommendation to use
protected virtual void OnFoo(FooArgs e)
{
FooHandler handler = Foo;
if (handler != null)
handler(this, e);
}Sorry, but this doesn’t survive my personal test for “is the important stuff easily discoverable”: Step back from the monitor, squint your eyes until things look kind of blurry, and then collect all information you can get from what you see with a quick look. For fun, try it with the code example. While “throw new blah blah” and “public event blah blah blah” give you a rough idea of what’s happening, you have to look again to find out what “protected virtual blah handler handler blah handler null blah this” is all about. To avoid misunderstandings: This is not about understanding a programming language without learning it. What I’m talking about is browsing code really fast, looking at each line only fractions of a second, and not actually thinking about the code, but just matching some basic patterns inside your brain — stuff we’re all doing automatically when scrolling up and down while editing text.
Ok, this post is longer than it should be, so let’s cut this whole thing short and get to the point:
Comparing raising an event with the way how to throw an exception, and keeping in mind that the official wording (according to the Design Guidelines for Class Library Developers) is that exceptions are "thrown" and events are "raised", I would personally prefer:
protected virtual void OnFoo(FooArgs e)
{
raise Foo(this, e);
}What should the “raise” keyword do internally? Let me play the role of the unfair customer here: I don’t care, just make it work. I want to raise an event and that should work without the danger of a race condition or whatever.
-
GhostDoc News
As mentioned on the GhostDoc homepage (which I use for the smaller status reports that also contain more private stuff), I’m back working on version 1.3.0. Since Christmas I have managed to spend a good amount of time on GhostDoc, but things are not progressing as fast as I had hoped. There are a couple of tough problems to solve that come with one of the major goals for 1.3.0: User-defined rules.
In addition to user-customizable rules as mentioned in a previous post, it will be possible to define new rules by specifying regular expressions for matching e.g. method signatures, and templates containing macros for generating documentation texts. This may not be as flexible as writing new rules in C# code (which will have to wait until the framework has been stabilized), but there’s a lot that can be done with this simple solution.
Things like upgrading from earlier versions (without losing customizations) and synchronizing configuration files between installations e.g. at home and at work turn out to be pretty tricky even though these topics already have been addressed in previous versions. Right now I’m busy refactoring and extending the code for reading/writing/importing/upgrading/merging configuration files, and hey — my existing unit tests actually caught a couple of nasty bugs and thus saved me a lot of time!
To finish this post, here’s a screenshot showing the rule configuration tree (no new rules shown here, though):
I’m far away from any release, which in turn is a chance for your suggestions and feature requests to be included in 1.3.0. Simply drop me a line in an email (ghostdoc at roland-weigelt.de).