Ayende @ Rahien

Refunds available at head office

Book Review: In Search of Stupidity: Over 20 Years of High-Tech Marketing Disasters

This book is good.

The author covers such things as IBM & the PC, Netscape vs. Microsoft, WordStart vs itself, and a lot more.

Above all, this book is funny, very funny.
I wasn't very much interested in software during the eighties, mainly due to the fact that I was eagerly unticipating my age moving into the two digit zone, but this book manage to capture the old mistakes and bring them to life.
I read it in three days {work got in the day, then the book got in the way of work :D} and it is awesome read.

The author's use of lanuague is superb, and manage to make me chuckle quite a bit.
The ancedotes include ancient history {a text co-proccessor?} to the dot com bomb. Some of them I can relate to personally.

Two things I didn't like:

  • "brainchild" - The first time ever I encountered this word, and the author uses it constantly, and it sort of jump out of the page at me everytime. Doesn't help the the Hebrew translation, literaly translated back, is: "Fruit of his Mind", which is just as rare.
  • The author include many instances where he made a projection that turned out to be correct - I couldn't find any instance where he admit to be wrong. I don't buy this, and it feel too much like ego-boosting.

Nevertheless, it's a facinating book. You can read it as a history book, a marketing advice, humor book or as a general information source.

Highly recommended.

Published at

Blog System

I'm thinking about replacing my dasBlog with another system.
I'm very happy with dasBlog, and not so eager to replace it, but the project seems to be dead.
Going here: http://workspaces.gotdotnet.com/dasBlog/ - where I used to be able to download it leads me to GotDoNet workspaces page.
I have a single problem with dasBlog, I don't have a rich editing in Firefox. But this is a killer for me.
AFAIK, there is a new version that fixes this, but I can't find it!

Anyone knows where I can:

  • Get the new dasBlog files.
  • Ger a new blog system that:
    • Uses the file system / MySql as storage, as my account doesn't have SQL Server.
    • Free.
    • .Net
    • Support rich editing in Firefox.

I've been Googled!

For the first time, my blog actually appears on Google*!

Whoa! :-D

[*] I'm the sixth result when searching for "Ayende Rahien Blog", but it a start!

Tags:

Published at

Computers Are Liars - Part 1 - Virual Memory And Eambezzlement

Had you ever had to explain some technicality about the inner working of your computer to a non-technical person?
Did you manage to make the other person grok what is actually happenning?
I'm trying to educate my little brother on how computers work, this is the result:

[Warning: The following conversation was taken while driving to a movie late at night, and in a different lanauge.]

Brother: What is Virtual Memory and why is it low {refering to an error message he got earlier}? I've a lot of memory in my computer. You just installed another 10GB!

Ayende: No, I installed a HD, not memory.

Brother: What is the difference?

Ayende: Well, it's like having a whiteboard and a dossier. You can write anything on the whiteboard, and you can see everything at one, but eventually you'll run out of room. With a dossier, you can put as much information as you want {at least until the dossier cracks} but it takes a lot of time to search for something. The difference is how much time it takes to read or write something, and how much information it can hold.

Borther: So, which is which?

Ayende: Your computer memory is is like a whiteboard, very easy to write or read, but limited in space. And can be deleted very easily. A HD is much larger, and it takes more time to read and write to it, just like a dossier.

Borther: So what is virtual memory? A divider in the dossier?

[Now it gets interesting]
Ayende: Well, no. The problem is that... that... {A this point I give up and decide to personify the computer}. The computer is like a bank clerk, and any program that you run is a client. The bank don't have a lot of money available, most of it is invested elsewhere. But when a program wants more memory {a client walks to the cashier and ask to withdraw} the computer gives it the memory. The problem is when there are too many request and the money run out.

Brother: What happens then? Does the computer tell it to come tomorrow?

Ayende: The computer is too nice a person to tell you to "Go away, we don't have any more memory! Sue us!"

Brother: But what actually happens?

Ayende: Well, the computer lies. It tells you, no problem, here is the check, just cash it in when you need. You see, it hopes that you want cash it in until some other customer make a deposit {a program releases memory}.

Brother: And what happens when you do use it before it has enough?

Ayende: Well, then it cheats. First, it looks into other accounts and find what funds {places in memory} are not likely to be used soon, then it embezzle the memory away and give it to the application that wants it.

Brother: And when the embezzled application wants that memory?

Ayende: Well, the computers lies again, it again find some place unlikely to be used soon, and give the application that place.

Brother: Sound like it would get caught sometime, because what if a lot of application suddenly wants their memory back at the same time? It would have to tell some of them that it doesn't have any.

Ayende: No, that would be rude. It just politely ask them to stand in line, and steals from any of them to satisfy the requests that they need.

Brother: And won't any of them notice that they were robbed?

Ayende: No, applications don't have wallets, so the only way to can get the money is through the cashier, and he is lying through his teeth to convince them that the bank has all the money in the world {or at least about 4 Billions of it}.

Brother: I didn't know that computers lied to each other as well.

Ayende: They do, all the time.

Brother: But it nobody notice that the computer is a liar, why I got this message about low Virtual Memory?

Ayende: Oh, now you are talking about swap...

[To be (hopefully) continued...]

In search of beauty

I've a major problem regarding art, I can't draw a straight line with a ruler and a gun to my head.
Nevertheless, that doesn't stops me from admiring beauty. Naturally, I want my application, web site, desktop etc to be pretty.

More than that, I want them to look professional.
But that seems to be very hard to do, I looked here and thought I'd found some promise, but even Googling didn't help me!

DeviantArt has great resources, but most of the stuff there is copyrighted.
I would've thought, with all the developers donating their time to GPL and OSS, there would be some artists as well.

Anyone familiar with some resource that I can use?

Currently I found Noia Warm KDE set, which are GPLed, but there are limited in their expressiveness.

[Just to clarify, I would love nothing more than to pay enormous ammount of money to strange people for 32x32 icons. I just find myself unable to do so at the moment, at least until I'll start writing software commercially, and not as {not inexpensive} hobby.]

New tools

Just wanted to report that I now have two new tools in my toolbox:

  • WB Editor - Blog client that support WYSIWYG
  • Copernic Desktop Search - What Google Desktop should've been.
    Indexed around 180GB in several hours, index size is 332MB, allows to define quite a bit of options.
    Very fast.

FireFox Cleanup

I just cleaned up my Firefox setup.
I'd a lot of problems with it (two windows appearing when openning a link from RSS Bandit, frex) and was generally displeased with the way it was operating.
I uninstalled it, removed the %APPDATA%\FireFox and %APPDATA%\Mozilla {Lost my bookmarks in the process, because I forgot to backup, but I rarely use bookmarks anyway.}

I then installed Firefox 1.0 Preview Release and the following extentions {In order of usefulness}:

  • Googlebar - Nothing more needs to be said.
  • Tabbrowser Extensions - Very useful, lots of options. But what buys me is that it removes the "Open Link in new window" when you right click a link. My default behaviour is to right click and choose "Open link in new tab", so it's very conveniant to me to have it as the first item on the context menu. Lots of other, very cool options.
  • All-in-One Gestures Extension - Allows simple {Left, Right, Up, Down} gestures, with a UI that I can understand. I used RadialContext for a time, and that was nice, but I had a lot of mistakes, because it's very small interface.
  • Adblock - My eyes usually remove ads because my mind gets them, but this is nice to have.
  • Linkification - Scan the page for plain text URL and turn them into links, a real time saver.
  • Google pagerank - Nice to have, currently this site doesn't even appear on Google.

One thing that sucks in Firefox is their approach on installing stuff. It {correctly} blocks anything that is not defined {Basically, anything not on update.mozilla.org} but it gives you no option to temporarily allows installations. You've to allow the site to install stuff, install it, and then remove the site manually.

IE's approach since SP2 is much more sensible, "Allow this time only."

Google Desktop Woes

I'm a funny guy. No, seriously.
I pay attention when the security experts advise: "Don't run as Administrator."
So I don't, I run as a normal user {not even a power user}.

So why the hell it is so bloody hard to do so?
There are many places where I've to get out of my way to make my setup work. One instance is VS.Net add-ins, a complete mystery all on itself.

Another, apperantely is Google Desktop.
Like most software I use, I install as administrator, and use as a normal user, so why, oh why do I get this error message?
"Google Desktop Search can only run when the user who installed it is logged in."
This is a killer bug for me, and the main reason why I unistalled Google Desktop.
There is a little page about it in the support section.

In this day and age, there is no reason for this. This is simply stupid.

Another things that irks me, why does it index my computer if the computer is idle for more than 30 seconds? That is insanely long time in computer terms.
When I work on the computer, I rarely leave it untouch for longer then 30 seconds, which means that Google Desktop will not run until I leave the computer.
This is broken.

Offline Blogging Tools

This is a test of WB Editor capabilities.
The previous post was posted using ::w.bloggar:: but I won't be using that (no WYSIWYG, and it messed up my title).

WB Editor  also just overwrote a half-finished post of mine when I explored the interface. Bad application, Bad!

But so far, this seems to be the only flaw in it.

[Listening to: 14 - We Are The Champions - Queen - Live Magic (Live)(02:01)]

Published at

TestDriven.Net

TestDriven.Net is finally working!
Jamie Cansdale sat with me through Messanger for quite a while before we managed to make it work, but now I can use it to run tests.
The experiance is so much better then running the command line... :-)

Highly recommended, and you won't get better support anywhere.

The problem was one of those strange stuff that you won't find anywhere else:
I could install as admin, and it would work, only as long as I used it as admin.
I couldn't use it as a nomral user (my usualy mode of operation).
I couldn't install it as user, even though it is a supported option, it kept complaining that I already had it installed.
Fast forward a bit, and you see me and Jamie trying everything from Regmon to Filemon to DebugView to find out what it was searching.
Finally we discovered that I previously installed NUnitAddIn (the former name of the TestDriven.Net package) on my user, and that was the problem.
Attempting to uninstall it require the msi file for this installation, yuck!
Fast forward again, get Windows Installer Cleanup Utilitity (AKA MsiZap) find out that it only work for administrators.
Then attempt to get the old msi file from Source Forge, uninstall the package, install TestDriven.Net, open Visual Stuido.Net.
Works!

[Listening to: She Drives Me Crazy - Fine Young Cannibals - (03:36)]
Tags:

Published at

Why I love TDD

{I don't know if you've noticed, but half of my posts are rants against software doing stupid things :-), this post also started this way, but I decided that I'm too negative.}

Well, I just finished a major refactoring season that would've been impossible without Tests.
I just started writing this software, but already it has several thousands of lines.
I started this project without any design, so I broke so many roles that it's lucky that I'm headed for prison tomorrow, or else I would be there today :-D.

I run FxCop on the project, and it popped several dozens of recommendations, which I know I wouldn't have been able to implement, if I didn't have the tests.
I'd a similar project, about half a year ago, I tested FxCop then, and wanted to do good, but the effort of changing & changing the project was just too much work to do.

Now, with the aid of TDD & ReSharper, the work goes very smoothly, and I'm confident that at the end, I'll have a better code, that does {roughly} the same thing.

If you aren't into TDD yet, try it. The best part isn't when you see that all the tests passed.
The best part is when you make a single inoccent change {such as moving a file from one folder to another} and you suddenly see half your tests bomb, and you just knows that this bug would've slipped to production.

I just came from such a bug, I moved a resource file to another directory, and suddenly I started seeing a lot of failed tests. After a false start {I made a change in the resource fetching code as well}, I finally found it.

P.S:
Why changing the path of a resource also change it's name in the assembly? This is stupid.

Tags:

Published at

CodeSmith & VS.Net frustrations

I just spent two hours trying to bring together CodeSmith & VS.Net.
The fault was not in CodeSmith's fault, but VS.Net's.
The problem is that I'm trying to get location independent project, and VS.Net model for running custom tools absolutely forbid it.

It all boils down to Vs.Net running Custom Tools with the current directory set to C:\Program Files\Microsoft Visual Stuido 2003\etc\etc\etc... and not in the current project folder, or the build directory.

What this mean is, I can't have CodeSmith's templates that reference to files in anything but absolute paths, which mean that if I change the project's path, I need to change the CodeSmith property set file.

Tags:

Published at

UIObjects.Net

I'm currently working on something similar to NakedObjects, a UI framework that should save you the time building UI.

Why am I building this?

  • NakedObjects dotNet implementation does not work on my system, throwing java.lang.ExceptionInInitializerError (WTF?? In a .Net application?)
  • I checked the Java implementation and I really like the idea, but not the implementation.
  • As far as I understand the .Net port, they use the same code {one of the JVM for .Net ?} to run it, which means that I've to write ugly looking code to make it work [Ugly meaning Java-style, which is fine, but I like my C# code to adher to the .Net naming conventions.]
  • The UI is horrible.
  • I want to experiment a little with Reflection & UI design, both of which I've very little experiance at.
  • If I'll finish it, that would be a cool thing to have.

 

Basic design is as follows:
Attributes:

  • [VisibleObjectAttribute] - decorate a class/struct. Means that this an object that is visible on the UI. Several built-in objects are treated by the framework as if they'd this attribute (string, all numeric types {short, int, double, numeric, etc}, DateTime, Enum).
  • [ActionAttribute] - decorate a method. Means that this is a method that is exposed to the UI.
  • [ValidateParametersAttribute] - decorate a method with [ActionAttribute]. Points to a method that validate the parameters for a the decorated method. This ensure that the method would get parameters in a consistent state.
  • [TitleAttribute] - decorate a string property. Used to get a nice name for an instance of an object.

  • [CoreObjectAttribute] - decorate a class/struct. Inherit from VisibleObjectAttribute, means that the object is visible as the root level of the application.

  • AppletCreatorAttribute - decorate a class/struct. Signify that this type supply it's own UI and should be ask to do so when presented to the user.

Classes:

  • VisibleObjectContainer - contain the info regarding a type decorated with VisibleObjectAttribute {FriendlyName, Icon, Type, etc}.

  • VisibleObjectInstance - contain the info about an instance of a type decorated with VisibleObjectAttribut. This is used everywhere to work with the object. This class also decide what Actions can be taken on a the object, based on its state and on the parameters.
    For instance, if you Act(“New name“) on an VisibleObjectInstance that has a method:
    [Action] string SetName(string NewName){}
    Then it will be called and the return value will be returned to you.

  • Action - wraps a method decorated with [ActionAttribute], allows to query if it's valid on an object, get the nice name for it, etc.

  • AppletFactory - Create the UI representation of a VisibleObjectInstance. It does so by checking a few builtin types to get the default implementation, then check if the type provide its own UI (through AppletCreatorAttribute), if not, then pass it to a default applet creator that read all the public properties/fields and gives you a form that you view/change it.I

Interfaces:

  • IAppletCreator - any type that want to create its own UI need to provide an implementation of this interface.

That is all that I've right now.
Some note about terminology:
Applet is my term for a piece of the UI that may stand on its own {in the framework, represented as Control} or may be hosted in another Applet / the main form.

Some UI consideration:

  • How will the UI look? I thought about dockable panels to represent the types, with the ability to drag icons to each other. But wouldn't it create a lot of clutter?
  • Actions on VisibleObjectInstances will be access via right click? A menu?
  • How to deal with Actions that require parameters? Pop another applet? What about complex parameters {Customer, Order, etc}.

Currently I'm working with FxCop to clean up the code, I can't maintain a naming convention in my own code, it seems.

P.S
Resharper is goodness.

Tags:

Published at

Something cool

I just stumbled on Desktop Sidear, and implementation of the Longhorn sidebar today.

What really impressed me, beside the polished look (I've just started learning to use this.) is that it has built-in support for multi monitors.

I do most of my work on a LCD screen set to Portrait, so I care ver much abour horizonal space, I was very please to find out that I can use it on the CRT screen when I don't care about space and clutter.

The Performance panel alone is worth using this application, I just had a major slowdown on the computer, and couldn't understand what was going on until WinRAR chimed to tell me that it finished de-compressing that 1.5 Gb archive.

It has a Disk, CPU, Mem, Swap, Network and several others.
And here I was looking at TaskMgr and seeing that everything should be fine.

Cool :-D

And free.
Go get it

Published at

MbUnit Mystery

Consider the following code:

using System;

using MbUnit.Core;

using MbUnit.Core.Framework;

using MbUnit.Framework;

 

namespace ConsoleApplication1

{

      [TestFixture]

      public class Class1

      {

            [STAThread]

            static void Main(string[] args)

            {

                  using(AutoRunner auto = new AutoRunner())

                  {

                        auto.Run();

                  }

 

            }

 

            [Test]

            public void TestOne()

            {

                  Assert.AreEqual(200,100+100);

            }

 

      }

}

 

What would be the result of running this code?
Well, one result is that my floppy drive lights up and Filemon register the following activity:

15:13:34.562 ConsoleApplicat:3784 IRP_MJ_CREATE  A: SUCCESS Options: Open  Access: All 
15:13:35.562 ConsoleApplicat:3784 FASTIO_DEVICE_CONTROL A: FAILURE IOCTL: 0x560000 
15:13:35.562 ConsoleApplicat:3784 IRP_MJ_DEVICE_CONTROL A: INVALID DEVICE REQUEST IOCTL: 0x560000 
15:13:35.562 ConsoleApplicat:3784 IRP_MJ_CLEANUP A: SUCCESS  
15:13:35.562 ConsoleApplicat:3784 IRP_MJ_CLOSE  A: SUCCESS  

MbUnit version 2.22.0.0;

If someone can find out what is going on here I would be more than happy.

I tried to debug it, but I can't lie my hands on a fresh pile of MbUnit code {which moved from MbUnit homepage to TestDriven.Net and for which I can find not a sign of in the TestDriven.Net site}.

Solutions are welcome.

Answer to C# Riddle

Omer van Kloeten solved it.

 test(typeof(bool));

static void test( object t)
{
    Console.WriteLine(t.GetType().FullName);
}

Print System.RuntimeType (a subtype of System.Type) to the console.

I was expecting System.Boolean and that caused some head scratching. It was a call hidden five or six levels deep, and I couldn't for the life of me understand what was going on.

C# Riddle

Consider the following code:

test(typeof(bool));

static

void test( object t)
{
    Console.WriteLine(t.GetType().FullName);
}

What would be printed?

Hint: It's not System.Boolean

Update: Omer van Kloeten pointed out that the original version worked, that is because I didn't write the example in VS.Net, or tested it.
Now it works (or doesn't work, depending how you look at it.)

TypeMismatchException

Well, apperantely I got burned because of a type mismatch.

The previous time was an IList insead of of TreeNodeCollection, now it was some strange behaviour on part of HybridDictionary.

Apperantely, hybridDictionary.Keys does not return an object[] or IList or anything like that, instead, they return a DictionaryEntry, and remember, we're talking about the Keys collection.

If not for Roy Osherove's help, I would still be stumped.
Thanks Roy.

Another bug

Apperantely I've discovered a bug in .NET where two identical strings are compared through object reference.

Consider the following code:

using

System;

using

System.Collections;

using

System.Collections.Specialized;

using

System.Reflection;

namespace

test2

{

class Class1

{

[STAThread]

static void Main(string[] args)

{

ReallyStrangeBug();

}

public static void ReallyStrangeBug()

{

HybridDictionary dic = new HybridDictionary();

foreach(MemberInfo member in typeof(object).GetMembers(BindingFlags.Public | BindingFlags.Instance))

dic.Add(member.Name,member);

Console.WriteLine("Using Objects comparision:");

Console.WriteLine(objectExistIn("ToString",dic.Keys));

Console.WriteLine("Using strings comparision:");

Console.WriteLine(stringExistIn("ToString",dic.Keys));

Console.WriteLine(dic.Contains("ToString"));

}

private static bool objectExistIn(object o, IEnumerable enumerable)

{

foreach(object current in enumerable)

{

Console.WriteLine("'{0}' == '{1}': {2}",o,current,o==current);

if(o==current)

return true;

}

return false;

}

private static bool stringExistIn(string o, IEnumerable enumerable)

{

foreach(string current in enumerable)

{

Console.WriteLine("'{0}' == '{1}': {2}",o,current,o==current);

if(o==current)

return true;

}

return false;

}

}

}

 

This produce the following output:

Using Objects comparision:
'ToString' == 'GetHashCode': False
'ToString' == 'Equals': False
'ToString' == 'ToString': False
'ToString' == 'GetType': False
'ToString' == '.ctor': False
False
Using strings comparision:
'ToString' == 'GetHashCode': False
'ToString' == 'Equals': False
'ToString' == 'ToString': True
True
True
Press any key to continue

 

Reason unknown

Published at

When "ToString" does not equal "ToString"

The following code fail in a test!

I’ve zero idea why this happened, or how it can happen.

 

 

 

[Test]

public void ReallyStrangeBug()

{

      HybridDictionary dic = new HybridDictionary();

      foreach(MemberInfo member in typeof(object).GetMembers(BindingFlags.Public | BindingFlags.Instance))

            dic.Add(member.Name,member);

      Assert.In("ToString",dic.Keys);

}

 

 

The Assert.In is this method:

 

public class Assert

{

static public void In(Object test, IEnumerable enumerable)

{

    Assert.IsNotNull(enumerable,"Enumerable collection is a null reference");

    foreach(Object o in enumerable)

    {

      if (o==test)

            return;

    }

    Assert.Fail("{0} not found in collection",test);

} 

}

 

I debugged it to o==test, and I can see in watch that the values are the same, but it just doesn’t work!!!

 

The Assert.In belog to MbUnit framework, btw.

 

Any suggestions as to how it can happen are welcome. 

Tags:

Published at