kenegozi.com

<form id='kenegozi' action='post'></form>

   
2009 Apr 13

Javascript and the extended Array prototype

tagged as: client-side | Javascript

I do quite a bit of javascript stuff lately, and I wanted to enjoy the easier syntax of array methods such as forEach, find etc.

As the current project is not using prototype.js, but rather a different js stack (jquery, various jquery plugins, EJS, and a bit more) I did not have the extended Array stuff that comes with prototype.js

 

But before I ran off to add the needed methods to Array’s prototype, I had an annoying voice in the back of my head, whispering “extending Array’s prototype is evil, extending Array’s prototype is evil”, so I looked at alternatives.

 

Alternative 1 – subclassing Array.

I went ahead to implement a MyArray (or Array2) type of solution.

using one method of JS subclassing I thought of

var MyArray = function() { }; MyArray.prototype = new Array; MyArray.prototype.forEach = function(action) { for (var i = 0, l=this.length; i < l, ++i) action(this[i]); }; ...

the problem with that approach is that IE does not like Array subclassing, thus the .length property becomes unreliable, rendering the whole idea of subclassing Array useless.

 

Alternative 2 – using a different object alltogether

It would work, however things like

if (anArrayInstance instanceof Array)

will naturally break.

 

Alternative 3 – extend any ‘interesting’ instances
function extendArray(arr) {
    if (arr.__wasExtended) return;
    arr.forEach = function(action) {
      for (var i = 0, l=this.length; i < l, ++i)
        action(this[i]);
    };
    arr.__wasExtended = true;
}

which is wrong as any instance will get a copy of all the functions, so too much memory will be used for non-core functionality

 

Alternative 4 – use the separated scoped Array trick

just read http://dean.edwards.name/weblog/2006/11/hooray/

the idea is to use an Array object from a separate iframe, thus enjoy the Array (instanceof), but not interfere with existing Array object on the main window

 

On top of all that. all three alternatives are problematic, as a regular

var a = [];

will not be extended. which is not such a big problem if you're disciplined enough, but it's terribly annoying to need to extend every array you want. think about JSON data you get from a service. you'd first have to iterate over the object graph and extend all of the arrays. yuck.

 

 

Now, do you remember that annoying voice from the back of my head? I decided to stand up to him !

Why actually not extend the Array prototype and be done with it?

It will solve the “instanceof” problem, it will solve the need to apply the functions manually on all arrays (as any [] will natively have the new functions), and it wouldn’t cost much memory as it will only be added to the single prototype of all array instances.

 

The usual reason for not wanting to do so, is that it would break the associative array ‘feature’ of javascript, and you won’t be able to

for (var i in myArray)

anymore.

 

You know what? that reason is a total bullshit.

Why? cuz there’s not such thing as an associative array in javascript !

If anything, the Object object is similar enough. However the Array object should be used with 0-based integer index, just like any native java/c#/c/whatever array.

 

Removing that ‘problem’ from the equation, and we can resort back to stuff like

Array.prototype.numSort = function() {
    this.sort(function(a, b) { return a - b; });
    return this;
};
Array.prototype.forEach = function(action, index) {
    for (var i = 0, l = this.length; i < l; ++i)
        action(this[i], index);
};
Array.prototype.find = function(func) {
	for (var i = 0, l = this.length; i < l; ++i) {
		var item = this[i];
		if (func(item))
			return item;
	}
	return null;
};
Array.prototype.where = function(func) {
	var found = [];
	for (var i = 0, l = this.length; i < l; ++i) {
		var item = this[i];
		if (func(item))
			found.push(item);
	}
	return found;
};

 

You just have to *love* dynamic languages :)

2009 Apr 9

Quick scripting – Boo to the rescue

Today I needed to run a SQL script that sat in a 1.4Gb text file.

It includes the schema creation, plus a massive amount of INSERTs, all for a project I need to complete in order to get my Bachelour’s degree from uni. The amount of data is due to the fact the it’s an Advanced DB seminar, and I’m demo-ing DB related stuff, so size matter.

 

Anyway, the script was lacking the “use DBNAME” at it’s top. and since the file was too large to open up in the Management Studio, I wanted to OSQL it. I just needed a way to add the “use” statement at it’s top.

 

Quick and dirty boo script to the rescue (add.boo):

import System.IO
import System.Text

r = StreamReader('openu.sql')
w = StreamWriter('new_unicode.sql', false, Encoding.Unicode)
w.WriteLine('use openuni')
l = r.ReadLine()
while (l != null):
	w.WriteLine(l)
	l = r.ReadLine()
w.Flush()
w.Dispose()

 

Running it with

booi add.boo

 

And executing with

OSQL -E -i new_unicode.sql

 

Who needs powershell ...?

2009 Apr 7

Programmer Competency Matrix

tagged as: miscellanea

I just got an email from a friend (thx Zeev) which simply contained a single URL:

http://www.indiangeek.net/wp-content/uploads/Programmer%20competency%20matrix.htm

 

Couldn’t come at a better time for me. We’re in the process of hiring new extraordinary people here at SHC Israel, and this matrix helps formalizing the things we want our candidates to know.

 

so, if you believe you’re a log(n) on quite a few of the fields, then please ping me

2009 Apr 5

I wish that it was an April fool’s thing

Not tagged yet

Last week I got a promotion on my Email. The title said:

Write 10,000 lines of code in 10 minutes

 

Any why the heck is that a *good* thing?

 

 

I would however buy a product that can *eliminate* 10,000 LOC in 10 minutes

Subscribe

Statistics

399
861

The Lounge

Related Jobs

Related Books

search page | Blog's home | About me