Saturday, March 31, 2007

RitaliaCamp

brainstorming and questions, questions, questions ... really interesting event but now I'm a bit confused :D

Stay tuned on official wiki!

Wednesday, March 28, 2007

JavaScript Metaprogramming and MetaDOM

I found really interesting Adam McCrea presentation about JavaScript Metaprogramming but I'm not, absolutely, a Prototype fun :P

I thought about another way to show Metaprogramming power and that's why I wrote a simple MetaDOM object.

What can You do with MetaDOM?
Nothing that You can't do with every JavaScript library, get elements, modify them ... but with this object You should use a sintax like this one:

with(MetaDOM){

While("p").Do(AddPNumber);

For("li").In("ul").Do(AddLiNumber);

If("div").class("some-div").Then(WriteSomeDiv);

If("*").class("paragraph").
Then(WriteSomeDiv).
ElseIf("*").id("paragraph").
Then(WriteSomeParagraphId)
;

With("body").Do(function(body){
body.innerHTML = '

MetaDOM Experiment

' + body.innerHTML;
});

If("*").name("h2").Then(AddH3);
};


Semmes cool? This is the example page, tested only with FireFox (and probably this alpha joke version works only with FireFox).

Do You understand better Metaprogramming and do you like it? :D

Friday, March 23, 2007

JavaScript constructor (did you know?)

Update! [2007/03/27]
to know if a generic object is cracked we don't need to create a new instance of its constructor. The fastest, safest and correct way is just to know if this object is an instance of its constructor.
return o instanceof o.constructor ? o.constructor : undefined;

Just fixed the Constructor function ;)


I'm absolutely a JavaScript noob!
Just today I "discovered" that a generic object constructor is not a read-only parameter and I based a lot of conversions with constructor parameter!

What a news for me, I can't believe that every kind of object, except for primitive vairables such String, Boolean and Number, could be modified in this way:

function MyObj(){};
var obj = new MyObj,
str = new String("test"),
sts = "test";
obj.constructor = Array;
str.constructor = Array;
sts.constructor = Array;
alert([
obj.constructor === Array,
str.constructor === Array,
sts.constructor === Array
]); // true, true, false


What does it mean?
This means that my PHP_Serializer object, used from a lot of developers, and my byteson library, with its JSON parser, are not so safe to use as I believed.

Malicius code should not be a problem but these objects should fail conversion in a really simple way because they rely on variables constructor.

What about a solution?
The first point is that to change a variable constructor is absolutely the worst JavaScript practice I can think on but we write code and we want a secure one so this is my proposal:

function Constructor(o){return o === null ? o : Constructor.$[typeof o](o)};
Constructor.$ = {
"boolean": function(){return Boolean},
"function": function(){return Function},
"number": function(){return Number},
"string": function(){return String},
"object": function(o){
var constructor = o.constructor;
return o instanceof o.constructor ? o.constructor : undefined;
},
"undefined": function(){return undefined}
};

This function returns a generic variable constructor, null or undefined if variable is null, is exactely undefined or if it has an unknown constructor.

That's true, if You change a constructor of a generic object is really difficult to know wich one was changed so this function guarantees, at least, that if returned value is undefined but value is defined, it was "cracked" changing constructor value and in this case, it should be deleted or discarded (IMHO).
This is a simple test case:

function Type(){};

var arr = [1,2,3],
obj = {one:"two"},
bot = new Boolean(1),
bom = false,
fun = new Type,
fum = function(){},
num = 1,
nun = new Number(123),
str = "test",
sts = new String("taste");

arr.constructor = String;
obj.constructor = String;
bot.constructor = String;
bom.constructor = String;
fun.constructor = String;
fum.constructor = String;
num.constructor = String;
nun.constructor = String;
str.constructor = Array;
sts.constructor = Array;

alert([
Constructor(arr),
Constructor(obj),
Constructor(bot),
Constructor(bom),
Constructor(fun),
Constructor(fum),
Constructor(num),
Constructor(nun),
Constructor(str),
Constructor(sts)
].join("\n---\n"));


Well, now you have a function to check constructors status so right now you can forget a totally nonsense practice as changing constructor is.

That's all folks :)