Archive

Archive for January, 2003

Aba Abb Aby Ait Ala

January 30th, 2003 No comments

I’ve recently starting playing Boggle semi-regularly. I’ve always enjoyed it, but now I’m playing it with people who are much more competitive.

While I was in Boston, I also read Word Freak, a rather scary insight into the world of professional Scrabble.

The combination of these two paragraphs have led me to need to know that an ‘aba’ is a fabric woven from goat and camel hair, that ‘abb’ is a yarn used in weaving, that to ‘aby’ is to make amends, or atone, for something, that an ‘ait’ is a small island, and that an ala (pl. alae) is an insect’s wing.

Tags:

More on Perlish Javascript

January 25th, 2003 No comments

After my recent playings with JavaScript, it’s nice to see that Jon Udell has also been discovering that JavaScript can be written quite neatly also: I always thought Perl had a role to play on the desktop. And now that it has transfused its genes into JavaScript, it does.

Tags:

The Decline of Harvard Coop

January 16th, 2003 No comments

I used to be a big fan of Harvard Coop. Any time I’d be in Boston, I’d end up spending quite a lot of it just sitting in the Coop reading. Each day I’d walk around, pick up a pile of maybe 8-10 books, find a comfortable seat, and gradually divide them into 3 piles – those that looked interesting on the shelf, but really aren’t; those that I’ll definitely buy; and those that I’m unsure about, or that I’m keen to read some of, but probably not to buy. And I’d usually end up buying 10-20 books on an average trip to Boston.

When I was in Boston again last summer, I noted with dismay that the comfortable seats on the middle floor had vanished. There were still the two in the basement, and a couch on the top floor, but the middle floor now just had the hard seats at tables, and those in the coffee shop area. Today I noted with even more dismay that the entire top floor is now also hard seats. The only comfortable seats remaining are the two in the basement. Which of course means that there’s virtually no chance of actually getting one. And as a result I spent much less time there than usual and only bought 2 books.

MIT Coop still has 4 comfortable seats by the window, so I can sit there and read OK. And the Borders downtown still has quite a few (although they’ve been rearranged in a very strange configuration). So these will now be getting more of my trade. (The Barnes and Noble downtown is terrible…)

I read somewhere once that Barnes and Noble were trying to position themselves as an alternative to the library, rather than other bookstores.
But I’m wondering if in general there’s a move away from the “our bookshop is really comfortable; come sit here all day and read our books” type of approach.

Tags: ,

Tips for Using Perltidy

January 10th, 2003 No comments

Things I’ve learned about perltidy.

When returning a hashref from a subroutine, make sure to explicitly give the ‘return’ command, or else perltidy will get confused, think it’s a bare block, and format it strangely.

Similarly, if the last statement of a script is complex, with nested subrefs etc, adding the trailing semicolon can change how perltidy indents the code quite significantly…

Tags:

Stored Procedures for Web Security

January 10th, 2003 No comments

V. Satheesh Babu has an interesting article on using Oracle Stored Procedures to add an extra layer of security to web applications.

Tags:

Object Oriented JavaScript

January 8th, 2003 No comments

I can see lots of similarities between JavaScript and Perl. Both are languages that are often written by people with no real programming experience, just to get a job done – usually involving web sites. A lot of the code in each isn’t written from scratch, but starts by taking some other code that almost does what you want, and hacking it around until it does do what you want. And, as a result, a lot of the code that exists in both languages is really ugly, clumsy, and contains lots of special case code and lots of subtle bugs. Which the next person to adapt the script hacks around until it does what they want. And so on.

But beneath it all, both are actually very powerful languages, which can be well written, clean, expressive, and well factored.

And whilst I’m perfectly at home writing Perl like that, my JavaScript skills are still rather lacking.

So, I was playing around with Object Oriented JavaScript over the holidays. I found a good example at ChunkySoup, but I still wasn’t entirely happy with the results.

The code for the test page is still a little uglier, and more repetitive than I’d like. In particular, each link on the page still needs to explicitly set up its
own handling code for the image rollovers etc.:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<div id="link1"><a href="DSCB1428.jpg"
onmouseover="elements[0].handleMouseOver()"
onmouseout="elements[0].handleMouseOut()" onclick="return
elements[0].handleClick()">1</a></div>
<div id="link2"><a href="DSCN4337.jpg"
onmouseover="elements[1].handleMouseOver()"
onmouseout="elements[1].handleMouseOut()" onclick="return
elements[1].handleClick()">2</a></div>
 
<div id="link3"><a href="DSCN4358.jpg"
onmouseover="elements[2].handleMouseOver()"
onmouseout="elements[2].handleMouseOut()" onclick="return
elements[2].handleClick()">3</a></div>
<div id="link4"><a href="DSCN4373.jpg"
onmouseover="elements[3].handleMouseOver()"
onmouseout="elements[3].handleMouseOut()" onclick="return
elements[3].handleClick()">4</a></div>
<div id="link5"><a href="DSCN1509.jpg"
onmouseover="elements[4].handleMouseOver()"
onmouseout="elements[4].handleMouseOut()" onclick="return
elements[4].handleClick()">5</a></div>

And setting up the JavaScript that gets called onLoad is a little repititive too:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var elements = new Array();
var thumbnailID = "thumbnail"; // this is universal for the page
var emptyimg = "blank.gif"; // this is universal for the page
var photoID = "bigimage"; // this is universal for the page
 
function initpage() {
  elements[0] = new csnPhotoNavObject(new
csnPhotoObject(thumbnailID,emptyimg,"DSCN1428tn.jpg",photoID,"DSCN1428.jpg"));
  elements[1] = new csnPhotoNavObject(new
csnPhotoObject(thumbnailID,emptyimg,"DSCN4337tn.jpg",photoID,"DSCN4337.jpg"));
  elements[2] = new csnPhotoNavObject(new
csnPhotoObject(thumbnailID,emptyimg,"DSCN4358tn.jpg",photoID,"DSCN4358.jpg"));
  elements[3] = new csnPhotoNavObject(new
csnPhotoObject(thumbnailID,emptyimg,"DSCN4373tn.jpg",photoID,"DSCN4373.jpg"));
  elements[4] = new csnPhotoNavObject(new
csnPhotoObject(thumbnailID,emptyimg,"DSCN1509tn.jpg",photoID,"DSCN1509.jpg"));
}

So, I figured it should be possible to abstract some of that away further too. The JavaScript should be able to dynamically alter the DOM and set up all the event handles. Then the links could just be set up as:

1
2
3
4
5
<a id="link1" href="DSCN1428.jpg">1</a>
<a id="link2" href="DSCN4337.jpg">2</a>
<a id="link3" href="DSCN4358.jpg">3</a>
<a id="link4" href="DSCN4373.jpg">4</a>
<a id="link5" href="DSCN1509.jpg">5</a>

And at the start of the page, I’d just want to associate images with each link:

1
2
3
4
5
6
7
function initpage() {
  addImage("link1", "DSCN1428.jpg", "DSCN1428tn.jpg");
  addImage("link2", "DSCN4337.jpg", "DSCN4337tn.jpg");
  addImage("link3", "DSCN4358.jpg", "DSCN4358tn.jpg");
  addImage("link4", "DSCN4373.jpg", "DSCN4373tn.jpg");
  addImage("link5", "DSCN1509.jpg", "DSCN1509tn.jpg");
}

The addImage JavaScript would then find the image element with the id of the first parameter, associate an onclick() with the second element, and a rollover() with the third.

After a lot of playing around I ended up with a nice abstract JavaScript addImage function that does just this:

1
2
3
4
5
6
7
function addImage(id, img, thumb) {
  var pno = new csnPhotoNavObject(new csnPhotoObject("thumbnail","blank.gif",thumb,"bigimage",img));
  var img = document.getElementById(id);
  img.onmouseover = function() { pno.handleMouseOver(); };
  img.onmouseout  = function() { pno.handleMouseOut(); };
  img.onclick     = function() { return pno.handleClick(); };
}

What I don’t like about this though, is the need to set up the anonymous closures. (Of course, before this I didn’t even know I could actually do that in JavaScript!). I can’t see why I can’t just say:

4
5
  img.onmouseover = pno.handleMouseOver;
  img.onmouseout  = pno.handleMouseOut;

The onmouseover and onmouseout need to be assigned a function. But if I give them the foreign object function directly, then something later gets confused. Whereas if I give it an anonymous function that just calls that other function, everything works just fine.

I don’t know if I’m doing something wrong. Or if there’s some strange JavaScript language issues I don’t know about yet. Or what.

Anyone any suggestions?

Tags: ,

zsh tab completion

January 7th, 2003 No comments

My name is Tony, and I’m a zsh user.

I have been for many years, and have steadfastly withstood the onslaught of upstarts like bash. For the most part I don’t really know whether zsh or bash is ‘better’, I just happen to have a whole series of startup scripts, built up over the last 10 years, that make my environment be the way I want, and that only work with zsh. I’m sure I could do them all in bash, but I don’t really have the time, the energy or the inclination to work out how, when it’s all there for me in zsh. (When I was at university, I would often spend days just working through all the man pages for something, testing all the different options, deciding which I liked best, and setting up my configuration accordingly. Those days are long since past…)

Of course, since I read my way through the zsh docs lots has changed. In particular tab completion has gotten a lot more advanced. I’ve known this for a long time, but have never gotten around to working out how to bring my setup up to date in this regard. Until yesterday, when I finally got fed up, and tried to investigate this.

However, that was harder than it should have been. I could find lots of information on how to build my own completion routines, but I couldn’t actually work out how to just get all the default ones to happen. I eventually found:

The function compinstall can be run by a user to set up the completion system for use, which also provides options for more advanced usage. However, if the system was installed completely, it should be enough to call the shell function compinit from your initialization file.

Well, with a fresh apt-get install zsh from Debian, it doesn’t seem to be “installed completely”. What I eventually worked out I had to do was source /usr/share/zsh/4.0.6/functions/Completion/compinstall, hit return a few times to confirm some things which gave me no options anyway, and then be faced with a menu system that seemed to expect me to be able to answer thousands of questions that I couldn’t possibly know the answers to. I eventually gave up, used ‘save and exit’ to write out some new config options to my startup script, and was slightly surprised that everything actually now worked.

So now I finally can tab complete everything sensibly. And I’m even more impressed than I thought I’d be. I knew it would be able to complete hostnames after an ‘ssh’ and things like that, but I’d never realised it would do really obvious things like only complete to directories (or symlinked ones) after a ‘cd’. Or that after a chown it’ll tab complete only to valid users of the system. And I’m really impressed that it’ll tab complete to valid debian packages after an ‘apt-get install’.

Tags:

Spatial Indexes in MySQL

January 7th, 2003 No comments

Jeremy shows how to use spatial indexes in MySQL:


  SELECT name
    FROM map_test
  WHERE Contains(GeomFromText('POLYGON((0 0, 0 3, 3 3, 3 0, 0 0))'), loc) = 1;
Tags:

Amazon Gift Vouchers

January 6th, 2003 No comments

Scott writes about how Amazon are being really nice by reminding him that he has an unused gift voucher.

In many ways this is indeed a nice touch, when most organisations probably would indeed just want to sit on the money as long as possible.

However, I have a theory that it’s not quite so straightforward. Technically any unused gift vouchers are classed as a liability on a company’s balance sheet. If they were solely booked as revenue then there could theoretically be a situation where a company has booked billions of dollars of revenue, look really healthy, and then, all of a sudden, people come along and demand the billion dollars worth of goods they’re owed. (Yes, it’s probably quite unlikely to happen like that, but these rules are made by accountants, and they’re even more pedantic than us computer programmers…)

Amazon are still in the stage where they’re trying to show that they have a real viable long term business. Their accounts come under intense scrutiny every quarter. Even if all the gift vouchers have contributed to the revenue line already, I suspect that Amazon don’t like having more in the creditors line than they can help.

Or maybe I’m just cynical, and they really are just doing a nice thing…

Tags:

Monthly Archives

January 6th, 2003 No comments

As I said a few days ago, I had planned to use the Month at a Glance calendar for my monthly archives.

But this proved much more difficult that expected. It should have been simple. Mark had already provided all the templates, the stylesheet, the images etc. But I couldn’t work out how to actually make MT know how to use different templates for the monthly archives that the daily ones. The templates menu only provides a single template for a “Date-Based Archive”.

I couldn’t find anything obvious in the documentation, so I asked Mark, and he pointed me to the Archiving section of the Configuration. Here you can choose which sort of template you use for each type of archive (Daily, Monthly, Weekly etc.) But, again I couldn’t easily see how to change the template file. Confusingly there is an input box for “Archive File Template” but that isn’t actually the template for the archive, but a way to specify what the filename for each of your archives should be (so that you can have 2003/01/01.html instead of 2003_01_01.html, for example).

I tried “Add new” from this menu, but again it only let me create yet another view of the month using the standard “Date-Based Archive”.

I eventually discovered that I had to go back to the Templates menu and add an entirely new type of Archive Template, which I called “Month at a Glance”. Then when I went back to the Archiving menu and tried “Add new” again, this time my new template was one of the choices.

Unfortunately it still didn’t work from there, as rebuilding the site had no effect. Because I now had 3 different monthly archives set up, MT didn’t seem to want to use my new one (even though it was the only one selected as being active). I had to delete the other monthly archives, and then everything seemed to work.

So I now have a nifty ‘browse’ link under my calendar that lets you step around month by month.