Sergio and the sigil

Language Envy - C# needs Ranges

Posted by Sergio on 2010-01-02

As soon as I started learning Ruby, a few years ago, I got immediately hooked on its Range class. I could not believe I had been programming in .NET without them for so long.

I like to think of range objects as the specification for a for loop, packaged in an object that can be passed around. That's not the whole story, though. Ranges also represent sequences or intervals, which can be queried for intersection or containment. See the following Ruby sample code.

#declare a Range object
summer_months = 6..9
#enumerate it
summer_months.each {|m| puts "#{Date.new(2000, m, 1).strftime('%B')} is a Summer month." }
#other handy features
summer_months.include? 7 # ==> true
summer_months.to_a # ==> [6, 7, 8, 9]  (converted to array)

I needed that in C#

That was back when the CLR 2.0 was just about to be released and I ended up writing my own Range

Guided Tour: jQuery - Array wannabes

Posted by Sergio on 2009-12-22
This post is part of a series called the Guided Tours.

In this second installment we are still looking inside the jQuery code. Trust me, even if it's hard to digest, you can still learn enough if you focus on a little bit at a time.

The code we are interested in today is the following.

//from jQuery 1.3.2
get: function( num ) {
	return num === undefined ?

		// Return a 'clean' array
		Array.prototype.slice.call( this ) : 

		// Return just the object
		this[ num ];
},

That's the code for the command jQuery.fn.get(index), which returns the element at the given index or the entire array if the index is omitted.

The JavaScript idiom that is really interesting in this function is that strangely long function call Array.prototype.slice.call( this ).

That line is needed because we need to return an array and, even though they look like one, the jQuery objects aren't arrays. And they aren't alone in that.

If it walks like a duck...

The Array object is one that we can't avoid becoming familiar with in JavaScript. They are everywhere. Data is passed to functions as arrays. Data is returned in arrays. Or are they?

Aside from jQuery objects there are at least two other important occurrences of data structures that are used like arrays but really aren't: the arguments variable and the DOM NodeList collections.

The arguments variable is the list of parameters passed to the current function and the NodeList is what is returned from members of the the DOM API such as document.getElementsByTagName() or element.childNodes. Both of these types have a length property and expose their items with indices, like arguments[1] or elements[0].

But don't let this small coincidence fool you. As soon as you stop paying attention and try to use another array method, like push, shift, join you'll have your dreams shattered and a TypeErrorto handle.

Help me, jQuery

To solve the above problem and return a real array object instead of the jQuery object itself, the code used the technique we highlighted.

Array.prototype.slice.call( this )

The idea is to use the array.slice() instance method to create a new array. The slice method returns a chunk of the array and it takes two optional parameters (the boundaries) that, when omitted, make the function return a copy of the array itself.

I've written about the prototype object

Filed under:

Guided Tour: jQuery - guard and default operators

Posted by Sergio on 2009-12-09
This post is part of a series called the Guided Tours.

I'm sure I'm not alone when I say that one of the best ways to improve our coding skills is by reading code written by someone else. Sometimes we don't realize how lucky we are to have so much source code at our fingertips, namely Open Source Software.

The guided tours

With this post I'll start another unbound series where I highlight some interesting piece of code that I studied. I'll share my notes and do my best to explain what I learned from it.

jQuery: Eating the elephant one bite at a time

I wouldn't dare to start things off with a complete overview of jQuery. It's a massive chunk of JavaScript and I'm afraid there isn't an easy entry point in the source code.

I chose to find parts of it that are relatively easy to explain separately from the rest and that contain something worth explaining. I'll do at least a few of those from jQuery but my plan is to not keep this series tied to jQuery or even JavaScript.

The code under the microscope

We're going to take a look at jQuery.fn.text(), which returns the textual content of all the elements in the jQuery wrapped set, combined in a single string.

Here's the code from jQuery version 1.3.2.

text: function( text ) {
  if ( typeof text !== "object" && text != null )
    return this.empty().append( 
	   (this[0] && this[0].ownerDocument || document).createTextNode( text ) 
	);

  var ret = "";

  jQuery.each( text || this, function(){
    jQuery.each( this.childNodes, function(){
      if ( this.nodeType != 8 )
        ret += this.nodeType != 1 ?
          this.nodeValue :
          jQuery.fn.text( [ this ] );
    });
  });

  return ret;
},

The text() function can be called with or without arguments, so initially it tries to detect if a string argument was passed to it, in which case it will be made the content of the elements in the jQuery object.

Be aware that in all methods defined inside jQuery.fn the value of this will be the current jQuery object.

The first thing that caught my attention was the following expression:

(this[0] && this[0].ownerDocument || document)

In the context of the code it's expected to return a DOM document object, but it's a boolean expression, isn't it? What gives?

Well, yes, it is a boolean expression. That leads me to explain a subtle but powerful difference between boolean operators in JavaScript to many other languages you may be more used to.

Guard and Default operators

The way I like to describe the boolean operators && and || is: They return the operand that short-circuited and resolved the expression. To put in a different way, when the JS interpreter detects that one of the operands has a value that makes the remainder of the comparison irrelevant, it stops right there and that operand (not necessarily true or false) becomes the result of the boolean expression.

Truthy and Falsy: In the context of a boolean expression, any value in JavaScript has a boolean meaning. It's actually easy to memorize which mean which. The values that are treated as false are: false, null, undefined, 0, "" (empty string), and NaN. We call them falsy. Everything else is treated as true and we call them truthy.

Here are some examples:

ABA && B
false123false
null123null
01230
undefined123undefined
undefinednullundefined
123nullnull
123456456
123"text""text"
"text"truetrue
ABA || B
false123123
null123123
0123123
undefined123123
undefinednullnull
123null123
123456123
123"text"123
"text"true"text"

Because of the above behavior, these boolean operators are often used as Guard or Default operators. The guard operation is commonly used when you want to avoid a null or undefined reference error:

//someObj can be null. text will also be null in that case.
var text = someObj && someObj.toString();

Which is a shorthand for:

var text = null;
if (someObj !== null) {
  text = someObj.toString();
}

The default operation is arguably a much more common occurrence. We see it a lot when functions support optional arguments with default values. When a value is not given for a function parameter, it becomes undefined. We can detect that and give a default value like this:

function addAll(numbersArray, step) {
  step = step || 1;
  var sum = 0;
  for (var i = 0; i < numbersArray.length; i += step) {
    sum += numbersArray[i];
  }
  return sum;
}
addAll([1, 2, 3, 4, 5, 6]); // ==> 21
addAll([1, 2, 3, 4, 5, 6], 3); // ==> 5

In the above example, the step parameter is optional. Not providing it would cause a problem if we hadn't defaulted it to one right at the beginning of the function.

Wow. We sure covered a lot of stuff just to explain a simple boolean expression. The good news is that we will see a lot of that in the jQuery code (or in pretty much any decent JS code base) so it's good to understand it well.

Back to our original expression.

(this[0] && this[0].ownerDocument || document)

Armed with our new understanding we can finally read this expression as: If this.ownerDocument exists I want that, otherwise just give me the global document object. This returned DOM document object will be the owner document of new text value being inserted.

What about the rest of that function

It's funny that a tiny bit of that function became this long post. But the remainder of the function, in its majority, isn't really all that interesting in terms of JavaScript. It's mostly boring DOM navigation, done recursively. If you know how to use the jQuery.each() utility function, you can figure out that code on your own.

Our time here is up and we have a whole lot more of code sightseeing to do.

Filed under:

JavaScript: Not your father's inheritance model - Part 1

Posted by Sergio on 2009-06-12
This post is part of a series called JavaScript Demystified.

This particular chapter is further divided in two parts. Read Part 2.

In a previous installment in this series we saw how we could create constructor functions in JavaScript. Back then I just mentioned that we don't have classes in JavaScript and that there's this weird prototype property in every object.

Let's dig into those concepts a little more and try to understand how inheritance is achieved in JavaScript.

Inheritance as we often know it

For myself and probably the majority of you reading this blog, inheritance in an Object Oriented programming language is directly associated with the concept of classes.

When we work with C#, VB, Java, Ruby, and many other popular programming languages, each of our objects is of some type, which is represented by a class. Our objects automatically inherit functionality from their associated class often called base or super class, and any other classes that the base class itself is associated with (i.e. derives from.)

That's nothing new to you, I'm sure. I'm just re-hashing that in the previous paragraph to make a comparison later. Let's call this model class-based inheritance.

That's not the end of the story

This may come as a surprise to some people, but class-based inheritance is not the only way to obtain Object Oriented inheritance (by saying Object Oriented I automatically excluded those of you that thought Copy/Paste Inheritance was one of them.)

It just so happens that the JavaScript language designers chose another inheritance model. And they are not alone in that choice. By opting for a prototype-based inheritance model , JavaScript joined the ranks of other programming languages such as Self , Lua , and Agora.

The prototype is the king

Objects in JavaScript don't inherit from classes; they inherit straight from other objects. The object they inherit from is called their Prototype (I'm using a capital P here to avoid confusion down the line.) The object's Prototype is assigned right at construction time.

You may be intrigued and say: But when I create my objects I don't remember specifying any Prototype stuff. What gives?

Let's see what happens then. When you create a plain Object using either of the following syntaxes

var obj1 = new Object();
obj1.name = 'box'
//or
var obj2 = { name: 'door' };

JavaScript will automatically assign a Prototype to each of these objects. This prototype will be Object.prototype.

Similarly, let's see what happens with a few of the other object types in JavaScript.

The Prototype objects is how every object in JavaScript is born with inherited functionality. For example, the substring() method that every String object has is a method defined in the object String.Prototype.

The prototype objects themselves also inherit from Object.prototype, that's how every object of any type has a toString() method.

When you try to access 1234.constructor, as an example, the runtime will look for a constructor property on our object (the number 1234). It doesn't have one so the next step taken is to check if that object's Prototype has it. The Prototype for 1234 is Number.prototype and it doesn't have that property either. The runtime then looks on the Prototype of Number.prototype, which is Object.prototype. That last object does have a constructor property, so that is returned. If it didn't, undefined would have been returned instead.

In Part 2 we will see how to create our own Prototypes.

Filed under:

JavaScript: Not your father's inheritance model - Part 2

Posted by Sergio on 2009-06-12
This post is part of a series called JavaScript Demystified.

This particular chapter is further divided in two parts. Read Part 1.

Build your own hierarchy

Let's pretend we are building some scripts that deal with musical instruments. We could define our own Guitar class type like this:

//The constructor
function Guitar(brand, model) {
    this.brand = brand;
    this.model = model;
    this.strings = ['E', 'A', 'D', 'G', 'B', 'e'];
}

//Instance methods
Guitar.prototype = {
    play: function (chord) {
        alert('Playing ' + chord); 
    },
    toString: function () {
        return '(Guitar: ' + 
            this.brand + ' ' +
            this.model + ')';
    }
};

var guitar1 = new Guitar('Gibson', 'Les Paul');

What may not be apparent by just looking at the code for the first time is that guitar1's Prototype will be Guitar.prototype, which means that guitar1 inherits from Guitar.prototype. Also guitar1.constructor === Guitar.

When the last line in the above example is executed, the JavaScript runtime will take care of initializing a new object that has Guitar.prototype as its Prototype and makes its constructor property point to the Guitar function.

But what if we want to create a different type of guitars and still reuse the existing Guitar type. We could do this:

function BassGuitar(brand, model) {
    //call the constructor of our base type
    Guitar.apply(this, [brand, model] );
    //change or add anything we wish
    this.strings = ['E', 'A', 'D', 'G'];
}

//Copy the Prototype of our base type
BassGuitar.prototype = Object.create(Guitar.prototype);

//Override whatever we want:
BassGuitar.prototype.toString = function () {
    return '(BassGuitar: ' + 
        this.brand + ' ' +
        this.model + ')';
};

var bass1 = new BassGuitar('Peavey', 'Cirrus');
bass1.toString(); //=> '(BassGuitar: Peavey Cirrus)'
alert(bass1.strings); //=> [ 'E', 'A', 'D', 'G' ]

But there's a problem with the above code. There isn't a method Object.create(). Yeah, that's one of the design omissions in JavaScript. Any prototype-based language needs an easy way to let use create objects from other objects.

Thankfully JavaScript is also dynamically typed, so we can add that function ourselves. Here I'm borrowing from Douglas Crockford.

//add this to the very beginning of your scripts
if (typeof Object.create !== 'function') {
    Object.create = function (o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
}

I'll leave the interpretation of the above function as an exercise to the reader. Once you understand what it is doing you will have mastered prototypes and constructors.

Handy Prototype tricks

Knowing what we know now and once again leveraging JavaScript's dynamism we can fix one of the things that has always annoyed me in JavaScript: the lack of a trim() method on strings.

String.prototype.trim = function () {
    return this.replace( /^\s*(\S*(\s+\S+)*)\s*$/, "$1"); 
}; 
var text = ' some user-entered value   ';
alert( text.trim() ); // => 'some user-entered value'

How about an easy way to pad numbers with zeroes?

Number.prototype.padLeft = function (width) {
    var text = this.toString();
    for(; text.length < width; ){
        text = '0' + text;
    }
    return text;
};

var num = 1234;
alert(num.padLeft(6)); // => 001234

Why do I need to know all this stuff?

Well, you don't. But why even bother writing JavaScript code if you're not willing to learn how it works?

As we have been seeing during this series, JavaScript bears only some syntax similarities with C# or Java. Underneath the surface it has been designed very differently. The web is riddled with attempts to mimic class-based inheritance in JavaScript only because programmers don't want to learn and leverage prototype-based logic.

My humble advice is that you will feel happier and smarter if you chose to learn how to use the language as it was intended.

Filed under: