Sergio and the sigil

Chicago ALT.NET tries an Open Space

Posted by Sergio on 2009-03-03

In the next meeting of the Chicago ALT.NET users group we will try an Open Space format — or rather maybe I should say a format with some characteristics of Open Spaces given our time and space constraints.

If you haven't been to a meeting held in this format, maybe you think this sounds crazy. I'd encourage you to see it for yourself. The meeting will be on March 11th.

Open Space

6:00 pm
Pizza and networking time

6:30 pm

This month we will have an Open Space-inspired meeting. Open Spaces are considered an effective meeting layout to find solutions to problems that would benefit from a wide range of opinions.

We don't have enough time to do a full-blown Open Spaces event so we will cut some corners. Here's the plan:

  • If you have a software development issue (code, design, process, human, etc) that you can't seem to figure out on your own or within your immediate team, bring to the meeting.
  • We will have a few minutes for participants to announce their problem and put on the board
  • Since we only have time for one session, we all will vote to choose the issue we will discuss
  • The issue "author" is expected to facilitate and stir the discussion
  • The group can decide the format of the session (panel, fishbowl, moderated, etc)

If the session, for whatever reason, ends too soon we can pick another issue to discuss.

So, come ready with some issue, willing to participate in the discussions, or even just to watch others tackle the problem.

JavaScript, inner functions and private members

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

In our last installment in this short JavaScript series we took a look at closures. In some of the examples, we saw functions being declared (and returned) inside other functions. The capability of declaring a function inside another one is not common to all languages — C# only added this ability in version 2.0, via anonymous delegates.

Here's an example of inner functions in use.

function printPriceLong(name, price, quantity, currency) {
	var formatCurrency = function(value) {
		return value + ' ' + currency;
	};
	return 'Item: ' + name + '\n' +
		'Unit price: ' + formatCurrency(price) + '\n' +
		'Quantity: ' + quantity + '\n' +
		'TOTAL: ' + formatCurrency(price * quantity);
}

alert( printPriceLong('100g Toblerone bar', 2.09, 3, 'USD') );
/* =>
Item: 100g Toblerone bar
Unit price: 2.09 USD
Quantity: 3
TOTAL: 6.27 USD
*/

If we try to call formatCurrency from anywhere outside of printPriceLong we are going to cause an error because formatCurrency is scoped only inside its parent function.

In this example we can also see closures in action once again. The currency value is referenced inside formatCurrency but it's declared in it's parent. It's a short-lived closure, mind you, because we are not returning that inner function. It's discarded as soon as the parent function exits.

Who said JavaScript objects can't have private members?

Developers sometimes get upset when they realize that anyone has read and write access to the fields and methods of their JavaScript objects. Most of us are used to work with languages that allow us to declare some of our object's members out of reach for the calling code. We say that these members are private and we don't want anyone changing or even seeing them.

Well, this is not exactly true. If you must have private members in your JavaScript objects, you can. Inner functions and closures will come to our rescue.

Let's build on our previous example. Let's create an OrderItem object that will hold those values (name, price, etc.) Let's assume we do not want anyone changing the object's price without changing the currency at the same time (to ensure some level of consistency.) We could code our object like this:

function OrderItem(productName, price, quantity, currency) {
	//regular properties
	this.name = productName;
	this.quantity = quantity;

	//read accessors
	this.getCurrency = function(){ return currency; };	
	this.getPrice = function(){ return price; };
	//write accessor
	this.setPrice = function(newPrice, newCurrency){
		if(typeof newPrice !== 'number' || newPrice < 0){
			throw { message:'invalid price' };
		}
		if(typeof newCurrency !== 'string'){
			throw { message:'invalid currency' };
		}
		price = newPrice;
		currency = newCurrency;
	};

	//a private function
	var formatCurrency = function(value) {
		return value + ' ' + currency;
	};
	
	//methods that need private members
	this.getUnitPriceString = function(){
		return formatCurrency(price);
	};
	this.getTotalPriceString = function(){
		return formatCurrency(price * quantity);
	};
}

OrderItem.prototype = {
	//overriding the string representation of the object
	toString: function(){
		return  'Item: ' + this.name + '\n' +
			'Unit price: ' + this.getUnitPriceString() + '\n' +
			'Quantity: ' + this.quantity + '\n' +
			'TOTAL: ' + this.getTotalPriceString();	
	}
};

That seems a bit long, but hopefully we can understand what's going on here. We are letting name and quantity be regular read/write properties but we never defined properties for price or currency. We made those two values accessible via the getPrice and getCurrency methods, respectively.

The trick here is that both getPrice and getCurrency are defined inside our constructor function so they have access to the local variables price and currency. They have access to these variables even after the constructor returns (thank you closures.)

The same can be said for the setPrice method. We will use this method when we need to change the object's price. It will force us to also provide a currency.

I'll leave the explanation of the methods getUnitPriceString and getTotalPriceString as an exercise for you.

Let's instantiate one of these objects and see it in action.

var item = new OrderItem('100g Toblerone bar', 2.09, 3, 'USD');
//public methods:
alert( item.getUnitPriceString() );
// => '2.09 USD'
alert( item.getTotalPriceString() );
// => '6.27 USD'
alert(item); //this will use the toString() method
/* =>
Item: 100g Toblerone bar
Unit price: 2.09 USD
Quantity: 3
TOTAL: 6.27 USD
*/

//changing private fields
item.setPrice(1.11, 'EUR');
alert( item );
/* =>
Item: 100g Toblerone bar
Unit price: 1.11 EUR   <-- it worked!
Quantity: 3
TOTAL: 3.33 EUR
*/

//proving that price is not a field
item.price = '5.00';
alert( item.getUnitPriceString() );
// => '1.11 EUR' <-- Gotcha, smart pants!

item.setPrice(2);
//ERROR: message = 'invalid currency'
alert( item.formatCurrency(1.23) );
//ERROR: item.formatCurrency is not a function

And what am I supposed to do with this information?

I have yet to find the need to use private members in my JavaScript objects. Maybe that's because I am not shipping any JavaScript library with complex enough objects.

I think it's nice to know that you can create those off-limits values in your object. Hopefully when the need for such thing arises, we won't just say Oh, no! Can't do that!.

What about you? Have you found a use for private members in your JavaScript code? How did you get around or implemented it?

JavaScript, time to grok closures

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

When I wrote about functions in JavaScript I mentioned that functions are more than just a block of code:

Function is a standard data type in JavaScript, an object indeed; you can pass them around and copy them.

Let's take a look at this small sample of a function that creates and returns another function. The returned function accepts one string argument and returns another string repeating the argument a number of times.

function makeRepeater(times){
	return function(text){
		var message = '';
		for (var i=0; i < times; i++) {
			message += text + ' ';
		}
		return message;
	};
}

Let's now write some code that uses that function.

var threeTimes = makeRepeater(3);
var fourTimes = makeRepeater(4);
alert( threeTimes('hi') );
// => 'hi hi hi '
alert( fourTimes('hi') );
// => 'hi hi hi hi '

Nothing spectacular, right? But look closely. The function returned by makeRepeater contains a reference to times, which is a local variable of makeRepeater. When we call threeTimes or fourTimes the makeRepeater call has already returned and times should be out of scope. Or should it?

Extra life for your local scope

You may try to argue and say that the times inside threeTimes is not a reference to the times from makeRepeater, but just a copy of that value. Well, sadly I'll have to prove you wrong. Let's modify our code just a little.

var times;
function makeRepeater(){
	return function(text){
		var message = '';
		for (var i=0; i < times; i++) {
			message += text + ' ';
		}
		return message;
	};
}

times = 3;
var threeTimes = makeRepeater();
times = 4;
var fourTimes = makeRepeater();
alert( threeTimes('hi') );
// => 'hi hi hi hi '  ---> What?!?!
alert( fourTimes('hi') );
// => 'hi hi hi hi '

If it's not clear yet, let me write it down for you. The returned function really keeps a reference to any outside values it will need when invoked. In our original example, it kept a reference to the times local variable at the time it was produced. If we had created other local variables inside makeRepeater they would also become available inside the returned function. In other words, all the scope created during the call to makeRepeater will be preserved for the returned function. This happens when the returned (or inner) function has a reference to anything defined in the parent (or outer) function, i.e. the parent local scope. When this happens, we say that a closure has been created.

Closures can be tricky

It's important to understand the mechanics of closures to avoid subtle bugs in our code. Look at this piece of code, adapted from a real bug I had to fix.

<input type="button" value="Button 1" id="btn1">
<input type="button" value="Button 2" id="btn2">
<input type="button" value="Button 3" id="btn3">

<script type="text/javascript">
	function createEventHandlers(){
		var btn;
		for(var i=1; i <= 3; i++){
			btn = document.getElementById('btn' + i);
			btn.onclick = function(){
				alert('Clicked button #' + i);
			}
		}
	}
	createEventHandlers();
</script>

If you put this code in a page and click the three buttons you will see that all of them will show the message "Clicked button #4". Armed with our understanding of closures we can immediately understand that this bug is being caused by that reference to i used inside the event handler. We can fix that.

function createEventHandlers(){
	var btn;
	for(var i=1; i <= 3; i++){
		btn = document.getElementById('btn' + i);
		btn.onclick = createOneHandler(i);
	}
}

function createOneHandler(number){
	return function() {
		alert('Clicked button #' + number);
	}
}

The above code works because we are not creating functions inside the for loop, hence not producing closures on the same local scope. There is a different set of closures being produced by createOneHandler, but those are not pointing to the same parent scope. Each of these three new closures contain a different scope, created by each call to createOneHandler

Closing thoughts

Closures, of course, are not an exclusive feature of JavaScript. It's a very important trait of functional languages. Even in C#, when we use lambdas, closures are created — many times without us noticing.

The key to properly using closures in our code is to pay attention to locally scoped values from the outer function being used in the body of the inner function. Most of the times this will work as intended by the developer but, when it doesn't, stop and check if more than one closure is sharing the same local scope or if these local values are changing between the inner function creation and its invocation.

Video - Uncle Bob Q&A at Chicago ALT.NET

Posted by Sergio on 2009-02-14

After his presentation, Robert stayed a little more answering questions from the audience.

Video - XP: After 10 years, why are we still talking about it?

Posted by Sergio on 2009-02-14

Here's my small contribution to the current avalanche of Uncle Bob references in the .NET world.

This video was recorded at the February's meeting of the Chicago ALT.NET group. This is the presentation that he will be giving as a keynote speech at the SD West conference next month.

The Q&A part of the meeting has also been recorded.