Debugging the problem that never was
I just spend ~3 hours trying to find out why my error reporting system doesn't work. The situation was simple, I wanted to have a tree view that display the structure of an XML document, and show an error icon if there are any schema errors. The idea was that the error would propogate up, so an error in any child would show in the parent, and the grandparent, etc.
But I couldn't get that to work. I debugged it endlessly, I made a lot of changes (some of them were even neccesary :-) ) in order to find out what the problem was. In the end, I verified that it work if I'm changing the text of the TreeNode it does propogate up. But it didn't work if I was using the icons.
Then I did something very simple, I moved the selection from the root to the second node, and the icon has changed! Apperantly the problem was that if you define an ImageList for a tree, you get 1+1, a selected image. That was my problem, both the selected image and the okay image were the same, and that was what was causing the whole problem.
It get weirder, you can't disable the SelectedImageIndex, and I'm not sure if this is the framework fault or VS.Net. I ended up with a SetImageIndex() method that set for both of them at once. Yuck!
ISmartDisposable
[Update: I create a ladybug suggestion for this, go vote for it]
I made some checking after this, by I seems that there isn't any way to tell whatever an exception occured when you're in a finally block. This is stupid, there are plenty of use cases where this is needed. Consider transactions, for instance:
{
// Do work with the transaction
transaction.Commit();
}
Because when you're in the Transaction.Dispose() there is not way to know if an exception was thrown or not, you must call the transaction.Commit() so it would know what to do. This is very easy to forget and can cause problems because the code look correct.
I suggest a new interface:
{
void Dipose(Exception exception);
}
And the previous using statement (without the transaction.Commit() ) would expand into something like this:
ISmartDispose sd = transaction as ISmartDispose;
Exception exception = null;
try
{
// do work
}
catch(Exception ex)
{
exception = ex;
}
finally
{
if (sd != null)//this line is s bug, removed
sd.Dispose(exception);
}
Now the transaction knows whatever an exception occured or not and can commit/rollback properly. In the case of an object that implements IDisposable, the using statement should just fall back to the current behavior.
This is not just limited to transactions, and disposable object that need to know if an exception was raise can benefit from this. Rhino Mocks' MockRepsitory currently raise exceptions when the problem is locate elsewhere if an exception was raised by something other than the framework.
Considerring that this is merely a compiler constrcut, I'm thinking about implementing it in Boo.
Rhino Mocks 2.0.7
Rhino Mocks 2.0.7 is mainly a bug fix for method orderring bug, but it also present a better package in that that you no longer has to have Castle.DynamicProxy.dll with the Rhino.Mocks.dll
No, I didn't implemented my own IL generator, I simply used ILMerge and the results are very satisfying. I'm thinking about doing the same for Brail (which comes with several dlls) but this cause tests to fail, and I didn't have the time to find out what the problem was.
A simple way to avoid repeated questions in forums
Check out this post by Lee, it show a very simple way that can reduce the amount of repeated questions in forums / bug tracking / support systems.
This should be very simple to implement and over time should truly reduce the amount of novice questions. Like all good ideas, it's actually a very simple one (with corresponding simple implementation).
Check the screenshot.
NHibernate Query Analyzer progress
After quite some time ( about two weeks ), I got started again with NQA, this time I'm concentrating on just getting the GUI for the hbm.xml editor done so I can ship the bloody thing already. It has been 6 months from the last release and that is certainly long enough.
The next version of Brail
I've purposed a couple of changes to the Boo's parser, which - if accepted - would make for a much better experiance in using Brail. But if not, I've been reminded that I can just fork the parser alone, and create a Brail parser which could do more crazy things to the langauge to make it easier to work on the web.
Currently I want to enable the use of raw string (and string interpolation) in the scripts, and perhaps also enable the <% %> syntax that should be familiar to everyone by now.
Proposal: Implementing contracts in Boo
(This is a suggestion I'm making for the Boo's mailing list, about a proposed syntax for Eiffel's like contracts for Boo)
[This proposal require inherited Ast attributes, which provides some challanges in the implementation. More on this in a moment.]
The idea is to allow to use attribute markup to create pre & post conditions for a method. Here are the sematics or this proposal:
- Pre conditions apply to the current method and all the method that override it:
- Considerring that difficulities in checking in compile time that a class accept equal to or wider range of parameters (rather than a narrow range) I don't think that this practical.
- It's not hard to implement this check in run time where you can ensure that if the base method pre condition has passed then the method must accept it or violate its contract. So this what this proposal does. An exception (with very silly name) is raise if a parent's base condition is satisfied but the child condition has failed.
- Post conditions apply to the current method and all the methods that override it:
- Again, statically checking the correctness of the post condition is prohibitive, and much simpler to do on run time.
- Post conditions are stacked, and a post condition that allows something that the base method wouldn't allow will cause a contract exception
Without further ado, here is the proposed code and the final translation (see more comments about the implementation below):
public class ClassWithContract:
#post & pre are Inherited AstAttributes
[post(PerformComplexVerification(result))]
virtual def FirstMethod([pre(foo.Property == "object")]foo as someType) as anotherType:
return DoWork(arg)
public class DerivedClassWithNoOverridingContract(ClassWithContract):
override def FirstMethod(foo as someType) as anotherType:
return DoDerivedWork()
public class DerivedClassOverrideContract(ClassWithContract):
[post(PerformValidationForDerived(result)]
override def FirstMethod([pre(foo.Property is not null)] foo as someType) as anotherType:
return DoDerivedWork2()
The above would be translated into the following:
public class ClassWithContract:
protected virtual def post_FirstMethod(result as anotherType) as bool:
return PerformComplexVeriication(result)
# the syntax for this is pre_<method name>_<arguments>_<arguments this method check>
# this is done in order to handle overloading
protected virtual def pre_FirstMethod_someType_arg(foo as someType) as bool:
return foo == "object"
# this attribute is check by the ocmpiler and if found it will invoke the specified
# attribute on any overloading method and then apply to it the same AST attribute
[InheritorUseAstAttribute("Boo.Lang.Useful.PostAttribute, Boo.Lang.Useful")]
[InheritorUseAstAttribute("Boo.Lang.Useful.PreAttribute, Boo.Lang.Useful")]
virtual def FirstMethod(arg as someType) as anotherType:
raise PreConditionFailedException("arg") if not pre_FirstMethod_someType_arg(arg)
__result = DoWork(arg) raise PostConditionFailedException() if not post_FirstMethod(__result)
return __result
public class DerivedClassWithNoOverridingContract(ClassWithContract):
# pre condition of base method is enforced
# post condition is enforced
# this doesn't have any special pre/post condtions of its own
override def FirstMethod(foo as someType) as anotherType:
raise PreConditionFailedException("arg") if not pre_FirstMethod_someType_arg(arg)
__result = DoDerivedWork()
raise PostConditionFailedException() if not post_FirstMethod(__result)
return __result
public class DerivedClassOverrideContract(ClassWithContract):
# override the parent post condition and then call it:
protected override def post_FirstMethod(result as anotherType) as bool:
currentCondition = PerformComplexVeriication(result)
baseCondition = super(result)
raise ContractViolationChildDontAcceptSuperDoesException() if currntCondition and not baseCondition
return currentCondition
protected override def pre_FirstMethod_someType_arg(foo as someType) as bool:
baseCondition = super(foo)
currentCondition = foo .Property is not null
# need to work on the name of this exception :-)
raise ContractViolationChildDontAcceptSuperDoesException() if baseCondition and not currentCondition
return currentCondition
[InheritorUseAstAttribute("Boo.Lang.Useful.PostAttribute, Boo.Lang.Useful")]
[InheritorUseAstAttribute("Boo.Lang.Useful.PreAttribute, Boo.Lang.Useful")]
override def FirstMethod(foo as someType) as anotherType:
raise PreConditionFailedException("arg") if not pre_FirstMethod_someType_arg(arg)
__result = DoDerivedWork2()
raise PostConditionFailedException() if not post_FirstMethod(__result)
return __result
A few comments about the proposal:
- Adding a class invariant would be a very simple matter if we take this approach
- Setting a contract for an interface may be problematic, since there is no place to put the methods, in this case I propose that a utility class will be created and used by all the classes that implement the interface.
- What happen when a post/pre condition raise an exception?
- I don't like the idea of easing the limitation, or of not implementing the contract exception. The reasoning is very simple, right now a post / pre condition need to takes into account each and every parent's condition. I suggest that we would simply stack them together, and if any fail the Pre/Post condition exception would be raised, without checking for the correctness of the contract.
- How do you debug this?
- How do you get the contract from a compiled dll so you would know what it is? Do we rely on documentation or should we live something in the IL to be read later?
What is needed to implement this?
Not much, actually :-) which is very good. I played with my mind a little with this and this is what is needed to create this proposal:
- An abstract attribute (AbstractInheritedAstAttribute) that inherit from AbstractAstAttribute that will handle inheritance to overriding methods (or derived class, if we wants class invariants as well). This attribute will "tag" any method/class that it is used upon with a normal attribute (in the sample InheritorUseAstAttributeAttribute which will have the full type name of the Ast attribute.
- Adding a compiler step that will process any method/class that has this attribute in their parentage chain and call the Ast attribute on the current memeber.
[This is a rough draft that was mainly formulate during IRC discussion early this morning.]
Exception Information From Finally?
I've a problem in a Dispose() routine, the problem is that I need to know if I got to the Dispose() as a part of normal execution or if I got there because of an exception in a using() block.
I know that it has been tried before for transactions, but I don't know if there has been any success there. Here is what I'm trying to achieve:
IDisposable dispoable = new MocksRepository();
try
{
throw new Exception();
}
finally
{
if (/*an exception occured*/)
return;
disposable.Dispose()
}
Sick with #Develop
[Update 31/07/2005 19:08: Fixed the name of the boo bindings for #Develop' author, sorry for the mixup.]
I'm getting sick of SharpDevelop, it can't handle even basic IDE stuff correctly. I'm not talking about rocket science here, I'm talking about basic functionality like moving files from one folder to the other, adding a folder and renaming it, drag & drop of project files to open the project and not the file's text etc.
The single saving grace for #Develop is that it has boo integration, which mean that I can get IntelliSense that mostly work. But when I need to quit the IDE and modify by hand the project file every time I want to add a directory... that is more than enough. I tested #Develop several times in the past. My final conclusion is that about the only mature part of this software is the text editor (and even that is missing basic functionality like word wrapping [notepad has it, for crying out loud]). It has gotten to the point where I currently can't compile Brail using SharpDevelop while it compiles cleanly using NAnt (and no, I didn't had things in NAnt that I didn't have in #Develop)!
I was chatting with a friend and he sent me this screen shot from XDevelop, check out their site, the demo in their site looks very good:
Do you the little green vees? Those are passing tests, and there are plenty more functionality where this came from (refactoring, code browsing, etc).
This is not freeware, and it doesn't support Boo, so I'm going to pass on it for now (although not forever!) and see what JetBrains has to offer with their .Net 2.0 IDE. Daniel Grunwald wrote the boo integration for #Develop. Arron has started a similar project for VS.Net (which is now on hold because of the VS Extensibility team stupidity) and he has plans to write an integration package for Boo. I already talked with JetBrains and they stated that not only will the IDE be open for extensibility, but you would get all the goodies regardless of the langauge. This is something that I would have too see to believe, but it's certainly better than what #Develop offers.
Currently I'm digging into jEdit with Boo syntax coloring and some nice plugins, here is my current work:
Notice that the syntax for Boo is nearly identical for the one used by VS.Net for C#. Do you see at the bottom the bulid script? Propertly syntaxed? It's not an IDE, but it's close enough, and it's certainly more stable than #Develop
Rhino Mocks 2.0.6
Okay, this release is actually an interesting one. The problem it solves is running Rhino Mocks on the .Net 2.0 Framework.
Somewhere deep in the bowels of Rhino Mocks, there is a method that return a default value for method that are called during the recording phase, it looks like this:
public
static object DefaultValue(Type type){
if (type.IsValueType == false)
return null;
return Activator.CreateInstance(type);
}
The problem was what would happen when you get a void type [ typeof(void) ]. On .Net 1.0 and 1.1 this just worked, and you actually got a System.Void instance that you could play with. On .Net 2.0, you get a not supported exception, which seems reasonable, except that it breaks my code and that is not reasonable :-)
Anyway, on a hunch, I modify the code to do this:
public static object DefaultValue(Type type)
{
if (type.IsValueType == false || type==typeof(void))
return null;
return Activator.CreateInstance(type);
}
And now it's working. And no, methods with void return type won't start to return nulls all over the place. Dyamic Proxy handles it, acutally. It simply discard any return value from the interceptor for a method with a void return value, so everything is happy again.
I'm currently installing .Net 2.0 and I'll give Rhino Mocks a twirl using C# 2.0, and see if all the tests pass on it. What do you think should change to accomodate 2.0 beyond the obvious:
Finished upgrading to DasBlog 1.8 RC1
Okay, I've finished upgrading to the new version of DasBlog. Unfortantely, I overwrote the site configuration and web.config files with the default ones, which broke the site for a short while. I've fixed it all and made some minor CSS adjusments that will make my life easier (change administrator menu location and style).
I hope that this will help reduce the spam, and at the very list this gives me a way to remove it :-D
New Version Of DasBlog
DasBlog 1.8 RC1 is out, and the feature list is very impressive.
The one thing I really want is the ability to remove trackbacks, which means that I will be able to remove the annoying spam from my old entries. Right now I can't do that since there is no interface for that and I would rather not edit the raw files.
The new spam features should really make a defense in depth against spam when combining them with ReverseDOS :-)
There are also a lot of new themes, but not mine, sadly.
[As an aside, nothing beats SmartFTP as an ftp client, I just told it to download my blog (for back up & upgrade purposes) using threads. I downloaded the whole thing (~20Mb, 1654 files) in about two minutes. With any other client I tried, I would've to wait for half an hour as it would process the files one by one.]
Brail 1.0.2
I released another version of Brail today:
- I added the ability to use sub views (NVelocity's #prase() ).
- I am now signing the assemblies.
- Added a lot of comments :-)
Phantom - The new Sword Of Truth Book
It seems that Amazon has puslished the info about a new Sword of Truth novel! Should be out in January, and the blurb seems cool.
This is the second in a trilogy, so there is one another after it to wait for.
Rhino Mocks 2.0.5
I'm now signing the assemblies, so you could use them in trusted environments.
Made some modifications to the build script as well, to add testing to the build process and to sign the assemblies.
Get it here: http://www.ayende.com/projects/rhino-mocks/downloads.aspx
About the Windows Vista beta 1 review
I just finished reading the Windows Vista Beta 1 Review on WinSuperSite, most of the stuff there was more or less expected, but there was one thing that made me go "Wow! Why didn't I think about it?"
Editable bread crumbs, check out the picture:
I can think of so much uses for this right now...
Beyond that, it seems that Vista is looking good for a (much delayed) beta 1.
Self Portrait
Here is a new picture of myself. I also updated the About Me section on the site.
Ayende's Google
Windows Grep
When I wanted to change Boo On Rails to Brail I needed some utility to do all those text replacements for me. I don't trust Windows Search, and while MSN Desktop Search is cool, it's not suited for search & replace job (and I forgot to tell it to index .boo files, so it didn't help anyway).
I thought about grep, and sent out to find a windows version. I found many ports, but none that seems to fit what I wanted (a simple recursive find in all files), then I found Windows Grep. This is one powerful package with really nice GUI. It allows you do regex search & replace on multiply files, which is really nice, and there are no arcane commands to remember.
On thing to note, don't use the Basic interface, as this is something that is taken from the Windows 3.11 days, use the Expert mode, and you'll get a modern UI.
Movie Review: Star Wars 1-6
To celebrate my newfound freedom I've had a two days marathon of the six Star Wars movies. I've never seen the recent batch, and the last time I saw the old Star Wars movies was when I was ~11.
I was certainly entertained, but I don't understand all the big noise around it. The plot normal SciFi one, designed to show off as many special effects as possible. Some of the things in the movies that really bothered me are:
- Blatant disregard of the laws of physics - I'm not talking about what they are doing with the Force, I'm talking about ignoring such things as gravity and failing to explain how this is done.
- Being a Jedi sucks - You get a cool weapon, a sucky job and you are not allowed to form attachments. Sorry, this doesn't work on a large scale if you are dealing with sentient beings. In addition to that, considering that the Force is supposed to be inherited trait, forbidding the Jedi from marrying & having children would cull the ability out.
- Androids are just plain weird - I can accept a robot that has emotions, Asimov did it very successfully. What I can't accept is a robot that show fear of pain, can't create a decent backup to save its life and in general acts like a human in a steel skin.
- Anakin's virgin birth - Yuck! Did they have to put that stuff there?
- Holes in the plot you can drive the Entreprise through.
The special effects are spectaculars, and the way the renewed the original movies is amazing, the only visible difference is that the battles' choreography, which is much reduced in the original movies.
All in all, what was all that noise about?
ReverseDOS 2.8
I just setup ReverseDOS 2.8 on my site, it has a vastly simpler configuration. This is the simplest solution I've seen to protecting the site from spammers, both to install and to use.
Leave to live by no man's leave
[The title of this post is taken from a poem by Kipling The Old Issue.]
I've alluded in the past for a Big Day coming. It had come today!
Today, 28/07/2005 @ 11:03 AM I was released from the IDF after four years of service.
This was one hell of a good day, to say the least. I'm now officially a mere citizen of Israel. The last four years have been... interesting.
I have served exclusively in military prisons, starting as a warder in Prison 6, which is a prison for holding IDF soldiers. The work load was crazy (19 hours a day was the norm) and the work wasn't fun. I met a lot of people that I wouldn't have met otherwise, I got to help to some of them, had two separate attempts by drug dealers (two different ones) to have a contract (the fatal kind) on me. I got a lot of people skill (mostly by necessity) and an aversion to Noblesse, which is the cigarette that the prisoners smoke.
Then I went for officers training and had the time of my life during Bahad 1 (the training base for officers in the IDF). I had a lot of really good people with me and I got to work on interesting problems (mostly unrelated to what I would do, but it's good to know that I can conquer the mountain if I have to.).
Afterward it was a post in the biggest prison in the Middle East. This time it was a prison for Palestinians terrorists, the place is called Qteziot, but most of the foreign media call it Ansar 3. I was quite shock to find out just how many horror stories there are about the prison on the net (most of it is wrong in so many levels I couldn't formulate a rebuttal even if I was allowed to).
The first thing I did when I got to Qteziot was to get personally acquainted with each of the ~500 prisoners that I was in charge of, which is something that I truly never want to do again. As a plain soldier I always thought that officers had the easy life, since they didn't deal with all the boring / ugly / annoying stuff, but for the first six months as an officer I worked much harder then I ever worked as a soldier. I had a lot of fun, and it was a good place to be in. The prison had just started to get established and I was able to influence quite a bit there (in fact, I designed the prison's logo, which caused a redesign in the logos of all the military prisons in Israel :-D ).
I served there just under two years, first as a Company Commander's Second (probably bad translation of the term), then as the prison's Operations Officer. I was also in charge of (the literal translation is Escorts Officer, which sound just as bad in Hebrew as it is in English) of securely transporting terrorists to courts, hospitals and other prisons. Near the end I was the prison's Instruction Officer, which allowed me to create some spectacularly bad Power Point presentations and some really cool movies ( in Windows Movie Maker, no less :-) ). At that point I was getting sick of the prison, there were quite a few personal changes, and I didn't like the atmosphere in the place so I had a stint in instruction soldiers fresh off Basic Training for about a month.
My new position was a prison's commander near Jenin. It is a small prison, which means that I was in charge of pretty much everything. The good side was that I was free to do mostly as I pleased, but the flip side was that I also had to handle a lot of the routine stuff myself. I'm not sure if it's good or bad that I couldn't blog about that time. Although what I'd to say would be of interest to very few. Nevertheless, it would have felt better to tell someone all those strange stories. Take for example the mess that crazy inmate in cell #3 did when he set fire to the cell because he wanted a bottle of coke (the drink, not the drug), or what happened when the transport to the asylum got to a completely different prison. Oh the other hand, maybe it's better that I didn't post those things, they are mostly insider's jokes. And I don't suppose that anyone who read this blog has spend any time working at a prison.
During the time I was in the army I had to deal with the strangest situations. What do you do when a soldier hands you a live scorpion as a parting gift, for instance? That is not something that Miss Manners ever covered, I bet. :-)
Four years have passed, I'm now a part of the reserve army of the IDF (and likely would continue serving in prisons when on reserve duty :-( ), looking back, it was interesting at times, often frustrating and hard, almost always the situation was when I had to a choice between what I was supposed to do and what I wanted to do. I got to discuss politics with a panel that included the Islamic Jihad, the Hamas and the PLO (the three main terrorists organizations) with side comments from the Democratic Front and the Communist Front (the two minor terrorists organization, which are even more fanatics than the rest, if this is possible). That was a good way to pass the night shits; we usually managed to resolve all the problems in a reasonable manner and reach world peace by 4:10 AM, by which time we had to stop so they could pray.
I was part of the Derech Chadasha (New Path) operation, during the Hudna's days (when it seemed that there might be peace in the Middle East), as Israel released close to three hundred prisoners, all of them have signed a declaration saying that they will not deal with Terror again. Just over a month later, two bombings, in Tzriffin and Jerusalem both of them were released in Derech Chadasha. It was this, among many other things, that made serving there so hard. On the one hand you are required to provide the prisoners with proper treatment and on the other hand... you listen to the news and see a bombing in Jerusalem and hear them celebrating. And that is in addition to the usual conflict of being in a position where you need to take care of people who would truly like to kill you.
I'm glad beyond words that I've finished with all of this.
I look back, and four years have passed. I'm not the same man I was when I entered the army. I grew, I learned (mostly thing I didn't want to know), I experienced both joy and sadness, had successes and failures. I wouldn't repeat it for anything, yet I wouldn't give up the experience for the world. How did a geek like me ended up being in such a place, I truly cannot say.
I remember that on the first few days of my last post I was in an interview with my commander and he mentioned that no one have ever finished such a post without at least a single criminal investigation. Talk about encouragement. I was the first to manage to do that. Thinking about it, I never once was on trial (and in this army, this means a lot, they put you to trail for losing a magazine).
I'm free to do as I please now, the Army's Phone (which they call VPN, for some reason) is no longer. I will not get calls in the middle of the night, or Friday's Shabbat Supper about whatever strange thing this or that prisoner did which require my personal attention. I will wake up in Sunday and I'll not have to go back to prison. I can now leave by no man's leave, underneath the law. Time to start a new life.
Most soldiers go to a trip abroad when they are released from the army, usually to the Far East, it's called "To Sit Under A Mushroom" and include high levels of alcohol and drugs and low level of personal hygiene. There is a nice song about such a boy, called: "Moshe, You're Not A Hedgehog." I've considered it carefully and decided that I've objections on several levels to that, so I'll pass.
Now I need to get a job and start living the life where you get up in the morning and you got a choice at what you wear.
rename BooOnRails to Brail
I've renamed BooOnRails to Brail, the web site has been updated, so the old adress doesn't work, here is the new one:
Need a new name for Boo On Rails
Apperantely David Heinemeier Hansson doesn't like people using the "X On Rails", saying that the name is a spesific to a framework and not to the general philosophy. This is a reasonable approach but this means that I need to find a new name.
Ideas?
Knife of Dreams prologue is out!
The prologue to the Wheel of Time 11th book is out!!!
You can get it here: Embers Falling on Dry Grass
I'm not that I'm going to read it, for the simple reason that my brain is on reading overload right now :-)
