2 Comments

IEMobile 6/7 bug: classes and id not supported on the HTML element

December 1st, 2009

As it turns out, IEMobile 6/7 (and presumably anything earlier) doesn’t support classes and ids that are attached to the HTML element. I confirmed this on both IEMobile 6 and 7. Fortunately it looks to be fixed in IEMobile 8 (which makes sense, since it works fine in desktop IE6, which it’s based on).

The consequence of this is that adding an id/class to the html tag will result in the style not being applied to the document:

<!doctype html>
<html id="a" class="b">
<head>
	<title>Cascade test</title>

	<style type="text/css" media="screen">
		#a span { color: red; }     /* style isn't applied in IEMobile 6/7 */
		.b span { color: yellow; }  /* style isn't applied in IEMobile 6/7 */
	</style>
</head>

<body>
<span>Testing 123</span>
</body>

</html>
1 Comment

PHP: dealing with stuff that doesn’t exist

December 1st, 2009

Introduction

As the application you’re coding becomes more and more complex, there’s more of an opportunity for things to go wrong in all sorts of unforseen ways.  One of these problems is variables or functions that don’t exist.  The problem is when you code in such a way that you presuppose their existence. But their existence isn’t guaranteed!

A simple case of this happening is when you’re dealing with user input.  As it turns out, the user didn’t fill out a text field, but the variable for that text field still gets passed around as if it did exist.  More specifically, the variable gets set, but it gets set to an empty string (”).

Check that the variable isn’t empty

A common way of dealing with this is to check that the variable isn’t empty before using it:

$name = 'Joe';
if($name != '') {
	echo 'Hello ' . $name;
}

This turns out to be ALMOST equivalent to the following, which uses empty():

$name = 'Joe';
if(!empty($name)) {  // make sure $name isn't empty
    echo 'Hello ' . $name;
}

However, as Zachary Johnson points out, empty($variable) evaluates to true when $variable=’0′, so you may want to avoid using this.

Check that the variable is defined

There’s another case we haven’t tried yet: what happens if we haven’t defined the variable?

error_reporting(E_ALL);
if($name != '') {
	echo 'Hello' . $name;
}

Nothing catastrophic happens, but if we turn on error reporting, we can see that PHP is a bit upset. We get a notice that the variable $name is undefined, yet we’re trying to evaluate it. The value hasn’t been set yet. And there’s a function to check for that:

$name = 'Joe';
if(isset($name)) {
	echo 'Variable is set';
}

We can combine what we’ve learned into the following:

$name = 'Joe';
if(isset($name) && $name != '') {
	echo 'Hello ' . $name;
}

There’s one neat thing here – if $name isn’t set, it evaluates the first part of the If condition as false (isset($name)) and doesn’t even look at the second part of the If condition ($name != ”). This is because it doesn’t matter what comes after, it will still evaluate to false (false && true evaluates to false, and false && false evaluates to false). Looking at the rest of the If condition is a waste of CPU cycles, so PHP doesn’t do it!

We can confirm this with the following code, which evaluates to false on the first If condition, then doesn’t even try to evaluate the call to a nonexisting function, and thus gives no errors:

if(false && function_that_doesnt_exist()) {
	// do stuff here
}

Check if a function exists

For functions there’s a similar helper called function_exists():

function my_function() { }
if(function_exists('my_function')) {
	my_function();
}

And it doesn’t matter if your function is declared before or after you call it! Check it out – this works fine:

if(function_exists('my_function')) {
	my_function();
}
function my_function() { }

Check if an object’s method exists

Similarly to checking if functions exist, we can check for the existence of functions belonging to an object (we call these the object’s methods) with method_exists():

// Create a test class
class myClass {
	// Create a test function
	public function my_function() {}
}

// Instantiate the class
$myObject = new myClass();

// Check to see if the test function exists
if(method_exists($myObject, 'my_function')) {
	// Do stuff here
}
2 Comments

Pitfalls of declaring variables in JavaScript

November 18th, 2009

Introduction

One of the things that’s always been confusing to me is that there are multiple ways to declare variables in JavaScript, and some ways are better than others. For the beginner programmer, just getting to code to work means complete success, but for the intermediate or advanced programmer, this is just the first step. The next step is to clean up the code and make sure everything is written in the best way it could have been written.

Declaring variables seems like such a basic thing that one almost feels insulted reading about it. Yes, this whole post is about declaring variables. But not just this – it’s about declaring variables the right way. This means declaring variables in the scope they were intended to be declared in.  For the most part this means writing variables in the scope of a function, as opposed to the global namespace (in which everything becomes a property of the window object).

Global variables can be declared in functions

When I was starting to learn JavaScript, I read about global and functional scope and wrongly assumed that functions completely protected the variables declared inside.  As it turns out, there’s many ways to create global variables in JavaScript, and none of them throw up red flags or sound off bells and whistles (unfortunately).

Here’s a few ways to create global variables in JavaScript:

// Creating global variables outside of a function
window.global1 = 1;
global2 = 2;
var global3 = 3;

// Created global variables within a function
function test() {
    global4 = 4;
    window.global5 = 5;
};
test();

You can confirm this for yourself by checking the values of the variables with alert().

Good practice: always precede variables with var

What I learned was that it was essentially good practice to always write variables preceded by the var keyword.  For variables declared outside of functions this has no effect – they are still global, but for variables within functions this ensures that they’re kept within their functional scope:

var global = null;
function test() {
    var local = null;
}
test();

Same name, but different variables

And check this out – confusingly, you can create a global variable, then create a variable with the same name that’s functionally-scoped, yet a completely different variable!

var number = 0;

function test() {
    var number = 1;
}
test();

alert(number);  // 0

When you precede a variable with the var keyword, you’re essentially saying you’re creating the variable for the first time.  So when you create “number” inside the function, no error is thrown because the variable is created in the function’s scope.  If you try to create another variable with the name “number” inside the function, you will get an error because it’s already been defined within the scope.

There’s no such thing as magical protective parenthesis

For some reason I was further mistaken into believing that extra parenthesis around an anonymous function magically protected the variables within:

(function() {
    global = null;
    var local = null;
})();

Nope – as you can see, the global variable is still global since it’s not preceded by the var keyword.  All the extra parenthesis do is execute the function immediately.  That’s it.

Shorthand for declaring multiple functionally-scoped variables

The following code ensures each variable is functionally (locally) scoped, even though only the first variable is preceded by the var keyword:

function test() {
    var local1 = null,
        local2 = null;
}
test();

Multiple variable declaration equivalence gives different scope to each variable

Today I learned another way to mistakenly create a global variable.  Trying to be fancy and declare multiple variables to be the same value, I mistakenly created a global variable (again, no bells and whistles went off to warn me, unfortunately):

function test() {
    var local = global = null;
}
test();

This sets both variables to “null” using the shortest code possible, but unfortunately only the variable “local” is preceded by the var keyword, so only that variable will be in its proper functional scope. Variable “global”, on the other hand, is… well… global. (thanks to Crescent Fish)

You learn something new every day…

Update 1

If you want to check your code for “accidental global variables” you can use JSLint or you can even use Firebug (click on the Script tab, then click on “New watch expression…”, then type “window”, which will display all the properties of the window object – these are all global variables!). Thanks to Nick for the Firebug tip.

Update 2

Just another quick note to remind you that after a variable has been initially declared, the scope will not change. Which is why you can redefine variables, but have them keep their scope:

function test() {
    var local = null;
    local = 5;    // still keeps its local/functional scope
}
test();

As you can see above, the variable “local” keeps its local scope, even though it’s redefined to be 5. This is one of the reasons it’s recommended to declare all variables at the start of a function – to make sure the scope gets set correctly.

One final note: var should only be used when declaring a variable for the first time. If you try to use var for the same variable name in the same scope, it will result in an error:

function test() {
    var local = null;
    var local = 5;    // throws an error!
}
test();

Update 3: Graphical representation

Scope in JavaScript

Scope in JavaScript

2 Comments

JavaScript Tidbit: Block scope with “let”

September 15th, 2009

JavaScript has functional scope. Meaning that if you (properly) define variables within functions, those variables remain accessible only inside the function.

Block scope, on the other hand, defines scope within a block of code, usually defined by braces. JavaScript now has block scope as of version 1.7, which means it’s available in these browsers:

  • Firefox 2+

Block scope is enabled in JavaScript with the use of “let”:

let(x=100) {
    alert(x);
};

It also works perfectly well on one line, without the use of braces:

let(x=100) alert(x);

Note that we can define global variables with the same name outside the block scope and the variables won’t interfere with each other:

x = 200;
let(x=100) alert(x);
alert(x);
// result: 100, 200

Note that there’s a slight caveat – not only is this not available in any version of IE, but it also requires a special script type declaration in order to work (at least for Firefox): type=”text/javascript;version=1.7″

References:
JavaScript Versions
Video: Best Practices in Javascript Library Design (John Resig)
New in JavaScript 1.7

Leave a Comment

PHP Tidbit: Dead simple singleton

September 14th, 2009
class Singleton {
    private static $instance;
    public static function getInstance() {
        if(!isset(self::$instance)) {
            $c = __CLASS__;
            self::$instance = new $c();
        }
        return self::$instance;
    }
}

And the explanation…

class Singleton {
    private static $instance;               // static variable to hold our 1 instance

    public static function getInstance() {  // function to get the 1 instance
        if(!isset(self::$instance)) {       // this will only run once (and instantiate once)
            $c = __CLASS__;                 // get the class (Singleton)
            self::$instance = new $c();     // instantiate the class and store it in our variable
        }
        return self::$instance;             // return the instance
    }

    public static function myFunction() {   // we can get to this through Singleton::getInstance()->myFunction()
        // ...
    }
}
Leave a Comment

JavaScript Tidbit: Shorthand Object Instantiation

September 14th, 2009

The skinny: here’s a neat little trick to reduce the amount of code users have to type to instantiate objects:

function jQuery(str, con){
    if ( window == this )
        return new jQuery(str, con);
    // ...
}

new jQuery("#foo"); // this is now equivalent...
jQuery("#foo");     // ...to this!

Explanation: when jQuery(“#foo”) is typed, the function first determines if the context in which it’s being called is the global object (window).  If it is, it returns an instantiation of itself.  When it’s instantiated, the context in which it’s being called is inside its own function, and NOT within the global object (window), thus it bypasses our little instantiation trick and moves on to execute any remaining code in the function.

From John Resig’s Best Practices in Javascript Library Design

Leave a Comment

IE Mobile 6.12 problem: browser ignores the specificity of CSS display styles

August 31st, 2009

UPDATE: I found that the problem is actually that inline-block is completely unsupported in this version of IE Mobile, and is likely also unsupported in IE Mobile 7, which is also based on IE4. This is in contrast to desktop IE6, where inline-block is supported on elements that are natively inline (span, em, etc.).

Just found this today, for what it’s worth.  If you’re unlucky enough to be working with older Windows Mobile phones you have probably realized that the browser is based on IE6, which all the desktop web developers notoriously complain about constantly.

Though the mobile version of IE6 has most of the same issues as its desktop counterpart, IEMobile introduces some new random problems.  And in most cases there’s no handy web resources to help you out, since almost everyone develops for the desktop.

This particular IEMobile quirk is a specificity problem.  We have a parent element styled with display: block and the child element is styled with display: inline-block or display: inline.  We’ve made the child CSS selector more specific so it should override the parent:

.parent { display: block; }
.parent .child { display: inline-block; }

This works on the desktop version of IE6!  But not in IEMobile 6.12, where the child element is still displayed as a block.  The same thing happens when we change the “.parent .child” style to “display: inline;”, but interestingly not when we change it to “display: none;”, where the style is correctly recognized and applied.  Doh!

And FYI: I checked and found that this bug is not occurring on IEMobile 8.12