Thursday, March 24, 2011

Why ==null, Not ===null

Sometimes in RightJS source code you might see a thing like this

if (value == null) {
// ...
}

And as every JavaScript optimization tutorial tells you to use '===null' instead of '==null' and JSLint yells at you when do otherwise, people immediately try to change it to the "right" way.

Meanwhile there is a pretty good case when it is much better to use '==null' than '===null'.

The thing is, that in JavaScript we have this ugly thing called 'undefined', which is quite clunky and often weird in use. Like say you might have a piece of code like that

var hash = {a: undefined};
console.log(hash.a); // -> undefined
console.log(hash.b); // -> undefined

console.log('a' in hash); // -> true
console.log('b' in hash); // -> false

Which is a bit strange. So, it is quite often, people use 'null' to predefine keys in hashes and then need to check whether a certain value is not 'null' or 'undefined', kinda like this

if (value !== null && value !== undefined) {
// ...
}

Another case is that the 'null' thing is an object in JavaScript and sometimes you might need to check if a variable is a plain type value, you go with things like that

if (
typeof(value) !== 'object' &&
value !== null && value !== undefined
) {
// ..
}

There are lots of cases where you need this double check. You also should keep in mind the fact that 'undefined' is a variable in JavaScript and someone actually can define a variable named 'undefined', and in general case you'll need to handle that too. Well, you get the ugly picture.


So, what about that '==null' business anyways?

The trick is that '==null', unlike other boolean comparisons (for example '==true'), returns 'true' only for 'null' and 'undefined' values.

null == null;      // -> true
null == undefined; // -> true

null == false; // -> false
null == ''; // -> false
null == 0; // -> false

Which basically means that you can use value == null instead of

value === null || value === unefined

More of that, except being more compact, 'value == null' also will be protected from 'undefined' replacements, and the browser also won't perform a variable name lookup, because null is a keyword and there is nothing besides it. Which will make the things faster.

How much faster? Let's see. I cranked this little script and run it in FF4

function test1() {
var i=0, t = new Date(), v1 = null, v2 = undefined, r;
for (; i < 100000; i++) {
r = v1 === null && v1 === undefined;
r = v2 === null && v2 === undefined;
}
console.log(new Date() - t);
}

function test2() {
var i=0, t = new Date(), v1 = null, v2 = undefined, r;
for (; i < 100000; i++) {
r = v1 == null;
r = v2 == null;
}
console.log(new Date() - t);
}

console.log('--');
10..times(test1);
console.log('--');
10..times(test2);

And here is the result

--
22
24
23
23
23
23
23
23
24
23
--
2
1
1
1
1
1
1
1
1
1


Well, that's the whole story. Think you can put it in a good use :)

Tuesday, March 15, 2011

Ruby + Gosu = Fun

Gosu is a nice simple 2D games engine for Ruby, which I used to work on this little game called pentix.rb. And I'd like to put in some good words for the folks who maintain the project.

What's particularly cool about Gosu is that it doesn't try to jump over its head and do everything by themselves. Gosu is a very small framework specifically made for 2D games, it will help you make things like windows, handle graphics, fonts, sounds and some basic animations. But it also easily integrates with Chipmunk to handle physics and with ImageMagic/OpenGL modules if you need some seriously looking graphics.

If you think about it, Gosu is a very cool thing, you leave all the rendering and heavy stuff to the native modules and use Ruby for what it's good for, for describing logic, units, interactions and so on. And Gosu does it right, it doesn't force you to inherit it's classes all the time, quite on contrary actually. Gosu itself has just a few basic classes to handle media things, like fonts and images, and for the actual units you can write plain Ruby classes, which certainly makes it much easier to implement, test and maintain.

And one more thing. Gosu is not just a Ruby toy. It also has all the C++ bindings, which kinda makes it a pretty interesting choice. You can use the power of Ruby to prototype and do all the R&D things. And later, if you actually make it to the investors, it will be relatively simple for you to port everything to C++ and make it running anywhere. Yup, iPhone is on the list :)

This is basically it. If you ever wanted to write some simple 2D games, but didn't want to deal with C++ check out Gosu, it's pretty awesome!

UPD: Check out also this simple ruby tutorial they have

Thursday, March 3, 2011

Super Simple Layout

I'd like to show you a little css-trickery thing I use on pages where you have a super simple content, like a documentation or a demo page, and all you want is just to make it look kinda decent without bothering with additional HTML scaffolding.

Say you have the following HTML page

<html>
<body>
<h1>The Main Title</h1>

<h2>Chapter Title</h2>
<p>
bla bla bla
</p>
.......
<div id="footer">Copyright ...</div>
</body>
</html>

It is super-simple, you've got an H1 for the page head title, you've got a bunch of H2 and P tags with the content and kind of a footer at the end.

And say, you want your page to have some sort of header/footer areas and a bit of paddings on the left and on there right.

Here is how you can do that with pure CSS, without bothering with additional tags

html, body {
margin: 0;
padding: 0;
}
html {
padding-top: 8em;
padding-bottom: 4em;
background: gray; /* header and footer background */
}
body {
padding: 1em 10em;
padding-bottom: 5em;
background: white; /* the main area background */
}
h1 {
position: absolute;
top: -.6em;
font-size: 4em;
color: white;
margin: 0;
padding: 0;
}
div#footer {
position: absolute;
bottom: 1.5em;
color: white;
}

As you can see the trick is very simple, you use top and bottom paddings on the HTML tag to create the header and the footer, and left/right paddings on the BODY tag to create, well left and right paddings. After that just move the header and footer elements in their place with absolute positioning and you're done!

That's the whole trick. An example is over here
Enjoy!