David Riggs, the Editor of the Delphi Informant, has given me permission to publish my old articles and editorials. He was even kind enough to provide the type-set copies as Word documents. We'll see how good the conversion from Word to HTML works.
The articles can be found - strangely enough - on the Articles page of my web site. For some reason, we don't have the original TIniSource article, but that just gives you an excuse to purchase the Delphi Informant CD archive.
Obviously, these are older articles, and some of the information may be dated, but hopefully, there will still be something worthwhile to take away. Let me know if you find anything glaring that needs correction.
I've developed a series of sayings that have evolved over time. I thought I'd share them here. I think it's safe to just post them without explanation, as they are meant to promote thought.
- Everything is easy when all you're doing is drawing circles and squares.
- It takes 3 times to perfect something.
- Anybody can look good on paper.
- When playing safe, be sure it's safe.
- If you don't know the shot, don't take the shot.
- Good enough to work isn't "Good Enough".
- If you want to act like a primadona, produce like a primadona.
- You can't stand on priniciple when you have none.
- Being busy is no excuse for a short-cut.
- A bug is no reason to lose sight of logic.
- Nothing in life is a failure if you learn from it.
- Think Less. Know More.
- The last thing you want to give me more than a big taste of success is a small taste of failure.
- Greatness comes from action, not those that critique it.
- Souce code is the source of all truth.
- Never empty all your chambers at the first thing that goes bump in the dark.
After reading Joel's article on Airset, I thought I'd give it a try. Normally, I am not a fan of web applications. However, this web application is incredibly well done. The GUI is rather impressive, with wizards, dialogs, menus, drop downs, and the like. It still feels nothing like the responsiveness of a desktop application, but the features are so good that I may have to overlook this.
This online calendar application has almost all of the features that I need. Things like: group calendars, integration with Outlook, SMS notifications, good permissions, and search. It also has features that I like that weren't necessarily part of my requirements, like blog content, shared contacts, lists, and links, and tight integration with most cell phone providers to provide an application that runs on most cell phones.
I looked at Office Calendar by Lookout Software, and I liked the concept very much, but the price tag seemed a bit steep. All in all, I am quite pleased with the features of Airset, and the price of free is hard to beat.
I've spent a lot of time here at my current place advocating refactoring. The concept of "code smell" is one that continually comes up. My esteemed colleague, Rich Werning, just came up with "Rich's ultimate code smell test". One simple question: if the project you are working on was to be released as open source, and thus available to the scrutiny and review of hundreds or thousands of other developers, would you want your name and professional repuation associated with the source code? If not, your code stinks.
100% agreed, and brilliantly stated.
As a follow up from my post yesterday, I have some work-arounds to get me past the problem. I still don't have the ultimate answer for why Math.Log(0.0) throws an exception only when called from COM interop, but I can at least move forward again.
I started out by changing the actual code in Lucene to simply avoid the Math.Log(0.0) statement. However, I started to worry about forking the code. I don't want that kind of maintenance headache as new versions of Lucene continue to come out. I was able to work things out so that I could descend a couple of classes, override some methods, and plug these into my API layer, and everything worked fine.
The one problem left was the arithmetic overflow that I got later on in the Lucene code. I was talking with Chris Bensen, and he recalled running into something similar before and sent this link to MSDN on _controlfp documentation. I implemented the following code in .NET in the constructor of my API layer, and the overflow error went away, but of course, I end up getting NaN results due to the new FPU masking behavior. I'll have to test thoroughly to make sure that this doesn't impact calculations further down the line.
[DllImport("msvcrt.dll")] private static extern int _controlfp(int IN_New, int IN_Mask); // this imports the call
private const int _MCW_EM = 0x0008001f;
private const int _EM_INVALID = 0x00000010;
public LuceneAPI()
{
// Add this code to squelch arithmetic overflow/underflow exceptions spawned from the FPU.
// See comments in the FixedDefaultSimilarity class for more information.
_controlfp(_MCW_EM, _EM_INVALID);
}
I still would like to find out the technical details for why I need to do any of this, but at least I have things running.
It seems that COM interop isn't always a good thing. I have a problem that I don't have a solution for right now, so if you have any feedback, I'd sure appreciate hearing it.
I wrote a wrapper around Lucene.Net to provide simple API access to some very basic operations (index, search, delete) that will be used by a Delphi Win32 application. Everything was working fine, but deep in the bowels of the Lucene code, in one code path, I encountered a line like this:
return (float) (System.Math.Log(numDocs / (double) (docFreq + 1)) + 1.0);
When there are no documents in the index, this essentially evaluates to a call to System.Math.Log(0.0), which according to the MSDN documentation, should return NegativeInfinity. In fact, when this library is called from a .NET client, it does just that. However, when called via COM interop, this results in an exception, "Attempted to divide by zero". I started to modify the Lucene source to do a check for this condition and just manually return NegativeInfinity, and that did get me past that point, but then later on in the Lucene code, I end up getting an "Arithmetic overflow/underflow" error when Lucene tries to do some math on the returned value. So rather than continue to band-aid this problem, I thought I'd try to dig to the root of the problem to see why this is happening.
You can find an extremely simple test case with a .NET Class Library, .NET test client, and Delphi test client here. Just build the .NET solution, and then you can run the createtlb.bat file in the LogClient directory to get the Delphi project ready.
When creating .NET classes that will be accessible via COM Interop, you need to be sure to add a default constructor to the class. If you don't, regasm will end up generating the tlb without the CanCreate flag for that class, and therefore, when registering the tlb, those classes will not be registered.
Yes, this makes sense, and yes, this is covered in MSDN, but I thought I'd mention it here, as it recently tripped me up for a little while.
Since I'm a programmer, I don't always keep up to date on other areas of software because it's always more fun to write your own tools.  I can find my way around Excel some, but I am not exactly a power user. I had a need to highlight the maximum cell value in a column today, and it turned out to be not entirely obvious. Fortunately, here's a Google post to walk you through this exercise if you need to do the same thing.
|