June 2004 Entries
My response to Dave Winer's post about Michael Moore's new movie has generated a lot (for me) comments. I appreciate the comments whether you're in agreement with me or not. I'd like to address them for a moment with this post. Dave Winer, in his response to my post, asks:
Who was it who said that "I disagree with everything he says but I'll fight to the death for his right to say it."
The answer, at least according to a letter printed in this article, is Rush Limbaugh (though he was probably quoting someone else). I feel the same way about Rush, but if he were to make a movie, I'd at least see it before speaking out against it. ;) And, I'd also like to point out that I am NOT making the claim (and I said this before) that Fahrenheit 9/11 is unbiased journalism. I don't think even Mr. Moore himself is that audacious. So with that, let me jump in.
Did I Miss the Point?
Randy says I miss the point because one of the senators has a nephew on the way to Afghanistan. However, for the record, the reason we went to Afghanistan is NOT the same reason we went to Iraq. Even the administration (when they try to get their story straight) will admit to that somewhat. Secondly, Moore does mention in the movie that one congress person has a son or relative in Iraq. I wish he had interviewed that person, but the fact that he didn't interview this one person out of the 433 (active) members of the House and 100 senators does not make the scene pointless.
Who Said Germany Attacked The US?
Several commenters questioned my grasp of history. Kris asks "Germany attacked the UNited States in WW2?. Anon.penet.fi says, "We were attacked by Germany prior to entering world war II? Really?... *snip* Seems like your grasp of history is pretty selective...". Why is everyone talking about Germany? I never said Germany. I'm referring to a little event called Pearl Harbor on December 7, 1941 in which the Japanese attacked the United States on U.S. soil. Though we supported the war effort prior to this event, we didn't enter the war until this event.
Is It Primarily The Poor In The Military
Kris says, "'primarily of the poorer sections of society' ... spoken like a true college graduate. What about the pro football player Pat Tillman?".
Are you implying that the army is primarily made up of NFL football players? No offense intended, but I assume you're not a statitician nor a demographer. My college education taught me not to look at anecdotal evidence as fact. I didn't claim everyone in the military is poor. My dad was in the military, he didn't come from that poor a family. However, the military attracts many more people from the less affluent than the more affluent. The rich don't need the GI bill to send their kid to college.
What About Putin?
Richard points out that Putin warned the U.S. about possible Iraqi terror attacks. That's actually an interesting point, but it's too early to say much about it, since that just came out recently and I don't know enough about it as it relates to timing and specificity. Richard's point leads into a whole 'nother discussion about the doctrine of preemption etc, of which I think is a mistake.
Conclusion
Whatever his goals, Michael Moore succeeding in generating a lot of discussion, even from those who haven't seen the movie. I agree that asking congress people to send their kids to Iraq is a ridiculous proposition, especially since you can't compell another person to join. It's a personal decision. But I still contend that Moore makes a good point with that stunt. Basically, its the point of the movie:
They serve so that we don't have to. They offer to give up their lives so that we can be free. It is, remarkably, their gift to us. And all they ask for in return is that we never send them into harm's way unless it is absolutely necessary. Will they ever trust us again?
Like I said, I appreciate the comments.
Dave Winer the founder of RSS and a popular member of the so-called blogosphere writes:
Yesterday on NPR they played an excerpt where he confronts members of Congress and asks if they would send their children to fight in Iraq. What a ridiculous question. No parent will say yes to that question. You could have asked that question on the Capitol steps during World War II and they still wouldn't say yes. See how this cheapens the question of whether we should be in Iraq? In a smart world, we wouldn't be there, but it isn't because Congress people won't say yes when confronted by a camera crew.
Moore is the worst of American politics, an opportunist, an anti-intellectual.
Vote no on Moore.
With all due respect, I think Dave misses the point of Moore's questioning. Of course it's a ridiculous question and no parent would say yes. That's the whole point. We're sending children (primarily of the poorer sections of society) to fight and die based on conspicuously absent evidence. Where are the WMDs? Where is the tie to Al Queda? Yet our Congress and the President so cavalierly send these troops to Iraq. Would they be so cavalier if their own children were in any danger of being sent to Iraq? The point of the question is to emphasize that these aren't faceless people we're sending. We're sending the sons of daughters of fellow Americans. The point is to get these Congress members to consider the pain they would feel if their own sons and daughters were sent.
As for WWII, I don't believe comparing the Iraq conflict to World War II is a useful comparison. First of all, we were attacked by the enemy we engaged. Iraq did not attack us, Al Queda did. In that effort, kids under 18 faked documents in order to join the effort. People were proud to serve or have their kids serve. It was widely seen as a just and necessary war.
Check out this video of a guitarist playing the theme to Super Mario brothers. I especially like the part where Mario grabs a few coins.
And I expect my arms to be tired (ba-dump pshhh).
We're heading over there on July 28 to see my wife's best friend (from back when they
lived in Japan) and her husband. She's working on her residency at some
hospital somewhere over there (I know so much). How's the weather been up
there? Being a transplanted Alaskan, I'm a big fan of the Northwest.
I expect that the days will be nice and long.
It's been a long time since I've been up to Seattle. Any
recommendations?
At least it wasn't what I expected. By default, the current directory for your Windows service is the System32 folder. I keep forgetting that which causes me problems when I try to access a file or folder using a relative path.
System.IO.Directory.SetCurrentDirectory
(System.AppDomain.CurrentDomain.BaseDirectory);
Use the above line of code to set the current directory to the same directory as your windows service. Don't say I didn't warn you. I shall never forget again.
This is a test. Do not be alarmed.
1///<summary>
2/// Testing.
3///</summary>
4public void TestCodeFormatter()
5{
6 int x;
7 DoSomething();
8}
Finally I've gotten around to contributing an article to the Code Project community. Writing articles and whatnot has always been on my //TODO: list, but until now, I've only had articles published on my blog (not counting the RSS Bandit user documentation)
Surprise of surprises, the article I submitted is about a configuration section handler. Basically the same thing I posted here. Code Project is fine with that as long as I'm the copyright holder of the article.
Ok, so that's two technical posts in a row, time to write something non-geek... Think! Think!
Ian Griffiths points out why he doesn't like configuration section handlers much, and one of the primary reasons is how they require extra "cruft" in order to tell .NET about the handler. I have to agree for the most part. I've always wanted a #region tag for the App.config file just to hide that junk away, but that's pretty much a cop out. Cyrus points out how the C# team was ambivalent about even having a region tag in the IDE.
One good point Ian and Craig (via email) brought up is that configuration sections are often misused. I should have stated this in my article, but I'll state it here for the record. Perhaps I'll even use an H2 tag and all caps. Here goes.
DO NOT STORE USER SETTINGS IN AN APPLICATION CONFIGURATION FILE!
That's not what it's there for. Remember, the application configuration file is stored in your application's directory of the Program Files directory (by default). If you're a proper windows logo programmer, you'll know that the typical user should not have write access there. Otherwise you don't deserve that shiny "
Designed forWindows XP" icon.
I tend to write a lot of Windows Services. I try to build an installer for each one that provides a GUI for the user to enter in some configuration data which gets written to the config file upon installation. That's pretty much the only time my config files get modified unless we need to adminstratively change something or other. Note the use of an administrator and not a user.
For more information about persisting user settings, check out:
Surprisingly, most of my good friends who read this blog don't care much about software development or .NET. They're not riveted by gripping stories of flexible configuration section handlers, or the heart palpitating episodes of my titanic battle with the StringDictionary's handling of string casing. Nor do they spend their leisure moments contemplating new and exciting IBlogExtension plugins.
What, pray tell, do these people do for fun, you ask? It's still a mystery to me.
Last night my friend Walter told me that his interest wanes when I post a long ode to code. He's one of those guys who like to read the "Human Interest" stories in the paper (and my blog).
Many blogs (mine included) have post categories to group entries. I could suggest that he subscribe to every category except for the Software Dev & .NET, but as he uses Yahoo.com to subscribe, that would really clutter his main page. It'd be great if Yahoo provided the ability to subscribe to multiple categories of a single blog and present that as one blog. At the very least they could display the category for blog items.
However, if you don't mind the clutter, here are links to the RSS feeds for each of my categories (thus far).
[Listening to: Star 69 - Fatboy Slim - Halfway Between The Gutter And The Stars (5:43)]
Brad Wilson (thanks!) pointed me to this hilarious 404 File Not Found page. Give it a second to kick in (I promise, no zombies will scream). It has my favorite (and as far as I'm concerned, the funniest) character on the web, Mr. Strong Bad himself. If you haven't acquainted yourself with Strong Bad, now is the time!
Today I ran into an annoying nuance of the StringDictionary class (located in the System.Collections.Specialized namespace so as not to be confused with the other imposter string dictionaries). It's not a bug, but I feel the API for it could have been slightly better on this minor point.
Right there in the documentation for the class it points out that:
The key is handled in a case-insensitive manner; it is translated to lower case before it is used with the string dictionary.
Thus it takes the key you give it, and changes it to a lower case value before storing it. I verified this with Reflector.
public virtual void Add(string key, string value)
{
this.contents.Add(key.ToLower(CultureInfo.InvariantCulture), value);
}
Whoa there! Stop the presses! Call Michael Moore! Ok, ok. So in the grand scheme of things, it's a minor issue. It's not a huge deal. However, API usability (and language design) focuses on keeping the minor annoyances to a minimum. Otherwise they'll add up and form a major disturbance and soon you'll have an angry developer standing on his/her soap box whining and ranting about it on a blog.
The issue for me is that this wasn't the behavior I expected. If an API is going to change data you give it, I wish it would indicate that somehow. Perhaps the method could be
AddKeyAndValueButLowerCaseTheKey() ;). All joking aside, it isn't necessary to lower-case the key before storing it in order to provide case-insensitive storage. Internally,
StringDictionary uses a
HashTable to store its keys and values. The dictionary could have made the
HashTable use a
CaseInsensitiveHashCodeProvider when storing keys. That way the key doesn't have to change, but you get case insensitivity.
In any case, like I said, it's normally not a big deal except for the fact that I am building a Setup and Deployment project within Visual Studio.NET for a Windows service. When building a project installer, the Installer (in the namespace System.Configuration.Install) class provides a property called Context of type InstallContext. This class gives you a property called Parameters which is a StringDictionary containing values you may have pulled from the user interface.
I'm trying to look up nodes within an XML file that correspond to the keys of the Parameters dictionary using XPath, hoping to update the node values with the values from the dictionary. However, XPath is case sensitive so I can't match these things up. Unfortunately I can't change the XML to be all lower case, and I can't change the Installer class to not use a StringDictionary (or better yet, correct the dictionary's behavior), so I'm stuck with resorting to a hack until something better comes along.
UPDATE: In ASP.NET 2.0, there’s an even easier approach that supercedes this one. I wrote about it here.
A while back Craig Andera wrote an excellent article entitled The Last Configuration Section Handler I’ll Ever Need which outlines a really nice and flexible configuration section handler. It is certainly a big time saver and was the leading contender as the last one I would ever need as well. That is until I realized it lacked one minor feature I need: the ability to reload itself when the config file changes.
Before continuing, please do go and read his article for background. It’s pretty short and well written. No really, go read it while I listen to
[American Dream (Joey Negro Club Mix) - Jakatta - Essential Mix - Mixed By Pete Tong (5:22)]
Having read his article, it should be apparent why reloading the settings when the file changes is a challenge. Mainly because you most likely will have a reference to your simple settings object (such as the MyStuff class in the article) which has to somehow be notified that a change has occurred. As you can see from the sample below, classes used to hold settings (such as the MyStuff class) are deliberately kept very simple in order to facilitate writing many of them. There’s no facility to watch for changes to the config file.
public class MyStuff
{
private float foo ;
private string bar;
public float Foo
{
get { return foo ; }
set { foo = value ; }
}
public string Bar
{
get { return bar; }
set { bar = value ;
}
}
So after a bit of thought and a bit more beer, I came up with a solution that I believe still retains the simplicity of his approach, while adding the ability to have the settings dynamically get updated when the config file changes. My approach is also backwards compatible with existing setting objects created using his approach. Existing setting objects will not need any changes to work, though they won’t get the benefit of this new feature.
I’ve extended Craig’s solution with the addition of the XmlSectionSettingsBase abstract class. The purpose of this class is to act as the base class for your simple setting object. To add the ability to reload itself, just have your class inherit from XmlSectionSettingsBase and call the UpdateChanges() method before each property getter. As an example, I’ve modified the above settings object:
public class MyStuff : XmlSectionSettingsBase
{
private float foo ;
private string bar;
public float Foo
{
get
{
UpdateChanges();
return foo ;
}
set { foo = value ; }
}
public string Bar
{
get
{
UpdateChanges();
return bar;
}
set { bar = value ;
}
}
That’s it! That is the total amount of changes to the settings class needed so that it will now track changes. I’ve also updated the XmlSerializerSectionHandler class as well. It’s now pretty small:
public class XmlSerializerSectionHandler :
IConfigurationSectionHandler
{
public object Create(object parent, object context,
XmlNode section)
{
return XmlSectionSettingsBase.LoadSettings(section);
}
}
Which leads us to the XmlSectionSettingsBase class which is the workhorse of my scheme. You’ll notice that I’ve removed all the logic from the section handler for loading the settings object from the config file. The reason for this is that the instance of the settings object has to know how to load itself from the config file if its going to watch it for changes. Since I didn’t want to duplicate logic, I moved that code to this class. I’ll outline the class with some broad strokes and let you download the source code for the complete picture.
First, let’s start with the static LoadSettings method.
public static object LoadSettings(XmlNode section)
{
object settings = DeserializeSection(section);
XmlSectionSettingsBase xmlSettings = settings as XmlSectionSettingsBase;
if(xmlSettings != null)
{
xmlSettings._rootName = section.Name;
((XmlSectionSettingsBase)settings).WatchForConfigChanges();
}
return settings;
}
This method deserializes an instance of your settings object and checks to see if it inherits from XmlSectionSettingsBase. If not, it just returns, keeping this approach backwards compatible. Otherwise it calls WatchForConfigChanges which sets up a FileSystemWatcher to monitor for changes to the config file. Also notice that it stores the name of the config section node in a private member (_rootName) of the settings class. This becomes important later when we need to reload the settings.
void WatchForConfigChanges()
{
FileInfo configFile = new FileInfo(
AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
try { _watcher = new FileSystemWatcher(configFile.DirectoryName);
_watcher.Filter = configFile.Name;
_watcher.NotifyFilter = NotifyFilters.LastWrite;
_watcher.Changed +=
new FileSystemEventHandler(OnConfigChanged);
_watcher.EnableRaisingEvents = true;
}
catch(Exception ex)
{
Log.Error("Configuration problem.", ex);
throw new ConfigurationException("An
error occurred while attempting to watch for file
system changes.", ex);
}
}
When a change occurs, the OnConfigChanged method is called. This method simply updates a boolean flag. This is the flag that the UpdateChanges method mentioned earlier checks before actually applying changes to the settings object.
void OnConfigChanged(object sender, FileSystemEventArgs e)
{
_isDataValid = false;
}
protected void UpdateChanges()
{
if(!_isDataValid)
ReloadSettings();
}
Now we hit upon the ReloadSettings method. This method uses the name of the node containing the config section we stored earlier (_rootName) in order to load an XmlDocument containing the new settings from the config file.
void ReloadSettings()
{
XmlDocument doc = new XmlDocument();
doc.Load(
AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
XmlNodeList nodes = doc.GetElementsByTagName(_rootName);
if(nodes.Count > 0)
{
//Note: newSettings should not watch for config changes. XmlSectionSettingsBase newSettings = DeserializeSection(nodes[0]) as XmlSectionSettingsBase;
newSettings._isDataValid = true;
CopySettings(newSettings);
}
else throw
new System.Configuration.ConfigurationException(
"Configuration section " + _rootName + " not found.");
}
The path to the config file is retrieved via a the AppDomain.CurrentDomain.SetupInformation.ConfigurationFile property. Once we have the section, we can call DeserializeSection to get an instance of our settings class with the new settings. This method is pretty is the same as the Create method in Craig’s version.
static object DeserializeSection(XmlNode section)
{
XPathNavigator navigator = section.CreateNavigator();
string typename =
(string)navigator.Evaluate("string(@type)");
Type type = Type.GetType(typename);
if(type == null)
throw new
ConfigurationException("The type ’" + typename
+ "’ is not a valid type.
Double check the type parameter.");
XmlSerializer serializer = new XmlSerializer(type);
return serializer.Deserialize(new XmlNodeReader(section));
}
After loading this new settings instance, I overwrite the current instance’s property values with the values from the new settings instance via a call to CopySettings.
void CopySettings(object newSettings)
{
if(newSettings.GetType() != this.GetType())
return;
PropertyInfo[] properties =
newSettings.GetType().GetProperties();
foreach(PropertyInfo property in properties)
{
if(property.CanWrite && property.CanRead)
{
property.SetValue(this,
property.GetValue(newSettings, null), null);
}
}
}
Copy Settings uses reflection to iterate through all the public get properties of the new settings object and sets the corresponding property of the current instance if the current property can be written to.
And that’s the gist of it. So that you can try it out immediately, I zipped up a Visual Studio.NET 2003 solution (Haack.ConfigurationSolution.sln) that contains two Class Library projects: Haack.Configuration and UnitTests.Haack.Configuration. The first project contains the code outlined in this article including the modified MyStuff settings class. The second project contains a unit test (for NUnit) that demos the config section handler in action. This project also has couple of sample config files that use the section handler and reference the MyStuff class. The test runs through the following steps:
- Creates a config file from an embedded resource (App.config).
- Obtains an instance of MyStuff via the configuration section handler.
- Verifies the original setting values.
- Overwrites the config file using the NewApp.config embedded resource.
- Verifies that properties of the MyStuff instance have been updated.
I made sure to package up NUnit as well so that you can run the test immediately. Also included with the zip file is some MSDN style documentation generated via NDoc.
[Download the Source]
Let me know if you find this useful, if you find any bugs, or if you have suggestions for improvement. Just drop me a line in the comments.
UPDATE: I updated the links to Craig’s articles and blogs so that they are no longer broken.
It's funny to me that this makes the news.
WASHINGTON (Reuters) - Vice President Dick Cheney blurted out the "F word" at Democratic Sen. Patrick Leahy of Vermont during a heated exchange on the Senate floor, congressional aides said on Thursday.
[Via Reuters: Top News]
So I'm definitely going to see this movie this Friday. Regarding the reviews I posted on Saturday, Koba makes the following good point in my comments section:
I find parts of that Slate review to be disingenuous. It makes the point that if Moore would (among other things of a supposed pacifist leaning) have allowed Saddam to keep Kuwait. However, I'm going to go out on a limb here and hypothesize that if Michael Moore were in charge of the White House, I'm pretty sure the U.S. would not have joined Germany and France in giving weapons to Uncle Saddam to fight the Iranians (and oppress those living within Iraq's borders). Apparently we are to believe that our aggression is better than (morally superior to) others' aggression.
Anyway, would Hitchens have us believe that our current motivations in Iraq are wholly noble? Please, our soldiers are sitting on the 1/9th of the world’s proven oil reserves. End of story.
Indeed!
Xamlon, Inc announces that Adam Kinney, aka Mr. Longhorn Blogs, has joined their team.
Basically, he's obtained a dream job, getting paid to do a lot of what he was doing for fun. And to think, I witnessed all this go down in the hectic week of Tech-Ed 2004.
For the uninitiated, a 404 message is a page that tells you that the file you requested cannot be found. Apparently, this site decided to have fun with it.
We went camping in Sequoia National Park a couple of weekends ago, a weekend which happened to coincide with our first anniversary! Somehow I convinced my lovely wife that a weekend of camping in the woods among the bears is much preferable to a stay at a nice hotel resort. I mean who wants to be pampered and massaged?
Sequoia National Park is the home of some truly immense trees. I mean really really big trees. The kind of trees that give you a big cramp in the back of your neck if you try to stare at the top for too long, forcing you to walk around staring at the sky causing everyone around you to wonder what the hell you're looking at. Redwoods may be taller, but no trees have the volume and bulk of the giant sequoias. These things almost seem to generate their own gravity.
The author loses his head, once again.
This trip found us reuniting with a several members of our intrepid Buring Man 2002 crew. Upon arriving I nearly lost my head at the astounding dimensions of the trees. Pictured above is a little tunnel carved out of a fallen tree. That's me sticking my head where the sun don't shine. This fallen tree is one of many among the myriad of trails within the park. If a tree falls in the woods, will it muss up my wife's pretty pink hat?
The tree was no match for the power of the hat.
Sequoias are notable for the crazy tree people (though so is Green Peace). If you look carefully, you can see them hiding within the burnt trunk of a large tree. Counterintuitively, Sequoias thrive on fire (though not in the same way Cheech and Chong did). They need the occasional forest fire to to survive and thrive. Fires burn off the undergrowth, removing competition for good soil and water, basically keeping out the riffraff. When procreation becomes a priority, they drop off cones containing hundreds of seeds. The seeds remain safely huddled inside until a fire heats up the cone enough to cause the seeds to release. Wandering through the forest, you'll notice a large number of trees that have grown a thick layer of bark around the scars from forest fires.
The last surviving member of Ponce De Leon's crew.
Like a runaway pituitary gland, it's seems that a giant sequoia never stops growing. They can live for a little over 3000 years and have a diameter (at the base) of up to 36.5 feet. If a tree survives fires and other hazards to reach a massive size, the typical cause of death is falling over from its own weight, much like the Lakers did in the finals recently. As can be seen below, its roots don't run very deep. They dig in a mere three feet.
So how do we drag this thing home?
We had this sequoia surrounded, but it wouldn't be bullied by us and didn't give up its wallet.
Hands across America...a tree.
When camping in Sequoia, the rangers go to great pains to make sure you observe proper bear safety. They'll go on and on about keeping all food and scented items safely stored away in bear containers. Don't keep any food in your tent. Don't feed the bears, no matter how cute they seem or how many GMail invites they offer. Apparently feeding a bear human is equivalent to giving them bear crack. They quickly acquire a taste for it and will go to great lengths to get more. They've been known to peel down the window of a car to get at the potential food inside. Sadly, this typically leads to the bears being put down. There were several bear sitings within the campgrounds, including the one sneaking up from behind me in the following photo.
Unbeknownst to Gandalf, a feral Frodo approached.
A nearby campsite had a black bear crawl on top of their truck and scratch it up a bit, apparently looking for the keys to take it for a joy ride. We spotted the culprit the next morning relaxing in the sun.
BooBoo was relieved to finally get rid of that annoying Yogi.
I found a nice tip for selecting random rows from within a SQL Server 2000 database. Well actually, pseudorandom. Since my undergraduate thesis was on the topic of pseudorandom number generation, I might as well be precise. For some reason, my non-geek friends find it awfully funny when I mention pseudorandom numbers.
I digress. In order to select 10 records from some table at random, try this:
SELECT TOP 10 * FROM someTable ORDER By NEWID()
Now for my homework, I should find out just how random this is. There's a whole slew of statistical tests I can run to gauge the randomness of pseudorandom number generator such as the Chi-square Test, Serial Correlation Coefficient, and 2-D Random Walk Test to name a few.
IMPORTANT: Please note that this will NOT work in SQL 7 on NT4 because the NEWID() function there generates sequential results (Bad SQL! Bad!).
UPDATE: My friend Erik referred me to this article that has an overview of several methods for random sampling. Thanks e.
I found this scathing review on Slate of Michael Moore and his upcoming flick, Fahrenheit 9/11 I have yet to see the movie but plan to soon. It's good to read a critical review to make sure I have a balanced view of the movie.
If Michael Moore had had his way, Slobodan Milosevic would still be the big man in a starved and tyrannical Serbia. Bosnia and Kosovo would have been cleansed and annexed. If Michael Moore had been listened to, Afghanistan would still be under Taliban rule, and Kuwait would have remained part of Iraq. And Iraq itself would still be the personal property of a psychopathic crime family, bargaining covertly with the slave state of North Korea for WMD.
I don't doubt that Michael Moore is biased and self-serving. His movie is designed to provoke a strong reaction, and whether the facts are misinterpreted or self-contradicting, that's not important to his goals. I figure I will have to take his message with a grain of salt. Many will see his movie once, while they watch Fox news every day. The truth probably lies somewhere in the middle.
As a counterpoint to the scathing review, I offer up another review that points out the great lengths the Moore team went to fact check all their assertions. The review does point out that Moore does insert his prejudices in places, but that his central assertion is well-founded.
Moore is on firm ground in arguing that the Bushes, like many prominent Texas families with oil interests, have profited handsomely from their relationships with prominent Saudis, including members of the royal family and of the large and fabulously wealthy bin Laden clan, which has insisted it long ago disowned Osama.
Plug-ins are a powerful way for users to dynamically enhance the functionality of an installed application. Is there a high priority feature you want that is low priority for the developers? Perhaps you can write a plug-in.
Many RSS aggregators support the ability to add plug-ins through the IBlogExtension interface. Started by Simon Fell, the IBlogExtension is intended to provide news aggregators an extensibility point so that they can be hooked into 3rd party blogging tools such as w.Bloggar.
RSS Bandit is one such aggregator. I recently added documentation which includes a walkthrough for building a very simple plug-in. Please let me know if it is helpful or if you find any errors by commenting here or in the RSS Bandit IBlogExtension forum.
I'm working on a more advanced plug-in complete with configuration settings and a GUI that I will present later.
We recently saw Margaret Cho try out some new material in Claremont. I think she's absolutely hilarious and poignant. Some say she relies way too much on her Korean mother, but having a Korean mother myself, I think she's spot on with the impression.
I'm looking forward to seeing her next big movie Revolution. Here's a nice review from Slate.com.
I'm a huge soccer fan so I had a good laugh at this funny video.
Regarding Syntax Highlighting, Daniel Turini pointed out that SnippetCompiler has the ability to export code to the clipboard (and to a file) as HTML.
Snippet Compiler has a lot of nice features and is a welcome addition to my toolbox, but purely for syntax highlighting, it has a few disadvantages compared to the manoli.net website I mentioned previously. First of all, although you can view snippets with line numbers, the line numbers aren't exported to HTML like Manoli does. Secondly, Manoli handles XML/HTML along with C# and VB, while SnippetCompiler seems to do well only with C# and VB.NET. Lastly, Manoli uses CSS for styling and you can have it embed the CSS definitions in the generated HTML, or reference the provided stylesheet. This is a really nice feature.
One thing I do like about the SnippetCompiler is how the summary tags in the comments are gray while the actual comment is green. That's a nice touch.
///<summary>
///Manages cool things
///</summary>
public class ThisIsSoCool
{
///
/// This is seriously neat.
///
public void YouShouldTryThis()
{}
}
I’ve probably read a hundred or so posts of people looking for a way to syntax highlight source code listings in HTML. Maybe I’m the last to discover this site, but http://www.manoli.net/csharpformat/ is the answer for me so far. Just cut and paste some C#, VB, html/xml/aspx code int the text box and click "format my code" and voila! You get some clean HTML displaying nicely formatted code.
The tool allows you to optionally format the code with alternating line colors and line numbers if you so desire.
public class ThisIsSoCool
{
/// /// This is seriously neat. ///
public void YouShouldTryThis()
{}
}
Let’s try it with line numbers.
1: public class ThisIsAlsoCool
2: {
3: ///
4: /// Look at me ma! I’m using line numbers
5: ///
6: public void YouShouldTryThis()
7: {}
8: }
You've probably heard the term Impedance Mismatch thrown around when discussing object relational mapping. I'm sure it comes up every morning at the water cooler. Maybe you've even thrown it around yoursef a few times. Do you know what the term means?
Object relational mapping refers to the process of mapping your relational data model to your object model. Object Spaces is a highly publicized framework for doing just that. The mismatch I refer to is a result of the differences in structure between a normalized relational database and a typical object oriented class hierarchy. One might say Databases are from Mars and Objects are from Venus. Databases do not map naturally to object models. It's alot like trying to push the north poles of two magnets together.
Interestingly enough, the term "Impedance", now bandied about in software engineering circles, is borrowed from electronics. I'm going to do a disservice to electrical engineers all over the world by offering a a very simple explanation. (My aplogies to you EEs out there).
Impedance is the measure of the amount that some object impedes (or obstructs) the flow of a current. Impedance might refer to resistance, reactance, or some complex combination of the two.
Perhaps an example is in order to illustrate impedance mismatching:
Imagine you have a low current flashlight that normally uses AAA batteries. Don't try this at home, but suppose you could attach your car battery to the flashlight. The low current flashlight will pitifully output a fraction of the light energy that the high current battery is capable of producing. Likewise, if you attached the AAA batteries to Batman's spotlight, you'll also get low output. However, match the AAA batteries to the flashlight and they will run with maximum efficiency.
So taking this discussion back to software engineering, if you imagine the flow of data to be analogous to a current, then the impedance of a relational data model is not matched with the impedance of an object hierarchy. Therefore, the data will not flow with maximum efficiency, a result of the impedance mismatch.
I'm right in the middle of reading this book right now and I can't heap enough praise upon it. This is a worthwhile read.
LONDON (Reuters) - U.S. author Bill Bryson, best known for his travel writing, has won a major award for something entirely different -- popular science.
[Via Reuters: Science]
Quick! What is the definition of the word moot? I'll use it in a sentence.
Upon reflection, Hezekiah realized that Ezekiel's argument was a moot point.
If you said something along the lines of "irrelevant", then you're wrong. Or perhaps, right. You see, moot is one of those strange words that can be self contradictory. Originally, moot started off as a noun. It was a legal term for a hypothetical case argued by law students. Sometime around the mid 16th century, it changed affiliations and became more commonly used as an adjective.
Thus, in my example above, Hezekiah believes in his heart that Ezekiel's argument is worthy of debate. However, around the 19th century, people started to use the word to mean "of no particular significance or relevance", which is the typical usage today. How confusing is that for the foreigner who looks up the word in the dictionary and finds both definitions? Context is everything. Perhaps we can submit the english language to ECMA for standardization.
We'll be out enjoying the wilderness this weekend at Sequoia National Park. I once worked at a company with Sequoia in its name. This park is not owned by them.
Wolfgang Puck could not be reached for comment.
AP - A food fight that started with fruit cup turned into a mealtime melee, serving up a full plate of arrests and injuries.
[Via Yahoo! News - Oddly Enough]
When you ask the average programmer, what problems plague the practice of building software, you’ll probably hear responses such as:
The impedance mismatch between relational databases and object oriented code.
The difficulty of writing secure code.
Managing complexity and requirement changes..
Certainly, these are all worthy problems to tackle, but the problem that comes to my mind is how much pain I’m in when I write code and how not many people really understand this. I hope to write a series of articles about typing pain and what to do about it based on my experience and research.
If you sit in front of the computer 8+ hours a day, you’ve probably experienced pain at one point or another in your hands, wrists, shoulders, and/or back. Typically, if you’re like me, you’ll ignore it at first, maybe blame yourself for being weak, try hitting the gym more. However, at one point or another, you have to deal with it because it gets too painful not to. Friends and coworkers may not understand, but if you dig around, you’re almost guaranteed to find one or more coworkers who are silently dealing with this type of injury.
And yes, I do mean injury. Everybody seems to want to call it Carpal Tunnel Syndrome (CTS), but CTS is only one small type of injury within a family of injuries often grouped under the term Repetitive Stress Injury (RSI). RSI ailments include tendinitis, neuritis, CTS, etc...
The real difficulty of these types of injuries is that they are a relative newcomer in the annals of medicine and are thus quite misunderstood. From outward appearances, you’re sitting on your ass all day, how can you get injured? Well let me give you some stats.
At the end of an average eight-hour workday, the fingers have walked 16 miles over the keys and have expended energy equal to the lifting of 1 1/4 tons. - DataHand
This rapid increase in RSIs coincides with the increase of personal computer use. There are now an estimated 70 million PCs in the USA. Dr. Pascarelli estimates that RSIs now cost companies $20 billion a year. - WebReference.com
Hopefully the first quote highlight just how much work we make our little fingers do in a day, and the second quote appeals to you (and your employer’s) pocketbook. Much of these costs can be easily reduced dramatically by taking a proactive and preventive approach to RSI. For the company, that means saving a lot of money by not taking a short-sighted approach. Make sure your employees have the right equipment and an ergonomic evaluation. For you the individual, that means making sure you work in an ergonomic fashion and get help at the first sign of pain.
I will talk a bit about my experience in upcoming postings. I continue to struggle with pain, but I currently have Workman’s Comp which pays for my treatments and hooked me up with an ergonomic chair.
Some references of note:
Keymileage calculates how far your fingers must travel to type something.
The Typing Injury FAQ has comprehensive information about RSI and typing injuries.
Test First Development, the process of writing unit tests to test the code you are about to write, is one of my favorite software practices that has an impact on producing better written code. However, it's no a panacea. It is true that I use the debugger much less often because of TDD, but there are still occasions where it's important to manually step through code line by line.
Personally, I use NCover as my first line of defense. It highlights the lines of code that haven't been executed by my unit tests. A lot of these turn out to be non-issues such as the last "}" in a method or an assertion that this line should never happen (for example in the default: section of a switch statement when I believe the default should never be reached).
There are those times, however, when you don't have time to write a unit test to excercise a particular line of code. Stepping through it is a wise idea.
Also, unit tests won’t uncover errors of omission. Stepping through your code will often jog your memory and remind you that, Hey, I forgot to make the code jump rope here AND I forgot the jump rope test fixture.
Be aware that there is a PayPal scam going around. I received the following email which had a forged from address of "DoNotReply@PayPal.com". There's a reason they don't want you to reply, because it exposes the scam. They'd rather have you run the attached program. DO NOT DO IT! This is a scam. It is easy to forge the headers of an email. It didn't come from PayPal.
Dear PayPal member,
PayPal would like to inform you about some important information regarding your PayPal account. This account, which is associated with the email address
phil@sequoiasoft.com
will be expiring within five business days. We apologize for any
inconvenience that this may cause, but this is occurring because all of our
customers are required to update their account settings with their
personal information.
We are taking these actions because we are implementing a new security
policy on our website to insure everyone's absolute privacy. To avoid
any interruption in PayPal services then you will need to run the
application that we have sent with this email (see attachment) and follow the
instructions. Please do not send your personal information through
email, as it will not be as secure.
IMPORTANT! If you do not update your information with our secure
application within the next five business days then we will be forced to
deactivate your account and you will not be able to use your PayPal account
any longer. It is strongly recommended that you take a few minutes out
of your busy day and complete this now.
DO NOT REPLY TO THIS MESSAGE VIA EMAIL! This mail is sent by an
automated message system and the reply will not be received.
Thank you for using PayPal.
uiaumzem
Sergey and Larry have moved up a couple of notches of coolness in my book. They're burners! They attended Burning Man in the summer of 1999. The logo above is what they put on the Google site while they were out of town. In commemoration of the upcoming Burning Man, I'll put up some picks later from 2002 when we went.
Just goes to show I can't draw.
Typically when you spawn a new thread, you want to give it a name to facilitate debugging. For example:
using System.Threading;
//.. other stuff....
Thread thread = new Thread(new ThreadStart(DoSomething);
thread.Name = "DoingSomething";
threat.Start();
The code in the method DoSomething (not shown) will run on a thread named "DoingSomething."
Now suppose you're writing a socket server using the asynchronous programming model. You might write something that looks like the following:
using System.Net.Sockets;
using System.Threading;
ManualResetEvent allDone = new ManualResetEvent(false);
public static void Main()
{
Socket socket = new Socket(...); //you get the idea
while(true)
{
allDone.Reset();
socket.BeginAccept(new AsyncCallback(OnSocketAccept), socket);
allDone.WaitOne();
}
}
public void OnSocketAccept()
{
Thread.CurrentThread.Name = "SocketAccepted";
allDone.Set();
// Some socket operation.
}
In the example above, we're setting up a socket to call the method OnSocketAccept asynchronously when a new connection occurs.
When you run this, it may work just fine for a while. It might even pass all your unit tests. Don't you just feel all warm and fuzzy when the green bar appears? Put this in production, however, and that warm and fuzziness may turn into cold dread as you're guaranteed to run into anInvalidOperationException.
Why is that? Underneath the hood, when the OnSocketAccept method is called, the CLR rips a thread from from the CLR's thread pool. When the method completes, the thread happily returns to the pool to finish its Pina Colada. Eventually, that thread will resurface, and that's where the problem arises.
You can change the name of a thread, but you can only change it once.If you try to change it again, you're greeted with an InvalidOperationException. When a thread is returned to the thread pool, it holds onto its name. Its happy to have a sense of identity and will hold onto it even when it resurfaces to execute another method. To protect from this, always check the name of a thread before setting it like so:
if(Thread.CurrentThread.Name == null)
Thread.CurrentThread.Name = "MyNameIsBob";
Your threads will thank you for it.
Guess he should have remembered to take out the trash... Oh wait, he tried.
WESTON, Conn. -- Max Miesel didn't get very far with his prom date -- who's a porn star.
Max won a date with adult film actress Tyler Faith on Howard Stern's show Friday. Max is a student at Connecticut's Weston High School. The Advocate of Stamford, Conn., reported school officials and Max's parents stepped in before Saturday's prom...
[
via http://www.channelcincinnati.com/education/3389768/detail.html]
This is one of the funniest tech support stories I've heard in a long time. Even you non-geeks can appreciate this...
We sold a computer to an elderly lady who took it home. We had tested it, and it worked great at the store. But, when she got it home, she could not get it to turn on. I work on the phone with her for an hour.
"Is everything plugged into the power strip, maam?"
"Yes, everything is."
So, I was sent to her home. Sure enough, everything was plugged into the power strip ... including the power strip.
[Via The Daily WTF]
Thanks to the help of the very talented Joel Bernarte, I have a nice new look to the site. He created the logo you see at top. I then spent a bunch of time trying to modify the layout and Css to do the logo justice.
If you're viewing this in an aggregator, you'll actually have to take a second outside of the aggregator to look at my site haacked.com using that antiquated piece of technology that used to rule your life called a Web Browser (which might just be integrated in your aggregator). Thanks. Now back to the new technology that's ruling your life...
I finally decided to quit being a cheap-ass and so I purchased web hosting with WebHost4Life. Now my blog is hosted at http://haacked.com/ rather than that old ugly domain name (http://haacked.europe.webmatrixhosting.net/).
If you subscribe to my RSS feed, please change the URL to http://haacked.com/Rss.aspx
Oh, and by the way, if you sign up for WebHost4Life, be sure to tell them I sent ya via this link.
See, this is exactly the type of comment spam I'm hoping to avoid.
Harrrrrr... shoulder of pork and ham!!! $4 dollars at the quickie-mart! I am a prince from Niger, please give me the keys to your Mercedes Benz. I love men who aren't afraid to blog!
Only in this case, I'm afraid I know this guy.
;)
By the way, the ASP.NET Resource Kit has a free version of the SAX human verification component. That ought to help combat automated spam.
Another option is to simply remove the web interface for comments and only allow comments via the Comment API.
I have a hunch that most of the comment spam comes from people who stumble on my site via the web. Most people who post via the CommentAPI are using an aggregator and are thus subscribed to my site, or were referred by another subscriber.
UPDATE: I may be confusing Comment Spam with Comment Graffiti. As far as I can tell, I do not have any comments from any automated sources, nor comments advertising products on my site. The "spam" I have seems to merely be comments by random people who occasionally write offensive comments.
In an email to Ian Griffiths I mentioned that I wished he had a comments section because some of his posts are so intriguing I have to reply. ;) His reply relayed a common angst regarding enabling comments on a blog, comment spam
Looking around, I see this is a common problem as evidenced by the following posts by Roy Osherove who wants to turn comments off, Chris Anderson who threatens to turn them off, and John Lam who did turn them off.
This is disheartening because comments can be a vital part of a blog encouraging lively and insightful conversation. But then again, not if your constantly getting these type of comments
Noticed on a dirty white van, letters made by hand:
"I Wish My Wife Was As Dirty As This."
Underneath, different style:
"She Is!"
Funny? Maybe. But off-topic. Unlike the garden variety email spam, the bulk of comment spam tends not to be automated. If it were, it'd be plenty easy to stop by requiring users to type in some text they see in an image.
Rather, much of the smelly meat is due to the fact Google is bringing droves and droves of visitors to blogs as bloggers all link to each other. Some of these unwashed masses decide to leave their mark on your site.
As John Lam pointed out, simple IP filtering isn't enough.
I've been thinking alot about how to leverage network effects to reduce comment spam. For example, in general I'll trust people who have subscribed to my blog to make comments, and if they've been subscribed a while, I'll trust those that subscribe to theirs.
I can imagine adding features to blogging back-ends such as .TEXT or DasBlog whereby trust relationships can be built by using something similar to the TrackBack API. Suppose I subscribe to your blog and you try to make a comment on my site. Since my blog knows that I am subscribed to yours (this will require aggregator integration), it automatically lets you comment. It then can go one step further. Perhaps it will ask you, "Any changes to your whitelist since we last exchanged data?". We can then exchange whitelist info. Certain spam engines work in this manner.
The big problem with this approach is that identity is a tough nut to crack without requiring that commenters create a login and password and building in some sort of verification system.
I received a lot of comments (a lot for me) on my post entitled "The Difficulties of Language Design".
I wanted to follow up on one interesting comment by a reader named Jocelyn:
"Language changes shouldn't break existing code..."Well, yes or:
- obsolete features (like the lock keyword) could be flagged
- tools could be developped to update existing source code
- the language could be versionned:
#version 1.1
#version 2.0
That's why I qualified my statement with "...Too Much.". There are certainly cases where you have to take the plunge and risk breaking existing code. The things she mentioned are certainly great ways to mitigate the impact of changes, but they aren't enough.
I think the real difficulty is when you slightly change the behavior of a language feature such as a keyword. This change won't show up when you recompile your code because you aren't marking the feature as obsolete. Likewise, it can be quite hard for code analysis tools to check to see if the semantics of your code relies on the old behavior (though in some cases this might be possible) and would have problems with the new behavior. The best it could do is flag the keyword and say "Hey! The behavior of this keyword has changed." This might be helpful in some cases, but imagine if the behavior of the lock statement changed slightly. That's a lot of places you're going to have to check by hand.
The end result is that you recompile your code using the newer language and everything looks hunky dory. But days, maybe weeks, later you find a subtle problem with your code that is difficult to track down. In the end, it may be the end result of a chain of events that started at the point where your code relied on a certain behavior of the language and that behavior changed. The point here is that the error might not occur at the point where you rely on the faulty behavior, but somewhere down the line.
I'm not advocating that the behavior of language features should never change, especially if the behavior is wrong to begin with. I'm merely pointing out the risks and hazards of doing so. It's a heavy cost and the benefit sure as hell better be worth it. I think this is why you see so few breaking changes.
This is too funny to be made up.
Raymond's first death threat.
I now have a WebHost4Life account. I'll be moving my site there sometime in the future. If you sign up for webhost4life, be sure to use this link or refer to me. :) http://www.webhost4life.com/default.asp?refid=haacked
UPDATE: I am no longer with WebHost4Life as my company now offers me hosting.
I'm trying out this sweet plug-in for the Windows version of iTunes. After installing this plug-in, you can click on the musical notes at the bottom of w.Bloggar and it will insert information about the currently playing song wherever your cursor is located. This page lists plugins for Winamp versions 2,3, and 5 as well as iTunes (the one I'm using).
Now you'll all get to experience (from time to time) my awesome music collection. ;)
This doesn't bode well for my buddy
Kyle.
Reuters - Strangers given separate photos
of dogs and their owners are often able to pair them,
suggesting that people often do resemble their canine
companions, according to new study findings.
[Via Yahoo! News - Most Emailed]
Apparently I’m not the only one who’s been contacted by the son of the late Democratic Republic of Congo President Laurent Desire Kabila. I’ve also been contacted by several other members of royalty or political dissidents who are fleeing the Congo.
Each of these people need MY help in transferring insane amounts of money. I’m talking barrels and barrels of cashola. Apparently, nearly everyone I know has been contacted by someone from the Congo wishing to transfer money. Congo must be a very very rich country. These guys are smuggling enough cash to make Bill Gates look homeless.
Found this out in the blogosphere:
Apparently, Time has obtained an internal pentagon email that links Dick Cheney directly to the no-bid contract that Haliburton received for rebuilding Iraq's oil infrastructure. Sadly, people most likely won't hear about this, and it will die with all the other smoking guns that practically scream out and demand some independent investigation into this administration. Clinton got one for getting a hummer from an intern, but the current administration, flagrantly flaunting its corruption, slips by over and over again. [via the ever-great, wish-he-blogged-more Marc
Goodner]
This weblog is brought to you by the color Orange and the sesame street character, Bert.
[Via Corey's Ramblings]
My car hates me. Or it should. Last week I made two round trips to SD. Last Friday night, I returned from SD, and Akumi and I left the following Saturday morning to drive up to San Francisco. I used to love road trips, but after all the hours of sitting on my ass in my car this weekend, I'm done for the time being (or at least for two weeks since we're going camping).
The highlight of the trip was the outstanding weather in San Francisco. Mark Twain supposedly once said "The coldest winter I ever spent was a summer in San Francisco." Well, too bad he wasn't there this past weekend. It was absolutely gorgeous up there. Even nicer than LA and SD. We laid out like cats in the sun by a fountain in a park with a view of the SFMOMA. I forget the name. We met up with Laura and had dinner at R&G Lounge. That was some of the best Chinese food I've had in a long while. It even met up to Laura's standards. Surprising coming from a place with such a droll name.
That evening we had drinks in The View, an aptly named bar on the top of the Marriot. The View that caught my attention was the view of the tab. Damn them drinks are expensive!
The next day, we spent with friends of Tim and Laura, Eric and Jenny, who have a cute chubby baby boy named Peter. Peter is an innovator. He claps by moving his hands vertically up and down slapping the top of one hand with the bottom of the other.
SF had its own Carnival going on which was pure craziness. The floats were fun to watch, but walking through the crowd got very tight and annoying.
Checked out the POP! art show at the SFMOMA. It was a bit disappointing as the size of the collection was really small and they didn't have enough Warhols or Lichtensteins for my wife's taste.
I have a confession to make. While at Tech-Ed, I did some bad things. Please look upon me not with a judging eye, but try to have a forgiving stance.
While at Tech-Ed, I missed several sessions I had planned to attend...in order to...*gasp* play Unreal Tournament 2004.
I know. I know. I'm supposed to be at Tech-Ed to learn the latest and greatest Microsoft technologies, not to waste my time manning the guns on a Leviathan, or sniping suckers with the lightning gun. But I just couldn't help it! My boys (and girls, but mostly boys) out there needed me! I couldn't just ditch my team as the other team was encroaching on the main base now could I? What did you expect me to do in the face of such temptation as a setup consisting of 32 networked AMD 64 bit servers with flat panel displays?
In any case, I've checked myself into Dennis Fong Clinic for 1st person shooter addicts. I'll get the help I need at the DFC. Hmmm... DFC... Sounds like a new weapon in UT... Wonder how I get that...
So we're going to keep the Media Center PC since we won't be able to get enough to buy a Tablet PC if we sold it and since we can get a lot of use from it. I have a lot more to write about Tech-Ed and my fabulous weekend in San Francisco. Stay tuned.