Clip Zip annoyance

OK, I partially take back my comments from yesterday. I found another thing about my new Sansa Clip Zip that's annoying.

Yesterday I tried upgrading the Clip Zip firmware. It came with firmware version 01.01.12, but the current release is 01.01.18, so I figured I'd get up to date. The firmware upgrade process itself was actually totally painless. You can use Sandisk's upgrade utility or just copy the file into the root of your device and disconnect it from the PC to start the upgrade. Nice and simple.

The problem is with the new firmware. As far as I can tell, there were no major bug fixes or improvements that I care that much about, but there is one major bug. In the 01.01.12 firmware version, the media refresh will pick up M3U files and add them to the device's list of playlists. The file paths need to be relative, of course, or else you end up with an empty playlist, but it's actually a very nice feature.

Well guess what's missing in firmware version 01.01.18 - no playlists. They don't even show up. A thread on the official Sansa forum suggests that this problem is actually shared by all the newer firmware versions, not just the latest. So nice going, Sandisk! Way to snatch defeat from the jaws of victory.

On the up side, reverting to the 01.01.12 firmware was dead simple. Just download the appropriate archive and follow the normal upgrade instructions. Once I did that, my playlists were back...after the hideously long media refresh.

New MP3 Player - Sansa Clip Zip

I got myself a little treat for the new year - a new MP3 player. I'd been thinking about it for a while, and a combination of my Christmas bonus and the fact that my old Sansa e280 would no long connect to my computer finally motivated me to take the plunge.

This time, I decided to go minimal. As I mentioned, my last MP3 player was a Sansa e280, which isn't exactly the Cadillac of MP3 players, but has a pretty decent feature set. It was certainly one heck of an improvement over the one I had previously - an old Digitalway MPIO with a whopping 256MB of internal storage and a massive 3-line monochrome display. The Sansa e280, on the other hand, has 8GB of internal storage, a decent sized screen, and can display pictures and videos. With the RockBox open-source firmware, it also has some simple games and apps, as well as microSDHC support (the Sandisk firmware only goes up to 2GB microSD cards).
My MPIO, Sansa e280, and Sansa Clip Zip
The thing is...I never really used any of that. Granted, the microSD slot is a God-send, and I used to occasionally play games on it. But I never had more than a couple of pictures of videos on it and really only used it for listening to music and podcasts. And for videos or games, I now have a CAANOO. So why not get something a bit smaller that just does the one thing I really care about?

So this time I went with the Sansa Clip line. In particular, the new Clip Zip, successor to the Sansa Clip+, which I was originally considering.
Close-up of the Sansa Clip Zip
The Clip Zip has a lot of things going for it. First, there's the form factor. It's tiny - only 2.25" by 1.42", about the same size as the pouch I use for my headphones. Second, it's cheap. The Clip Zip comes in both 4GB and 8GB models and starts at $50. I got a 4GB model on sale for $40, which is about what you'd pay for a 4GB no-name MP3 player. Third is the storage capacity. Of course, there's nothing impressive about the internal storage, but it doesn't matter because the Clip Zip has a microSDHC slot. So for another $30, I added a 32GB microSD card to my order, giving the Clip Zip a total capacity of 36GB. Not bad for a $70 investment.

So far, I really like the Clip Zip. I was initially disappointed that RockBox didn't have a stable port for it yet, but it turns out that the Sandisk firmware is actually pretty nice. The menu system is easy to use and looks nice, as does the "playing" screen with background cover art turned on. The firmware automatically sorts by artist, album, genre, etc., and separates podcasts and audio books into a separate menu item, which is kind of nice. It also includes the option to let you browse the actual folder structure on disk rather than using the database, which is something I always wanted in the Sandisk firmware on the e280.

The only thing I don't like about the firmware is the media refresh. As with the e280, the Clip Zip will do a "media refresh" every time you write data to the disk when it's connected to a computer or when you insert a microSD card (even if it's the same card you just removed and nothing has changed on it). This normally wouldn't be a huge deal, except that with a large media collection the refresh can take a very long time. I have a little over 20GB of audio on my microSD card, and the refresh was initially taking between 12 and 15 minutes. With some adjustments to the ID3 tags on my files, I was able to knock it down to about 8 minutes - still a long time, but not as bad. (For future reference, I used Mp3tag to tag everything as ID3v2.4 UTF-8, removing all other tag versions and blanking the comments field.)

As far as the hardware goes, I have no real complaints. I must confess that the Clip Zip does feel a bit flimsy compared to my e280, probably because the casing is all plastic as opposed to the metal backing on the e280. However, it seems to be reasonably well made. The controls are easy to use and I've found myself using the clip on the back far more than I ever thought I would. And I have to say the that the micro USB charging port is a welcome change from the proprietary port that the e280 used. With the Clip Zip, I don't even have to bring a dedicated cable with me when I travel - I can just use the same one I use for my cell phone or Kindle.

So I would definitely recommend the Clip Zip. It's simple, inexpensive, does its job well, and is surprisingly full-featured for the price and size.

Ruby on the Cross

Author's note: This is a piece I wrote back in 2006, but didn't publish because I was afraid people might find it offensive. I found it while looking through the backlog of unpublished/unfinished entries in my drafts folder and thought it was funny enough to share. It's a satire of "magic" frameworks like Ruby on Rails (which was the big thing at the time), which are sold as the solution to all your problems. Thinking about "Rails evangelist", my mind naturally jumped to the new testament evangelists, so this is sort of a merger of the two. No offense intended to any Christians in the audience - I just thought software and eternal salvation made for a funny juxtaposition. But maybe I just have a weird sense of humor. Enjoy!

That's it - the "programming problem" will soon be solved. Next week is the official first, last, and only ever release of the ultimate web development framework - Ruby on the Cross.

What is it

What is RC? It's the ultimate web development tool based on the Christian faith. Think of it as a cross between Ubuntu Christian Edition and Ruby on Rails, but infinitely more productive. It was inspired by the Book of Matthew, chapter 17, verse 20:


And Jesus said unto them, Because of your unbelief: for verily I say unto you, If ye have faith as a grain of mustard seed, ye shall say unto this mountain, Remove hence to yonder place; and it shall remove; and nothing shall be impossible unto you.


Using this principle, RC is able to reach untold levels of productivity.

What does it do?

As you probably already know, Ruby on Rails takes all the pain out of developing CRUD applications by taking your database schema and automatically generating models, controllers, and default views for it, giving you a working, if simple, web application just by running a few commands. RC takes this one step farther: it generates your domain logic for you.

That's right, you heard me: Ruby on the Cross is capable of doing your business analysis for you. In fact, not only can it generate your domain object, but it generates fully functional controllers; rich, AJAX-driven views (which are fully backward-compatible with Mosaic 1.0, by the way); and even writes your database schema. Best of all, it is 100% guaranteed to be future-proof and to be maximally performant. Thus there will never be any need to maintain the generated program!

How does it work?

At this point, you're probably thinking that this is too good to be true. How could anyone possibly promise those things?

Well, remember the quote from Mat.17:20? By drawing on the faith of the programmer, RC is able to miraculously harness the power of God to create genuinely perfect software. There are no algorithms to debug, no trade-offs or design compromises to make. Just the pure invokation of divine power, which not even Murphy's Law can resist.

Hard to believe? It shouldn't be. Just think about all the things people thank God for. If He can get someone a parking space or help the high school basketball team win their big game, why can't He write software?

How do you use it?

Using Ruby on the Cross is quite simple. You simply need to run a few shell commands. You start with:
ruby cross praise jesus
This command initializes Cross and prepares your system for an infilling of the Holy Spirit.

The next command is:
ruby cross supplicate <app_name>
This command forms a prayer, asking the Almighty to design your application. Note that no configuration, or even knowledge of the problem domain, is necessary for this step. Being omniscient, the Lord is able to determine exactly what your customer needs, and will need in the future, with perfect precision.

Lastly, you simply need to ask God to put the project files on your PC so that you can deploy them. To do this, you simply run:
ruby cross create ex nihilo <app_name>
This will cause the completed project source code to appear on your hard drive. Note that you do not need to specify a path on the filesystem - the Lord knows the most appropriate place and will put the code there. And don't worry about source control: God has already added the code to your RCS - not that you're ever going to need to change it.

Coder self-esteem

You know, I've been making my a living writing software for over 10 years now. If my resume is any indication, I'm pretty good at it. But every now and then I still read something that gives me that. just for a minute, like maybe I've just been fooling myself all these years, like I'm actually completely inadequate as a software developer.

This Slashdot article gave me such a feeling. It links to a Google case study that involved porting MAME to the Chrome Native Client. The summary ends with this quote from the article: "The port of MAME was relatively challenging; combined with figuring out how to port SDL-based games and load resources in Native Client, the overall effort took us about 4 days to complete."

Now, I don't follow Chrome development at all, so when I read this, I had absolutely no idea what the Native Client actually was. My initial guess was that it was probably some API to access native libraries or hardware from JavaScript, or something like that. So it sounded like "porting MAME" would entail porting the code to a different programming language, or a different set of APIs for audio and video, or some similar.

That sounds like a pretty huge undertaking to me. And they did it in four days?!? Wow! I know Google is supposed to be all about hiring the best and the brightest, but that's just ridiculous. I mean, that would take me months to finish! And even if I was already familiar with the internal workings of MAME and Chrome, it would still be a matter of weeks, not days. How did they do it? Are they really that good? Am I just some third-rate hack by comparison?

Well...turns out they're not actually that good. This comment on the article sums it up nicely. Turns out that the Native Client isn't actually a totally different API, but presents a POSIX-like API with support for compilers and build tools. So really, this was less like porting MAME to something totally new and more like making it run on a different operating system. And they didn't even do a real production-quality port. Instead, they simly removed several problematic parts of the code and just sort of "made it work." Granted, that's still a pretty impressive amount to accomplish in only 4 days, but it's hardly the super-human feat it seemed a first.

This sort of story is one of the things that's always bothered me about the culture of software development - it's full of tall tales. Listening to the stories people tell, you'd think everyone was building big, impressive programs in a couple of days. It's not until you pry for details that you realize that the impressive sounding thing is actually little more than a prototype. Sure, Bob may have built a working C compiler over the weekend, but he doesn't mention that it can only reliably compile "Hello, world" so far.

It's almost a lie by omission - you report a truncated version of your accomplishment and rely on an implicit comparison to something much more involved to make you sound super-human. And I say "almost" because it's not just self-aggrandizers doing this. In many cases, the tale just grows in the telling. This case is an excellent example - Slashdot took an impressive sounding quote, stuck it in a brief summary, and made the whole thing sound bigger than it was.

I sometimes wonder what effect this sort of rhetoric has on beginning programmers. Do they find it inspirational? Does it make them want to become the "programming god" who accomplished this sounds-more-impressive-than-it-is feat? Or is it discouraging? Do they hear these stories and think, "I'd never be able to do something like that."

Looking back, I think that it was kind of a progression for me. When I was first learning to code, those stories sounded cool - I could be the guy telling them one day. Then, after a few years in the industry, they started to be discouraging. I mean, I'd been doing this for years and I still wasn't the guy in those stories. Now I'm over ten years in and I'm just skeptical. Whenever I hear one of those stories, my first thought is, "So what's the catch?" (Because, let's face it, there's always a catch.)

And the worst part is, I don't even know if that story should be inspiring or just sad.

Pathological PHP

You know what annoys me? People with crazy ideas. Especially when they pimp them like crazy.

That's why this tutorial on "code separation" from a web forum I occasionally visit annoys me so much. The author links to this thing like his life depends on it. Whenever somebody has the nerve to post a code snippet that has both HTML and PHP in it, he brings it up. Even if the code is just echoing a variable inside an HTML block. It's ridiculous.

Don't get the wrong idea - separation of concerns is obviously a good thing. If you're outputting HTML and querying the database in the same file, you're doing things wrong. But this guy takes it to absurd lengths and insists that you should never have any PHP code mixed in with your HTML. Not even echo statements.

The real kicker is the content of this "tutorial". It's basically a half-baked template system that does nothing but string replacement of pre-defined placeholders. At best, it grossly over simplifies the problem. I suppose it does demonstrate that it's possible to output a page without having HTML and PHP in the same file (as if anyone really doubted that), but that's about it.

The thing that really bothers me about this approach is that the author promotes it results in code that's easier to understand than code that has both PHP and HTML in it. Except that it's not. The guy apparently just has a pathological fear of having two different languages in the same file. it's completely irrational.

The problem with his approach is that it doesn't actually solve the problem, but just moves it. Sure, basic replacement like that it's fine for simple cases, but as soon as the requirements for your markup get more complicated, things blow up. For example, how do you do conditionals? Well, you have another template file and you do a check in your controller for which one to inject into the page. What about loops? Well, you have a template file for the loop content and you run the actual loop in your controller, build up the output, and inject that into the page.

The net result? What would normally be a fairly simple page consisting of one template with a loop and two conditionals is now spread across six template (one main template, one for the loop body, and two for each if statement) and pushes all the display logic into the controller. So instead of one "messy" template to sort through, you now have a seven-file maze that accomplishes the same thing.

I find it difficult to see how this is any sort of improvement. At best, it's just trading one type of complexity for another in the name of some abstract principle that mixing code and markup is evil. Of course, if you want to follow that principle, you could always go the sane route and just use something like Smarty instead. But let's be honest - that's just using PHP code with a slightly different syntax. It may be useful in some cases, but it's not really fundamentally different from just writing your template files in PHP.

Personally, I've come to be a believer in keeping things simple. PHP is a template system. It was originally designed as a template system. It's good at it. So there's no need to introduce additional layers of template abstraction - just stick with PHP. There may be cases where things like Smarty are useful, but they're far from necessary. And the half-baked templating systems like those advocated in that tutorial are just intellectual abortions. There's no need to reinvent a less functional version of the wheel when you can just use a working, tested wheel.

More Mercurial hooks - well that was confusing

OK, that was a little confusing.

So after my initial attempt at a Mercurial hook to connect my public repository to my Mantis instance, I decided to rearrange things a little. Initially, I was using a "commit" hook on my local machine. However, for the public bug tracker with the public repository, it made more sense to put the hook on the server. So I switched it to an "incoming" hook in my hgweb.config.

Actually converting the script to work with my Linux based web host was pretty easy. Just one command, really:

#!/bin/bash

basedir='/path/to/base/hg/install/dir'
mantis='/path/to/mantis/wwwroot/scripts/checkin.php'
hg="$basedir/hg"

$hg log -vr $HG_NODE --style $basedir/mercurial/templates/multiline | php $mantis

Nice and simple, right?

The hard/annoying part was in the style template file. Seem I wanted my commit message to have multiple lines and indent the file list, like this:

Changeset 85:5f7504e02f1c by Peter Geer, Mon Jan 17 23:12:46 2011 -0500
Updated plugin for PHP5 and fixed blog root when taken from defined constant (fix bug 0000021).
lib/blog.php
plugins/menubar_breadcrumbs.php

Problem was, it just didn't work. I was using exactly the same template text as in the old hook script, but I was getting everything on the same line. By switching from "\n" to "\r\n" as my newline escape code, I was able to get newlines to work, but the indentation still didn't.

Guess what fixed it - switching from double to single quotes.

changeset = 'Changeset {branches}{rev}:{node|short} by {author|person}, {date|date}\n{desc}\n{files} '
file = ' {file}\n'

Seriously. That's it. No mention of that in the manual - they're supposed to be the same. In fact, the example of this in the manual uses double-quotes.

Oddly enough, using double-quotes worked just fine on the command line. I'm wondering if it has something to do with the fact that I'm using hgweb or something. Either way, that really sucked.

New job - at home

Well, it's been a while since I've posted anything here. That's because I've been busy with a new job.

The new job is doing LAMP development for a major online community site. True to form, I'm not (yet) going to name the company. That policy has served me well so far. However, I will share some details of my new position and some of the challenges I've faced with it, both expected and unexpected.

The first innovation with regard to this job is it's location - my house. Yes, it's a 100% telecommute, work-from-home position. In fact, it's a totally distributed team, so everybody on the development works from home. And while that's great, so far I've actually found it to be one of the biggest challenges with the job. The challenge isn't motivating myself to actually work, which my mother thought it would be (seriously, she was concerned about that). In fact, quite the opposite. Until recently, I've had more problems with spending too much time working.

There are a three main reasons for this. Part of it is because I was still learning our system and felt like I had to "catch up" to the rest of the team. Another part is simply schedule diversity. We communicate primarily via Skype chatrooms, so we can when people are online. And since we have developers literally from California in the west to Russia in the east, many of them work non-standard schedules, there's always somebody "on", which adds some subconscious pressure. And lastly, of course, part of it is probably emotional damage from my last job. At that (highly dysfunctional) company, we were allowed to work from home on occasion, but if we did it too often, the CEO would make needling comments to the VP of Engineering suggesting that "working form home" was a code-word for "taking the day off". So I think I've partly been stuck in the mindset of trying to prove that, "No, really, I am actually working!"

The other new feature of this position is the sheer size of the operation. And I mean that in pretty much every conceivable way - the amount of traffic, the infrastructure, the size of the code-base, the size of the development team. In fact, pretty much the only thing that isn't big (to me) is the size of the overall company. By way of comparison:

  • The largest site I'd work on was when I was at ebaumsworld.com, where we had something like 30 servers in our environment and were ranked about 1200 in the world by Alexa. The current job has nearly 100 web servers alone and is ranked in the top 150 in the world by Alexa.
  • The largest code-base I'd worked on was at my last job - a little over 200K total LOC when you include unit tests. The new job has over 500K lines of just PHP code (that's not counting CSS or JavaScript) in just the web portion of the tree.
  • The largest group I'd worked in was when I was with the county IT department - about 30 people total, about 9 of them programmers, no collaborative projects to speak of. My last two teams have been very tight 4-man operations. At the new job, we have about 30 people on the tech team, all of them programmers and all of them very good.

So, needless to say, I've been very busy figuring things out in my new position. I've been there for about three months now and I think I'm finally getting comfortable. I'm still learning the code-base, of course (nobody understands the entire thing - it's just too big), but I'm getting more confident and feel like I'm making progress. So in other words, so far, so good.

And most importantly, I'm much happier than I was at my last job. It's nice to feel like you can trust your colleagues and that the work you're doing is helpful. Amazing how increased morale boosts productivity.

Developer interviews

At my current company, we've been trying to hire a new back-end PHP developer for some time. As the senior engineer on staff, and the only back-end person, it's my job to handle the technical portion of the screening process, including resume screening and technical interview. Unfortunately, I have lots of other work to do, so I never had time to come up with a really good procedure to test candidates. In addition, most of the interviews are over the phone with people in other cities, which makes it difficult to have them write code without some advanced preparation - which, again, I haven't had time to do.

So, as a compromise, I came up with a standard list of questions that I ask candidates. I originally wrote this list with the intention of using it for junior developers (1 to 3 years of experience), thinking that anyone with 5+ years of experience would breeze through it. However, I've found that a disturbingly large percentage of more experienced developers fumble more than one of the questions. Unfortunately, I'm not yet sure if that's just because we're getting poor quality applicants, or if it's because my standards are too high.

Therefore, in the interests of helping my fellow developers - both those looking for new opportunities and those who are interviewing the first group - as well as in the hopes of getting some good feedback, I present my list of interview questions. Note that I do not include answers. There are two reasons for this:
1) There is not always a single "right" answer - it is perfectly valid for the question to turn into a conversation.
2) If you're an interviewer and you don't already know the answer, you shouldn't be asking the question; if you're an interviewee and you don't know the answer, you should look it up and learn something new.
With each question I've included some notes on the question's intent. Some of these are conceptual, some are simply tests of knowledge, and some are spring-boards to further discussion.

  1. Solve the FizzBuzz problem. How would you solve it in an object-oriented fashion? Using recursion?
  2. OK, I hardly ever ask this question; you really need to be in the same room to make it work. However, it's still useful to see if the candidate can program and to see how they think. For the object-oriented and recursive versions, I'm not so much looking for the right answer as I am for the approach - and I tell them as much. In particular, I'm looking to see where the candidate goes with the open-ended requirement for object-orientation. Do they go for procedural code that just happens to use some objects? Or do they go straight to polymorphic classes, maybe with a factory pattern thrown in?
  3. Define "inheritance" and "polymorphism". Give an example of when you might use each.
  4. This is your "OOP 101" question. Any half-competent developer should be able to describe inheritance and give the stock "shape" or "animal" example. Polymorphism is a bit more slippery - I often don't get a good answer to that part of the question. In fact, a lot of people seem to think that polymorphism is basically the same thing as method overloading and don't really make the connection to inheritance.
  5. What is the difference between an "abstract class" and an "interface"?
  6. I actually ask this because one of our products is built primarily in FLEX, and interfaces abound in our ActionScript code. With this, I'm really interested in seeing if the candidates understands the idea of explicitly specifying a contract in the code, as opposed to relying on, e.g., PHP's loose typing to make things "just work".
  7. What is "SQL injection" and how might you protect against it? What about XSS/CSRF?
  8. This is, of course, the basic security question. On the SQL injection side, I'm specifically looking for awareness of prepared statements, e.g. in MySQLi or PDO. More generallly, I'm looking for an awareness of filtering an validation. On the script injection side, I like to see what candidates say they use to filter input. An awareness of standard escaping and sanitizing function (strip_tags(), htmlentities(), etc.) is always good - knowledge of the filter extension gets bonus points.
  9. In JavaScript, what does it mean to say that functions are "first class" or "first order" objects?
  10. This is a lead-in to determine how much, if anything, the candidate knows about the more functional aspects of JavaScript - anonymous functions, closures, etc. Surprisingly (at least to me), hardly anyone seems to be familiar with the terminology of "first class" entities. So far I've only had two people know what I was talking about right off the bat.
  11. What is the difference between NULL and the empty string in SQL?
  12. This one is more of a trivia question to test the depth of knowledge of SQL. Bonus points if the candidate mentions SQL's three-valued logic in the follow-up question: "What is the result of the comparison NULL = ''"?
  13. What is an "index" in a database and how would you decide what columns to index?
  14. This one is just to check that the candidate has some basic knowledge of database performance considerations.
  15. Given a sample HR database that contains the following tables:
  16. Employees (employee_id INTEGER PRIMARY KEY, employee_name TEXT, ...)
    Departments (department_id INTEGER PRIMARY KEY, department_name TEXT, ...)

    What would you have to add to the schema to associate employees with departments?

    This is the basic SQL competency question. The typical answer is to add a foreign key from Employees to Departments, at which point I spring the "what if an employee needs to be in two departments" scenario and see if they come up with a join table. Also, it gives a good opportunity to see if they understand when to use inner versus outer joins. It's surprising how many people struggle with this question.
  17. Describe a project you worked on that was particularly enjoyable or interesting. What did you like about it?
  18. I stole this from an interview I did once where I was the applicant. It can be enlightening to see what catches a person's interest. If nothing else, it can help you get an idea of where their head is; are they a hard-core CS person, a touchy-feely UI person, or something else entirely?

Personally, I consider this list to be inadequate at best. But as I said, I haven't had time to develop an adequate test and this is at least better than asking "So how well do you know X?", if for no other reason than it's harder to BS an acceptable answer. Any thoughts or opinions are welcome.

Command-line shortcuts

I came across an interesting little program the other day. It's called Go. It's a Python script for quickly navigating directories via what are essentially command-line shortcuts. I discovered it while perusing the settings in my Komodo Edit preferences - it was mentioned in the settings for the Fast Open extension, which I believe is included by default as of Komodo 5.1.
komodo-fast-open.png
The beautiful thing about Go is how simple it is. You run a simple command to set an alias and from there on out, you can just type go alias and it will change you to that directory. You can also add paths after the alias, such as go alias/dir1/dir2 to switch to a subdirectory of the alias. Great for switching between deep hierarchies, like how Windows programs like to bury things three levels under your "Documents" directory.

However, as I played around with Go, I did come across a few annoyances. The biggest one, or course, was that it didn't work under Powershell. The go.bat wrapper script would run...and do nothing. The current directory stayed the same. Turns out this was because go uses a driver-based system for changing directory which is based on your current shell. The Windows driver was using batch file syntax and running cmd.exe. Powershell does this in a new process, so naturally the current directory wasn't changing.

So, in the spirit of open-source, I decided to fix that problem. And while I was at it, I fixed a couple of other things and implemented some of the feature requests posted on the Google Code issue tracker. Here's the quick list:

  • Added support for Powershell.
  • Added built-in shortcut "-" pointing to the OLDPWD environment variable. On Windows, Go handles setting this variable (on UNIX, "cd" takes care of that).
  • When invoked without any argument, change to home directory.
  • Resolve unique prefixes of shortcut, e.g "pr" resolves to "projects" if there's no other shortcut starting with "pr".
  • Made -o option work without having the win32api bindings installed.

Below are a patch file for the official Go 1.2.1 release (apply with patch -p2 < go-posh.patch) as well as a fully patched setup archive for those who just want to get up and running. Note that, to enable Powershell support, prior to running the Go setup, you'll need to set the SHELL environment variable so that Go knows to use Powershell. You can do this by adding $env:SHELL = "powershell" to your Powershell profile script.

Patch file: go-posh-1.2.1.patch
Full Go archive: go-posh-1.2.1.zip

Edit: Fixed support for "-" so that it actually works like it does in UNIX.

New year's link clearance

In the spirit of Raymond Chen, it's time for new year's link clearance! In other words, I'm posting all those links that have been sitting open in my Opera window for weeks which I'm probably never going to actually do anything with.

  • A posts with some code for doing prototype-based inheritance in PHP. As in, writing your PHP like it's JavaScript. Yeah, cause good things always come from trying to openly defy the conventions of your langage of choice.
  • MVC is a lie. Good, at least I'm not the only one who finds some of these "MVC" frameworks a little questionable, with their grossly anemic domain models. Although I guess I have to give the CakePHP people credit on that one. They're at least in touch with reality. What with passing around of arrays of database records, they don't even pretend they're working with real model objects.
  • A helpful link from F5 about parameters for Powershell scripts and some other useful stuff.
  • Request/response testing in Powershell using the handy, dandy .NET WebClient class.
  • A Get-ScriptDirectory function for Powershell. Kind of like PHP's __FILE__ trick.
  • An interesting article on object-oriented event listeners for JavaScript.
  • Wikipedia page on the SEI's Personal Software Process (PSP). I was put onto that by reading Smart Bear's book on code review, which was actually quite interesting. I'd definitely recommend it. It's totally free, but is published in dead-tree format, which is weird, but I haven't gotten any sales calls or anything, so they're cool.