April 26, 2012

Relics of the browser wars : All browsers are Mozilla

A web developers life is like this:

  • The beginning : I'll do the coolest site on the Internet, I feel so lucky.
  • Also in the beginning : What? Is not working in Internet Explorer? OK, let's fork the code for it.
  • After a couple of days : WTF?! Am I seeing things? Is not working in IE6, IE7, IE8, IE9 but the problem is different?! Stack Overflow.. Stack Overflow..
  • The end : Find some work on the server-side or move on.

People freak out when they suppose to do web development and we wonder why. After a couple of days of work on the best site ever everyone realizes that the site is not working well in all the browsers (i.e. IE.) We need to know what browser we are dealing with so we can do something (e.g serve a minimal version of the site.)

How this madness started?

And behold, then came a new web browser known as “Mozilla”, being short for “Mosaic Killer,” but Mosaic was not amused, so the public name was changed to Netscape, and Netscape called itself Mozilla/1.0 (Win3.1), and there was more rejoicing. And Netscape supported frames, and frames became popular among the people, but Mosaic did not support frames, and so came “user agent sniffing” and to “Mozilla” webmasters sent frames, but to other browsers they sent not frames.
In that moment, when none of today's browsers even existed, the "user agent sniffing" was born. Whow, is so old.

Internet Explorer

And Internet Explorer supported frames, and yet was not Mozilla, and so was not given frames. And Microsoft grew impatient, and did not wish to wait for webmasters to learn of IE and begin to send it frames, and so Internet Explorer declared that it was “Mozilla compatible” and began to impersonate Netscape, and called itself Mozilla/1.22 (compatible; MSIE 2.0; Windows 95), and Internet Explorer received frames, and all of Microsoft was happy, but webmasters were confused.
IE wanted to be Mozilla. Funny that it didn't matched many other features of Mozilla or next generation's Gecko/Firefox.

KHTML

And the followers of Linux were much sorrowed, because they had built Konqueror, whose engine was KHTML, which they thought was as good as Gecko, but it was not Gecko, and so was not given the good pages, and so Konquerer began to pretend to be “like Gecko” to get the good pages, and called itself Mozilla/5.0 (compatible; Konqueror/3.2; FreeBSD) (KHTML, like Gecko) and there was much confusion.
KHTML wanted to be Gecko, so was some kind of Mozilla.

Webkit

And Apple built Safari, and used KHTML, but added many features, and forked the project, and called it WebKit, but wanted pages written for KHTML, and so Safari called itself Mozilla/5.0 (Macintosh; U; PPC Mac OS X; de-de) AppleWebKit/85.7 (KHTML, like Gecko) Safari/85.5, and it got worse.
Safari wanted to be KHTML, so was some kind of Gecko which means was so kind of Mozilla

Chrome

And then Google built Chrome, and Chrome used Webkit, and it was like Safari, and wanted pages built for Safari, and so pretended to be Safari. And thus Chrome used WebKit, and pretended to be Safari, and WebKit pretended to be KHTML, and KHTML pretended to be Gecko, and all browsers pretended to be Mozilla, and Chrome called itself Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13, and the user agent string was a complete mess, and near useless, and everyone pretended to be everyone else, and confusion abounded.
You know the drill..
Here is the full article, History of the browser user-agent string

Post Mortem

Today the madness continues but is not useful anymore.
A fine web developer knows this days that he should not sniff for the browser but instead check if features are available.

April 23, 2012

5 books every app developer should read

I can tell what kind of developer you are if you tell me what are your favorite development books. What can you tell about me? Here are my favorites:
  1. Getting real by 37signals

    If I could recommend a single book, Getting Real would be my choice.
    This was the book that helped me understand that software development can be done so much better.
    It is a revelation.

  2. Universal principles of design by William Lidwell

    If you want to understand why some designs are great and why some suck you need to read this book. Not only once, but again and again.
    This book should be kept on your desk.
    It is the times table for designers.

  3. Design patterns by Erich Gamma & Co

    This book is one of the Object oriented programming cornerstones. It is invaluable if you need to design relations between objects in code. Unless you have one or two object types in your apps, you need to read this book.

  4. Envisioning information by Edward R. Tufte

    After you read this book you have the feeling that whatever you chosen to display information in your app, you could have done better, that you can use something more simple and elegant.
    It can be shocking how many alternatives are out there.

  5. Mac OS X Human Interface Guidelines by Apple

    If you ever need to create an app for the Mac, read the HIG.
    If you ever need to create an app for iPhone or iPad read the iOS HIG.
    Yep, Apple tells you how to create great apps for their great hardware.

April 21, 2012

How a simple rule can make your code bulletproof

No matter what programming language you use, if it has objects, you likely make the same mistake as I used to do. And is not even your fault because that was the way you learned to code, because the teachers, books or tutorials don't like to talk about murdane things even if they are vital.

Null pointers

What am I talking about? I'm talking about the number one cause of bugs : null pointers. Suppose we have a function that draws a circle. The function needs a Circle object parameter to know how to draw the circle.
public drawCircle(Circle circle){
 int radius=circle.getRadius();
   
 //draw circle here 
}
Sooner rather then later, somebody will call the function with null:
drawCircle(null);
Since circle is null, the circle.getRadius() call will throw null pointer exception. That will stop the execution thread, no code after that line will be executed. A simple mistake like this in only one method in only one source file can crash an app with thousand of methods and source files. One mistake is enough.

A simple rule

There is a simple and effective way for the above problem, ALWAYS check any object you get from outside for null:
public drawCircle(Circle circle){
 int radius= null!=circle ? circle.getRadius() : 0;
   
 //draw circle here 
}
I wish some day teachers, books and tutorials will talk about simple things like this over and over again. I wish they will teach code that doesn't crash.