Unsticking Quicksilver “Go to Directory in Terminal” Command
[Quicksilver](http://quicksilver.blacktree.com) is the best thing since any kind of bread. I can’t live on a Mac without it, and I even find myself attempting to use it on Windows when I’m at work.
One its tricks that I use all the time is “Go to Directory in Terminal”. This command opens a Terminal window and cd’s to the directory that was the subject of the Quicksilver sentence. Very handy.
Recently, this command got “stuck”. Every time I would open a Terminal window, it would change to a directory I had opened with Quicksilver. Nothing seemed to make Terminal forget the command. Since I didn’t know how Quicksilver caused the command to be run when the window was created, I wasn’t able to do anything about it.
My first guess was a term file that was created by Quicksilver and set as the default. No dice. I wasn’t able to find any term files that I hadn’t created myself.
Next, I thought it might have altered my .profile file. Nope. It was still just like I left it.
Turns out there is a Terminal preference I was unaware of. If a key named ExecutionString exists in the com.apple.Terminal domain, all new Terminal windows will execute it upon creation. My cd command was found there. My best guess is that Quicksilver modifies the key, opens a window, and then returns it to its previous state. It must have somehow lost its mond and forgotten to return ExecutionString to its original state. Quicksilver *does* crash on me sometimes.
If this happens to you, correcting it is fairly easy:
defaults delete com.apple.Terminal ExecutionString
When I first found this, I tried to think of some other way to put the preference to use, but I think I’ll just use .profile and term files.
The Snizzlator
Here’s another one for all you Greasemonkeys out there. The [Snizzlator](http://davidsidlinger.com/svn/greasemonkey/all/snizzlator.user.js) solves one of the world’s most pressing problems: How do I inject Snoop-speak into the web? I can’t take much credit for this one. One of the code monkeys I keep in a subterranean lair, P. Carl Wilson, recognized this need years ago and solved the problem with a JavaScript bookmarklet. My only contribution was to make it a Greasemonkey script. Like every good partnership, we’ve decided to split the fame, money, and groupies 50/50. You should definitely grab the script regularly. P to the C has found his calling in life and regularly updates the script. Those of you interested in what you can do with Greasemonkey should take a look under the hood. There’s all kinds of JavaScript goodies in there.
On a Roll
I posted another Greasemonkey script last night. [This one](http://davidsidlinger.com/svn/greasemonkey/amazon.com/searchgoogleproducts.user.js) puts a link to search [Google Products](http://google.com/products) on Amazon pages, based on the name of the item you’re viewing. It’s more complicated than the last one, but it didn’t take too much time to throw together. I realize that I’m pretty late to the Greasemonkey party, but I’m having _fun_, and isn’t that the point?
One thing that bugged the hell out of me when working on this script is that it seems like Amazon adds absolutely no semantic meaning to their product pages. Does the product name sit in an element with an ID clearly labeling it as such? No. Here’s the XPath I had to use to extract the name:
//div[@class='buying']/b[@class='sans']
Isn’t that cheesy? It feels really fragile. I suppose I could have parsed the page title to strip out extraneous information, but I wouldn’t feel much better.
__Update:__
Surprise, surprise! It _is_ fragile. The different templates that Amazon uses based on product category (I think?) break the script. Oh, well, at least it doesn’t fail spectacularly.
Known good:
* Books
* Music
* Electronics
Known bad:
* DVD
Created a Greasemonkey Repository
I’ve created a [Subversion repository](http://davidsidlinger.com/svn/greasemonkey/) to hold any [Greasemonkey](http://greasemonkey.mozdev.org) scripts I might come up with. The [first one](http://davidsidlinger.com/svn/greasemonkey/amazon.com/setsearchfocus.user.js) sets the focus to the search box when viewing [Amazon](http://amazon.com) pages. It will save me a bajillion tabs every time I hit the site. Is it worth talking about? Probably not. Am I disproportionately pleased with myself? Yes.
I Really Tried…
This marks the end of my _third_ attempt to use [Safari](http://apple.com/safari) as my default browser. I just can’t seem to tear myself away from [Firefox](http://www.mozilla.com/en-US/firefox/).
The main reason is extensions. Safari doesn’t seem to be nearly as extensible as Firefox or even [Internet Explorer](http://microsoft.com/ie). I can’t find the equivalent to plug-ins that I use on a daily (hourly?) basis like [del.icio.us](http://del.icio.us/help/firefox/extension) and [Firebug](http://www.getfirebug.com/). If I am completely off-base, please let me know.
There are quite a few things I like about Safari. It does seem to be a lot snappier, and, being a Cocoa application, it integrates with OS X and it’s services, like Summarize, tightly. I also get the drawbacks and _slight_ bugginess of Firefox, but I just can’t bring myself to give up all the additional functionality. I really wish Apple would take a long, hard look at the extensibility available in Firefox and realize that it is the main force driving users to ditch Safari.
Inbox Zero Talk
[Merlin Mann](http://merlinmann.com), of [43 Folders](http://43folders.com) fame, recently gave a talk at [Google](http://google.com) about [Inbox Zero](http://www.43folders.com/izero/). Dealing with the deluge of email, personal and professional, is a topic near and dear to my heart. It’s nice to see a company that’s taking an interest in helping their employees with this. A video of the talk is embedded below. If you want the slides, you can grab them [here](http://www.slideshare.net/merlinmann/inbox-zero-actionbased-email) [PDF].
Via [43 Folders](http://www.43folders.com/2007/07/25/merlins-inbox-zero-talk/)
The Numbers Table
Over the years, I have been treated to a wide range of what I can only call [perversions of technology](http://worsethanfailure.com/). By far, the funniest I have seen is the Numbers Table. Why would you need a table of numbers, you ask? Because you need to count, of course.
The team of “developers” that came up with the Numbers table had heard that making a database call has overhead. Apparently, they had not heard about [M.A. Jackson's Rules of Optimization](http://portal.acm.org/citation.cfm?id=1095595):
1. Don’t do it.
1. (for experts only) Don’t do it yet.
The system in question used pessimistic locking, another great story. There was a method to release multiple locks, which were stored in a database table. There was no way this performance critical code was going to call the LockRelease procedure for every lock. That would be _insane_! Presented here is the code that used the Numbers table. It’s reconstructed from memory, because I am too lazy to go digging through source control history. I have expanded a SQL function into the procedure definition and left out the irrelevant code.
First, the C# code:
public void ReleaseMultipleLocks(params Lock[] locks)
{
StringBuilder builder = new StringBuilder();
foreach(Lock lock in locks)
{
builder.Append(lock.LockId.ToString().PadLeft(11, “0″));
}
// Code to call the stored procedure with the (potentially) gigantic string
}
Now, the SQL:
CREATE PROCEDURE dbo.ReleaseMultipleLocks
(
@LockIds nvarchar(4000)
)
AS
DECLARE @locks TABLE
(
LockId bigint NOT NULL
)
INSERT
@locks
SELECT
CAST(SUBSTR(@LockIds, (11 * (Numbers.Number – 1)) + 1, 11) AS bigint)
FROM
dbo.Numbers
WHERE
Numbers.Number <= (LEN(@LockIds) / 11)
ORDER BY
Numbers.Number
— Use the @locks table to update the release datetime on
— the specified lock records. If I remember correctly, it
— used a cursor.
Wow.
So, in order to avoid those "expensive" database calls, we: build a string out of all those pretty, compact integers, pass that big string on the wire to the database server, create a table that holds (wait for it) integers, and use a huge table of numbers to do string parsing in SQL. Before you ask, this table was not used for anything else.
For your additional amusement:
* A long/bigint holds [19 digits](http://msdn2.microsoft.com/en-us/library/ms187745.aspx), not 11.
* The Numbers table had hundreds of thousands of rows. You only need 364 numbers to parse the maximum string length that could be passed.
* There were mysterious gaps in the numbers table. None of them were in the range that would have affected this procedure, but…c'mon.
* The Numbers table was rebuilt every time the system started from hundreds of thousands of INSERT statements…in multiple databases.
* Why you need to use a double-byte character set for a string that holds only digits is beyond me.
* The team that came up with this was supposed to be our crack team of Enterprise Infrastructure Developers.
I'm posting this story and, soon, others I can bring myself to remember for a few reasons:
1. We have told them plenty of times to developers joining the team. Pointing them to a link will take a _lot_ less time.
1. I want to remind myself how good I have it now, relatively speaking.
1. To, hopefully, stop myself from falling into the optimization trap.
1. Poking fun at this helps me get rid of the bad feelings associated with it.
__Update:__ A co-worker corrected some of my code. SUBSTR is 1-based, and my WHERE clause was jacked up.
Pownce Client Bug
I was lucky enough to get an invitation to [Pownce](http://www.pownce.com) from [Patrick](http://www.paltman.com). I like some of the ideas in Pownce (e.g. file sharing, threaded replies), and it will be interesting to see if they can overcome the inertia of [twitter](http://twitter.com) to have some success in the micro-blogging space.
One thing that is nice about Pownce is the client they have written using the [Adobe AIR runtime](http://labs.adobe.com/technologies/air/), which functions a lot like [Twitterific](http://iconfactory.com/software/twitterrific). I did find one bug, though. If you have colons (and maybe other “special” characters) in your password, you get an error when logging in. Probably something to do with URL encoding. If you change your password to alphanumeric characters, it works like a champ.
Feeding the Revenue Beast
The latest on the reading list is [Programming WCF Services](http://www.amazon.com/gp/product/0596526997?ie=UTF8&tag=davidsidlinge-20&link_code=as3&camp=211189&creative=373489&creativeASIN=0596526997) from Juval Löwy. I’m having a real hard time maintaining interest in this book for a variety of reasons, but I’ll save the review for when I’m done.
I was only in the first paragraph of the preface when I hit a statement that sums up how I have been feeling about Microsoft development lately. In Juval’s own words:
> Then, in July 2002, during a C# Strategic Design Review, the remoting program manager
> outlined in broad strokes plans to rework remoting into something that developers
> should actually use.
Now, Juval is not a Microsoft employee so much as a Microsoft shill; so, nothing he says can be taken as anything official from on high. However, I think that one statement has focused my frustration enough that I can articulate what has been bugging me. It shows a _complete and utter disregard_ for the people that have been building their products on the .NET platform by Microsoft and their evangelists. This type of behavior can be seen in almost all facets of their development tools and technology stacks (e.g. distributed systems, data access, web applications.) They come out with yet another new solution to a problem only to turn around and rework it from the ground up and tell us what a piece of crap that last implementation was.
Outside of the standard disclaimers on alpha and beta software, I have _never_ seen or heard Microsoft say that we shouldn’t be using their current technology stack. If remoting was so bad (I do think it was and _still is_,) why didn’t they caution us against using it? Why do they continually come out with shiny new toys that require the people driving their success to rewrite mountains of code?
The simplest answer is that most of what they put out _does_ suck. While there have been some real “gems” thrown out there for people to risk their business on, I don’t think that completely explains it.
The second simplest answer is that Microsoft has shareholders and loads of salespeople and middlemen to appease. They cannot survive without a constant stream of revenue pouring in. They could accomplish that by being the hands-down best platform out there. Instead, they choose to feed the MSDN beast and get developers whipped into a frenzy about something that will require more upgrades, training, etc. Incremental, but substantial, improvements with a lot of thought put into maintaining compatibility with existing code do __not__ keeping cash flowing into the maw.
A lot of people have [written](http://www.joelonsoftware.com/articles/APIWar.html) about this. Some of Microsoft’s own people have had [moments of sanity](http://blogs.msdn.com/dareobasanjo/archive/2004/08/25/220251.aspx). I just wanted to register my disgust. If anyone from Microsoft comes upon this, know that you’ve lost another “heart and mind.” I have unwittingly done my part to push your products and agendas in the past. I won’t be doing it anymore. Will I stop using the .NET platform altogether? No. Will I avoid subjecting my employers and clients to change for change’s sake? Absolutely. Will I make every _reasonable_ effort to get them to consider alternatives? You better believe it.
__Update:__ As with all things, I should have looked to Looney Toons for an appropriate analogy. We developers are Elmer Fudd, and whatever Redmond is pushing is [Bugs Bunny in a dress](http://www.youtube.com/watch?v=OyxPxpSvXQ8&mode=related&search=). We just keep falling for it every time.




