Tuesday, November 18, 2008

Javascript undefined

I've seen lots of blogs written about how to tell if a Javascript variable has been defined, but all I've seen are incomplete. Here's are some good and bad ways.

If you know the variable has been declared or assigned in global scope:

if (window.x) {

is efficient,

if (x) {

simple.

If you know the variable has been declared in function scope:

if (x) {

is efficient and simple.

But those are not really very good. "if(x)" fails if x has not been declared, and they give wrong answers if x = 0;

I recommend the following as it works even if the variable has not been declared:

if (typeof(x) == 'undefined') {

The hardest case is if for some reason you need to find out if the variable has been declared or not:

var declared = true;
try {
x;
} catch (e) {
declared = false;
}
if (declared) {

And BTW, null is just a reference of type Object that does not point to an instance.

Sunday, June 8, 2008

Bank Security

The other day I went to 1stBank without my account number. They asked for my verbal password. Funny, I never set such a thing. They assured me I did and wrote it down on a slip of paper. It was my login password! They tried to convince me I had set it once and forgotten it, and that all their customers do. The problem is, it is not a word at all but a string of characters that is awkward to say. I would never say it out loud in front of other customers as it could allow anyone to use my online account to transfer funds. In fact the teller could just do that anonymously from the comfort of his home, if he realized what it was. He could do that for any number of accounts.

The other scary part of this is, online passwords are supposed to be encrypted using a one-way hash. If you forget a password, they are supposed to reset it to a random string, then you have to change it when you next log in. They are not supposed to have any way to recover a password. That way, disgruntled system administrators cannot get them. The fact that they created verbal passwords from their online passwords means they are not securing the online passwords. This is much worse than keeping credit card numbers in their database. 1stBank has $8 billion in deposits!

Sunday, May 4, 2008

Firefox DHTML

After many years of corporate (Internet Explorer only) web development, I got my first taste of Firefox DHTML and it wasn't pretty. Here's the code (minus some styles to counteract the default blog stylesheet):

<table border="1" cellspacing="1">
    <tr>
        <td>Column 1</td>
        <td>Column 2</td>
    </tr>
    <tr id="trhidden">
        <td>x1</td>
        <td>x2</td>
    </tr>
    <tr>
        <td>y1</td>
        <td>y2</td>
    </tr>
</table>
<script>
function Toggle()
{
    var h = document.getElementById('trhidden').style;
    if (h.display == 'none')
        h.display = 'inline';
    else
        h.display = 'none';
}
</script>
<button onclick="Toggle(); return false;">Show/Hide</button>

And the result is:
Column 1Column 2
x1x2
y1y2



Click the button a few times in Firefox and IE to see the difference. How Firefox can screw up something so basic is beyond me.

Gratuitous Configuration

I have always been annoyed by developers who try to put every possible option into configuration files.

First, they inevitably fail. The space of possible application behavior is more than exponential in the number of actions the user performs. It is exponential in the amount of actions available to the user. This abstract fact has a simple practical result. Most changes requested by the business are not feasible by adjusting a configuration file, no matter how universal you try to make it. So you have gained almost nothing.

Second, they are difficult to use. Nobody ever documents these monsters, and you have to dig through code to figure out what you have to change, or whether the change is configurable at all.

I recently had an epiphany on why so many developers continue to use them. It is related to the fact that good application architects are about as common as flying pigs. There is a mindset that the code on large projects is expected to be a tangled mass of spaghetti. Since it will be virtually unmaintainable anyway, it is beneficial to set aside a fixed space of customizations which will always be possible. Configurations do just that. The more behaviors which are controlled by configurations, the more customization which will be possible.

I reject this mindset. I have never had trouble designing maintainable systems. My challenge has always been preventing self appointed experts from mucking up the architecture.

Virtual PC

Using Virtual PC can be frustrating as it is easy to screw up and end up wasting lots of time, and little guidance is available. So here are some tips.

First some concepts. A real PC can be described by the hardware, the contents of the hard drive and the state of memory. So a virtual PC is described by a settings file (hardware, sort of), a virtual hard drive, and a state file. The state file will not be saved if you 'shut down' within the virtual OS. If you stop the VPC while it is running, the state file can be saved. If you then delete the state file, it is as if you powered-off the PC without shutting down. For example, the OS will complain when you start back up. You can swap hard drives when the VPC is not running, or change memory size. What is hard, and the subject of this blog entry, is changing the hard drive size.

When you set up a hard drive, you can choose fixed size, or dynamic. Dynamic is nice because the file adjusts itself to whatever space is needed, instead of taking up the full space from the getgo. It's a little confusing, because it asks for a maximum size, and offers a size much larger than your real hard drive. You should resist the tempation to reduce it at all as it is hard to change later. This is the number which will show up in the VPC as the size of the disk. It has little to do with the actual size of the virtual disk file.

But lets suppose you already made that mistake and installed XP on a 16GB-max dynamic disk. That's plenty of space, of course, as XP takes up about 4GB. Then your boss tells you to upgrade the virtual OS to Vista. You refuse of course, so he waterboards you to make you do it. You confess to terrorism after 20 seconds, and finally agree to upgrade to Vista after 3 minutes of torture.

First thing you find out is that the Vista upgrade requires 15 GB of free space, beyond the 4GB you already use (despite the fact that the final result only uses about 7GB).

Tip #1: There is a 3rd party utility from vmToolkit called VHD Resize.

Sounds like just what you need. So you follow the instructions and you get a 64GB max dynamic virtual hard drive file. You then boot up your VPC and the hard drive size is unchanged *frown*. What the instructions fail to tell you is that there is a step you always have to do after resizing. They don't tell you this because to them it is completely obvious. What you have done is analogous to buying a new hard drive and copying your old smaller one bit by bit. That too will look to the OS like the size hasn't changed, because the partition hasn't changed. Aha! we have to expand the partition.

Tip #2: There is a DISKPART utility which comes with the OS.

I forget the exact syntax (yeah, it's a console app with text commands, fun), but you have to SELECT the drive, then SELECT the partition or volume, then EXPAND to fill all available space.

Ok, now you have enough space to do the upgrade. Once that's done, your disk is all fragmented and takes up about 14GB, even though there's only about 7GB of data on it. This is bad becuase you want to copy your disk file to a safe place whenever you have finished a critical and time consuming step (like after you activate the OS). You know there is a command to compact the disk file, so you defrag and then run it. Takes a while, and there is no improvement. If you read the instructions carefully, there is a little tidbit in there about running precompactor (what's that?).

Tip #3: You have to run precompactor before compacting.

Precompactor is located on a virtual CD ISO file in the Virtual PC directory in Program Files. You will find it next to the extensions ISO that you probably have run by now. Just attach to it in the usual way (sorry, this is not a general help screen), and it will blank out the disk sectors so compactor can remove them.

Still, the drive file will be significantly larger than the data. This is because compactor does not move data, it only truncates empty space at the end of the disk. Unfortunately, I don't know of a defragmenter which does a good job of moving files to fill the unused space. If you do, please add a comment.

Tip #4: <your defrag suggestion goes here>

Saturday, April 12, 2008

To Tab or Not To Tab

Modern code editors format code automatically, providing indenting so that looping and other control logic is visually apparent. Indenting can also be added manually, normally using the tab key. Different developers have different preferences for how much to indent each time, so they configure their editors as to how much space a tab character should take on the screen, typically between 2 and 8 characters wide. Different developers also have different preferences as to whether the tab should remain a tab character, or whether it should be converted and saved as some number of space characters.

On a shared project it is important to agree on a convention. If some lines use tabs for formatting, and others use spaces, the lines get out of synch whenever two developers have different tab widths. The code looks jagged and becomes difficult to read.

There are essentially two conventions. One has all tabs converted to spaces at an agreed width, the other keeps tabs always. This choice often turns into a religious argument.

Both conventions work if followed by all group members. Both can fail if a heretic is present. But one convention has a distinct advantage. It allows different developers to use different tab sizes to suit their preferences without affecting other developers. This is the better convention. I'll leave it to you to figure out which one this is.

Sunday, January 27, 2008

Age of War Spoiler

Age of War is a cute little Flash game by MaxGames. Here's how to beat it on 'Impossible' level:

1. Your fighters are useless for attacking, they get killed in one blow. Only use turrets and special attacks to defeat enemies.
2. Create fighters in front of your cave to absorb attacks.
3. Stay in the stone age. Stone age fighters get created faster than the enemy can kill them.
4. Buy 3 egg shooters for turrets.
5. When you get 45000 exp, modernize, send one bomber, and buy double rifles.
6. It's pretty easy from there, just buy 4 blue ion cannons.

Warning: A couple days after I beat it the first time, the got harder. Maybe the author wants to keep it impossible.