My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.

Sunday, October 11, 2009

Named function expressions demystified II

Update If after this reading things are still the same, please read the part 3 of this post, thanks.


I have been criticized just for fun and in a impulsive way without analysis or tests (I am not talking about Juriy who gently replied with interesting points in the part 1 of this post - and I replied back).
First of all, if the purpose of an article is to describe a behavior and provide a solution, there should not be any challenge or run for the copyright ... we are developers, and we want the best solution, for us and others, if this solution has been published.

Specially for a complicated language as JavaScript is, Virtual Machine and cross browser troubles speaking, is really difficult, sometimes impossible, to find the ultimate and perfect solution, so let's keep the argument in a professional way, agree?

What Is Wrong With Juriy Solution

Somebody does not get it, and it could be my fault. So this is about inconsistencies, and I'll show you Juriy code to avoid any kind of misunderstanding, OK?

var fn = (function(){

// declare a variable to assign function object to
var f;

// conditionally create a named function
// and assign its reference to `f`
if (true) {
f = function F(){
// now try to create a setTimeout here
// assuming we need it

// error, there is no F reference
// anymore in this context.
// This function obviously exists and
// the entire point is to find a solution
// to replace arguments.callee
// so do you think is a good design
// we cannot use the function name
// with every browser?
setTimeout(F, 1000);

// insted we have to use another name
// but there is NO REASON to do this
// if you understood my precedent post
setTimeout(f, 1000);

// so the purpose is to make function
// call possible via name and the solution
// is to do not use the function name
// am I the only one spotting
// inconsistency here?

alert(f == F); // FALSE
// because F was the last option
// and F has been referenced to null
}
}
else if (false) {
// same as above
f = function F(){ }
}
else {
// same as above
f = function F(){ }
}

// Assign `null` to a variable corresponding to a function name
// This marks the function object (referred to by that identifier)
// available for garbage collection
var F = null;

// NO, this does not mark anything
// this is another layer in JScript
// the function exists, as exists the last one
// if we are nullify a reference, the garbage
// will discard the function because not
// referenced ANYWHERE in this contest

// This behavior is EXACTLY THE SAME
// if we have last option callback
// in IE since the last function reference
// will be the only one, then other functions
// will be collected

// Moreover, with "Re Solution"
// the function is trapped in the reference
// where the reference HAS THE SAME NAME
// this means we have THE FUNCTION NAME
// as valid one in the current scope
// NO ALIASES, and garbage is fine


// return a conditionally defined function
return f;
})();


Re Solution

To keep best compatibility the last option could be a bit messy in Opera or old Safari. That is why I have suggested my Re Solution.

var fn = (function(){

// declare the FUNCTION NAME we want to use
var F;

// conditionally create a named function
// and assign its reference to ITS NAME
if (true) {
F = function F(){
// EASY!!!
alert(F == arguments.callee); // TRUE
setTimeout(F, 1000);
}
}
else if (false) {
// same as above
F = function F(){ }
}
else {
// same as above
F = function F(){ }
};

// In this cotext there is
// ONE AND ONLY ONE
// reference to function F
// being the reference evaluated
// AFTER function declaration
// It does not matter if
// there are other functions
// with the same name because
// the reference, which comes after
// WILL POINT TO THAT FUNCTION
// which is a named one

// EASY ???
return F;
})();


As Summary

I hope things are finally clear for everybody. I hope Juriy will get my point, and I am always ready to negate everything I wrote as soon as somebody will demonstrate it is wrong. Again, we are developers, there's no trophy here if we want make something public for developers community.

Saturday, October 10, 2009

Named function expressions demystified

Update If after this reading things are still the same, please read the part 2 of this post, thanks.



This is a re-post, and few considerations, about the good Juriy article, which I suggest for every JavaScript developer with a deeper knowledge than just an API (jQuery or others).

Github For Everything!

My first consideration is about github, something I've never used that much since via Google Code I feel pretty comfortable with subversion. I find truly interesting the way Juriy is tracking his documentation, I've never thought about an article, as my old JavaScript Prototypal Inheritance could be, in a code repository as kangax did: good stuff!

My Alternative Solution

There are few extra consideration to do over Juriy explanation, plus minor inconsistencies. The first thing is that Internet Explorer basically manages Function expressions and Function declarations in the same way, there's no such VS in the middle.
The fact we assign the function to a whatever named variable does not make any difference:

alert(F); // (function F(f){/*IE Function*/return f})

F((function F(f){/*Function Declaration*/return f}));
F((function F(f){/*IE Function*/return f}));

var f = (function F(){return F}); // <== which F?
function F(){/*IE Function*/}; // this one!

alert(f()); // function F(){/*IE Function*/};
We can play with above IE traps for ages but the point is simple: the last defined function with that name, will simply take the place of the other one, if any, in the same scope, and at the end of its resolution, before code execution.

What IE does is basically a top-down parsing over functions without taking care at all about code execution or normal and expected syntax execution flow.
This simply means that return whatever, var whatever = function whatever(){} ... does not change anything for our loved IE:what we see or what we expect is not what will be, otherwise IE would have been a perfect browser.
To better understand what I am talking about, this example should speak for me:

var f = 123;
alert(F); // last function
(function(){
alert(F); // (function F(){alert(f);return arguments.callee})
var f = (function F(){alert(f);return arguments.callee})();
// undefined
})();
function F(){};

After these two snippets is quite logical understand this behavior:
  1. scope resultion
  2. function resolution plus optional inline assignment, if any, before next function resolution
  3. code interpretation/execution over scope resolution

Accordingly with this Richard Cornford post, in JScript every function is performed sending the execution context, a behavior somehow similar to the injected context via eval in Firefox few months ago.
The latter one has been considered a security hole ... same kind of hole we need to deal with IE on daily basis every time we would simply chose a name for a bloody function.

My Solution

Juriy perfectly knows my point of view about this problem, he knows it so well that his addEvent solution example is created ad hoc to make mine inefficient (and I'll tell you later why).
It does not matter, as long as I can use the same example, avoiding IE4 support ...

var addEvent = (function(){
var docEl = document.documentElement;
if (docEl.addEventListener) {
/* return */ function addEvent(element, eventName, callback) {
element.addEventListener(eventName, callback, false);
};
} else {
// IE has to be the last option
// other addEvent will be "lost"
// cause this will be the only named reference
// in this scope ...
function addEvent(element, eventName, callback) {
element.attachEvent('on' + eventName, callback);
}
};
return addEvent;
})();

The key is simple, and is based exactly over same considerations and suggestions Juriy gives in the Alternative solution paragraph, except my suggestion uses an explicit last option callback, without requiring var this or that plus var this or that = null in any place, and for this purpose.

Indeed, for the same reason Juriy did not perform this task at the end of his latest suggestion and before the returned function:

if (typeof docEl.addEventListener != 'undefined') {
attachEvent = addEventAsProperty = null;
return addEventListener;
}
elseif (typeof docEl.attachEvent != 'undefined') {
addEventListener = addEventAsProperty = null;
return attachEvent;
}
addEventListener = attachEvent = null;
return addEventAsProperty;


totally boring and absolutely anti pattern, on daily basis and real case scenarios, with my suggestion there is absolutely no need to remember to nullify variables used only to refer inline assignments and, moreover, only as Internet Explorer workaround!!! That's too much, I mean we have to change our code, change JS logic, to support such drama JS engine, we even need to write more and nullify everything? No way!

But It Could Be Inefficient

The only real side effect about my suggestion, surprisingly working in Safari 2 as well and solving its problems with names, is that if we have to deal with two different versions of IE in the same scope, we cannot use the "last definition" trick, 'cause one out of 2, 3, or 234567 versions of the most problematic browser since Web epoc, still Internet Explorer and JavaScript speaking, will mess up like a charm ... to be honest, IE4 days, the one without try catch and much more support, are far away from 2009, and I've never had to deal with such problem but in this case, there is nothing better, so far, than Juriy proposal.

Update
In my addEvent example Opera, thanks to its duality, will behave IE like. This is not a problem, since addEvent will work in any case, but we can return if we would like to force Opera with addEventListener (avoiding Safari 2 then). To solve this problem, when necessarym we can use the best from both proposal.

Re Solution


var addEvent = (function(){
var docEl = document.documentElement,
addEvent;
if (docEl.addEventListener) {
addEvent = function addEvent(element, eventName, callback) {
element.addEventListener(eventName, callback, false);
}
}
else {
addEvent = function addEvent(element, eventName, callback) {
element.attachEvent('on' + eventName, callback);
}
}
return addEvent;
})();
Quite semantic, isn't it? ;)
The principle is still the same suggested by Juriy except there is nothing to nullify, just a reference to return, and being based on variable assignment, we can have 2345IE versions in the if else without problems at all.

As Summary

In Internet Explorer there is no difference between function expression and function declaration, this is the whole point of this post, plus the updated suggestion which makes things a bit more logical, from a developer point of view - addEvent is a well defined reference, and that's what we need.
The var F = null; in Juriy suggestion is useless for IE. References comes after, in the interpretation flow, while references come before in the execution one. var F = null; will nullify a reference, it won't mark anything for the IE garbage collector.
Juriy article is in any case a must read as soon as we understand JavaScript scope and lambdas, and specially if we would like to support multiple browsers.
Hopefully these gotchas will disappear with ES5 and the next "dreamed" IE9 with its totally new fabulous V8 engine ( OK, OK, ... let me dream please ... )
The day IE will disappear from browsers panorama I'll be the most happy and drunk web developer in the area but until that day, we can say the panorama is still weird, at least well explained, and with all possible solutions, we have choices!

Friday, October 09, 2009

devpro.it is down

As usual, when there is a merging or an acquisition, the classic "Dear customer, don't worry, everything will be just like before and even better" becomes automatically "Who are you, what'ya want from us, do we know each other? Re-buy the service if you have troubles!" ... in few words, devpro.it and 3site.it are down because there is no such thing anymore: the host! ... a little detail, that will be hopefully solved soon (next week at some point).
Fortunately, I have my backup, thanks to SQLite, actually version 2, which has maintained in performances and stability for years and hundreds of thousands of records both read only or constantly changed (counters, stats, code serving).

Maybe it's a good occasion to re-think devpro.it? Dunno yet, and time is zero, I am just sorry for any inconvenient caused by my different programming languages sources.

At least we can have fun with a classic video from The Web Site Is Down

Tuesday, October 06, 2009

NWMatcher - A Quick Look

As usual, as soon as I decide it's time to go to sleep, somebody :P has to post a stunning benchmark about a selector matcher ... did I shut down? No, I had to read the entire source code of the library, and this is my quick summary, but consider I am tired ...

NWMatcher, A Selector Monster

First of all, I did not know or remember this project and I must congrats with Diego Perini for different reasons.
The first one is that Diego used almost all best and unobtrusive technique to make it as reliable as possible, which is good, the second one is that Diego introduced something new to achieve its goal: create a Ferrari matcher via pre-compiled functions.

About NWMatcher

It is a lightweight stand alone library (so far, but already namespaced) which aim is to standardize some common DOM related task. The initial aim was to create a faster way to understand if a node matches a specific selector, something truly useful with event delegation.

About The Technique

To make things as fast as possible, Diego used a pre compilation strategy which is absolutely brilliant. Without XPath transformation, which is also not fully compatible with CSS in any case, and taking care of every single browser "gotcha", Diego creates once, and never again, the function able to perform selector related tasks. The result is that first call a part, with a new selector, the match method will perform a light speed!

This is the notable good part of NWMatcher, and now there's the bad one (not that bad in any case)

Few Inconsistencies

Except a weird procedure to understand if array slice could be performed over nodes, something I always got in 3 lines:

var slice = Array.prototype.slice;
try{slice.call(document.childNodes)}catch(e){slice=function(){
// whatever to emulate slice for this scope
}};

Diego uses a callback to understand native methods from fakes. This is generally good, and this function is isNative, but since these kind of checks are for greedy developers with global pollution maniac, I cannot understand why at some point there is a root.addEventListener ? ... and no checks if addEventListener is native one, something that could make the entire caching system useless or able to generate errors. OK, that would be silly, I mean to inject an event like that, impossible to emulate in Internet Explorer, but who knows what a library could do with such event ...
Another inconsistency is about being unobtrusive, goal reached 99.9% ... what is that, a public property attached directly in the used context? We need to be aware that the document will probably have a snapshot, plus an isCaching property, not a drama, but I think those are the exception that confirm the rule.
Another thing I'll never get is the usage of new in front of functions which aim is to return a non primitive value.

function A(){
return {};
};

Above function could be called with or without new and the result will be always the same, the returned object. This simply means that if we use new we are consuming CPU and RAM for no reason. So why a performances based library should not take care of this simple fact?

// example
function Snapshot(){
// here this exists
// and it has a prottype attached
// and it has been internally initialized
// to be used as Snapshot instance

// we return an instanceof Object?
// well done, so the garbage collector
// has to consider this instance
// which is a ghost instance, never used
// but it has been created
return {
// whatever ...
};
};

// let every comment inside the function
// make sense simply adding new
var snap = new Snapshot();

// a non-sense, imho, since this
// would have produced exactly the same
// without instance generations
var snap = Snapshot();

That's it. This stuff is really simple to get with C, C++, or those languages where we have to declare types, names, etc etc, and a new in front of a function is not transparent, is something to think about, cause a new is a new, we are asking for an instance, and a function able to return always another value, rather than the generated instance, shouldn't be called via new.

Diego, I am sorry, I am using this irrelevant gotcha simply because I wrote about these things dunno how many times ... please remove every new Snapshot from your code, or just use the instance, attaching proeprties.

Snapshot =
function() {
this.isExpired = false;
this.ChildCount = [ ];
this.TwinsCount = [ ];
this.ChildIndex = [ ];
this.TwinsIndex = [ ];
this.Results = [ ];
this.Roots = [ ];
}

Makes sense? For performances reason, I still suggest to simply remove every new, leaving just Snapshot ... OK, that is probably more than I was planning to say ...

Mutation Events Side Effects

For compatible browsers NWMatcher uses mutations events such DOMAttrModified, DOMNodeInserted, and DOMNodeRemoved. The cache is partially arbitrary, activated by defaults, deactivated via setCache(false).
Mutations events are used to cache results. Why mutation events? Let's say in a single function is so common, specially in jQuery world as example, to search the same bloody thing hundreds of time ...

$("body").doStuff($whatever);
$("body").doOtherStuff($whatever);
$("body").doSomethingElse();

Above way to code is present in dunno how many examples, articles, books, and is as elegant as illogical. If we need a collection, I know we all like the $("thingy") style, but it's that difficult to write code such:

var $body = $("body"); // that's it, wrapped once, SPEED!
$body.doStuff($whatever);
$body.doOtherStuff($whatever);
$body.doSomethingElse();
I am sure it is difficult, and Diego knows this stuff better than me, indeed he is using result cache to avoid repetitive expensive searches over potentially massive structures as a DOM could be, in order to guarantee best returned results performances. So far, so good ... and mutations events, attached to the root of the DOM, the document, are able to clear the cache ... how? via a callback. Simple? Sure, it is simple ... but there is a little detail we should consider.

Nowadays, Ajax based Web applications are constantly muted, eachAjax call aim is to change something, show something, or remove something. With these perpetual changes whatever event is attached into a mutation event will be fired dozen of times but Diego, which is not the last JavaScript hacker, found a way to partially avoid this problem. He removes the mutation so the first fired one, will avoid same operations for other N times. This is good, but there is still an event to manage, internally, and a callback to call, but the bad part is that for each select, those events have to be reassigned, or checked, again (isCached attaced property).
Talking about performances, we need to consider the real case scenario, rather than a static benchmark over the same selection, or couple of selections, where nodes are, as I have said, constantly changed via innerHTML, innerText, appendChild, removeChild, insertBefore, insertAfter, all operations probably present in every single function of our JavaScripted page.

Now, is it truly worth it to cache results? Why, if it was the key, browser vendors are not caching results when we perform a getWhateverByWhatever or querySelectorAll?
Is our library truly that slow that a couple of searches performed consecutively are such big problem so we need to increase libraries complexities, side effects, and browser problems/behaviors, for something that on daily basis will be used I guess 5% of the time due to constant DOM manipulation?

Always Cached Matches

The brilliant strategy used to pre compile functions could be a bit greedy if used lots of time, over lots of different CSS queries, and for a long online session. What am I talking about? Mobile devices, a la iPhone with 2Mb of RAM limit, and all those lambdas stored in any case in memory. Is there any test about this? I'd love to see or create one, but I need a good iPhone web app before. Finally, this is just a hint, when the selector "*" is present, I think there is no point to parse anything or create the pre-compiled function. That return true in the body, should be enough, so in dozen of reg exp, I would have used a simple "*" check, and return just true. OK, talking about consistency, this is not a real case scenario, 'cause we have to be silly to know if a node matches "*" ... of course it will ... but what we should not forgot, at least in version 1.1.1, is that a node, not present in the DOM, will match "*" in any case, as is for every other match. This could be Diego aim as well, not sure WebKit and FF nightly behave the same, but I honestly don't think a non rendered element should match a CSS selector...

As Summary

NWMatcher is definitively the best answer I have seen so far to match a css. Diego experience is everywhere in the code, and people in credits gave good help and advices as well. I have been probably too strong about these few things I have spot in the code, but I am planning to use NWMatcher and to test it on mobile devices as well so the purpose of this post is: please, make it perfect Diego, and thanks a lot, truly good stuff!

Monday, October 05, 2009

Chrome Frame Options

As posted in Frame ML, twitted after (exactly 140 chars :D), and uploaded on my chromefix page, there is a new batch script file able to launch frame and let us clear, as example, the cache or perform some other operation.

start "Frame" /B "%PROGRAMFILES%\Google\Chrome Frame\Application\chrome.exe" "--user-data-dir=%APPDATA%\Google\ChromeExp\User Data\iexplore"

The reason this launcher could be useful is that apparently the cache used via Frame could be blocked and the user unable to clean it via common IE options procedure.
Enjoy, and thanks Tommi for the tip.

Sunday, October 04, 2009

[Q&D] Fix Decimal Module Operator

This is a Q&D solution for some JavaScript precision problem when we use the module operator with floating point numbers.

The Problem

If we are dealing with the module operator we could have this case:
alert(
8.25 % .05
);
// 0.049999999999999545

We expected 0 but we have a floating point inconsistency instead. This is a well known problem, and not only with JavaScript, truly annoying when we have to show run-time computed money/trends operations.

The Solution

This comes from my reply in a JS forum, knowing that the module will be a simply floating point, let's say .1 to .001, if we remove floating point from the right side of the operation everything works just fine:

function mod(num, mod){
// Another WebReflection silly idea
var pow = Math.pow(10, (("" + mod).split(".")[1] || "").length);
return ((num * pow) % (mod * pow)) / pow;
};

alert(
mod(8.25, .05)
); // 0


alert(
mod(8.25, .1)
); // 0.5

That's it, have a nice Sunday

Thursday, October 01, 2009

Randomly Speaking ...

These days have been a bit chaotic, lots of news, good and bad, unfortunately somebody decided a day has only 24 hours and somebody else decided sometimes we need to sleep, so from 24 we pass to 18 ... this is a quick random post about changes and thoughts

I Am One Of The Ajaxians!

Thanks to Dion Almaer, or if you prefer "it's Dion fault!!!", I am glad to be one of those guys there talking about everything Web related, development, techniques, news, mobiles, whatever, as long as it makes sense and will keep us updated with the latest kill app.

Formaldehyde Has Been Updated

My simple Ajax / PHP debugger has slightly changed to solve a couple of annoying bugs. One was a typo, another one a new XHR feature (or better, limit) so theoretically, Formaldehyde should not caouse problems anymore.

The Real Problem Is Not IE6 But Windows 2000, 98, Me

Google Chrome Frame demonstrated that people want a better browser but there are still so many companies stuck in deprecated operating systems.
The most interesting analysis I could do is thanks to this reply in Frame ml:

Our company uses ALMOST 100% Windows 2000 OSes ... in our business, we always use a web application that uses a LOT of javascript, IE6 is Slow and always gets a javascript Error and needed the browser to restart.. the employees productivity
is continually monitored, this browser failures are a big problem.

Please let me summarize with a reply ...

Dear Companies

If your business is mainly based over a web/network architecture, the only one that will fall down day after day will be simply your business. An upgrade does not cost anything, and old PCs could install without any problems whatever free Operating System without slowing down your productivity making you, and your business, updated, 'cause the rest of the world and everything that works behind a browser is moving forward, so you are simply deciding to stay behind without a valid reason.
How can you justify slow productivity? How much this slow productivity, missed IE6 features, and an old, deprecated, application based over IE6, can mean for your incomes? Think!

The London JavaScript Group Should Survive!

This is the bloody Europe financial capital and one of the main IT center and nobody is interested into the programming language of the past, the present, and the future? This is unacceptable, is often thanks to JavaScript ignorance that our business is not that interesting as USA one ... with all those new thingy that "must be Flash or Silverlight!" while nowadays, 70% of the time, it is simply JavaScript!!! If I could have produced some silly stuff like the Liquid FX, guess how much JavaScript skills and knowledge could bring inside your on-line applications. Be interested, and do not follow Jurassic patterns a la "server side developer and just a web designer with jQuery knowledge", this is not enough for whatever start-up or whatever web based service.

TechHub Is Getting Started

This IS what I was expecting from this city when I moved here almost 2 years ago and not a dead JavaScript group ... ThechHub, finally some fresh air outside deprecated development models so loved in most of those companies fell down during the credit crunch ... Innovation is the key, everything that let us survive is wrong, everything that let us grow up, is good ... even in latter case, we could grow up even more, doing right steps, Think!

That's it, told'ya it was random ... have a nice week end if I won't have time to post again.

Friday, September 25, 2009

Chrome Frame Always On IE Toolbar Button

As promised in the CF ML, here I am with the first Chrome Frame Button application.



It's beta not because of its functionality, it works 100% at least in my old laptop, but because when you click the button the Chrome Frame is always on or of as expected, but to see the new icon or the new label we need to restart IE.

Anyway, this button is not created to switch every second, this button is "just for fun", as fun was the first always on application.

How it works? Grab the zip file from my chromefix project. Unpack it, and read the file README.TXT ... it's really simple, basically a double click and nothing else

Thursday, September 24, 2009

Software Quality - We Are Loosing It

This may sounds silly, surely not technical, but today I've lived the last drop before crackpots!

IE6 Inside The Cash Point

I am not joking, I have no idea how many cash points use windows and IE to run a 7 screens software. Have you never noticed a "click clack" while you are performing your operations?
OK, maybe banks do not even buy Microsoft licenses, or maybe those are dedicated cache machine version of Windows, but I could never imagine to find a windows popup with an error in a cache machine, it is ridiculous!
Those one with just text? Well, they look old and ugly, but I've rarely seen one disabled.
We have dozen of valid Operating System able to perform the same software for years without requiring a single reboot. How difficult will be to create an OS specific for a cash point where operations are always the same, adding just 1 image format supported? What I mean is that you can find active screens with lottery ads inside running 24/7 without problems over a hilarious hardware.
Take one of them, add 20 buttons function, that's all we need to click: £10 and digit few numbers, isn't it?

The Hub 2.0 Router Firmware Disaster

I am having constant problems with my ADSL since the first day. First of all the company wrote in the website that for first 10 days I could have noticed disservice but after everything would have been fine. So far, so cool, I was freaking out thinking "OMG, my router is alive, it programs itself!!!" ... then I have simply realized that this company is just selling, so once they bring you the router they have a ready excuse if things are not working as expected ... you have already signed, and good luck with assistance 5 days a day, without specific hours, and during the week ... sure, I day off to wait somebody for somethig I am already paying.
Moreover, without touching anything, and monitoring the router directly via its interface, they asked me via phone if I was in Wireless or Cable ... I mean: WHAT? THE ROUTER IS TELLING ME ITS SPEED, I HAVE NOT A NETWORK PROBLEM!!!
It does not matter, I am struggling with 160kbps of bandwidth and apparently, even if for 2 weeks everything was almost fine, now it's my problem ... they need to come here ... to do what?
Checking online the firmware of this router has the worst history ever.
Is it that difficult to develop a firmware or this company just payed the cheapest one "who cares about the software if it works somehow"?
Right, now I have the latest version of one of the most problematic firmware I have ever seen. I was complaining with ASUS and its firmware nightmare where nightmare meant 1 every year and now I have discovered than a much simple device has so many software problem ... OK, cheap router, but they sell it like gold, and crappy software ... that's cool!!! I wonder how many problems there could be in a standard configuration as whatever phone line is. Is too noisy? Cable problems? No, it's the router, but they'll never tell us their router has problem. Most likely they'll let us buy a new PC to discover that the problem was not the PC ... cool!

Supermarket Big Chains With Bugged Self Check Out

Again, I am not joking, in the place where I go almost every day to buy something for lunch I hve never seen all self check out machines active without problems, never!
The hardware is pretty simple though, touch screen with basically 3 big buttons, a barcode reader, and a money counter for the change. Simple, isn't it? It's not, 'cause these machines never work more than 2 consecutive days ... always problems. Well done Big Chain, as summary you paid the cheapest machines, and your are paying 10 times more due to constant problems these machines have. Everybody does its business, right? Today there were 2 3 of us stuck in front of these machines all without notes change ... I mean, the machine counts money, it is never wrong with the change, and it does not understand when it is finished? The money scanner knows there's no money left there, and it tries again, and again, and again ... used software did not think that when it's finished, it's finished, the machine should simply start to flash the top red light with a clear warning: I HAVE NO MORE MONEY
This would make everything more efficient, since I spent 10 minutes in a self check out machine rather than 1 in the human driven one ... cool!


Run To Deliver

Too many competitors, but apparently it's not the same about developers quality. This is true for the web, for microwaves, for every electric stuff ... the hardware does not cost anymore, what we pay is always the software. 20 years ago there was less software but hell if it was working as expected. Nowadays, software development time is too frenetic, there is no time to do a proper analysis, no time to properly structure the code, no time to write decent comments, no time to describes problems, no time for brainstorming, no time to find the best solution, the first that quickly work is fine ... everything is a quick fix, and if it is not and we had time to things properly, we won't have time to create unit tests. Agile, SCRUM, Extreme, these therms are rarely concretely applied over whatever development team but they are fashionable therms, so everybody is Agile today ... We used that OS lib, without showing credits anywhere in our sold application, we have quickly fixed everything without testing, but we have respected the ridiculous deadline 'cause the customer is waiting ... but isn't the customer the one unhappy when things do not work as expected?

AS Summary

We need to slow down, we need to think more, we need to understand why that program worked better, why that library is solving this or that problem and how it is doing it, if we would like to be able to extend it or to customize it. This "1 hour deadline" for everything is visible, touchable, on daily basis with daily software wherever it is ... what is going on? We can't blame always outsourcing though, isn't it?

Chrome Frame On By Default ?

A quick one for those interested into Frame switch on.
Two options
  • use regedit to add or modify the key HKCU\Software\Google\ChromeFrame\OptInUrls with char *
  • download my Chrome Frame Switch executable application.

Latter one, is a zip with two versions of the same application, one for 32bit, one for 64bit. The application allows us to automatically set or remove that register key.

Wednesday, September 23, 2009

Google Chrome Frame - A First Look

In one single day the news about Google Chrome Frame has reached, I suppose, every web related company or developer. As posted before, I hope this plug-in will be adopted soon throwing away every other plug-in "record", thanks to its target: the most used, discussed, slow, and not standard, casa Microsoft default browser, Internet Explorer.
I have spent part of my precedent night sleeping testing this little revolution from Big G. and here there are first suggestions, impressions, results.

The Correct Way To Set Chrome Frame

The Google Getting Started guide is a good lecture, but it is not enough.
The Making Your Pages Work with Google Chrome Frame is incomplete, and I will tell you why.
First of all, we need to understand that Chrome is a Runtime Embedded Browser plug-in, not a tag related one then, as Adobe Flash Player is.
Writing something like:
Just add this tag to the top of the page: That's it!
is confusing and not that detailed info.
A meta tag is normally placed in the header one, top of the page, but as soon as developers read about "that's it" most of them tried to add via JavaScript this meta tag to switch engine: this is wrong.
We cannot mess up IE default Trident engine with a completely different one as WebKit via Chrome Frame is. Different are also variables, if any, globals, if any, render itself, and the best case scenario is that everything will break up!
As summary, runtime browser switch is not truly a good practice, for both main page, or iframes, since the Chrome Frame nature is to change the entire browsed content and since it does not make sense to have such hybrid, non-sense, configuration between JScript and V8, Trident and WebKit.
Accordingly, the best way to activate Chrome Frame is to put in the head tag, top of the page, and before whatever JavaScript action, the meta.

<!DOCTYPE html>
<html>
<head>
<title>Google Chrome Frame</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
... the rest of the page, scripts, css, whatever

That is still not it!

Detecting Google Chrome Frame and Prompting to Install

One more time, we need to thanks Google for all this effort but suggested solution is not ideal! (quick update: Alex Russel agrees, so the page is hpefully gonna change soon).
Chrome Frame is, so far, an Internet Explorer related plug-in which means that the external script will not do anything interesting with every other browser such Firefox, Opera, Safari, or Chrome.
Google truncates web pages (body tag) to make things as fast as possible but it is suggesting us a "slowdown without reasons" practice.
The best way to suggest Chrome Frame is to put that external script in a conditional comment:

<!DOCTYPE html>
<html>
<head>
<title>Google Chrome Frame</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
<!--[if IE]><script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/chrome-frame/1/CFInstall.min.js"></script><![endif]-->
</head>
<body>
</body>
<script type="text/javascript">
document.body.appendChild(
document.createTextNode(navigator.userAgent)
);
</script>
</html>

If for some reason we are worried about how to know if IE supports the plug-in, all we need to do is this:

var cf = (function(i,ua){
return i<ua.indexOf("chromeframe")||i<ua.indexOf("x-clock")
})(-1,navigator.userAgent.toLowerCase());
// cf is true when plug-in is installed


Do We Truly Need To Know?

I think IE support cannot disappear today, I wish it would, but that's not gonna happen. If we develop a cross-browser Web application/site is quite useless to understand if we are using the plug in or not, 'cause if Google Chrome will be supported, special features detections a part, the website will simply looks exactly as it looks in Chrome.
I cannot spot a single valid reason, except the Install Prompt for IE, to include that file but my crystal ball says that Chrome Frame is planning to be installed as plug-in in other browsers as well in a not that far future ... so one day maybe it will make sense to remove that script from conditional comments.

Server Side Chrome Activation ?

Not yet, apparently an header in the server with chrome=1 value is useless. I hope this is a temporary issue 'cause to avoid switch delay once Trident has been already started, the server side header could be the best solution. On the other hand, being Chrome a Trident plug-in, I think Trident needs to start before the plug-in can be activated ... uhm, hell problem!

// this won't have effect so far ...
header('X-UA-Compatible: Chrome=1', true);

Update
To understand if the browser will be render the page via Chrome Frame we can use this snippet as example:

<?php
$userAgent = $_SERVER['HTTP_USER_AGENT'];
if(
strpos($userAgent, 'chromeframe') !== false
) {
// your cool standard layout for Chrome
} else {
// your crappy IE dedicated one
}
?>


My First Impression

Enabling runtime Chrome Frame via url, cf: as url prefix, I have tested Taskspeed and many others benchmarks realizing that if I had used Google Chrome the result would have been exactly the same.
The only difference is the little delay, not that little with extremely old hardware, when the meta tag is interpreted and the switch activated runtime, specially the first time.
Chrome Frame is in any case 100% WebKit and Chrome. IE features, included conditional comments, for both layout or script, attachEvent and friends or CSS expressions, are not supported.
While features such V8 multi tab threading is supported ... again, 100% Chrome.

What's Next ?

I am prety much sure the reason this plug-in is not stable is the native OS integration nature of Internet Exploer.
Talking about IE8 we have Accelerators and other specific stuff that will probably not work with this plug-in, but personally I have never used them.
In the Jurassic IE6 case the Operating System dependency is more than hard, and so far it is the most problematic browser but right now I have never encountered a single problem with this plug-in and to make it stable as soon as possible we all need to install it and test it in every single page. This procedure will help Chromium team to better and faster understand possible troubles, if any, so let's contribute: in the worst case scenario we'll have a better Web experience thanks to Chrome overall stunning performances, standards and HTML5 support.

P.S. the Developer console in IE8 should be activatd before the switch, and not after, otherwise with this version it won't work!

Tuesday, September 22, 2009

Web Terminator Salvation - Google Chrome Frame

Google Chrome Frame Bookmark, if you are surfing for whatever reason in IE, right click in precedent link, add to favorite and save as: FINALLY THE WEB, or simply copy this code and past in the website url you are surfing with IE

// corrected via kangax
javascript:void(location.href='cf:'+location.href));



It's the beginning of a Web Revolution, it's the dream of every Web developer, it's the annihilation of the most slow, problematic, non-standard, engine ever: the whatever version inside Internet Explorer!

It's the "Say Fucking What? Buggy Flash Player Yes For Ages And Chrome Frame No?" era, it's something I've been trying for ages without that direct switch, provided by this plug-in, able to forget Internet Explorer except its frame (weird choice about the name though, Google) ... it's the new stats where IE could increase again it's market share who fuckin' care as long as we can finally develop real web applications, is the no more need to wait that pachyderm libraries development ... is that ...

... uh wait, now we have another IE scenario to test ...

Monday, September 21, 2009

One Function To Trap Them All

This is a quick one. This technique could have some side-effect I am not aware about but I've never seen it so far in any library. Talking about LiveMonitor I have successfully tested same concept to create faster implementation of some of my DOM common code, not yet updated in vice-versa.

document.getElementsByClassName Example


(function(childNodes){

/* Another (C) WebReflection Silly Idea */

// how to re-use them all, just an example
if(!document.getElementsByClassName)
document.getElementsByClassName = function getElementsByClassName(className){
for(var
re = new RegExp("(?:\\s|^)" + className + "(?:\\s|$)"),
ret = [], i = 0, l = 0, length = childNodes.length, node;
i < length; ++i
){
if((node = childNodes[i]).nodeType === 1 && re.test(node.className))
ret[l++] = node
;
};
return ret;
}
;

// let the magic happen
})(document.getElementsByTagName("*"));

What we have here?
  1. A trapped live object, probably used in 90% of selector libraries, but performed via scope resolution (the document) and a function execution (the getElementsByTagName method) over all nodes ("*")
  2. a theoretically zero performances impact to retrieve again every node, being live there is no need to refresh it, and being trapped run-time, it will contain few nodes during the first execution
  3. a single scope able to create N functions based on one of the most common created HTMLCollection


What do you think?

CSS Position Fixed Solution

Who does not know CSS 2.1? ... silence (maybe) ...
Good, so who does not know the CSS 2.1 position property? ... silence (still maybe though) ...

Excellent! Finally, who would like to use in a lightweight, cross-browser, unobtrusive way, without JavaScript dependencies, the property fixed? ... silence again, but this time I can spot a different expression in your face ...


Common Browsers With position:fixed Support

  • Chrome
  • Firefox
  • Internet Explorer 7 and 8 but NOT in quirks mode
  • Opera
  • Safari


Common Browsers WithOut position:fixed Support

  • Internet Explorer 6
  • Internet Explorer 7 and 8 in quirks mode
  • WebKit for Android
  • WebKit for iPhone


To Quirks Or Not To Quirks

For backward compatibility reasons IE let developers choose between two box models ... Our loved bloody 64 years* old browser Internet Explorer 6 has never supported such property while both Internet Explorer 7 and 8 do nt support it if we are in quirks mode, a modality tendentiously dead thanks to new simple HTML 5 doctype declaration: <!DOCTYPE html>.
To solve this issue I have created a dedicated file to include via conditional comments which includes a set of "never before that useful" expressions.

Why Expressions

CSS expressions are compatible, so far, only with Microsoft IE browser and they are totally alien for both other browsers and developers. The reason I am saying that is because they are completely unpredictable: it is not possible to easily understand or to predict when expressions will be executed, where, and how!
Technically speaking, being expressions dedicated for CSS hacks, their executions will be performed at least every time the element is somehow involved, and to make it involved, we need to touch some property in order to make expression useful (in this solution case the property offsetHeight of the current node).

The Direct Example

Here we have two pages: the standard or strict mode and the quirks one.
As you can test via your favorite browsers, there are always 5 elements in that page, a top div, a center one, a bottom one, and two divs one left and one right, above and over the center one.

How Does It Work

It is very simple, consider these CSS classes:

/** A WebReflection Solution */
.position-fixed-top {
position:fixed !important;
top: 0;
}
.position-fixed-center {
position:fixed !important;
top: 50%;
}
.position-fixed-bottom {
position:fixed !important;
bottom:0;
}

Hopefully choose name are semantic enough, so it's quite clear that these classes aim is only to position elements, and nothing else, in order to be able to add other classes for whatever other property, zIndex if necessary included.
Choose classes are about most common usage of fixed elements in a page, top, center, or bottom, and adjusting positions or margins it is really simple to put the element in whatever part of the page starting from the bottom, from the top, or the left.
To let the magic be in Internet Explorer 6 and others in quirks mode, these classes are completely replaced, as you can read in IE dedicated file.
Being the IE solution based on CSS expressions, there should not be anything better or quicker than that, render time and call speaking, same should be for memory leaks, timers, and whatever strategy we have adopted 'till now (but of course if there is something better please share!).

Android & iPhone - Not Worth It

These mobile devices implement a stunning browser as dedicated WebKit is, able to render faster than IE8, for example, my last Liquid FX, based on 1 image, and one div, that's it! (congrats IE8 for stretched images rendering time! 7, 6, and 5.5. are much better) ... uh, wait, it's not about IE ...
Android and iPhone have both a great CSS 2.1 support, and even some CSS 3. Unfortunately the position fixed does not work as expected. To fix it I have tried different scripts failing each time. The reason is quite simple: both Android and iPhone block timers or render during scroll, so the effect is that divs move with the scrolled page and only after, eventually, divs come back in the expected position. This is against position fixed idea, and having a truly small screen we should ask our self if it makes sense to cover precious pixels with something fixed there.
It does not matter, as soon as I'll be able to test an iPhone I will continue to optimize my script in order to make the position fixed property usable somehow with mobile devices as well ( center right or center left could be interesting, bottom or top bar quite intrusive for user and/or zooming features ).

How To Implement My Solution

It's simple, if we are in a quirks page, we should include the CSS hacked file after the normal one, and for every IE:

<link rel="stylesheet" type="text/css" href="position-fixed.css" />
<!--[if IE]>
<link rel="stylesheet" type="text/css" href="position-fixed.IE.css" />
<![endif]-->

While for every standard or strict web page we can include the hack only for IE less than version 7:

<link rel="stylesheet" type="text/css" href="position-fixed.css" />
<!--[if lt IE 7]>
<link rel="stylesheet" type="text/css" href="position-fixed.IE.css?444" />
<![endif]-->

I can spot a new expression in your face, isn't it?


* if we multiply per 7 dogs age, I think it is reasonable to say that in IT each year could be multiplied for 8

Saturday, September 19, 2009

JavaScript Liquid Image FX

Yesterday I have been in Brixton Academy for Massive Attack concert: amazing!

I have been totally impressed by their choreography: it looked apparently rudimentary stuff but once they started playing I could not avoid to think all the time how beautiful special effects are and how simple, sometimes, they could be for a stunning result.

Liquid FX

I cannot forget my ActionScript Developer past and of my favorite coded special effects has always been the liquid one. What is a liquid effect? Here a preview:


Test Liquid FX Directly In Your Browser

Well, if the preview image is not explicative enough, I am sure this demo page is :)

Update, this Sony VAIO Flash Style Splash Page could be interesting as well, isn't it? And all in 14Kb images, JS, and layout included ;)


How Does Liquid Work

There is a Liquid function, and its configuration object:

Liquid({

// image src, whatever format
src:"myimage.png",

// element to use as Liquid FX container
target: document.getElementById("fx") // $("#fx")[0] for lazy people,

// optional direction, left by default
// accepted: left, right, bottom, top
direction: "left",

// optional scale factor, 2000% by default
// it is how much the image should be stretched
scale: 2000,

// optional speed, 1 to whatever, by default 10
speed: 10,

// optional callback,will be executed at the end of the FX
callback:function(){alert("it's Liquid!")}

// NEW IN V1.3

// optional onload to perform some operation after the image has been loaded
onload:function(){FX not started yet but image loaded}

// optional reverse property over a completed liquid FX
reverse:true
});

New in version 1.3, the Liquid function returns the configuration object and it adds two methods: pause and play.
Specially pause is useful to stop FX if we need to clean the target container.
// pause/play example
var lq = Liquid({
src:"mycoolimage.gif",
target:document.body,
onload:function(){
setTimeout(function(){
lq.pause();
setTimeout(function(){
lq.play();
}, 500);
}, 500);
}
});


This is pretty much it, so far. I am planning to implement a LiquidReversed function as well, in order to let the images disappear in the same way they appear.
The source code with Mit Style License is here while the inspiration is from my 2005 ActionScript 1 imageStretcher code.

enjoy

Wednesday, September 16, 2009

I Would Simply Like To Support iPhone But I Cannot

Update
Before other silly flame/blame will start, I have already twitted that my next laptop will be a netbook. Here the related tweet.


let me summarize the story: at that time I had a girlfriend with an iPhone so I though why on earth shouldn't I buy an Android instead? If I need some test online I'll have both to test it, and I've rarely been that wrong.

Wanna Develop for iPhone? Buy a Mac

As marketing strategy sounds "cool" except I do not want to develop iPhone application, the present and the future is online, why on earth should I learn another programming language from the scratch, Objective-C, to develop something that will be relatively soon replaceable via WebKit and a good host?

Wanna Develop Web for iPhone? Buy a Mac

Again!!! Unbelievable, there is not such a thing: online iPhone tester, everything I found Googling was about a silly image with an iframe just to test the iPhone size ... are you kidding me?
It's like put IE inside an iframe inside an "Android frame" ... where is webkit? Where is the real JS engine? Where is the real render engine?

Wanna Develop for Apple Devices? Buy Apple

OK, I got your point, so now I am stuck with an Android contract and moreover I "love" my Android and it's about a year I am using it writing at light speed thanks to hidden keyboard, and using for whatever Web purpose thanks to its WebKit which is maybe not perfect but it works like a charm, generally speaking.
I do not want to buy a Mac only to test iPhone Web engine via Xcode, I'd love to have better reasons for a Mac, and I don't want to buy an iPhone only to test it online.
That will mean another contract to surf the Net as well ... and why on earth should I do this while I am simply trying to support iPhone?

I Would Simply Like To Support iPhone But I Cannot

Now I am a single developer, but I cannot imagine all other engineers, JavaScript hackers, W3C "slaves", cross-browser maniacs, unable to develop a web application for iPhone. With this strategy Apple is missing the possibility to fix a wider range of problems related to iPhone WebKit dedicated build and moreover it is avoiding iPhone Web support for "silly developers" like me that in this case was only trying to fix a common problem, the css position fixed property, but I am unable to make it works in an iPhone while every other A-Grade browser is supported, Android included, and here is the example!

As Summary

People like Peter-Paul Koch have the privilege to try any kind of mobile device in order to test compatibility. Unfortunately for Mobile Devices Vendors Peter-Paul alone will never be able to cover every kind of test. Even Microsoft releases time bombed images for Virtual Machines in order to test other versions of Internet Explorer. The Android OS is Open Source and it is possible to test it almost via whatever platform, same is for other browsers but not the iPhone. I know you do not mind but you are missing my contribute and support for projects a la sessionStorage, Formaldehyde, the incoming position-fixed, vice-versa or noSWFUpload ... and again, I am only one out of million of web developers.

Please think about it,
Best Regards

Monday, September 14, 2009

LiveMonitor - Asynchronous Property Monitor

Today I would like to introduce you a quite uncommon JavaScript trick, a trapped Live Object or, generally speaking, a lightweight monitor able to understand when a generic property has been changed.

About Live Objects

A live object could be described as a particular object able to change without our interaction. The most common live object example is this:

// this is the most common live object
// the HTMLCollection
var divs = document.getElementsByTagName("div");
divs.length; // let's say 4

// let's add another div inside a generic node
document.body.appendChild(
document.createElement("div")
);

divs.length; // 5!

In few words DOM searches are dynamic, which is the reason almost every selector library needs to transform the current result into a static Array.

About LiveMonitor

Specially suited for live objects, LiveMonitor is a function which aim is to notify us when the specified property change:

// LiveMonitor example
var lm = new LiveMonitor(
// the entire list of elements trapped
document.getElementsByTagName("*"),
// the property to monitor
"length"
);

// add one or more notifier
lm.onchange(function(collection){
// this, will be the lm object
this.value; // will be collection.length
collection.length; // is the new length

alert([
"All nodes collection contained ",
this.value,
" nodes but now there are ",
collection.length
].join("\n"));
});

The example is quite silly, but the concept is that as soon as the monitor will check the "length" property, in this case in the one of the trapped collection, it will fire the onchange event, notifying us that somebody did something somewhere, and this something changed our monitored property.

LiveMonitor Code


var LiveMonitor = (function(){

/** LiveMonitor :: Asynchronous Property Monitor
* @author Andrea Giammarchi
* @license Mit Style
* @blog http://WebReflection.blogspot.com/
*/

function LiveMonitor(object, property){
this.value = object[property];
this._property = property;
this._object = object;
this._event = [];
this._i = 0;
};

LiveMonitor.prototype.onchange = function onchange(callback){
this._event.push(callback);
if(this._i === 0){
var _property = this._property,
_object = this._object,
_event = this._event,
self = this
;
this._i = setTimeout(function _i(){
if(self.value !== _object[_property]){
for(var i = 0, length = _event.length; i < length; ++i){
if(_event[i].call(self, _object) === false)
break
;
};
self.value = _object[_property];
};
if(0 < self._i)
self._i = setTimeout(_i, 15)
;
}, 15);
};
};

LiveMonitor.prototype.offchange = function offchange(callback){
for(var _event = this._event, i = 0, length = _event.length; i < length; ++i){
if(_event[i] === callback)
_event.splice(i, 1)
;
};
if(_event.length === 0){
clearTimeout(this._i);
this._i = 0;
};
};

LiveMonitor.prototype.clear = function clear(){
this._event = [];
this.offchange(null);
this.value = this._object[this._property];
};

return LiveMonitor;

})();


Not Only DOM Searches

LiveMonitor could be actually used as asynchronous notifier for any kind of variable.
Let's say we have an environment able to load runtime scripts but we cannot change loaded scripts (external source inclusion).
At some point we press the "load jQuery" button and we would like to be able to be notiied when it is available ...

if(!window.jQuery){

// create a LiveMonitor instance over
// jQuery property
var jqlm = new LiveMonitor(window, "jQuery");

// add onchange event
jqlm.onchange(function(window){

// remove this event
this.offchange(arguments.callee);
// remove jqlm as well, it is not useful
// anymore for this example

// use jQuery, it's here for sure!
$("body").html("Hello LiveMonitor!");
});

// load external script
loadScript("http://external/jQuery.js");
};


Conclusion

With a cross-browser, portable, and lightweight function, we can use notifications without effort over objects, HTMLCollections, Arrays, or everything else we would like to monitor. Let's say this is a sort of asynchronous cross browser Object.prototype.watch, but this time without alchemy.

Thursday, September 10, 2009

Formaldehyde JS - The Circle Is Close

As announced in Ajaxian, I have created Formaldehyde JS with exactly the same Zero Config logic.

We put this file before everything else and that's it, Formaldehyde will automatically decide how to show errors in a wide range of browsers:
  • Chrome
  • Firefox
  • Internet Explorer 5, 5.5, 6, 7, 8 with or whout console
  • Opera
  • Safari

Logs will naturally degrade until the most primitive alert but hey, Formaldehyde is for debug and development environments, not for production.

Enjoy ;)

Wednesday, September 09, 2009

double tweet - up to 280 chars tweets!

Update
At least one other person did the same and before this post, here there's the prove.
The algo seems to be almost the same, except the length is probably padded to be module of 2 (\x00 at the end) so you can use double-tweet gadget to decode gareth message as well :)


Via encode template and same bookmark link, I would like to introduce my last simple experiment: WebReflection::double-tweet (just a click to give it a try, another one to remove)

The Concept

Twitter lets us type messages with a maximum of 140 characters. Fortunately, twitter accepts Unicode characters and still fortunately, it is extremely easy to pack two ASCII characters into a single Unicode one. Accordingly, 140 ASCII characters could be packed into 280.

A Fast ASCII pack / unpack

function ASCIIPack(s){
// WebReflection Mit Style License
for(var r = [], i = 0, length = s.length, c; i < length; ++i){
c = s.charCodeAt(i);
r.push(++i < length ? (c << 8) + s.charCodeAt(i) : c);
};
return String.fromCharCode.apply(String, r);
};

function ASCIIUnpack(s){
// WebReflection Mit Style License
for(var r = [], i = 0, length = s.length, c; i < length; ++i){
c = s.charCodeAt(i);
0xff < c ? r.push(c >> 8, c & 0xff) : r.push(c);
};
return String.fromCharCode.apply(String, r);
};
The main reason my code could be faster than others common de/encoder, is the usage of apply over a single String.fromCharCode call. You can try to pack and unpack massive documents but please do not forget I am using this for twitter ;)

Safe Pack - What Is It

I have already tested this technique for a 280 tweet but instantly I realized that except some geek one able to decode the message, nobody could receive, understand, or be involved in that tweet. In few words, I somehow killed twitter beauty, concept, and that is why I have added a safe option.
Basically, targets, specified via @target, keys, specified via #key and urls are preserved by defaults. It is still possible to disable this feature and send a 280 ASCCI characters tweet, but I think it does not make much sense.

About Searches Or Search Engines

Being a tweet search inevitable small, all we need to look for is a combination of the clean word, plus the packed one, trying with and without a space before to be sure that word has not been encoded in a different way. Moreover, if for some reason twitter will implement this search option, something I honestly do not think at all, its internal conversion will be still fast, assuming the search is performed via binary match and that the unpack option is that simple/fast (I know, we are talking about billions or records, that is why I think they'll never do it)

Conclusion

If I am not late with this double-tweet idea, I guess we can add the sixth way to send more than 140 characters via twitter :)

P.S. if you pass a link with some text after the anchor, it will be automatically put in the text area

P.S.

As somebody suggested, with few changes the function could theoretically pack 3 ASCII in a range 0 - 0xFFFFFF (3 bytes per char, UTF-8)
The problem is that JavaScript supports mainly range 0 - 0xFFFF so there is no point to even write down the function ;)

Monday, September 07, 2009

PHP Serialization And Recursion Demystified

Introduction

PHP has different in-core callbacks able to help us with daily deployment, debug, improvements. At the same time, PHP is loads of intrinsic "gotcha", too often hard to understand, hard to explain, or simply hard to manage. One common problem is about debug, caching, or freezing, and the way we would like to debug, cache, or freeze, variables.
For freezing, I mean those procedures able to regenerate a stored variable and its status, in order to reuse that variable, to understand what happened in that moment with that variable, or just to speed up expensive tasks already completed.


The Problem

One of the most common procedures to freeze variables is their serialization, performed in core via a well known serialize function.
Please consider this example:

$person = new Employee('Mr. Lucky Me');
// ... do some useful task
myCompanyFreezer($person);

// the myCompanyFreezer function

function myCompanyFreezer(Employee $p){

$company = Company::getInstance();
// note that this company has exclusive
// control over the employee work (reference)
$company->employees[] = &$p;

// on the other hand employee
// has finally a company to work with
// but no control over the company
$p->company = $company;

// update and freeze the employee status
$company->add(serialize($p));
}

So, while company has an exclusive contract, and each employee is totally under company control, the employee has nothing to do with company decisions, but it can proudly say: "Look at me, I work for Company::getInstance()!".
But being serialization recursive, we will find the company instance present as employee "company" property.
The problem is that the company instance has an "employees" property which contain one or more employees, included the employee Mr. Lucky Me.
And so on and on until infinite recursions, a massive waste of resources and ... ALT!, serialize is clever enough to understand when there are recursions and rather than going on with nested serializations it simply put a reference to the serialized object.
Got headache already?

Two Different Kind Of Recursions

Being serialize main purpose to freeze a variable status, and being PHP still a bit hybrid about references and shadow copies, serialize could produce two kinds of pointer: r and R.
The lowercase "r" will be a recursion, while the uppercase "R" will be a recursion by reference.

// serialized recursion - the ABC
$o = new stdClass;

// recursion
$o->normal = $o;

// recursion by reference
$o->reference = &$o;

echo serialize($o);
// O:8:"stdClass":2:{s:6:"normal";r:1;s:9:"reference";R:1;}

We should focus into r:1; and R:1;.
While the "r", or the "R", means there is a recursion, the unsigned integer indicates the exact object that "caused" that recursion.
When we perform an unserialize operation, the parser cannot obviously de-serialize as we read, because if we have an instance or an array, internal values should be ready to be assigned already "unserialized".
This simply means that the number after the R is not sequential, and there is no relation with the length of the string, but only a relation with de-serialization process.

What Is WrongWith Serialize

First of all, PHP serialization is not human readable as JSON, as example, or an XML is.
If we use this format to debug our application we'll definitively need an extra layer able "to introduce" us the object as is. In few words, what we need is something that is not serialized.
Moreover, serialize and unserialize would like to be as much reliable as possible, and for these reasons these functions are 3 times slower than json_encode or json_decode.
The truth is that JSON, as is, cannot compete with serialize and unserialize, due to protocol simplicity which is unable to store class names, lambdas, or public, protected, and private instances properties.
Last, but not least, JSON PHP parsers are a bit ambiguous, because an array not fully populated is usually converted into an object:

define('MY_WELCOME_STRING', 1);
$a = array();
$a[MY_WELCOME_STRING] = 'Hello World';

echo json_encode($a);
//{"1":"Hello World"}

// in JavaScript would have been
// [null,"Hello World"]
// where square brackets mean Array, and not Object

So again, another serializer is not worth it to freeze variables, what's left for us?

var_export

var_export() gets structured information about the given variable. It is similar to var_dump() with one exception: the returned representation is valid PHP code.

EUREKA! There is a core level function which aims is to serialize PHP into valid PHP, how can we ask something more efficient? I mean: "native performances to serialize and native performances to have back, it must be the solution"!
It's not!

$o = new stdClass;
$o->normal = $o;

echo var_export($o);

Fatal error: Nesting level too deep - recursive dependency?

Nice one! From bogus 39116 and Derick reply:
We can't change this by adding some text when this happens, as that
would not result in valid PHP code in that case (which is the purpose of
this function
).

Let me summarize:
  1. serialize/unserialize understand recursions almost without problems but unserialize is slow and both are PHP dedicated

  2. json_encode is not compatible with recursion, and as general purpose PHP serializer, it looses too much PHP information
  3. var_export would be perfect but in PHP we cannot manually represent a recursion that will be valid and correctly parsed
  4. var_dump is magic but its produced output is not reliable, *RECURSION* won't be recognized as valid PHP value
  5. I had already headache at line 10 of this post, and now I am still here to see there are no solutions?


How To Remove Recursion Without Loosing It

Well, solutions are different, but performances speaking, we do not have too many chances. A first solution could be a maximum nested level limit, where an object cannot serialize its properties "forever" and after N times it has to stop!
This technique has more cons than pros, and reasons are these:
  • it could require a manual parser, slower, and due to the problem nature, not that simple to maintain or debug
  • it could be extremely redundant, causing a lot of wasted resources, due to its artificial stupidity, since a recursion should never be serialized, being indeed a recursion, and in this way a waste of time, references, and resources
  • as mentioned 5 words ago, in this way we are loosing the recursion, so we should stop saying we are serializing ...
Accordingly, there is only another chance to perform this task: understand recursions, and remove them without loosing their meaning.

$o = new stdClass;
$o->n = $o;
$o->r = &$o;

echo serialize($o), '
',
serialize(
remove_recursion($o)
)
;

Produced output:

O:8:"stdClass":2:{s:1:"n";r:1;s:1:"r";R:1;}
O:8:"stdClass":2:{s:1:"n";s:12:"?recursion_1";s:1:"r";s:12:"?Recursion_1";}

Et voilà! problem solved! ... but what is that?
The remove_recursion function has been introduced in latest Formaldehyde Project Version 1.05, and its purpose is to make debuggable any kind of trace, backtrace, or logged information.
The resulting var_export will be something like this:

stdClass::__set_state(array(
'n' => '' . "\0" . 'recursion_1',
'r' => '' . "\0" . 'Recursion_1',
))

The chosen form to store a recursion is exactly the same used by PHP for lambdas

echo serialize(create_function('',''));
//s:10:"?lambda_1";

In PHP a lambda is stored as "protected" string, and the number at the end of the string "lambda_" indicates its reference. Until we restart our webserver, lambda functions will persist in the entire PHP context, that is why it is possible to serialize lambda functions and unserialize them, as long as the environment does not change, or restart.
The additional difference between "r" and "R" in case of recursion is necessary to avoid info about references.
On the other hand, recursions are truly useless to debug or export variables, but they can always be present.
PHP will not understand my chosen syntax, but only and if necessary, we can always use a function like this to recreate correct recursions:

function recreate_recursion($o){
return unserialize(
preg_replace(
'#s:[0-9]+:"\x00(r|R)ecursion_([0-9]+)";#',
'\1:\2;',
serialize($o)
)
);
}


Pros

  1. we can finally forget every kind of recursion problem, letting PHP understand them via serialize, without doing anything
  2. performances and produced size will be better than every other nested based parser, thanks to a simple parser which ... surprise!!! ... it does not use recursion at all!
  3. once we pass a variable through formaldehyde_remove_recursion we can transform that kind of variable in whatever format, included var_export, JSON and XML, forgetting recursions headaches


Cons

  1. being based over serialize and unserialize, the transformation could implicitly call, if present, both __sleep and __wakeup events, it's gonna happen in any case if we use serialize/unserialize, but if we serialize a transformed variable __sleep will be called twice
  2. it could require extra effort to regenerate internal recursions, in any case it is better than loose them forever as most of us have done 'till now
  3. the convertion is assumining that a serialized string will not contain an exact match, such a manual string. This is actually the same assumption PHP developers did about serialized lambdas.


Conclusion

With a lightweight function, and after this post, I hope we can better understand recursion problems, and relative serializations. My suggestion is to give Formaldehyde a try, but as long as the Mit Style License is respected, you can extract its internal formaldehyde_remove_recursion.

Any question? :)

Sunday, September 06, 2009

PHP How to var_export a debug_backtrace

Just a quick post, and I am not sure if this is documented, or if this works with every PHP version, but apparently a truly common problem with var_export is the logical inability to manage recursions.

Well, one of the most important function in PHP is the debug_backtrace, which contain recursion, and one thing you would probably like to know is that this trick allowed me to avoid recursion problems:

$backtrace = unserialize(
serialize(debug_backtrace())
);

After this, it is possible to use json_encode, var_export, or whatever other serializer.
The reason is that serialization discover and remove some implicit recursion, so that unserialize will return a cleaner object.
This technique has been used in Formaldehyde, but manual recursions are not supported yet (for example via formaldehyde_log). recursions, for a debug purpose, are in any case redundant. All we need to know is what is there, rather than where.
Regards

Saturday, September 05, 2009

Formaldehyde - Ajax PHP Error Debugger

I am proud to announce my last Web 2.Next creation, Formaldehyde, the most simple, lightweight, scalable, and complete (for its simplicity) Ajax and PHP Error Debugger.
I described everything in its dedicated Google Code Project Page, but just to summarize without many other words, this is the common deployment situation:


while this is what's up with a single formaldehyde.php file inclusion:


I hope you will like it, can't wait for some comment :geek:

Friday, September 04, 2009

@font-face we are already doing wrong

Update - Now We Do Right

Thanks everybody for your tests and contributions. For those interested about why we were doing wrong please read both post and comments but for those just interested about the best way so far to serve correctly one or more font-face, this is the hack:

@font-face {
// define the font name to use later as font-family
font-family: "uni05_53";
// define the font for IE which totally ignores local() directive
src: url(../font/uni05/uni05_53.eot);
// use local to let IE jump this line and
// redefine the src for this font in order to let
// other clever browser download *only* this font rather than 2
src: local("uni05_53"), url(../font/uni05/uni05_53.ttf) format("truetype");
}

You can test directly this technique in my HTML5 Prime Directives Test Page



Credits

  • Paul Irish for its Bulletproof @font-face syntax

  • Mikuso, comments, for his suggestions about server configurations, instantly followed by Weston Ruter for its excellent article Efficiently Serving Custom Web Fonts

  • last, but not least, Scott Kimler, for his Better @font-face Syntax and his patience, testing directly inside a trace log, rather than trust 100% Fiddler or Firebug - P.S. my hat is off for that page, unfortunatly you have trolls problems as well, reading the first comment from somebody that got -1% of what you have done!
Links, snippets, tests, we have got everything we need to understand why font-face CSS plus file serving has been generally misunderstood and how we should do correctly, trolls included (the problem is not the browser).

Good Stuff!
Just last quick info for Scott Kimler, IE simply lacks "local" directive support, and this is the reason it ignores the second call.
If we put local(fontName), url(fontName.eot) it will not load the eot, neither the ttf - local is the key for this trick, but we'll have problems the day IE will understand local, unless the first src will not considered synchronous.
Hopefully, that day IE will support ttf since windows does already without problems.


Few weeks with new browsers and @font-face support that suddenly everybody started to suggest the "cross browser way" to include them ... which is 90% of cases apparently wrong.

The Wrong Way



/* IE first */
@font-face {
font-family: nomeDelFont;
src: url( /nomeDelFont.eot );
}

/* Firefox 3.5/Safari/Opera 10 */
/* but IE will download in any case */
@font-face {
font-family: nomeDelFont ;
src: url( nomeDelFont.ttf );
}

almost the equivalent showed here, via Ajaxian, and Edit ...

What Is Exactly Wrong


It does not matter if we use conditional comments, it does not matter if we put the right font for Internet Explorer before the other one (tricky, since IE does not overwrite the rule just because it does not understand the truetype format).

Our "favorite" browser, and others as well in some case, will always request the truetype as well, and being fonts not that lightweight, our page response could sensibly increase.

HTML5 Prime Directives


Inspired by RoboCop, I have created a simple test page that does not suffer the problem described before.
What we have there is an extremely compact and valid HTML5 page which size is up to 140Kb, and almost 67Kb just for the font.

Plus, as I've said, If we use common suggested snippets Internet Explorer will download in any case the non IE font, try yourself!

First Suggestions To Try To Solve The Problem



  1. never forget to specify the format, format("truetype"), which is apparently able to let IE misunderstand correctly the url and the result is a Error 404, still better than 70Kb to download

  2. moreover, use whatever strategy you know to avoid non IE file serving for IE as well (use Fiddler to monitor the network)

  3. try to create gzipped or deflated version of each font, possibly not runtime, and serve them via proper headers (69Kb down to 22Kb, as example, with 7Zip deflate)

  4. please tell us how you avoided IE wrong font download without using an horrible JavaScript document.write as I did in my little test page


Thanks, and I hope you agree about Prime Directives :D

Thursday, September 03, 2009

JScript Console - A Simple One

After I've read Ajaxian post about JavaScript as a command line scripting language I thought it could be interesting to know how to create the first Windows console.

The console.js File


function print(text){
WScript.StdOut.WriteLine(text);
};
function quit(){
WScript.quit(1);
};
while(!WScript.StdIn.AtEndOfStream){
try{
eval(WScript.StdIn.ReadLine());
}catch(e){
print(e.message);
};
};
WScript.StdOut.WriteLine("bye!" + "\r\n");


The console.bat Launcher


@echo off
cscript console.js

A double click in latter file, and that's it, the most basic native JScript console ever has landed in your PCs - enjoy :)

Wednesday, September 02, 2009

PHP 5.3 Singleton - Fast And Abstract

In this same blog I talked different times about Singleton Pattern, in latter link "poorly" implemented in PHP 5.

I say poorly, because being Singleton a pattern, there are many ways to implement it and via PHP 5.3 things are more interesting.

There are several ways to define a Singleton class and to extend it, being able to automatically create another one that will follow that pattern.

Here is my implementation, which is extremely fast, logic, and simple as well.

<?php // Singleton :: The WebReflection Way

namespace pattern;

// this is just a pattern ...
// so no new Singleton is allowed
// thanks ot abstract definition
abstract class Singleton {

// note, no static $INSTANCE declaration
// this makes next declaration a must have
// for any extended class
// protected static $INSTANCE;

// @constructor
final private function __construct() {
// if called twice ....
if(isset(static::$INSTANCE))
// throws an Exception
throw new Exception("An instance of ".get_called_class()." already exists.");
// init method via magic static keyword ($this injected)
static::init();
}

// no clone allowed, both internally and externally
final private function __clone() {
throw new Exception("An instance of ".get_called_class()." cannot be cloned.");
}

// the common sense method to retrieve the instance
final public static function getInstance() {
// ternary operator is that fast!
return isset(static::$INSTANCE) ? static::$INSTANCE : static::$INSTANCE = new static;
}

// by default there must be an inherited init method
// so an extended class could simply
// specify its own init
protected function init(){}

}

?>


The static Trick


static is a magic keywords able to open hundreds of closed doors with old PHP versions. Thanks to this keyword it is possible to avoid a lot of redundant code, being sure that when static is called, it will be the current class call and not the one where self has been used. Thanks to this keyword is then possible to refer directly the current class instance, the one that will extend pattern\Singleton, using its own init method if preset, the empty abstract inherited otherwise.

Example



<?php

// for this test only, this class
// is in the root, same level of autoload.php

// include basic stuff ...
require_once 'autoload.php';

// define a singleton class
class SingA extends pattern\Singleton {

// my Singleton requires a
// protected static $INSTANCE variable
// if not present, nothing will
// be executed - Fatal error
protected static $INSTANCE;

// let's define something else
protected $a = 'A';
protected $b;

// let's try the init method
protected function init(){
// assign a random value to b
$this->b = rand();
}
}

// define another singleton class
class SingB extends pattern\Singleton {
protected static $INSTANCE;
}

// let's try the Singleton
$sa = SingA::getInstance();
$sb = SingB::getInstance();
$sb->runTime = 'here I am';
$sa2 = SingA::getInstance();

echo '<pre>',
var_dump($sa),
var_dump($sb),
var_dump($sa2),
var_dump($sa === $sa2),
var_dump($sa !== $sb),
'</pre>'
;

?>

Above test case will produce exatly this output:

object(SingA)#2 (2) {
["a":protected]=>
string(1) "A"
["b":protected]=>
int(31994)
}
object(SingB)#3 (1) {
["runTime"]=>
string(9) "here I am"
}
object(SingA)#2 (2) {
["a":protected]=>
string(1) "A"
["b":protected]=>
int(31994)
}
bool(true)
bool(true)

assuming the file autoload.php is present in the same level:

<?php

// simple autoload function
spl_autoload_register(function($class){

// assuming this file is in the root
// (just as example)
require __DIR__.
DIRECTORY_SEPARATOR.
// fix namespace separator ...
str_replace(
'\\',
DIRECTORY_SEPARATOR,
$class
).
// add classes suffix
'.class.php'
;
});

// that's it

?>


Why This Is Faster, Why This Is Better


The reason I posted about my own PHP 5.3 implementation is a php mailing list discussion which pointed to another extended Singleton for PHP 5.3.
That implementation will perform for each getInstance() call a callback which aim is to discover the class caller, get_called_class(), plus 2 up to 3 lookups plus an assignment over a static associative array, self::$instance[$class].
Finally, even if it could not make sense, extended Singleton classes cannot access to their own Singleton instances, aka: less control and overhead being Singleton a truly common pattern.
At least you know there is an alternative which aim is to let us remember that a singleton is a unique instance, the one we need to define as protected $INSTANCE, and that performances are always welcome, at least in my daily code/life style.

Enjoy!

Tuesday, September 01, 2009

94 bytes to quickly get a var type

I surpassed myself for the third time but I tweeted too much about, so here a quick one ;)

// was getClassName but people prefer type
// while kangax prefers var
var type=(function(s,u){return function(o){return o==u?""+o:s.call(o).slice(8,-1)}})({}.toString);