October 2004 Entries

Ordered a Tablet PC

So after much deliberation, I've decided on the M205 with a 60GB hard-drive, 512MB Ram, and a DVD-CD ROM drive etc... etc..

This is my first laptop ever so I'm pretty excited. Anyone have recommendations on synchronization software etc?

Thanks to people like Scott and Iggy for their input.

Last Game of the Season

Soccer Ball Today the soccer team I started playing with had their last game of the season. This was only my second game with them and we were playing the first place team in the league. This team was much slower than our last opponent and not as skillful, but were known for playing very dirty.

Fortunately on this day, the ref ran a tight ship and a nice game of soccer ensued. At least nice for the other team who proceeded to pound us for five goals to our two. We started off strong, but with no subs to speak of, the second half found us weary and unable to keep up.

The highlight for me was putting the ball in the back of the net in my second game with this team. The play involved flicking the ball over the defender and taking a shot off the bounce. They invited me to join them when the season starts in January. Hopefully by then I'll have some fitness to contribute.

Ali G Translator

Ali Gif you've watched da show yous probably ave wondered, ow can i attract da wicked bitches dig dat awesome omeboy? da secret is to learn to bang dig im? well in da house's your chance to learns da ons and out of ali g-speak. respek!

In English, that translates to...

If you've watched the show you probably have wondered, how can I attract the lovely ladies like that awesome homeboy? The secret is to learn to speak like him? Well here's your chance to learns the ins and out of Ali G-speak. Respek!

Check it out, the Ali G translator.

This is So Me

If blogging had been around when I was a kid...

Well, Yes, We could read your blog... or you could just TELL us about your school day.

From the Cincinnati Enquirer, courtesy of Kevin Dugan and Tom Murphy ...More

[Via Scoble]

Deploying ASP.NET Apps With UnleashIt

I answered a question about ASP.NET deployment in a newsgroup recently where the person asked which files should he deploy when moving his site to a production server.

As a followup to my answer, Jon Galloway pointed the person to a neat deployment utility called UnleashIt.

UNLEASHit
Ready to deploy, Sir!

UnleashIt provides integration with VS.NET 2003 as an add-in. You can create deployment profiles and share them with other team members. I plan to use this for any customization of my .TEXT blog I plan to do.

So why not just use Visual Studio's copy project option? I've never used it but Jon had this to say:

Visual Studio has a copy project option for web projects, but it depends on your setup and you may miss files (javascript, css, images).

As usual, I have a few minor complaints as I'm just a nitpicky person. The first is that the application is not resizeable. The fonts on the main screen seem smaller than in other applications.

More problematic is that the application doesn't seem to support adding file masks. Currently the application is missing *.asmx and *.ashx, but more importantly it would be nice to create a deployment profile using this tool that could handle Word docs (for example) if they were a part of the site.

RSS Bandit Synchronization Using GMail Drive Shell Extension

If you haven't heard, RSS Bandit can synchronize its state (feedlist, read/unread, etc...) across multiple machines. I wrote about it in the RSS Bandit docs.

So far, there are four means for synchronizing feeds: Ftp, dasBlog, local or network file, and webDav. For the average user, these options might not be always be available.

However, using GMail Drive Shell Extension, you can create a local drive letter that maps to your GMail account. Then in RSS Bandit, open up the properties dialog, click on the Remote Storage Tab, choose the File Share protocol and enter the GMail drive in the UNC directory path (it doesn't have to be UNC). In the screenshot below, I have the e: drive mapped to my GMail account.

Remote Storage Tab

Now you can use your GMail account for synchronizing your RSS Bandit state between multiple machines. Note that this usage of GMail is not supported by Google nor the developers of RSS Bandit. So if Google suddenly decides to disrupt this usage of GMail, you've been warned.

As you can see in the RSS Bandit Roadmap, there will be support for more synchronization sources in the next major release.

Bloglines subscription

Weird. I did a google search for an entry in my blog and one of the results was a bloglines account that had my blog subscribed. I was basically seeing all the blogs that some bloglines user was subscribed to. Is that a feature of bloglines to expose your subscriptions like that? Or is that a privacy flaw?

UPDATE: Nevermind. I'm just being paranoid. Bloglines supports public profiles.

SOAP vs. REST in the Real World

There’s a lot of focus these days on SOAP vs REST and the proliferation of WS-* specifications. Sometimes you wonder if WS-* solves problems that aren't all that common or have already been solved.

For example, some in the REST camp will say, HTTP has security built in. It#8217;s called SSL. Why not use it instead of building WS-Security.

Another example is WS-Addressing. This places addressing information within the SOAP envelope so that the message can be delivered via transports other than HTTP. At first glance, I wonder how often this will be useful for web services when HTTP is the predominant mode of transport.

However, Pat Caldwell illustrates a real world scenario in which WS-Addressing solved a real need that REST couldn#8217;t and doesn#8217;t address.

REST has its place, but for some of those nitty gritty situations, SOAP keeps everything clean.

Why Not Convert HTML to XML?

Pat Gannon (no blog) makes a great point in the comments on my post about using regular expressions to parse HTML. He says:

Just to play devil's advocate for a minute, it seems like HTML is just too darned close to XML to have to parse this way. Isn't there a library out there for converting HTML into XHTML? If you can do that, you can just read the file in using XmlDocument::LoadXml(). Once you've done that, you can find your tags using an XPath query. Sorry, I just couldn't let a parsing post go by without tossing in my two cents ;)

In fact, there are two approaches to this. The first recognizes that HTML is really just a subset of SGML. Thus if you have a SGML parser, you're done. So one option is to try Chris Lovett's SgmlReader.

In fact, this is what the current version of RSS Bandit uses for auto-discovery of RSS feeds within HTML content. However, I recently replaced it with regular expressions because of some memory use and performance problems we were having with it. In our case, finding these tags is a lot faster and uses less memory by just using a regular expression. (Now you see the motivation for the post).

Another option is to use Simon Mourier's HTML Agility Pack. He takes an interesting approach in that he provides an HtmlDocument class that implements System.Xml.XPath.IXPathNavigable. Thus his approach provides the same interface as an XmlDocument for querying nodes, but doesn't change the underlying HTML content as many other approaches would by converting them to XML.

And just to toot Pat's horn a bit, I used to be his manager at Solien when he was just starting out in his career. Now he works at Univision and has inherited reams of code that parse through Fortran code as well as proprietary database files. He's also written his own grammar engine and xml syntax for describing computer languages such as C#. So he knows a thing or two about parsing text. He's become quite a top notch developer. I'm just waiting for him to get off his arse and start a blog.

Comment Spam

Spam Adam tells me he doesn't support comments nor the CommentAPI because he doesn't want to deal with comment spam. So the day after admonishing him for being anti-social, I get hit by a slew of comment spam pointing to porn sites and selling Ginzu knifes. Did you know those things can cut right through a can?

I removed the offensive comments. Don't worry, as a duty to my readers I checked out the porn sites and you're not missing anything.

This torrent of comment spam means only one thing. I have arrived!

Using a Regular Expression to Match HTML

UPDATE: There was a big mistake in the above expression. Unfortunately .TEXT (trying to be helpful) munged the code I posted and uppercased some characters. I’m using FireFox to post so that I don’t get the helpful text editor. Also, the above didn’t take into account multi-line html tags. That’s been corrected now. You’ll have to use the SingleLine RegexOption for it to work.

I just love regular expressions. I mean look at the sample below.

</?\w+((\s+\w+(\s*=\s*(?:".*?"|'.*?'|[^'">\s]+))?)+\s*|\s*)/?>

What’s not to like?

Ok I admit, I was a bit intimidated by regular expressions when I first started off as a developer. All I needed was a Substring method and an IndexOf method and I was set. But after a few projects that required some intense text processing, I realized the power and utility of regular expressions. They should be on the tool belt of every developer. To that end, I recommend Mastering Regular Expressions by Jeffrey Friedl. This is really THE book on Regular Expressions. Reading it will make your Regex-Fu powerful.

So let’s look at a common task of matching HTML tags within the body of some text. When you initially think to parse an HTML tag, it seems quite easy. You might consider the following expression:

</?\w+\s+[^>]*>

Roughly Translated, this expression looks for the beginning tag and tag name, followed by some white-space and then anything that doesn’t end the tag.

Now this will probably work 99 times out of 100, but there’s a flaw in this expression. Do you see it? What if I asked you to match the following tag?

<img title="displays >" src="big.gif">

Hopefully you see the issue here. The expression will match

<img title="displays >

Unfortunately, this implementation is too naive. We have to consider the fact that the greater-than symbol does not end a tag if it’s within a quoted attribute value. Thus we must correctly match attributes.

Now there are four possible formats for an Html attribute

name="double quoted value"
name='single quoted value'
name=notquotedvaluewithnowhitespace
name

Each of these cases are quite simple. In the first case, you could do the following:

\w+\s*=\s*"[^"]*"

The portion "[^"]*" matches a double quote, followed by any non double quote characters, followed by a double quote. Another way to express this is to use lazy evaluation as such:

\w+\s*=\s*".*?"

The portion ".*?" uses lazy evaluation (the "lazy star") to match as few characters as possible. For example, if we had a string like so

<A name=test value="test2">

evaluating ".*" (aka greedy) would match

"test" value="test2"

However using the lazy evaluation consumes the fewest characters that match the expression, thus the first match using ".*?" would be "test" and the second match is "test2".

The full expression for matching an HTML tag is that lovely mash of characters presented at the very beginning of this post. It’s a modified version of the one presented in Friedl’s book

However I wouldn’t recommend you just plunk that down in your code. Rather, you should consider adding it to a regular expression library assembly.

Don’t know how? Well I’ll show you a code listing for an exe that when run, builds a fully compiled version of this regular expression into an assembly that you can then reference in any project. In a later installment, I’ll explain in more detail just what the code is doing and how to use the compiled assembly. How irresponsible of me not to do that now. ;)

Source Listing

Technorati Tags: ,

Dare Makes a Move to be More Social

Dare Obasanjo, the project lead on the RSS Bandit project (of which I contribute) is leaving his post as a Program Manager on the XML team at Microsoft to work as a Program Manager on the MSN Communication Services Platform team.

When Microsoft revealed a blogging service similar to Blogger, I had a feeling it was only a matter of time before Dare would somehow be involved with that seeing his interest in Social Software.

It will be interesting to see the direction Microsoft takes with social software. Although Microsoft perhaps doesn't see entering the aggregator market as a profit center, I wouldn't be surprised if that changes in the next year or so.

As aggregation continues to take off, it seems natural to incorporate it into Office. Remember that "Information At Your Fingertips" mantra Mr. Gates touted a while ago? Well I get most of my online information through two sources, Google and RSS Bandit.

In any case, I wish Dare well. Hopefully this is the platform for him to have some of his ideas implemented. I have to admit, I'd love to work on social software such as RSS Bandit and .TEXT full time. But I have a mortgage to pay.

Whidbey Update

Scott Guthrie has returned to blogging with a tremendous piece on his team's effort towards reaching "ZBB" or Zero Bug Bounce.

I've personally never worked on software project as large as the ASP.NET 2.0 project, so it's fascinating for me to read Scott's description of the testing and check-in process. Typically, my check-in process is to get latest on any files I didn't change, build, and run my unit tests. Assuming everything passes, I check in my files, get latest again build, and run the the unit tests again. If everything still passes, I'm done with the check-in. If all went smoothly, it's all done under half an hour.

For the ASP.NET team, every check-in undergoes peer review and is run through a few hours of checkin test suites. They then run more exhaustive nightly tests over the product to catch issues in the latest builds. That's pretty impressive.

Partisan Bush Joke: Intelligence Riddle

Since I like to stoke the fire of partisanship... This joke was sent to me by my friend Walter.

George Bush meets with the Queen of England. He asks her, "Your Majesty, how do you run such an efficient government? Are there any tips you can give to me?"

"Well," says the Queen, "the most important thing is to surround yourself with intelligent people."

"Bush frowns. "But how do I know the people around me are really intelligent?"

The Queen takes a sip of tea. "Oh, that's easy. You just ask them to answer an intelligent riddle. " The Queen pushes a button on her intercom. "Please send Tony Blair in here, would you?"

Tony Blair walks into the room. "Yes, my Queen?"

The Queen smiles. "Answer me this, please, Tony. Your mother and father have a child. It is not your brother and it is not your sister. Who is it?"

Without pausing for a moment, Tony Blair answers, "That would be me."

"Yes! Very good," says the Queen.

Bush goes back home to ask Dick Cheney, his vice president, the same question.

"Dick, answer this for me. Your mother and your father have a child. It's not your brother and it's not your sister. Who is it?"

"I'm not sure," says Cheney, " let me get back to you on that one."

Cheney goes to his advisors and asks every one, but none can give him an answer. Finally, he ends up in the men's room and recognizes Colin Powell's shoes in the next stall. Cheney shouts, "Colin! Can you answer this for me? Your mother and father have a child and it's not your brother or your sister. Who is it?"

Colin Powell yells back, "That's easy. It's me!"

Cheney smiles, and says, "Thanks!" Then, Cheney goes back to speak with Bush. "Say, I did some research and I have the answer to that riddle. It's Colin Powell."

Bush gets up, stomps over to Cheney and angrily yells into his face, "No, you idiot! It's Tony Blair!"

VIDEO: Funniest DUI ever.

Just watch the whole thing. It's not that long and you won't be sorry. VIDEO

It's no iPod, but it is 100GB

Xclef Saw this on Gizmodo. It's bigger and not as nice looking as an iPod, but it is 100 GB.

The DMC Xclef 500 also supports Ogg Vorbis and even WAV—with a 100GB drive, you could start ripping your CDs with no compression at all. The 100GB version is $450 from DMC's online store.

FUNNY: Alternate word meanings...

My friend Michael who lives in London for now sent me this.

Once again, The Washington Post published its yearly contest in which readers are asked to supply alternate meanings for various words (& leave it to the Post to search for new meanings).

And the winners are ...

1. Coffee (n.), a person who is coughed upon.

2. Flabbergasted (adj.), appalled over how much weight you have gained.

3. Abdicate (v.), to give up all hope of ever having a flat stomach.

4. Esplanade (v.), to attempt an explanation while drunk.

5. Willy-nilly (adj.), impotent.

6. Negligent (adj.), describes a condition in which you absentmindedly
      answer the door in your nightgown.

7. Lymph (v.), to walk with a lisp.

8. Gargoyle (n.), an olive-flavored mouthwash.

9. Flatulence (n.) the emergency vehicle that picks you up after
     you are run over by a steamroller

10. Balderdash (n.), a rapidly receding hairline.

11. Testicle (n.), a humorous question on an exam.

12. Rectitude (n.), the formal, dignified demeanor assumed by a
      proctologist immediately before he examines you.

13. Oyster (n.), a person who sprinkles his conversation with
      Yiddish expressions.

14. Pokemon (n), A Jamaican proctologist.

15. Frisbeetarianism (n.), The belief that, when you die your Soul
      goes up on the roof and gets stuck there.

16. Circumvent (n.), the opening in the front of boxer shorts

Workspace Pictures: Work and Home Offices

I know a lot of people like to post pictures of their workspace online. Not sure why (vanity!), but they just do. So I thought I'd jump on that bandwagon and do the same.

This first picture shows my work office with it's nice 17th floor view.

Work Office
Strange green bands take over the screens.

This next one is our home office.


If you look carefully, you'll notice the hastily minimized porn application.

As you can see, the home setup is much nicer than the work setup with dual 17" flat panels monitors, and a slick looking aluminum Shuttle case. I wish my company would invest in nice monitors. My work monitors flicker, make me cross-eyed and spit in my food. If you look closely at the top picture, the computer case is literally held together with scotch tape on top. The IT department wouldn't budget duct tape.

The little figurine on top is the "Buddy Christ" from Dogma. You can purchase that on Kevin Smith's website. My wife painted the red shoe on the left.

Row based testing in MbUnit (i.e. RowTest)

Jonathan de Halleux, aka Peli, never ceases to impress me with his innovations within MbUnit. In case you're not familiar with MbUnit, it's a unit testing framework similar to NUnit.

The difference is that while NUnit seems to have stagnated, Jonathan is constantly innovating new features, test fixtures, etc... for a complete unit testing solution. In fact, he's even made it so that you can run your NUnit tests within MbUnit without a recompile.

His latest feature is not necessarily a mind blower, but it's definitely will save me a lot of time writing the same type of code over and over for testing a range of values. I'll just show you a code snippet and you can figure out what it's doing for you.

 

[TestFixture]
public class DivisionFixture
{
[RowTest]
[Row(1000,10,100.0000)]
[Row(-1000,10,-100.0000)]
[Row(1000,7,142.85715)]
[Row(1000,0.00001,100000000)]
[Row(4195835,3145729,1.3338196)]
public void DivTest(double num, double den, double res)
{
Assert.AreEqual(res, num / den, 0.00001 );
}
}

 

And if you're anal like me and wondering why I chose "num" instead of "numerator" etc... Purely for blog formatting reasons. ;)

UPDATE: Jonathan points out that negative assertions are also supported. Here's an illustrative code snippet. I can't wait to try this out.

 

[RowTest] 
[Row(1000,10,100.0000)]
...
[Row(1,0,0, ExpectedException =
typeof(ArithmeticException))]
public void DivTest(double num, double den, double res)
{...}
Technorati tags: ,

Free Idea For Google Desktop

Allow users to configure Google Desktop to search their GMail accounts. Most of my personal email isn't going to be in Outlook. It'll be in my web-based accounts.

Evaluating Free Desktop Search Options: Copernic

Copernic LogoAfter reading the reaction around the net about Google Desktop (GD for short), one common complaint I noticed is the use of a web browser for local searching. Why use a web browser to search locally and forego all the utility and benefits a rich client can provide?

So I thought I'd start trying out some of the free alternatives to GD. One that is mentioned quite often is Copernic. I decided to uninstall GD and give it a whirl.

So far, I'm not quite satisfied. I left it running overnight and it's still not done indexing my hard drive. Not only that, while it's indexing, my computer runs at a snail's pace at times. I often have to restart it to reclaim my computer's resources. In comparison, GD finished indexing within a much shorter time span with a nearly imperceptible impact on my computer's performance.

One area where Copernic shines above GD is the UI. Copernic provides options for refining the search parameters just below the search input. When you search for emails, the search result window breaks down the results by date. You can see them grouped into emails received Today, Yesterday, Last Week, Last Month, This Year, and so on...

One shortcoming that both engines share is the inability to specify file types to search other than the preconfigured ones. For example, I would like to search my C# files that have the .cs extension. No can do.

So the search continues. I could shell out for X1, but I'd like to find a free product I can use at both work and home. I read about another product to try at home, but forgot its name. In any case, I'll keep you posted.

UPDATE: Whoops! Apparently you can configure Copernic to index arbitrary file types through the advanced options dialog. Thanks to Eric for the tip.

What Is That Liquid Falling From The Sky?

A strange phenomena occurred last night and into this morning here in Los Angeles. I kid you not, but water... fell from the SKY!

Near panic ensued throughout the city as Angelenos tried to make sense of this unexpected situation. My league soccer game was cancelled due to poor field conditions (aka mud).

Fortunately, I had a backup plan. Every Saturday and Sunday I have a pick-up game with a wonderful group of people. The field we play on was in need of water and by 2 PM was in perfect condition. Water even fell from the sky again in the midst of our game. It was a beautiful experience.

Afterwards, my brother-in-law took us out for dinner at The Lobster. Oh man, is that food ever good! Try the scallops.

TDD Is Great...Except When It Isn't

Saw this post by Craig Andera about Test Driven Development and I have to say I completely agree with him.

I've been doing TDD for several years now and I tend to restrict it to testing business and data access layers. Currently, it's not practical to perform comprehensive TDD for UI layers (though tools like NUnitAsp and NUnitForms help).

Even these tools don't address one of the biggest challenges when it comes to testing a UI layer. The UI layer is the layer most likely to change and change often. After spending a few hours building your tests, some guy in marketing will call you up and say, "can we replace that button with a table of data with clickable rows?" What now?

Unit tests tend to be quite fragile when faced with a changing UI layer. Human testers have no problem dealing with such change, but your unit tests definitely will.

My recommendation for testing the UI layer are combining test scripts (for human testers) along with writing unit tests when a bug is found in the UI layer. At that point the UI should hopefully be frozen enough that writing a unit test that exposes a bug and then fixing the bug will be a worthwhile investment for regression purposes.

Work-life balance

FastCompany Read this article at FastCompany pointed to by Steve Maine and maybe I'm lazy, but I totally disagree.

The article makes the point that the concept of "work-life balance" is a pipe dream. What the article fails to mention are the associated health problems for many workaholics. For programmers in particular, ailments such as RSI are common (though many programmers such as myself count programming as a hobby as well which would also contribute).

The article briefly dismisses the European notion of "Working To Live". I think in doing so, it fails to address the societal and cultural issues that often drive a work-life imbalance. How successful is this notion of succeeding at all costs as a source of fulfillment? The article mentions that imbalance is required to gain real productivity, but is that the measure of one's success?

It's well documented that Americans tend to spend their hard earned money on things and possesions while Europeans spend more on vacations and events. Should work be the primary defining character trait of a person? In the U.S., the first question in any social setting is "What do you do?". In many European countries, it's a social gaffe to ask that of a stranger. Why not ask, "What do you like to do?".

It's my contention that this single minded focus on materialism (and I'm not totally against materialism as I LOVE my iPod) is the driving force behind working too much. If one were to step back and look at what really gives one fulfillment, I think priorities will often be rearranged. Not that I'm against working hard. I love to write code and read books about coding and software management in my spare time. However, I also realize the value of defining myself along other interests as well. I realize the value of maintaining my health via excercise and of my mental health through maintaining meaningful relationships with friends and family.

It reminds me of something I've heard somewhere or other. How often do you hear people in the twilight of their lives or on their death beds reflect on the wonderful time they spent at the office?

Hilarity: Bible Study With Bush

Bush PraysSaw this going around the web. Classic!

Dear President Bush, Thank you for doing so much to educate people regarding God's law. I have learned a great deal from you and try to share that knowledge with as many people as I can. When someone tries to defend the homosexual lifestyle, for example, I simply remind them that Leviticus 18:22 clearly states it to be an abomination. End of debate. I do need some advice from you, however, regarding some other elements of God's Laws and how to follow them:

1. Leviticus 25:44 states that I may possess slaves, both male and female, provided they are purchased from neighboring nations. A friend of mine claims that this applies to Mexicans, but not to Canadians. Can you clarify? Why can't I own Canadians?

2. I would like to sell my daughter into slavery, as sanctioned in Exodus 21:7. In this day and age, what do you think would be a fair price for her?

3. I know that I am allowed no contact with a woman while she is in her period of menstrual uncleanliness (Lev. 15:19-24). The problem is, how do I tell? I have tried asking, but most women take offense.

4. When I burn a bull on the altar as a sacrifice, I know it creates a pleasing odor for the Lord (Lev. 1:9). The problem is my neighbors. They claim the odor is not pleasing to them. Should I smite them?

5. I have a neighbor who insists on working on the Sabbath. Exodus 35:2 clearly states that he should be put to death. Am I morally obligated to kill him myself, or should I ask the police to do it?

6. A friend of mine feels that, even though eating shellfish is an abomination (Lev. 11:10), it is a lesser abomination than homosexuality. I don't agree. Can you settle this? Are there "degrees" of abomination?

7. Lev. 21:20 states that I may not approach the altar of God if I have a defect in my sight. I have to admit that I wear reading glasses. Does my vision have to be 20/20, or is there some wiggle-room here?

8. Most of my male friends get their hair trimmed, including the hair around their temples, even though this is expressly forbidden by Lev. 19:27. How should they die?

9. I know from Lev. 11:6-8 that touching the skin of a dead pig makes me unclean, but may I still play football if I wear gloves?

10. My uncle has a farm. He violates Lev. 19:19 by planting two different crops in the same field, as does his wife by wearing garments made of two different kinds of thread (cotton/polyester blend). He also tends to curse and blaspheme a lot. Is it really necessary that we go to all the trouble of getting the whole town together to stone them (Lev. 24:10-16)? Couldn't we just burn them to death at a private family affair, like we do with people who sleep with their in-laws (Lev. 20:14)?

I know you have studied these things extensively and thus enjoy considerable expertise in such matters, so I am confident you can help.

Bush Not Concerned About Osama

Time to get political. I loved how Kerry caught Bush off-guard when he pointed out that in 2002, Bush said he wasn't concerned with Osama. Realize this is at the same time our troops were in Afghanistan looking for the bastard. I think that beats the out of context "nuisance" quote by a mile, because even in context, Bush's quote is damning.

Calling Google Desktop A Disappointment Is Premature

Dave Winer points to a blog posting by Erik Speckman calling Google Desktop Search a disappointment. One complaint that Dave shares is that Google search only works with certain file formats. He wants to be able to add plug-ins for file formats it doesn't already understand.

Well first of all, this is a BETA technology. I think it's a tad bit premature to call it a disappointment just yet. It's already far better than any other free desktop search utility out there.

Secondly, it may well be as extensible as Dave and Erik would like, but as a BETA product, we can't be sure yet because such interfaces are not published. Scott Hanselman started digging into it a bit and noticed various dlls used to implement searching across IE and Outlook. That suggests that there might be a plug-in architecture they will expose later (perhaps after getting feedback during the BETA trial). In any case, Scott's peek inside is a worthwhile read.

UPDATE: Erik notes in reply on his blog that I have a valid point regarding Google Desktop's BETA status, but that the point of a BETA is to gather criticism. I agree wholeheartedly and I think he gives some solid suggestions to the Google team. The title of his reply is "Google Desktop Search BETA is a disappointment" (emphasis mine). That clears it up for me. :)

If you're a Windows, Office, and Outlook user like me, I think you'll find the BETA worthwhile. If not, Google has some work to do to make sure the final product isn't a disappointment for users like Erik and Dave. Hopefully we'll see an extensibility framework come out for it.

Google Brings You Desktop Search

Now use the power of Google on your desktop via Google Desktop.

[via Doc Searls]

VS.NET Add-In For Source Code Formatting as HTML

Colin sent me an email pointing me to an add-in he wrote for VS.NET that allows you to copy selected source code to the clipboard as syntax highlighted HTML.

By selecting some code and right clicking the code editor, you'll see an option to Copy Source as HTML.

Selecting that menu item brings up a dialogue where you can configure some options. It's based on my favorite code to HTML formatter by Manoli.

Below is an example of a code snippet using this tool:

/// <SUMMARY>
/// Sets the stack trace for the given lock target 
/// if an error occurred.
/// </SUMMARY>
/// <PARAM name="lockTarget">Lock target.</PARAM>
public static void ReportStackTrace(object lockTarget)
{
  lock(_failedLockTargets)
  {
    if(_failedLockTargets.ContainsKey(lockTarget))
    {
        ManualResetEvent waitHandle = 
            _failedLockTargets[lockTarget] 
                 as ManualResetEvent;
        if(waitHandle != null)
        {
            waitHandle.Set();
        }
        _failedLockTargets[lockTarget] = new StackTrace();
        //TODO: Now's a good time to use your
        //favorite logging framework.
    }
  }
}

Colin, thanks for pointing me to this. This is freakin' awesome!

Now, if I could have a short-cut that would use the default options and immediately put the selected source in the clip-board, that would just rock my world. Also, one minor niggle I've had with the Manoli formatter is that the xml comments tags and the triplle slashes (such as ///

) should be gray to mimic VS.NET instead of all green. How hard would it be to fix that?

TimedLock with Stack Traces Strikes Back

By now you probably think I have an unhealthy obsession over the TimedLock struct. Well, you're right. I think it's emblematic of the right way to do things and shows that the right way isn't always the easiest way.

In Ian's last post on the TimedLock, he talked a bit about the performance considerations with my solution to keeping track of stack traces in a multi-threaded situation. To sum, my solution is pokey in certain situations. As always, measure measure measure.

However, Ian mentioned a solution outlined by Marek Malowidzki that avoids creating a stack trace on every lock acquisition. Instead, he only stores the stack trace when a lock timeout occurs, thus avoiding the performance penalty of my implementation. Unfortunately, there's no source code posted for examination.

So I decided to implement Marek's solution based on Ian's write up. As Ian mentioned, it would probably be best if the blocking thread didn't throw an exception, but logged diagnostic information if it detects that some other thread timed out while trying to acquire a lock on the target. I put a very helpful //TODO: right where that should happen since everyone has their own preferred logging framework.

As stated in the write-up, when thread fails to acquire a lock, it adds the object it was trying to lock to a Hashtable as a key with a NULL value. When the blocking thread is about to exit the synchronization block, it checks this hash table and if it finds the object it is locking in there, it will set the value for the Hashtable item as its own stack trace.

Thus if you catch the LockTimeoutException, you can have it try to obtain the stack trace from the Hashtable (supplying a wait since it might not be there immediately). However, there's one potential problem here. If you don't remove that object from the Hashtable after you've looked at it, the next time you lock on that object and then release it, your blocking thread will think an error occured and log some diagnostic information. This isn't too bad since it doesn't cause a LockTimeoutException to be thrown.

One thought I had was to check the Hashtable when I first successfully acquire the lock on a target and remove the target if its already there. However, that's not safe as it's quite possible that another thread failed after the blocking thread acquired the lock but before it examines the Hashtable.

Instead, when you call GetBlockingStackTrace, it retrieves the stack trace from the Hashtable, stores a reference locally, and then removes it from the Hashtable.

In any case, I've posted the source code here.

DISCLAIMER: The code to keep track of stack traces is designed for debugging only and is turned on by setting the conditional compilation variable #DEBUG = true. I make no guarantees and pity the fool who deploys this version of TimedLock.cs in a production system with #DEBUG = true. Please let me know if you see any problems with this implementation. So far it passes my tiny suite of unit tests.

UPDATE: I accidentally linked to the old TimedLock. The link above has been updated.

UPDATE #2: Eric discovered a subtle bug in my older implementation of TimedLock which he describes here. Nice work in tracking that down!

RIP Christopher Reeves aka Superman

Heard on NPR this morning that Christopher Reeves died of complications due to a bed sore infection. I sincerely hope the legacy of his activism lives on.

Joined a Soccer Team

My knee is now to the point that I'm ready to play in a local soccer league. My first game is this Sunday in Van Nuys. Wish me luck and no injuries. I've been watching World Cup Highlights so I'm ready to samba the beautiful game.

Class photo fun

Found this on Boing Boing. School photos will never be the same. I always thought the point was to look miserable.


Mrs. Xiang sex-ed class demonstrate a keen knowledge of their studies.

Click the pic for the larger image.

UPDATE: Found a news story about this particular photo here.

Blogging Is Pure Vanity: Profile Of A Vain Blogger.

PubSub is no longer around, so those links will be broken. I’ve written a new post that provides fresh opportunities for being a vain blogger.

Vanity I'm not the first to say it and I probably won't be the last. But blogging is pure vanity, and new services out there just make it easier and easier to inflate one's head.

For starters, the vain blogger will subscribe to his own RSS feed (or ATOM feed) in his favorite RSS reader. The vain blogger will assure you that this is for quality assurance purposes, but the astute reader can see right through that smokescreen. Obviously this is just the blogger's vain longing to gaze at his own writing akin to staring at a mirror.

The next step is to install the Google Toolbar so the vain blogger can check his Google PageRank every day, in hopes of seeing even the slightest climb validating his pathetic existence.

"Hey! Look at that. It moved up a notch from 3 to 4!!! I'm a GOD! You really love me! Now please click on the ads below and make me RICH!"

Naturally, if the vain blogger is using .TEXT, he'll religiously check the admin section hourly for page view and aggregator stats and pore over the referrer lists looking for that lone referral that is NOT a result of a Google search.

The more sophisticated vain blogger realizes poring through referrer logs is futile and steps it up a notch by using tools such as Technorati, Feedster, and PubSub. These tools enable the vain blogger to register his or her blog on their search engines and then subscribe to a feed of blogs that mention or link to his own. Ah... this takes the blogger to the next level of vanity. But it doesn't stop there.

Pubsub provides a link rank page. Enter a domain and it displays where it ranks in the blogosphere. Today my blog jumped from 2048 to 1893! Wohoo!...I think. I have no idea what that number means or what the total range is, but that's inconsequential to the vain blogger. It's a number, and it's better than it was. That's all that matters.

What is vanity if there is nobody around to behold it. Thus the vain blogger whores himself out by linking to Scoble or Dave Winer in hopes of a back referral and perhaps endorsement. Better yet, he'll try to get link to his blog posted on BoingBoing to drive some real traffic to the site.

Ah yes, as we see, blogging is pure vanity. As the author of this respectable blog, I vow not to drag it and its readers through the dirt of such degrading procedures. No no. I will not debase myself in such manner and will strive to stay on the high ground. I will retain my dignity and integrity.

Unless of course you can get me on Slashdot...

UPDATE: One tool on the vain blogger's utility belt I forgot to mention is blatant self promotion. Got that one from Brian Bailey's tips for a better blog, but it applies just as well to vanity.

VP Debate Photo


Cheney vs Edwards

Clubs In L.A. and The Price Of A Drink

With my brother-in-law in town from Tokyo, it is important that we survey the local club scene. Serious business. The past two Saturdays we went out to see different DJs at Avalon. I'm not sure I want to go back any time soon.

One thing that bothers me is the price of a drink at a club. I expect a mark up, but $10 for a few squirts of alcohol in a plastic cup!? Give me a break! Those prices are insane and it literally sickened me. After my fourth drink.

Some More Pics Of Twiggy

So Twiggy's a fast learner. She now knows that the proper place to do her thing is outside and not in the house. She even knows to whine if she needs to go so. The vet removed her stitches and she has an appointment to get spayed soon. We're a little worried about it as we hear it can be a difficult operation, but I'm sure she'll do fine.


Twiggy in her favorite spot

She's also a friendly dog. She scared this poor chihauha puppy by trying to run up to it and greet it. The only time Twiggy barks is when she can hear a dog nearby and wants to play.


Twiggy on alert for terrorists while the shadows approach.

We're waiting for some sweaters and a parka we ordered for her. She's all skin and bones and we hope to take her along when we visit my folks in Alaska for Christmas.


Giving us the evil eye.

In any case, we're doing all we can to provide her with a good home and she seems happy for it. She never comes to me when I call her to, but the instant I sit on a couch, she shows us her true speed with a mad dash and a hop by my side.


With her mommy.

The next step for Twiggy is to start her off on some elementary topics in OO design and hopefully progress to an understanding of how to build enterprise systems using the .NET platform. The expense is getting to the point that she needs to earn her keep. Besides, I hope this to be a technical blog and she should be providing content. Her first assignment is to provide an overview of generics in .NET 2.0. Good girl! Good girl!

Mother-In-Law Visiting

Akumi's mother is visiting us from Tokyo for a couple weeks. I have to say, if she decided she wanted to move in, I would not complain.

The other day she cooked us a fantastic Japanese dinner, with a couple dishes I had never tried before. When I got home yesterday, she had cleaned our back patio and fed the dog.

The only problem is that she doesn't speak much English (though she understands more than she lets on) and I speak even less Japanese. So we don't spend a lot of time in conversation, but she seems to enjoy my style of physical comedy (intentional or not).

Response.Redirect vs Server.Transfer

When conducting phone interviews, I like to ask a few technical questions just to make sure that a candidate isn’t trying to blow smoke up my... well we don’t need to be overly illustrative do we?

I absolutely do not intend the questions to be nitpicky. Nor do I feel they are totally representative of an interviewee’s depth of knowledge. I save the probing questions for an in-person interview.

However, if a candidate claims to have one or two years experience working with ASP.NET, there are some basic facts and principles that a mid-level developer should know.

For example, please compare and contrast the result when calling Response.Redirect and Server.Transfer from within a Page class. It boggles my mind that most candidates I talked to couldn’t answer this question. These methods are used quite commonly and the differences are important.

Sure they both present the user with the contents of a new page. But how they do it has ramifications for you web app. With a call to Response.Redirect, the server basically sends an HTTP header back to the client browser with an HTTP status code stating that the object has moved along with the new location to find it.

See the snippet of an example HTTP header below when Response.Redirect("somewhere/newlocation.aspx") is called.

HTTP/1.1 302 Object moved
Server: Microsoft-IIS/5.0
Location: somewhere/newlocation.aspx

This tells the browser that the requested resource (page) can be found at a new location, namely somewhere/newlocation.aspx. The browser then initiates another request (assuming it supports redirects) to somewhere/newlocation.aspx loading its contents in the browser. This results in two requests by the browser.

One ramification of this is that if the initial request was a form POST, the posted form fields are not available in the second request. Likewise query string parameters are unavailable unless the page that issues the redirect explicitly tacks them on. Also, since the browser initiates the second request, it is possible to redirect to a page on an external site.

In contrast, Server.Transfer transfers execution from the first page to the second page on the server. As far as the browser client is concerned, it made one request and the initial page is the one responding with content (this point often confuses new ASP.NET developers as the browser still shows the URL of the initial page even though the content is generated by the second page. It all makes sense when you understand what is happening.).

The benefit of this approach is one less round trip to the server from the client browser. Also, any posted form variables and query string parameters are available to the second page as well (however these can be cleared by passing in false for the second parameter).

One thing to be aware of is that if the first page wrote something to the Response buffer and you don’t clear it, then any output from the second page will be appended to the output of the first. This is often the cause of a weird behavior where it seems that a page is returning two different pages. Also, since the transfer happens on the server, you cannot transfer a request to an external site.

You’ve been warned. Make sure you wow that next interviewer with your knowledge of ASP.NET.

For extra points, explain how ASP.NET sometimes returns a "View State Is Invalid" error message when you call Server.Transfer("URL", true). The explanation is here.

Also, note that the "Response" and "Server" objects I refer to are properties of the System.Web.UI.Page class. The types for these objects are System.Web.HttpRequest and System.Web.HttpServerUtility respectively.

If you like understanding how things work under the hood, I highly recommend Fritz Onion’s book, Essential ASP.NET 2.0. It is personally my favorite book on ASP.NET as it covers only what is essential, but at a deep enough level to really get something out of it.

His 2.0 book is actually a continuation on his 1.0 book, Essential ASP.NET With Examples in C#.

VIDEO: Flying To India For Tech Support

This is a hilarious video from the Conan O'Brien show.

What happens when you need a personal touch to your computer problem and your tech support department is in India? Most people would just call a tech support hotline, but not comedy writer Andy Blitz. He decides to fly to India with his computer and get it fixed in person.

Watch and find out.

My Four Tips For Job Seekers

Ok, I just have to take a moment to rant a bit. We’re currently looking for some mid-level developers as well as a System Administrator. Naturally we posted a job description on Dice.com and craigslist.org. In general I find the best candidates through referral, but occasionaly I’ll get a few good ones through a job site.

If the crop of resumes and cover letters I received is a fair indication of the quality of developer job applicants out there (and I hope and believe this is not the case), then either the U.S. developer population is nearly fully employed (in which case I’m cool), or outsourcing to offshore countries is starting to make a lot of sense.

So let’s start of with an episode of:

Haacked.com’s 4 Tips For Job Seekers

1. Your cover letter and resume should be an example of the best work you can do.
Initially, I have absolutely nothing to judge you by except your resume and cover letter. So take the time to get it right. If you’re applying to be a system administrator and you spell virus as viurs, I have to wonder if you’ll take the same care with our production servers.

If you are a developer, don’t tell me I spend 5 years working ASP.NET sites. Try to squeeze a preposition in there. I get absolutely giddy with joy when I receive a cover letter that is concise and well written. Compared to the other gruft I get, a well written cover letter is page gripper. I’ll take it to the beach and read it over and over.

2. Learn to use a spell-checker and have someone else proof-read your resume.
As a developer, I understand that a spell checker chokes on the line where you list your skills as

Expert in C#/C++/C/PERL/J++/WMD/ASP.NET/Stamp Collecting/Java/J2EE/Oracle/Cisco/SQL/Table tennis/Chess/Jai-Alai/Math/
But you’re supposed to be a problem solver. Figure it out. If your resume has obvious spelling and grammar errors, it reflects poorly on yourself (see tip #1).

3. Provide working and professional contact info
I kid you not, I received a resume with the email address WatchYoBack@[Domain Witheld].com.

Trust me, I’ll do exactly that by not calling you. In this particular situation I didn’t notice the email address and tried to call the applicant. Both his cell number and land line were disconnected. Apparently you didn’t watch yo phone bills.

I can’t imagine what would compel you to send me a resume with phone numbers that don’t work.

And why use such an email address when you can create one for free. It doesn’t have to be your name. It can be something obtuse or abstract. But I’d recommend against threatening people to watch their back in your email.

Another applicant had an email address where the domain name is slang for sexual intercourse. Something to do with uglies. That one I found funny, but would not recommend it as not everyone shares my sense of humor.

4. Lastly, do provide an updated resume
I was speaking to one candidate and he started talking about recent employers that I could not find on his resume. His last job listed ended in 2003. When I asked about this discrepancy, he apologized and said that he hasn’t updated his resume in a while. That’s odd I thought, I downloaded this resume off his website like he asked me to. There were two links, one for a resume as a Word document and one for a resume as a PDF.

Apparently neither of those resumes were updated. I was supposed to click on a tab of his website with the word experience and look at his HTML formatted resume. Are you trying NOT to find a job? Do us all a favor, send a nicely formatted resume when you apply for the job, or don’t apply at all.


That’s it. Only four. I don’t have time to tell you how to look for a job. Besides, I think Joel Spolsky did a fine job in this article. You might be quite qualified, but you’ve disqualified yourself by using poor English, bad spelling, and general inability to communicate well. Undoubtedly I’m preaching to the choir. But if you know people looking for a job, remind them of these four tips.

And with that, I end my rant. Have a nice weekend everybody.