|Ned Batchelder : Blog | Code | Text | Site|
» Home : Blog
I finally (!!) heard from my old hosting provider about why my site was hosed. To help with security, he installed PHPsuexec. He says it is incompatible with this line in my .htaccess file which lets me serve .html URLs but have PHP code in them:
# Treat .html files as PHP
I did find other tips on the web that said this might be a problem with PHPsuexec, but this thread from the textpattern support forum seems to imply that this is solvable. (Note how I keep bumping into those textpattern guys..) I don't care to solve the problem with my old host, but I get the feeling PHPsuexec may be in my future in any case, so I'm interested if there is other information out there about it.
Update: JumpDomain fixed my old site, by changing the line above to:
# Treat .html files as PHP
You can't call me unresponsive! Rick Copeland wrote a comment this morning requesting a change in Cog's behavior. I made the change, and Cog is at version 1.3. Now all generators in a single source file run with the same global dictionary, so they can share state. Bottom's up!
I just updated my code generation tool Cog to version 1.2. New are a compact one-line mode, module attributes to know which file is being processed, and bug fixes. Bon appétit!
A friend has put together a page describing a number of organizations helping relief efforts in Sri Lanka. Give it a look, and donate something.
Many thanks to all of those who sent in hosting recommendations. I chose TotalChoice Hosting because they had low prices and very helpful support people.
The hosting provider that was mentioned the most (three times), and which definitely stood apart from the rest, was TextDrive. These guys are more expensive, but clearly hit the sweet spot for l33t geek bloggers. Where the run-of-the-mill hosters offer PHP and MySQL, and the feature-stuffed ones add in Python, TextDrive blows out the list with Ruby, Subversion, Movable Type, Wordpress and Instiki, plus some other stuff I've never even heard of. If I hadn't already signed up with TotalChoice, I might have signed up with them (and I still might!).
In any case, if you are in need of hosting, here are the other sites that were mentioned, and that seemed at first glance like reasonable choices, in no particular order:
While I was trying to debug the problem with my old host, I got back into my commenting code, and while I was in there, I made a few upgrades. Now URLs are auto-linked, and the problem with fancy HTML entities losing their specialness during preview was fixed. There's also some simple-minded spam prevention that's been in there for a few weeks (it's just a blacklist of words, but it works for me so far).
Actually, I'm a little flattered that my system is getting any comment spam. I would have thought the spammers would rely on details of widely-used blogging and commenting systems to write their bots. Since my blog and comment system is entirely home-grown, some filthy spammer must have specially coded for this site. Sweet of them to have thought of me.
Well, I have left JumpDomain for good, and am now hosted at TotalChoice Hosting. Soon the DNS changes should shuffle around the globe, and soon it should be as if this whole nightmare never happened.
While I was growing up in Manhattan, I walked a lot. A famous event in my youth was walking six miles home in the third grade because of a miscommunication about a subway token. But I never walked as much as Caleb Smith, who has walked every street in Manhattan. His web site (newyorkcitywalk.com) has details, and photos. I'd love to see some of these things first-hand.
Thank goodness for RSS feeds, or I wouldn't be able to get this message out: my web site is majorly hosed. It looks like my hosting provider botched the upgrade to PHP 4.3.10, because now every page returns a 500 error. I've been thinking about switching providers for a while, so this looks like a good time. My current one is JumpDomain, which worked well if you didn't need a lot of hand-holding. But the support was always a little iffy, and now I can't get hold of them. If you have a provider you like, send me an email to let me know.
There are a bunch of super-cheap hosters out there (hostcolor, hostony, siteground), but I'm not interested so much in super-cheap, as accessible. The cheap hosters all seem to be off-shore. I've got nothing against Bulgarians (or whatever), but it would be great to be able to get an English speaker on the phone during my usual hours.
Damien linked to Occupational Adventure's question about What would you do with a free year? I know what I would do: take piano lessons, pursue my own large software projects without regard to saleability, spend time with my wife and kids, swim, juggle, write, and hang out in used book stores. The good news is that I do all these things now, but I have to squeeze them into the cracks left over after working at a stressful startup. So I would do them more than I do now. Maybe I'm thinking small by saying "just what I do now, but without the job".
As much as I like the question about the free year, I'm a bit conflicted about sources like Occupational Adventure. I'm interested in fine-tuning my life, and gaining insight, and all of that. But an entire blog devoted to it seems like over-doing it. It feels a little too touchy-feely for the engineer in me. And if the goal is to acheive the right balance, isn't it a little out-of-balance to spend that much time focusing on the techniques of achieving balance?
Maybe because people like Curt spend all their time talking about it, I can spend the right amount of time listening, and it all works out.
I thought this photo and its caption were funny in an incredibly subtle and geeky way.
The I-Top is an electronic top. On the upper side of the top is a row of eight LEDs. A magnetic sensor in the top detects its orientation relative to north/south, so the top knows exactly where the LEDs are as the top spins. While the top is in motion, the LEDs are modulated to produce text messages on the top. It has a handful of games and modes. For example, it will count how many times it has rotated, and remember the high score, so you can try to beat your own best spin.
One of the reviews on the i-top page at amazon describes extra modes that include a compass mode: the top displays N/E/S/W on top, acting as a compass. I thought this was one of the coolest toys I'd seen in a while. Also: the center spindle folds into the body of the top, leaving it with a sleek UFO profile. E-bay is displaying listings for a new i-top Pro which can do even more. I want one.
The classic XML design question came up the other day: whether to use elements or attributes. During the discussion I became somewhat heated, for a few reasons:
First, we weren't debating whether to create a design using elements or attributes, we were talking about changing an existing design using attributes to a new one using elements. To my mind, the reasons for switching had better be pretty good to change an existing system.
Second, I had designed the system in question, and I thought the attribute decision was a sound one. They were all simple datatypes, and were order-less, and could appear only once. In this case, attributes are perfectly reasonable, and mean that you can avoid the overhead of end tags.
Third, I sensed ill-reason, or worse, dogma, approaching.
I say: Use attributes unless you truly need elements. You need elements for a thing if the thing can be repeated, or is itself structured, or has semantics based on its order among its peers.
The anonymous waiter who runs the Waiter Rant blog seems like a pretty angry person, but his entry Random Brokenness struck a chord:
He's talking about tolerance of homeless people. The brokenness I deal with is disability, but the principle is the same. Compassion for the less fortunate, and an understanding that we are all in the same boat, and all of us abled and disabled in different ways, is extremely important. It isn't always easy to remember. It isn't even always a simple thing to recognize the brokenness around us. But holding on to that feeling of generosity towards that brokenness helps to keep me grounded and in touch with the people around me.
One of my favorite essays is Fix error handling first, which argues that if something goes wrong in your code, and then something goes wrong while handling the error, you have to fix the error handling before you fix the problem (because fixing the problem will eliminate the possibility of reproducing the error handling bug). An example of this is that if an error message is logged which doesn't tell you all you need to know, you should beef up the error message to add more information before you do the work to avoid the error condition.
But suppose it's impossible to tell if you've done everything you can do? When do you stop?
While on the subject of Subversion, the Trac project looks very cool. It's a wiki bug tracker repository browser thingy. I'm not running it (it's just me, after all) but someday, maybe.
Back in November, I described darcs as perfect for my needs. After using it for a while, I'm switching again. Darcs is very cool, and has a real advantage over traditional source code control systems (it's completely decentralized). But for my one-person projects, I don't need that decentralization, and darcs has disadvantages as well: it isn't as mature or as widely adopted as other tools, and it sometimes gets very slow.
Also, I can't get out of the sequence-of-revisions mindset. So now I'm trying Subversion, the "compelling replacement for CVS".
It does a better job identifying executable statements than the original version by Gareth Rees, which was confused by docstrings and global statements. And you can use code markers to exclude lines or suites from consideration as executable statements.
In the end, this job required a three-pronged attack to get everything I needed out of a Python module. Line-oriented regular expressions found the exclusion markers, the parser module told me about tokens and line numbers, and the compiler module told me about execution semantics. There may be an easier way to get all the information I needed, but I couldn't find it.
Those clever devils at Google have done it again: Google Suggest is just like regular Google, but it auto-completes your search terms as you type, complete with an indication of how many hits the search will get.
This could lead to a whole new form of self-Googling: How many characters of your name do you have to type before you are the suggested search term? I have to type "ned bat".
And as is usual with Google, it isn't clear how they decide what to show. For example, after typing "ned bat", the suggested list is:
Why those suggestions, and why in that order? It isn't alphabetical, and it isn't by the number of search results. "ned batey" has no prediction of search results, but searching on it shows 660 results, which is more than the absurdly specific "ned batchelder atari 2600", so why is the right-hand blank for "ned batey"?
Update: Simon Willison has a short piece about some of the browser technology that makes it work.
Here's a teaser trailer for the new Charlie and the Chocolate Factory movie. This movie was supposed to be more faithful to Roald Dahl's book, but the trailer makes it seem much too Tim Burton. It can be hard to tell from trailers, they often have a very different feel than the movie itself, but this seems a little more wacky than whimsical.
My employer (Kubi Software) is looking for a part-time (20 hours/week) IT person. Here's the job description:
If you're interested, drop me a line. You could be the guy I'll whine to when my computer flakes out!
I've been hacking on code this weekend, and I've managed to get myself stuck. I started using Gareth Rees' coverage.py to measure the code coverage of some unit tests. It works well, but counts docstrings as missed lines of code. I have a lot of docstrings, so the results were too noisy to be useful. I wanted to fix it so that it understood docstrings for what they were. I also wanted to add some other features, for example, the ability to mark lines of code as not expected to be run, so that they would not be counted as missed lines.
So I dug into the code. It works by using the debugging trace hook to record which lines of code are executed, and parsing the source of the modules to understand which lines are executable. I decided to switch it from the parser module to the compiler module for the parsing half of the job. The parser module returns a low-level, grammar-centric representation of the source text, making it difficult to distinguish a docstring from any other expression statement. The compiler module is higher-level, returning a tree of nodes that corresponds more to the semantics of the program. It seemed like a no-brainer, and it all went very well.
Then I wanted to add another feature, so that an entire suite of statements (the Python equivalent of a block in other languages) could be marked as "not expected to be run". For example, if a module has a chunk of code at the end to allow it to be run from the command line, it would be nice if the entire suite could be marked without having to put a marker comment on every line. So a single marker could do it like this:
if __name__ == '__main__': #-notrun-
And if we're going to do that, then it should work uniformly for all suites:
And there's the problem: the compiler module completely discards any trace of the else. It has both suites of code, but the actual line with the "else:" on it isn't represented in the parse tree at all. So it's impossible to match up line-oriented regular expression results (finding the markers) with the parse tree results (what code does it apply to?).
So I'm pondering my options. Go back to the old parse technique, and hack up something to exclude docstrings? Disallow excluding "else" suites? Do something else completely? It had all been going so well. Sigh.
Phillip Eby gives a long list of ways that Python is not Java. Talking about some Python code written by Java developers:
He then describes in detail ways that Java idioms aren't right for Python. One he mentioned I wasn't familiar with: the property built-in function, new in Python 2.2.
We had a head-scratcher bug the other day. Our system is written in C++, and has a custom reference counting system for managing memory (see Greenspun's Law). We were seeing an assertion that we had thought was long debugged and solid. Here's what we found. (Warning: lots of arcane C++ stuff ahead.)