John Resig writes very positively about Jaxer. It runs Javascript on the server while serving documents to the client, with seamless communication between JS on the client and JS on the server.

Jaxer provides:

  1. Full DOM on the server
  2. Shared code between client and server
  3. Database, file, and socket access from JavaScript
  4. Familiar APIs
  5. Integration with PHP, Java, Rails, etc. apps

In other news, IE8 will use the latest rendering mode by default for documents with the HTML5 doctype:

Finally, Good Math has a published a good defense of Google’s MapReduce algorithm.


Base2 has just come out in beta on Google Code. It’s hosted there and can be included straight off the Google Code server.

I think it’s a really neat library because it basically fixes all browsers so that the built-in DOM, events, etc work the same way. Instead of providing an API of its own, it makes the existing API work consistently and reliably.

Base2 Features:
– A fast implementation of the Selectors API
– Fixes broken browser implementations of the DOM events module including document.createEvent(), dispatchEvent(), addEventListener(), etc
– Supports DOMContentLoaded
– Fixes getAttribute()/hasAttribute()/setAttribute() (Internet Explorer)
– Implements a few other useful DOM methods like getComputedStyle() and compareDocumentPosition()
– Supports a variety of browsers including ancient browsers like IE5.0 (Windows and Mac)

Dean Edwards has also done the excellent Packer Javascript minifier. It has probably the most in-depth support for obscure language features that simpler minifiers tend to mangle.

ECMAScript 4

John Resig has posted a whitepaper outlining the new features in ECMAScript4 (aka the Javascript standard), how it differs from ECMAScript3, and the rationale for any incompatibilities.

Many of the features have already made their way into Opera and Firefox, which is at Javascript 1.7 level. ES3 is equivalent to JS1.3, and ES4 is the basis for forthcoming JS2.

I look forward to optional strict typing, multiline strings, comprehensions, and generators making their way into browsers. A lot of the new features make Javascript more like Python without losing all the nice things tabout Javascript.

Some Facebook network stats

I’m part of three Facebook networks, and I’ve been keeping track of their size since May of this year.

Facebook network size stats

Toronto has gone from 600k people in May to 800k people in September. That’s 32% of the municipality or 16% of the metropolitan area, which is an impressive proportion.

University of Toronto has been stable at 55k, but there should be a flurry of new users in September when first-year students get their UofT email addresses.

The population of IBMers on Facebook has actually declined. Conversely, I suspect our population on LinkedIn, a career-oriented networking site, has not.

Array access and virtual memory

(This applies to Java and C, but the code is given in Python for readability.)

Is it faster to iterate over multiple separate arrays (tuples) of simple variables?

for i in range(0, n):
	phone = phones[i];
	# ...
	email = emails[i];

Or over a single array of complex variables?

for i in range(0, n):
	phone = people[i].phone;
	# ...
	email = people[i].email;

One array is faster than multiple arrays. This is because an array is stored in a contiguous block of memory. Accessing data in different arrays at the same time can require several different pages to be loaded from virtual memory. Memory access, especially hard drive access, is slow. As your application and data set grows, a significant performance difference may manifest itself.

Arrays from the Second Dimension

When iterating over a multidimensional array with indexes i and j, is it faster to iterate over j inside i?

for i in range(0, n):
	for j in range(0, m):
		cell = cells[i][j];

Or over i inside j?

for j in range(0, m):
	for i in range(0, n):
		cell = cells[i][j];

In Java and C, a multidimensional array[n][m] is stored as contiguous m-block of contiguous n-blocks. Let i be in n and j be in m. For a given i-cell, j-cells will be far apart. For a given j-cell, i-cells will be adjacent. Accessing adjacent values in memory is always faster.

For an array[i][j], putting j in the outer loop and i in the inner loop will significantly reduce potential virtual memory slowdowns.

This is the right way:

for j in range(0, m):
	for i in range(0, n):
		cell = cells[i][j];

The above only makes a difference with large data sets, but I like to cultivate good habits.

Creating Start Menu shortcuts with Javascript

While preparing the installer for the Web 2.0 Starter Toolkit for IBM DB2, I had to set up Start Menu shortcuts. The way to do that is to work through the Windows Scripting Host (WSH).

The WSH supports two built-in languages – VBScript and Jscript – and a theoretical number of third-party alternatives. VBScript is the better documented of the two in terms of examples, but I find its syntax ugly and constrained. Fortunately, Jscript can do anything VBScript can.

So here’s how we can create Start Menu shortcuts with Javascript.

Locate the Start Menu Programs folder

Most interesting Windows folders can be found by working with special folders

var shell = new ActiveXObject("WScript.Shell");
var startmenu = shell.SpecialFolders("Programs");

The shell object will be reused in code below, but you can redeclare it every time if you like.

Create a Folder

Scripting Guy has more details

var folder = "My App";
var group = startmenu + "\\" + name;

var fso = new ActiveXObject("Scripting.FileSystemObject");
if (!fso.FolderExists(folder)) fso.CreateFolder(folder);

startmenu is defined above.

Create an LNK Shortcut

The very hidden file extension of standard Windows shortcuts is LNK. This distinguishes them from website shortcuts, which have the equally hidden extension of URL.

If you are interested in something closer to the symbolic links of Unix, the NTFS equivalent is called junctions. You may find Junction Link Magic of interest.

var name = "My Shortcut";
var file = "myfile.txt";
var path = "C:\\Program Files";

var shortcut = shell.CreateShortcut(group + "\\" + name + ".lnk");
shortcut.TargetPath = path + "\\" + file;
shortcut.WorkingDirectory = path;

See the full list of properties. I recommend always setting the working directory for application links. If you don’t, your program won’t be able to load resources from it’s installation folder.

shell and group are defined above.

Create a URL Shortcut

This is very similar. The main difference is that you set the extension to URL.

var name2 = "My Other Shortcut";
var address = "http://example.org/";

var shortcut = shell.CreateShortcut(group + "\\" + name2 +".url");
shortcut.TargetPath = address;

See the full list of properties.

shell and group are defined above.

Locate Program Files

When creating shortcuts, it is often useful to know where a user’s Program Files directory is located. It is called different things in different versions of Windows, and some advanced users like to move it or rename it.

var REG_PF = "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ProgramFilesDir";

var progFiles = null;
var process = shell.Environment("PROCESS");
if (process)
	progFiles = process("ProgramFiles");
if (!progFiles)
	progFiles = shell.RegRead(REG_PF);

shell is defined in the first code excerpt.

Setting up svn with trac

Trac is an excellent web-based wrapper for SVN that adds bug tracking, a wiki, and several handy project management features. I keep setting up new repositories up for all the little projects we cook up in DB2 Technical Marketing, so I thought I’d write up a guide.

Installing Trac, SVN, and dav_svn for Apache2 is left as an exercise for the reader.

Create a new SVN repository:

svnadmin create /var/svn/Project

Create a new Trac environment:

trac-admin /var/trac/Project initenv

Change the owner to Apache so that it can read and write:

cd /var/svn
chown -R www-data Project
cd ../trac
chown -R www-data Project

Navigate to Apache site settings:

cd /etc/apache2/sites-enabled

If you want Trac to support multiple repositories, edit the trac file to look like this:

        ServerAdmin me@somewhere.com
        ServerName mysite.com
        DocumentRoot /usr/share/trac/cgi-bin/
                Options Indexes FollowSymLinks MultiViews ExecCGI
                AllowOverride All
                Order allow,deny
                allow from all
        Alias /var/trac/chrome/common /usr/share/trac/htdocs
                Order allow,deny
                Allow from all
        Alias /trac "/usr/share/trac/htdocs"

                SetEnv TRAC_ENV_PARENT_DIR "/var/trac"
                AuthType Basic
                AuthName "Trac"
                AuthUserFile /etc/apache2/trac.passwd
                Require valid-user

        DirectoryIndex trac.cgi
        ErrorLog /var/log/apache2/error.trac.log
        CustomLog /var/log/apache2/access.trac.log combined

The above assumes that all the repositories are in /var/trac

Navigate to Apache settings:

cd /etc/apache2/mods-enabled/

Append to dav_svn.conf:

   DAV svn
   SVNPath /var/svn/Project

   AuthType Basic
   AuthName "Subversion Repository"
   AuthUserFile /etc/apache2/dav_svn.passwd

  AuthzSVNAccessFile /etc/apache2/dav_svn.authz

    Require valid-user

The above lets you check out from http://yoursite/svn/Project

If you like, you can add a new user to dav_svn.psswd:

cd ..
htpasswd2 /etc/apache2/dav_svn.passwd NewUser

Users can then be granted permissions by editing the dav_svn.authz file. Sample file:

developers = NewUser, OtherUser
others = ThirdUser

# Restrictions on the entire repository.
# Anyone can read.
* = r
# Developers can change anything.
@developers = rw

# Other can write here
@others = rw

@others = rw

Restart Apache:

killall apache2

You now have have an Trac/SVN install with SVN at http://yoursite/svn/Project and Trac at http://yoursite/trac.cgi

Rails and DB2 data types

When creating a table in a Rails migration, you have to specify data types using platform-agnostic names. The mapping of Rails types onto DB2 types is defined in ibm_db_adapter.rb:

:primary_key => @servertype.primary_key,
:string      => { :name => "varchar", :limit => 255 },
:text        => { :name => "clob" },
:integer     => { :name => "integer" },
:float       => { :name => "float" },
:datetime    => { :name => "timestamp" },
:timestamp   => { :name => "timestamp" },
:time        => { :name => "time" },
:date        => { :name => "date" },
:binary      => { :name => "blob" },

# A boolean can be represented  by a smallint,
# adopting the convention that False is 0 and True is 1
:boolean     => { :name => "smallint"},
:xml         => { :name => "xml"},
:decimal     => { :name => "decimal" }

Useful Resources

InfoCenter | DB2 Data Types
dW | DB2 and Ruby on Rails, Part 1 (May 2007)
dW | An Introduction to Ruby on Rails for DB2 Developers (June 2006)

The DB2 adapter is now called ibm_db. You can refresh your installation by typing gem install ibm_db at the command line and choosing the latest win32 release.