| |
 |
Tuesday, March 16, 2004 |
 |
Monday, June 02, 2003 |
 |
Saturday, November 16, 2002 |
John Lam comments on Joel Spolsky's Law of Leaky Abstractions.
... they had to understand their technology at one level of abstraction lower than where they worked every day. ADO programmers needed to understand how their database worked, ASP programmers had to understand how IIS worked, Visual Studio developers needed to understand how the wizard-generated code worked.
11:24:36 PM
|
|
 |
Wednesday, October 30, 2002 |
 |
Tuesday, October 22, 2002 |
 |
Sunday, October 20, 2002 |
I'm interested in .NET clients without client-side installs. Chris Sells has a great example in his Wahoo game. I love to click on a link in a browser and see a Windows program run with no (visible) installation. He has an article about .NET Zero Deployment on MSDN, where he says Only a technology that provided a deployment as compelling as HTML would stand a chance of unseating it. Jason Clark covers the same issue in his piece, The Return of the Rich Client.
The same feature, along with CLR hosting in IE, lets .NET controls work in the browser without that annoying installation dialog that ActiveX control have. Jay Allen's article on Host Secure, Lightweight Client-Side Controls in Microsoft Internet Explorer describes how that works.
And to round out the topic with some good overall perspective on why browser front-ends are so effective, Paul Prescod has this piece - The Browser will Rise Again.
10:48:22 AM
|
|
 |
Saturday, October 12, 2002 |
From the beating-my-head-against-a-brick-wall department: I snagged GotDotNet's Message Board sample and put it up on my machine at work to start a new intranet for the engineering group I'm in. In keeping with the idea that an intranet must be a communications tool that all employees check every day, I made a "Daily DotNet" forum and posted a code puzzle every day, to get some discussion going.
The questions were mostly snagged from books. I got this one from Prosise's book:
Spot the bug in the following code:
int a = 1;
Monitor.Enter(a);
try {
a *= 3;
}
finally {
Monitor.Exit(a);
}
I was hoping to have some conversation about value types and boxing, but I had to just explain the answer, because there was no conversation. (a is boxed twice into 2 different objects, so there's a runtime error when Monitor.Exit tries to unlock an object that isn't locked). In five days of posts like the one above and in spite of repeated e-mails, I got exactly two one-line responses to the same question. From a group of thirty engineers. What's up with that?
3:24:56 PM
|
|
My first impulse was to take exception to this from Petzold's .NET
book:
Don't do this, however:
Size.Width *= 2; That's
setting a property of a property. For reasons beyond the comprehension of people
who don't write compilers, it's not allowed. In a later example, he
gives the right way to do this kind of thing, but he doesn't explain why
the statement doesn't work. Should he have explained it?
.NET has merged all Microsoft development cultures (Visual C++, Visual
Basic, ASP) into one, so the new culture must satisfy the needs of those diverse
groups. I've enjoyed developing in all three environments, but have often been
frustrated by the lightweight nature of many VB conference sessions, books, and
magazines, relative to the C++ equivalents (DevelopMentor providing some notable
exceptions). Obviously the reason is that VB has a wider appeal than C++. It takes less skill to use VB but that doesn't mean it can only be used for development projects where
less skill is needed. Just ask Joel.
So
back to Petzold's comment above. Should a comprehensive book like this just skip
over this issue, because developers don't need to know it or won't be able to
understand it? Shouldn't all .NET developers understand the differences
between reference types and value types? I think so. I hope so.
9:22:14 AM
|
|
 |
Friday, October 11, 2002 |
Ah Google, how I do love thee. I had to restore Radio because of a complete hard-drive refresh and I somehow lost some of the latest posts. Gone from my hard drive and of course when I started Radio it automatically posted everything, thereby wiping them from the server as well. But I simply searched Google for something in the the latest one and clicked on that beautiful "cached" link on the results page. There they were, waiting to be copied and pasted, for reposting on another day. Not that they are long lost treasures, of course; but the confidence with which I went to Google to salvage them without missing a beat was a nice feeling.
11:19:13 PM
|
|
 |
Sunday, September 15, 2002 |
Fontscape is a new site intended to help graphic designers select fonts. I'm a software designer, but I can still appreciate art (occasionally) and I spent a fascinating hour just admiring the work. I also tried Identifont but it didn't find Lucida Console and it thought Anonymous was Pueblo. Maybe I'm using it wrong. Wait! It got Century Gothic right. Whoops - it thinks Georgia is Berling. I don't expect I'll ever actually need to use it for its intended purpose, luckily. [from webgraphics]
10:23:21 PM
|
|
 |
Saturday, September 14, 2002 |
A great gift combination.
[from DaveZilla]
1:49:01 PM
|
|
 |
Monday, September 09, 2002 |
Cassini managed code web server (link from On The Mark). Why is this interesting? Well, for starters it shows how you can easily host your own light-weight http server. Second, a .NET-based server should be immune to buffer overrun attacks (since the CLR is watching for array indexing errors). Finally, it might make a great host for web services (without some of the other overhead that IIS introduces for a general purpose site).
It seems to me that another use for an easy-to-create local web server is to make the type of application I'm using right now, Radio Userland.
8:48:17 PM
|
|
Ten Best Intranets of 2002. We also found several companies that used a daily lunch menu as their killer app.
I think the killer app phrase has lost a bit of its weight since it was used to describe the spreadsheet, e-mail, and the web itself. But the point here is simple: if the goal is to get every employee to visit the Intranet every day, you need to post something new every day that they care about. Lunch!
8:34:20 AM
|
|
 |
Tuesday, September 03, 2002 |
Wow! I made a haiku!
Ask this one question
Of each particular thing
What is its nature?
2:38:43 PM
|
|
 |
Sunday, September 01, 2002 |
My favorite scene from Silence of the Lambs:
Hannibal Lecter : First principles, Clarice. Read Marcus Aurelius. Of each particular thing ask: what is it in itself? What is its nature? What does he do, this man you seek?
Clarice Starling : He kills women--
Hannibal Lecter: No! That is incidental. What is the first and principal thing he does, what need does he serve by killing?
Clarice Starling : Anger, social resentment, sexual frustration--
Hannibal Lecter : No, he covets. That's his nature. And how do we begin to covet, Clarice? Do we seek out things to covet? Make an effort to answer.
Clarice Starling : No. We just--
Hannibal Lecter : No. Precisely. We begin by coveting what we see every day. Don't you feel eyes moving over your body, Clarice? I hardly see how you couldn't. And don't your eyes move over the things you want?
I was reminded of it while reading First, Break All the Rules. The authors claim (based on the results of a huge Gallup study) that the one thing that all great managers have in common is that they know that "each individual ... is true to his unique nature".
People don't change that much,
Don't waste time trying to put in what was left out,
Try to draw out what was left in,
That is hard enough.
I feel sure Peter Drucker would agree. Don't focus on people's weaknesses (especially if you call them "opportunities for growth"). Focus on people's strengths.
11:07:14 PM
|
|
 |
Wednesday, August 28, 2002 |
.NET books
One of the many things I'm enjoying about .NET is the unprecedented high quality of the stuff written about it. Reading Petzold's .NET book reminded me of his venerable Programming Windows 3.1, of course, because he covers the same material (and nothing else). The earlier book was simply indispensible because that's all we had. He's been such a hero all these years because, for many of us, we wouldn't have been able to write software at all if not for his book. But things have changed. With our new learning challenge, .NET, there are many excellent sources of knowledge (not the least of which is the Dynamic Help built into Visual Studio).
I've just finished Jeff Prosise's Programming .NET and it's just wonderful. His huge section on ASP.NET - half the book - is exactly what I needed; and every one of the five big chapters on WinForms, ADO.NET, Multithreading, XML, and Remoting covers the material in a masterfully clear and simple way. It's almost the best .NET book I've read. But, ahh, I doubt whether anyone else can write technical books as well as Jeff Richter. I've read every word of his .NET Framework book twice and referred to much of it a dozen times. Every .NET developer, whatever parts of .NET he or she specializes in, should read Richter.
I'm also enjoying using Drayton, Albahari, and Neward's C# in a Nutshell as a reference. I take it with me everywhere I go (no, seriously) and dip into it several times a day for a satisfying .NET snack. I particularly enjoyed reading a chapter in one of the other books, then going through the corresponding chapter and FCL references in Nutshell. It's a pity it doesn't have ASP.NET, ADO.NET, WinForms, and Remoting, but at more than 800 pages it's already a big Nutshell. I suppose there'll be a .NET Enterprise in a Nutshell soon. I hope so.
Excellent books!
5:26:36 PM
|
|
 |
Tuesday, August 27, 2002 |
 |
Monday, August 26, 2002 |
There just isn't enough bandwidth to do good design when a team is geographically dispersed. I'm not saying it can't be done at all, but the results are vastly better when the entire team is physically in the same location. I'm convinced of this, and will never agree to do software development with a dispersed team. [Joel on Software]
I love to work from home, and yet I agree with Joel. I live twenty minutes from the office and go in three or four times a week to meetings, lunches, training sessions, and, most importantly, design sessions. We have guys who call in from the Connecticut office and one guy who works from his home in North Carolina, and it's not nearly as effective as being there. At home I do all my programming and my deepest thinking and I just love the increased productivity. Plus it lets me integrate my work with my life in a way that's more natural to me.
Working from home and the office is the best of both worlds.
2:09:32 PM
|
|
 |
Sunday, August 25, 2002 |
Ray Ozzie is encouraging Groove employees to write blogs and has posted some Personal Website and Weblog Guidelines. What an enlightened company! I seriously doubt whether my employers have heard of weblogs.
10:25:40 AM
|
|
 |
Wednesday, July 10, 2002 |
A question I ask myself quite often these days: am I doing exactly what I should be doing right now?. Yesterday I played Warcraft III for four hours straight from 7 am, when my wife left for work, until 11, when my kids woke up (recovering from many late nights during our recent vacation). I never get a block of uninterupted time like that to just play. Absolutely the right thing for me to do. And again this afternoon; I've been reading The Salmon of Doubt. It's sad to stop reading now and then and look at Douglas's photo on the back flap, but I find I'm really appreciating this final work from one of my very favorite writers. I'm getting better at doing exactly what I should be doing right now.
4:29:18 PM
|
|
 |
Friday, June 14, 2002 |
Deterioration at Amazon
The customer reviews at Amazon have been one of the unexpected successes of the web for me, because I had no idea that I would find strangers' opinions so useful. I have come to rely on them. So it's sad to read stuff like this (along with a rating of 5 stars):
Haven't yet received the book (...) but judging by the cover it is going to be an excellent and helpful tome.
The saddest part is that 11 out of 56 people found that review helpful. And this, for the same book, (also worth 5 stars):
Could be considering ordering the book (...) I must agree that the ease of use of the Times font is a superb idea.
In fact, all four reviews of the book are completely content-free.
3:38:09 PM
|
|
 |
Wednesday, June 05, 2002 |
A moment of XSLT clarity from the most incredibly useful mailing list I've ever used:
> I understand that the value of a variable cannot be modified
> once it has been assigned, but is it possible to allocate a
> global variable at the start of a stylesheet and then assign
> it a value at a later time, such as within a named template?
No, it isn't possible. You need to stop thinking sequentially.
There is no such thing as "a later time" in XSLT.
Michael Kay
9:24:05 PM
|
|
Including the same JavaScript file on the client and the server
I've often been frustrated that there is no simple way to include a file of JavaScript functions on the server (ASP) and the client (the browser). I have a whole library of functions that convert, format, process and otherwise stretch and squeeze dates, strings, and xml documents. I keep copying code from a server-only file to a client-only file or vice versa. So today I finally fixed the problem by writing a function (to be executed on the server) that reads the file, chops off the silly <% and %> that the ASP include insists on, and writes it into the page. It's just:
function convert_to_client(filename) {
var fso = Server.CreateObject("Scripting.FileSystemObject");
var ts = fso.OpenTextFile(filename, 1); //ForReading
Response.Write("<script language='javascript'>");
var code = ts.ReadAll();
Response.Write(code.substring(code.indexOf("%")+1, code.lastIndexOf("%")));
Response.Write("</script>");
}
My test ASP is like this (the convert_to_client function is in script_converter.js):
<%@language="javascript" %>
<!-- #include file = "test.js" -->
<!-- #include file = "script_converter.js" -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
<head>
<% Response.Write(convert_to_client(Server.MapPath("test.js"))); %>
<script language="javascript">
function runtest() {
client.innerText = test("from the client");
}
</script>
</head>
<body onload="runtest();">
server: <% Response.Write(test("from the server")); %>
<hr/>
client: <span id="client"></span>
</body>
</html>
Notice that test.js is included on the server, and also passed to the convert_to_client function to be written to the page so that it is available on the client. The test.js file is just this:
<%
function test(parm) {
return parm;
}
%>
The output when the test ASP page executes is:
server: from the server
--------------------------------------------------------------------------------
client: from the client
4:54:19 PM
|
|
A good article (as usual) from Zeldman on DOCTYPES. In case anyone else uses UltraEdit, here's my taglist for all seven doctypes (remove the linebreaks when you paste it into your taglist.txt):
[Tag Group - DOCTYPES]
0="HTML 4.01 Strict :UEDS:<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd"> ... "
1="HTML 4.01 Transitional :UEDS:<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd"> ... "
2="HTML 4.01 Frameset :UEDS:<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
"http://www.w3.org/TR/html4/frameset.dtd"> ... "
3="XHTML 1.0 Strict :UEDS:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> ... "
4="XHTML 1.0 Transitional :UEDS:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> ... "
5="XHTML 1.0 Frameset :UEDS:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"> ... "
6="XHTML 1.1 DTD :UEDS:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> ... "
7=
8:19:57 AM
|
|
 |
Friday, May 17, 2002 |
The introduction of Cascading Style Sheets was a great idea, but the invention of Hypertext Markup Language was an even better one - and the former depends on proper application of the latter. I'm guilty! But no more. Thanks to dive into mark for links to excellent CSS advice from Jim Byrne, Brainstorms and Raves, and Eric Meyer.
6:03:58 PM
|
|
 |
Thursday, May 09, 2002 |
The only English in an e-mail from this company: The certainly big help is will become firm belief like this to send the mail to the minutes when, our services use the transactions the at the electron it gives. To the minutes when it refuses the mail reception the toil which stands it is but it will grow a reception refusal, when lik it does, it will eliminate you mail from our data immediately and it will give the very last on push. I couldn't have put it better myself.
6:56:33 AM
|
|
 |
Tuesday, May 07, 2002 |
Not Enough Information
Two signposts: Bus to Car Park and Path to Car Park. That's all. No more information. Jeez, it's so simple to get this right. Just give users the information they need to make a decision. How far is the car park?
7:43:41 PM
|
|
 |
Saturday, May 04, 2002 |
My weblog isn't being published anymore! Oh yes it is. Must have been a "touch" issue because this entry fixed everything. rss.xml had been published fine, but not index.html. I'm still getting those "Poorly formed XML text, we were expecting . (At character #172.)" errors, but they don't seem to be causing a problem.
It makes me uneasy, though, that I really don't understand how Radio works. It's wonderfully easy to setup and use, but there's a lot of stuff lurking just out of sight. If I have a problem with an ASP site, I know I can fix it. If it's Perl it will take me a little longer, but I know it's all there for me to discover. But I haven't put in the time to understand Radio's underbelly, and I'm not inclined to do so (I don't know why -- some technologies make me want to uncover their deepest secrets and others just don't). So I know that one day, something inexplicable will go wrong, and I'll end up moving to a tool that has understandable (to me) innards.
2:50:25 PM
|
|
 |
Thursday, May 02, 2002 |
An interesting essay from Boxes and Arrows - The age of findability by Peter Morville:
High-arched ceilings soared above. Luxury retail stores lined the hall. Straight ahead, a black granite elliptical water fountain fired choreographed, illuminated streams of water, “representing the connections made via global travel.” Unfortunately, what I couldn’t find was a sign pointing to one of the 475 public restroom stalls inside this 2-million square-foot complex.
This reminded me of the first paragraph of Len Deighton's novel "Faith":
"Don't miss your plane, Bernard. This whole operation depends upon the timing." Bret Rensselaer peered around to spot a departures indicator; but this was Los Angeles airport and there were none in sight. They would spoil the architect's concept.
11:07:32 PM
|
|
 |
Tuesday, April 30, 2002 |
 |
Sunday, April 28, 2002 |
Suicidal Woman Blocks Traffic, Angry Drivers Tell Her to Jump. She does. A Fredericksburg, Virginia woman suicidal over a split with her husband sat on the edge of an interstate bridge contemplating suicide. A lone officer tried to persuade her away from the edge. However, drivers angry that they had been slowed by the events called on her to jump. With an apology, she does. [kuro5hin.org]
That's it. No more kuro5hin for me. The sadness of this story and the coldness of the discussion about it is just too much. I'm out.
8:52:15 AM
|
|
 |
Saturday, April 27, 2002 |
Zoe Search is slowly taking over from folders in how I use e-mail. [from John Robb's Radio Weblog]
Yes. I don't use Zoe but I feel the same way about searching email. The two issues here are:
- searching email should not be a separate operation from searching my other stuff;
- a hierarchy of folders is an ineffective organizational structure.
Intertwingularity is not generally acknowledged -- people keep
pretending they can make things deeply hierarchical, categorizable and
sequential when they can't. Everything is deeply intertwingled.
-- Ted Nelson
8:53:34 AM
|
|
 |
Wednesday, April 24, 2002 |
This so needed to be said: ...this notion of a cloud of anonymized services that you can discover in real-time and bind together at run-time to create a new application from scratch is just an absurdity. Clay Shirky [from John Robb's Radio Weblog]
6:51:22 PM
|
|
The Joel Test: 12 Steps to Better Code. A score of 12 is perfect, 11 is tolerable, but 10 or lower and you've got serious problems. The truth is that most software organizations are running with a score of 2 or 3, and they need serious help, because companies like Microsoft run at 12 full-time." I score our group at six. Looks like we need serious help. [On The Mark]
I can only claim a puny 2, and that's the obvious ones of source control and bug tracking. But I get to do a pretty respectable amount of .NET and XML work; and I work from home.
6:00:36 PM
|
|
 |
Tuesday, April 23, 2002 |
Another intriguing idea from Simplicity is the Project Room. Every project that is currently in development should have a room dedicated to it. The room has tons of whiteboard space, walls for taping up documents and schedules, and at least one computer. All shared project documents, books, and collateral material are stored there. All face-to-face meetings are held there. It's the place where the project comes together. ... teams need dedicated workrooms where the walls reflect their thinking. If people can leave their work up and continually come back to it, the room itself facilitates rapid decision making.
10:20:43 PM
|
|
 |
Monday, April 22, 2002 |
 |
Sunday, April 21, 2002 |
Should every .NET developer understand the CLR? Here's my opinion:
I've been a Visual C++/MFC/ATL/Win32 developer for a long time now. When I added VB to my toolbox I was struck by two things: first, how much more effective a developer I became (see Joel's article for an excellent explanation of this phenomenon). This was expected, of course. It's what VB is for. The other thing was a surprise - the dumbing-down that went with the VB lifestyle. Books, conferences, magazines, newsgroups. Tons and tons of patronizing, simple stuff intended for people who were using VB because they couldn't handle C++. The Windows development world was split into two camps, serious C++ and simple VB. It sucked.
Note that I'm not saying that VB developers were dumb. I'm saying VB developers were treated as though they were dumb. Keep it simple, stupid. (Things did get better, of course. Eventually there were a few speakers and authors who were clearly heavyweight developers and they spoke highly of VB and encouraged its use for serious work and didn't patronize us. Ted Pattison, Matt Curland, Don Box, Francesco Balena, for example. But these were the rare exceptions.)
So now to the present. One of the major changes that .NET brings is that we now have one development environment that we all share. The differences in the languages are not enough to warrant two such diverse cultures. So what will happen? Will the "serious" culture get dumbed down or will the "simple" culture smarten up?
The article above is a call for all .NET developers to have a general understanding of what's going on, and I'm all for it. It's not enough for even an introductory class or book to just teach the syntax of one of the languages. The .NET culture must span a huge spectrum of developer abilities but there is a base level that it should not be allowed to go below. Instead of "Keep it simple, stupid", prefer Einstein's "Everything should be made as simple as possible, but not simpler".
9:17:32 PM
|
|
There is only one success - to be able to spend your life in your own way.
- Christopher Morley
9:03:54 AM
|
|
 |
Saturday, April 20, 2002 |
Payload
I had a strange discussion recently with some co-workers about what our software is for. I suspect that a couple of them thought the topic rather pointless, so I asked the question I ask myself most often when I design software: What does the user want to do? (I learned that question here more than ten years ago). Many of the answers were that the user wants to log on to the system and the user wants to monitor the system status and the user wants to be alerted if the system fails. No. These are the things we require the user to do. These are all overhead. In using Windows, for example, all this file management stuff and virus checking and installing and defragmenting and setting up security: it's all overhead. The payload, for me, is this: writing, reading, playing. If most of your software is for logging on and configuring and checking the status of the software and managing the software's files, there's too much overhead and not enough payload. What are the user's goals? Only if a feature directly helps the user achieve a goal, is it payload. Otherwise it's overhead and should be eliminated if possible.
4:38:59 PM
|
|
 |
Tuesday, April 16, 2002 |
More about testing.
In my HTTP testing, for each test in the suite I save expected and actual HTML output into files. If they're different, I launch WinDiff from the GUI to compare them. This gives me a great way to inspect differences without doing much programming. It's a bit lame because there are many minor differences that show up as errors when they have no effect. An HTML-aware comparison would be better; but not worth the effort.
I was planning on doing a similar thing soon for a program that modifies an Access database: programmatically export the expected and actual databases into text files and using WinDiff again if they differ. But clearly a SQL statement that could do a smart comparison would be better. Hey! Here's one: Comparing Data Sets with SQL.
9:03:49 PM
|
|
This five-step process works for any security measure, past, present, or future:
1) What problem does it solve?
2) How well does it solve the problem?
3) What new problems does it add?
4) What are the economic and social costs?
5) Given the above, is it worth the costs?
Read all about it in the latest Crypto-Gram.
8:26:30 PM
|
|
Peter again: Nice idea - the email equivalent of using Google instead of bookmarks. Exactly. The only bookmarks I have left are for things like my kids schools and the local library site (awful, though it is) and some company intranet pages - all things I can't find in Google (I keep them at Yahoo! Bookmarks so I can get to them from anywhere).
I have always disliked the way bookmarks work. Hierarchies are so often a convenience for programmers, but not for users. That decision of which folder to put the bookmark in bugs me. I can make a folder for "SVG" and one for "JavaScript", but then where do I put "Generating SVG with JavaScript"? In both? What happens when I become interested in new things? Do I go through all my bookmarks and reorganize them? Ranting about bookmarks is silly, I know, but the same organizing principal applies to other things, like file systems and wikis. Sometimes I don't want to decide where to put something. Just save it for me and when I want it I'll search for it. Just make sure the search is fabulous.
4:14:33 PM
|
|
 |
Monday, April 15, 2002 |
From Peter Drayton: However, when Dave says "...three useful ways to view the Web: 1. Search. 2. Heirarchy. 3. Time." I think he is over-emphasizing time as an organizational tool (maybe because Radio focuses on time-oriented content?). Information architecture people talk about there being 2 primary modes of navigation: 1. Searching. 2. Browsing. IMO hierarchical and time-oriented views merely faciliate different modes of browsing - other modes based on geography, rankings or proximity also exist. There's even a flow between the modes: Google displays the ranked results of a search, and one then browses the results.
I think the lack of a time component is often a problem on the web. Nobody bothers to update their old pages to let us know what has changed, where new or better pages are, or even if the whole page is obsolete. If we ever get this holy grail of Google on the Desktop, I think time will play a greater role. The linking algorithm won't work, so Google must use a more traditional best match algorithm. But how recently a file was changed or a message was written is a really big deal to me when I'm searching through my own stuff. I wrote an inverted index for a large number of text files a while ago, with words being scored based on frequency and importance. But when I boosted the scores of recent documents, users found the results considerably more useful.
In my mail archiving, I've given up browsing completely in favor of a magic bag approach (I wish I could remember where I read that phrase). You just toss everything into a magic bag and when you put your hand in, the thing you want is on top. I love that because when I save something, I don't want to spend any time anticipating how I expect to retrieve it. For web searching, Google is the magic bag. And now for my mail, I don't put things in folders anymore. Everything I want to keep is forwarded to a POP address I use only for archiving. I have a program that grabs everything from that address, saves it, converts each message to an HTML file, pulls out the attachments and links to them, and stores everything where Index Server will find it. So now I only search. Where I used to have a folder called "SVG" that I could browse, now I must search for "SVG". So what?
8:34:58 PM
|
|
Joel Spolsky talks about his .NET strategy [via Peter Drayton's Radio Weblog]
First problem: we don't know enough about .NET to write good code. As usual in any development environment there are many ways to do any given thing, and we haven't quite learned the first way, let alone the second way. So the quality of .NET code that we can write is not good enough to ship. ... So our first priority is education, which we will accomplish by doing all future in-house and web-based development in .NET -- basically, all the software that nobody is paying money for.
I like this strategy. I've been using it myself, every chance I get. A test data generator, an HTTP test driver, a mail archiver, various test programs. And of course every new COM component must play well with .NET (see Adam Nathan's book for a good chapter about that). Even for those of us in companies that are slow to embrace change, there's a lot we can do to be ready. But why (oh why) am I still trying to convince people that a C++ class is not a good unit of reuse?
8:18:05 PM
|
|
 |
Sunday, April 14, 2002 |
The Google API certainly is a nice piece of work. The doc page is excellent, the .NET sample is simple and easy to follow, the WSDL is clean. A genuine, horizontal market, web service. I expect they'll decide on a commercial-use pricing model in a month or two. I sure hope the newsgroups are included. I've got the list of special search operators and the list of results values pinned up next to my monitor, to stimulate ideas. There are more uses of this than we've thought of so far.
11:11:47 AM
|
|
 |
Friday, April 12, 2002 |
Just what I needed! A really good reason to learn WSDL. The Google API of course!. And a good article about it from Rael as well.
8:26:52 AM
|
|
The last thing I want to do: Radio Blogging from Word. I have been Word-free for more than a year now. I'm high on ASCII.
7:46:11 AM
|
|
 |
Thursday, April 11, 2002 |
Simon Fell's vsGoogle utility adds several web searches to Visual Studio 6. Very handy. Thanks.
11:10:34 PM
|
|
XSLT is fun
Can't Understand It? Don't Worry. For some time I used this argument against getting deeply into XSLT. I had used XSLT many times as part of an MVC architecture: an XML document is the model, an XSLT file is the view and some ASP JavaScript is the controller. In this architecture it's important to put all processing in the controller, so I would do whatever manipulation of the XML was needed to keep the XSLT as simple as possible. For example, rather than do any complex processing in XSLT to calculate a value, I would do the calculation in script and make an XML element or attribute containing the calculated value before doing the transform. Good separation of data, format, code. So all of the hard stuff in XSLT was not needed and this fits in well with Joel's point, I think. COM monikers = <xsl:key> and <xsl:variable> and all the other hard stuff.
Thankfully, I came to my senses a few months ago when I realized this simple fact: XSLT is fun. It's a challenge. I put it in the same category as regular expressions and advanced SQL. A regular expression replaces many lines of simple code. A complex SQL select statement does the same. I love both those technologies and relish the complexity. (I'm so glad we finally have a compiled language with regexes built in.) So now I jump at any chance to use XSLT in a new way (and there have been many opportunities).
I'd like to thank Michael Kay and his participation on XML-DEV and his most excellent book for helping me to see the light.
8:27:58 AM
|
|
 |
Wednesday, April 10, 2002 |
Looks like the My Pictures Tool works. Knew it would, squire.
9:28:03 PM
|
|

9:25:59 PM
|
|
There's only one thing I'm not happy with in Radio - the calendar. Or rather, the fact that the calendar is the standard way to read more stuff. I do like looking at my own calendar to see how frequently I have been writing. But when I find some new and interesting weblog and get to the bottom of the front page, I have a simple decision to make: either I want to read more of this person's ideas or I don't. If I want more, I just want a link right there that says More. I don't want to go to the calendar and figure out which days I've read and click on a day I haven't read. Then after reading that day do it again. I just want more. This is done wonderfully by Zeldman on his My Glamorous Life page. It always shows the latest essay. At the bottom, right where your eyes are when you've finished reading and want more, is a link to Previous Glamour. It's so simple and so perfect. I like Radio's default week of entries on the front page; I just want a way to link to the previous week at the bottom.
6:20:56 PM
|
|
 |
Monday, April 08, 2002 |
Using Unit Tests. Thoughts on unit testing and refactoring. [The .NET Guy] I hadn't heard of NUnit before. It looks interesting, but I can't use it yet. I use .NET to write tests for COM components, not for .NET assemblies.
I have an HTTPTester project that is going well. A test suite is an XML file. Each test is a URL. HTTPTester provides the facilities to save the result in a file and compare it with the expected file. Because the results are usually long XML or HTML strings, I don't define the expected results before running the test, the way I usually do. Instead, HTTPTester has a Copy to Expected button which I use after a careful manual inspection of the actual output. The Compare button took a few minutes to implement - it just calls Windiff for the two files - and it's all I need to see where the differences are. There's also a side-by-side view that is simply two frames that both implement an IE browser. Small cost; huge benefit.
One thing I always add to a test project that I didn't see in NUnit is a way to automate it. HTTPTester can take a test file on the command line and there are command line switches to shut itself down if there are no errors and send an email if there are errors. It also posts the last run results in a file. So I'll be able to schedule it on my machine at the office and check it from home and be alerted if it failed.
8:14:57 AM
|
|
 |
Thursday, April 04, 2002 |
The Register: Yahoo! Rips! Up! Privacy! Policy!. I'm glad I followed the link in thie article to the Yahoo marketing page. Like they say in the article, I was subscribed to everything, even phone and postal mail (not that Yahoo have my phone number or address, of course). The last thing I want is more spam. I've been using my Yahoo account as my primary email account for a long time now and I still love being able to check mail from anywhere. I also use Yahoo briefcase, bookmarks, calendar, notepad and address book. It's a very useful bunch of services, especially with the Yahoo toolbar installed on my primary home and office machines. But, of course, I can get to all the services from any machine, which is the whole point.
6:39:56 AM
|
|
 |
Wednesday, April 03, 2002 |
A trivial thing, but it makes me happy: I use three sounds in Visual Studio and today I synchronized them on every machine I use to write code and in both versions of Visual Studio that I use. "IR_INTER.WAV" is Breakpoint Hit. "GLASS.WAV" is Build Error/Build Failed. "ChatWhsp.wav" is Build Succeeded/Build Complete.
8:58:35 AM
|
|
Joel makes a good point, as usual. Can't Understand It? Don't Worry. Whenever somebody gives you a spec for some new technology, if you can't understand the spec, don't worry too much. Nobody else is going to understand it, either, and it's probably not going to be important. This is the lesson of SGML, which hardly anyone used, until Tim Berners-Lee dumbed it down dramatically and suddenly people understood it. For the same reason he simplified the file transfer protocol, creating HTTP to replace FTP. You can see this phenomenon all over the place; even within a given technology some things are easy enough to figure out and people use them (like COM's IUnknown), while others are so morbidly complicated (IMonikers) when they should be simple (what's wrong with URLs?) that they languish. Trust your own judgement. Just because some authority says a technology is vitally important, does not make it so.
6:46:49 AM
|
|
A fascinating description of a most unusual style of writing.
He makes some good points about expressing ideas simply.
I doubt if I could go that far in my own writing, though.
But it's tempting to make the attempt. Maybe I will.
How come it's boring when I do it? Rats.
[From Peter Drayton's Radio Weblog]
6:46:34 AM
|
|
 |
Tuesday, April 02, 2002 |
Jon Udell has a good take on the significance of instant outlining. An authoring tool that aims to replace email as the primary mode of communication in closely-knit collaborative teams. Right. Now where can I find a closely-knit collaborative team?
7:08:18 AM
|
|
 |
Friday, March 29, 2002 |
An interesting experiment: I added win32 status to my server logs a while ago and made a reminder to check the results: it popped up this morning.
I did a grep -e"- 5[0-9][0-9] [1-9]" * to find all the 500 range errors with non-zero win32 error codes. Sadly, nothing. (The 500 errors are the ones that could most benefit from some help from Win32). Same with the 300 range. The 200 range had 2 win32 errors with 200 HTTP responses: 64 and 22. The always useful Net HelpMSG nn told me that 64 is The specified network name is no longer available and 22 is The device does not recognize the command. I don't see how a 200 HTTP code can match either of these.
In the 400 series, I found these combinations: 401 5, 403 5, 404 2, 404 3, 405 1. 401 is Unauthorized and 403 is Forbidden, so the win32 5 ("Access is denied") doesn't add a whole lot. 404 is, of course, Not found, so the win32 codes divide that into 2 (The system cannot find the file specified) and 3 (The system cannot find the path specified), distinguishing between directory name errors and file name errors. 405 is Method not allowed and win32 1 is Incorrect function. Those errors were on a FrontPage module, author.dll, so I don't know what's going on there. FrontPage Extensions is only installed because ASP.NET put it there; I dislike the directory clutter.
A fun hour, but I'd better get back to work.
8:54:29 AM
|
|
 |
Thursday, March 28, 2002 |
Two Ways to Implement Session Tracking is a good explanation of using hidden fields and URL rewriting. We need to store some simple user preferences and there's no current need to scale to a server farm, so the ASP Session is the current team choice. But I want to make scaling work with no code changes, so I'm gonna do it a better way.
3:52:32 PM
|
|
 |
Sunday, March 24, 2002 |
An excellent description of a solid despamination process: "How I Prevent Spam. A quick overview of how I prevent having to wade through spam. [The .NET Guy]". I've been quite careful with my email addresses, but they always eventually grow too much spam-fungus and I start a new one. Next time that happens (soon I think), I'll start Brad's system.
10:13:18 AM
|
|
 |
Thursday, March 21, 2002 |
Phew. I'm starting a new project so I spent the afternoon brushing up on ASP, especially performance, scalability, and security. Some very interesting stuff here! Some of the best articles:
And the winner is: 25+ ASP Tips to Improve Performance and Style
5:21:29 PM
|
|
 |
Wednesday, March 20, 2002 |
Hmmm. RCS makes me wonder if it's time to try to stir up some community at the office again. I ran a project blog for a few months for a project I did alone and I loved writing in it every day, but in spite of a link at the bottom of every email I sent out during those months, my IIS server log didn't strain my hard drive's capacity at all. I tried a wiki when I was teaching a .NET class over several weeks, and a few people read it but nobody contributed a thing. Should I try again?
Maybe I'll install RCS, make a radio weblog for everyone, send out introductory emails, post interesting stuff in my weblog every few hours, and then...? What? Could it work? I can only imagine how it must improve communication to have several of the team members regularly blogging about the project.
9:43:13 PM
|
|
 |
Tuesday, March 19, 2002 |
I finally have written a JavaScript HRESULT error display function that I like. It gets around JavaScript's lack of unsigned integers by just chopping off the severity and putting an "0x80" before the hex value of the facility and scode.
function show_error(e) {
var msg = "";
var errnum = (e.number & 268435455); // get rid of severity
var facility = errnum >> 16;
var scode = e.number & 65535;
msg += " number: " + e.number + " (" + translate_errnum(errnum) + ")\n";;
msg += "facility: " + translate_facility(facility) + "\n";
msg += " scode: " + scode + "\n";
msg += " msg: " + e.description + "\n";
return msg;
}
function translate_errnum(num) {
var msg = "" + num.toString(16).toUpperCase();
while (msg.length < 6) {
msg = "0" + msg;
}
return "0x80" + msg;
}
function translate_facility(num) {
switch (num) {
case 0: return "FACILITY_NULL";
case 1: return "FACILITY_RPC";
case 2: return "FACILITY_DISPATCH";
case 3: return "FACILITY_STORAGE";
case 4: return "FACILITY_ITF";
case 7: return "FACILITY_WIN32";
case 8: return "FACILITY_WINDOWS";
case 9: return "FACILITY_SECURITY";
case 10: return "FACILITY_CONTROL";
case 11: return "FACILITY_CERT";
case 12: return "FACILITY_INTERNET";
case 13: return "FACILITY_MEDIASERVER";
case 14: return "FACILITY_MSMQ";
case 15: return "FACILITY_SETUPAPI";
case 16: return "FACILITY_SCARD";
case 17: return "FACILITY_COMPLUS";
case 18: return "FACILITY_AAF";
case 19: return "FACILITY_URT";
case 20: return "FACILITY_ACS";
case 21: return "FACILITY_DPLAY";
case 22: return "FACILITY_UMI";
case 23: return "FACILITY_SXS";
case 24: return "FACILITY_WINDOWS_CE";
case 25: return "FACILITY_HTTP";
case 32: return "FACILITY_BACKGROUNDCOPY";
case 33: return "FACILITY_CONFIGURATION";
}
return "unknown:"+num;
}
It displays errors like this:
number: -2146828235 (0x800A0035)
facility: FACILITY_CONTROL
scode: 53
msg: File not found
In ASP pages, I use it like this:
catch (e) {
Response.Write("<pre>" + show_error(e) + "</pre>");
}
2:28:36 PM
|
|
 |
Sunday, March 17, 2002 |
 |
Friday, March 15, 2002 |
Inspired by Peter Drayton's sample code, I turned on Index Server for a local folder containing years of notes and code and emails. I used a simple article from Code Project for help in setting up the catalog and search page. And it works. I've made a link to it on my quick start bar, so now I'll see how much I actually use it.
The column names were kind of interesting. I couldn't find a simple list of available columns in the documentation, so I just used samples to find out what was available in the index. But then I found a list of properties in the MMC Indexing Service snap in, that turn out to be the columns accepted by the query.Columns property. I guess they can be diferent for each Index Server plug in, which is interesting.
9:57:54 AM
|
|
 |
Thursday, March 14, 2002 |
How much ass does Google kick? All of it. The great thing about Google is how it has changed the way we use the web. There's no need for me to bookmark a great site because I know I can find it again when I need it. When I first began using the web (woah! there was a time before the web?) I wasted way too much time building a comprehensive bookmark hierarchy; time that should have been spent actually reading and using the content.
I also love the site search. Some sites have such bad indexes that it's better to do a site search from the google toolbar instead.
Google=search
8:09:53 AM
|
|
 |
Wednesday, March 13, 2002 |
I did some CSS brushing up today. Here are the links I found most useful:
8:16:50 PM
|
|
Being a good HTTP citizen
I never really got the importance of the W3C HTTP axioms:
In HTTP, GET must not have side effects and In HTTP, anything which does not have side-effects must use GET; until today.
I'm implementing some web services using Jon Udell's Power of the URL-Line principle. In other words, the web service request is done with the URL-Line, and the response is simple non-enveloped XML. No SOAP in sight. Every service is a different ASP page. It's very elegant and simple to develop and test.
Most of the services are simple find using this, find using that methods that return XML containing the results of the search. These work great with the URL-line-request/simple-XML-response technique. But two of the services have side effects, similar to logon and logoff methods. I had done them as URL-Line services:
http://127.0.0.1/playbackservice/agentlogon.asp?agent=agent1&extension=12345
but I realized how dangerous this is. An URL-Line can be emailed and bookmarked and the page can be cached. Not what you want for a service like AgentLogon. So I changed the services that have side-effects to require POST. It makes it a bit harder to test (I need to make a form) but it's worth the trouble to do it the right way. And to finally GET it. (Get it?)
5:05:05 PM
|
|
 |
Tuesday, March 12, 2002 |
SVG is the way to go for complex graphics, but I have a soft spot for JavaScript and the ole' 1-pixel-gif trick: Drawing Charts with JavaScript is low-tech and low overhead.
8:20:48 PM
|
|
 |
Monday, March 11, 2002 |
COM and ASP debugging
I've finally learned how to debug a C++ COM component called by ASP. I don't know why I've avoided it for so long. I suppose because I test my COM components with quick VB test apps, so they generally work fine by the time I call them from ASP. This time was different (it works from VB but not from ASP).
I've been immersed in Keith Brown's most excellent book, so I actually know what the difference is! When running from VB, the security token is from the interactive logon, i.e. me running as an administrator (but I will follow Keith's advice soon and break that bad habit, I promise). When run from ASP, the component is running under ISR_WONKO, who is merely a guest. So the required authorization is not there. QED. Keith's very useful TokenDump component, available here, showed me the security token being used for various security settings in IIS.
Debugging the COM component was as simple as watching DLLHOST appear in the Task Manager when I went to the page in the browser and selecting Debug from the right button menu (in Task Manager). Then opening the file in Visual Studio, setting the breakpoint, and refreshing the page. Beautiful. It's been a fine afternoon.
5:08:18 PM
|
|
Don't take any chances with ASP caching:<% Response.Expires = 0 Response.Expiresabsolute = Now() - 1 Response.AddHeader "pragma","no-cache" Response.AddHeader "cache-control","private" Response.CacheControl = "no-cache" %>
12:52:22 PM
|
|
Maybe I'll start with a quick review of a book I've just finished - Applied Microsoft .NET Framework Programming by Jeffrey Richter. There are many smart people in our industry and lots of them share their intelligence with us through writing and speaking. In my view, Richter is the best of them, not for how smart he is, but for how much smarter he makes me. No other writer conveys so much.
His chapter on Exceptions, is a good example. I've used them for many years, in C++ and JavaScript, so I expected to learn just the C# syntax. And he starts with that, of course. But then he has eight pages on "How to Use Exceptions Properly", including an error I'm guilty of: Don't Catch Everything:
catch (Exception) { ... }
"This code indicates that it was expecting any and all exceptions and knows how to recover from any and all situations. How can this possibly be?"
I hope he is even now writing the sequel, about Collections, Threading, Remoting, Messaging.
11:06:44 AM
|
|
© Copyright 2004 John Sands.
|
|
|
|
| March 2004 |
| Sun |
Mon |
Tue |
Wed |
Thu |
Fri |
Sat |
| |
1 |
2 |
3 |
4 |
5 |
6 |
| 7 |
8 |
9 |
10 |
11 |
12 |
13 |
| 14 |
15 |
16 |
17 |
18 |
19 |
20 |
| 21 |
22 |
23 |
24 |
25 |
26 |
27 |
| 28 |
29 |
30 |
31 |
|
|
|
| Jun Apr |
|
|