enjoying salad since 1978.

Sunday, February 17, 2008

JavaScript undefined vs. null

I was reading a modern, popular book on JavaScript last night and was disappointed by the handling of null. The author started out doing a lot of checking like:

if (foo == null) {   alert('foo is not set.'); }

Then told the reader that they could just remove the == null because javascript knows you mean "== null"

What?! This isn't why you don't check for equality with null. It's because foo == null doesn't even remotely do what most people think it does in this context.

It's a commonly held belief that uninitialized properties in JavaScript are set to null as default values. People believe this mostly for 2 reasons: 1) foo == null returns true if foo is undefined and 2) authors don't teach JavaScript properly.

A property, when it has no definition, is undefined. Put that way, it's pretty obvious.

null is an object. It's type is null. undefined is not an object, it's type is undefined. That part is less obvious.

The real trouble is that == does type coercion. === checks for both type and value and is the most intuitive form of equality in JavaScript, in my opinion.

I fired up a Jash console to hopefully clear things up for you.

>> window.hello
>> window.hello.something
window.hello has no properties
>> window.hello == null
>> window.hello === null
>> window.hello === undefined
>> if (window.hello) { alert('truthy'); } else { alert('falsy'); } // will print falsy.
>> window.hello == undefined
>> null == undefined
true // there's the rub, sir.
>> null
>> undefined
>> typeof null
>> typeof undefined

So people write

if (foo == null) {
   foo = "Joe";
When what they really mean is
if (!foo) {
   foo = "Joe";
If you find yourself with a lot of null checks in your JavaScript, set aside some time and watch Douglas Crockford's "The JavaScript Programming Language" talk on Yahoo Video. It's part 1 of a 3-part series of excellent and enlightening talks.

Sunday, February 10, 2008

Ubuntu on the Mac Pro

Last year I bought a Mac Pro to replace my aging Linux PC. It was a pretty significant upgrade, from a HyperThreaded 2.5Ghz Pentium 4 to a dual-processor, quad-core 3Ghz Xeon with 8G of RAM. Leopard is nice but I wanted to try and get Ubuntu running on it.

Here's the setup, I have 4 drives:

  • 750G - Leopard
  • 200G - Windows
  • 750G - Backups
  • 750G - To be Ubuntu
and wanted to install Ubuntu on the 4th drive.

Here are the basic steps I followed:

  1. Install refit
  2. Install from LiveCD (7.10)
  3. Select manual Manual Partition and from the advanced options, choose hd3,0. I setup my disk with one ext3 partition and 1 swap partition.
  4. After install, boot the linux disk from the refit menu
  5. Grub will get to stage 1.5, you will see the menu but be unable to start the system, it will complain about unknown partition type
  6. hit 'c'

Here's a transcript of my tinkering with grub to find the right drive with my initrd and kernel on it so I could boot my fancy Apple-branded Linux machine.

grub> root (hd<TAB>
showed a bunch of drives with various partitions but most importantly showed that hd0,0 had the Linux partition I was looking for. Even though with the ubuntu installer, we told it to use hd3, here we use hd0. the boot manager has shuffled the order of the drives. Telling the ubuntu installer to use hd0,0 will only result in an unbootable disk.
grub> root (hd0,0)
grub> kernel /boot/vmlinuz<TAB>
will show you some vmlinuz files. typically just the one ubuntu installed. pick it.
grub> kernel /boot/vmlinuz-2.6.22-14-generic root=/dev/sdd1 ro
grub> initrd /boot/initrd.img-2.6.22-14-generic
grub> boot

Now your system will boot. Edit your /boot/grub/menu.lst to point the root (hd0,0)

Now reboot and you will be in Ubuntu. Your wifi adapter won't work. Follow these steps to enable ndiswrapper to use the windows drivers.

I used a usb thumb drive to move the windows drivers zip file between my laptop and desktop.

Once you have networking up, don't forget to enable ssh so you can login in case you screw up your X config.

Edit /etc/apt/sources.list to include what you might want.

I have an ATI Radeon X1950 Pro video card. To get it working, I simply installed Envy which downloaded the right drivers and installed them for me.

But it didn't span monitors, they were just clones so I ran aticonfig (which Envy installed for me)

aticonfig --initial=dual-head --overlay-on=1

And we were good to go.

Banshee imported all my music from my iPod after converting it's database from an iTunes format it didn't recognize.

Using hibernate left the Mac's wifi adapter in a weird state. Rebooting it didn't help but booting into OS X and back into Linux corrected the wifi card.

The fan speed still isn't quite right, various fans will become louder and softer at odd intervals. I will try monkeying with lm-sensors later.

I have nice smooth fonts by running Emacs 23 from Alexandre Vassalotti's repo and the Inconsolata font for programming.

Overall, it's a great Linux machine and maybe one day it won't be so much trouble to get running. Hopefully my instructions will help you get it up and running.