Matt: I wonder if SPAM is good, I have never had it before (while holding up a can of SPAM).
Me: Ya, haven’t you ever fried SPAM before?
Matt: Only at the gateway level.
Oh the joys of working for an email company.
The exciting life of a software developer and nerd
I downloaded Amazon’s Unbox this weekend to watch some BSG (yes I am a nerd). Unbox is Amazon’s video download service. I say service because it is much more than just another download. Amazon allows me to re-download videos or transfer them to multiple machines. Obviously, the Unbox player doesn’t allow burning to DVD, but I am over my purist-open-world days.
As with any service, there is room for vast improvements. The software is slow and buggy, but not bad enough to piss me off, which means it is still very usable. Also, the software only works on Windows XP or Vista, which is annoying for me because I run Ubuntu and Windows. In the future, software for linux that could be integrated with MythTV would be stellar-sweet. (Something tells me the suits are worried about the ability to rip the videos easier in linux).
All things considered, it is exactly what I wanted when my craving for season 4 of BSG got the best of me. I can’t compare it to similar services, but it is worth trying if you don’t care to hook your laptop up to your TV and pay $1.89 an episode.
Today I found some odd behavior when working with LINQ. It is hard to describe, so here is the code.
public void Foo(IEnumerable<string> strings) { IEnumberable<string> stringsInDb = strings.Where(s => this.QueryTheDbAndTakeALongTime(s)); foreach(string str in stringsInDb) { //Where clause in LINQ is actually executed } foreach(string str in stringsInDb) { //Where clause in LINQ is actually executed AGAIN } }
Luckily, some unit tests detected this behavior. It actually isn’t surprising when you think about it though. The proper thing to do for this case is actually call ToList() after the Where().
IEnumberable<string> stringsInDb = strings.Where(s => this.QueryTheDbAndTakeALongTime(s)).ToList();
Don’t let this behavior bite you.
Today I was thinking, and I realized something odd. My development computer is Windows. My personal computer is Ubuntu. Weird huh?
Every developer has heard the phrase document your code. The reason this is important is the functionality is now coupled with a description of how it works. Now a future developer can load up a single source of information and understand the functionality. But, more importantly, the odds of the documentation staying updated are higher because of this coupling. The same can’t be said for a standalone document.
Well, shouldn’t the same be true for documents, specifically those that describe some sort of process? For example, a document describing the steps to setup an IIS web server for a particular application is perfect to convert to an automated script. So, today, I started on a simple script to setup IIS compression using MSBuild.
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 | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <!-- Types --> <PropertyGroup> <adsutilPath>C:\inetpub\AdminScripts\adsutil.vbs</adsutilPath> <cscriptPath>cscript</cscriptPath> <StaticFilesToCompress>html htm js txt</StaticFilesToCompress> <DynamicFilesToCompress>aspx asp dll exe axd</DynamicFilesToCompress> </PropertyGroup> <Target Name="IisCompression"> <Message Text="Turn on static and dynamic compression for all of IIS." Importance="high" /> <!-- http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/502ef631-3695-4616-b268-cbe7cf1351ce.mspx?mfr=true --> <Exec Command="$(cscriptPath) $(adsutilPath) set w3svc/filters/compression/parameters/HcDoStaticCompression true" /> <Exec Command="$(cscriptPath) $(adsutilPath) set w3svc/filters/compression/parameters/HcDoDynamicCompression true " /> <Message Text="Select files to compress for static and dyanamic compression." Importance="high" /> <!-- http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/d52ff289-94d3-4085-bc4e-24eb4f312e0e.mspx?mfr=true --> <Exec Command="$(cscriptPath) $(adsutilPath) set W3SVC/Filters/Compression/Deflate/HcFileExtensions $(StaticFilesToCompress)" /> <Exec Command="$(cscriptPath) $(adsutilPath) set W3SVC/Filters/Compression/gzip/HcFileExtensions $(StaticFilesToCompress)" /> <Exec Command="$(cscriptPath) $(adsutilPath) set W3SVC/Filters/Compression/Deflate/HcScriptFileExtensions $(DynamicFilesToCompress)" /> <Exec Command="$(cscriptPath) $(adsutilPath) set W3SVC/Filters/Compression/gzip/HcScriptFileExtensions $(DynamicFilesToCompress)"/> </Target> </Project> |
Not only does this script automate the process, but it serves as a living document for the process. By doing this, the documented process is now coupled to the task itself.
The next step to coding processes is coding tasks that can’t be automated. For example, during a deployment, if some sort of fatal error occurs, the next task might be to call your boss and clean up your resume. Why not code a message in the deploy script to give you the list of people and phone numbers to call in case of an emergency, then load up your resume in Word? Again, the documented process is now coupled with the task itself.
Obviously, this article grows out of my dislike of documentation. I dislike it, not because it isn’t useful, but because it takes a lot of time and, in my personal experience, isn’t used very often. By integrating the documentation with the task itself, I think we gain more value from it.