This is both an update and a news about my little Phomet project.
I am sorry because I have not found time to write better examples or to explain possibilities as well, but I am sure you would like to know that now the project is called Phico (click there to download them)
See you as soon as possible to talk again about Phico :geek:
behind the design
My JavaScript book is out!
Don't miss the opportunity to upgrade your beginner or average dev skills.
Sunday, April 27, 2008
Monday, April 21, 2008
Phomet - PHP Comet tiny library
Comet is a particular technique to interact asyncronously with the client.
Instead of perform a lot of calls using Ajax (polling) the server is able to send to client, whenever it wants, a generic response.
Unfortunately in the PHP world there's no simple way to implement this kind of technique and I'll write more posts to explain better how to implement this library and what is generally possible to do, or not possible yet, with Comet idea inside a dedicated PHP environment.
At the moment, the only thing you can do is read documentation inside JavaScript and PHP files (truly few lines) and test the first basic example, a server side clock in less than 30 lines of mixed code.
As last information, Phomet comes with all necessary to be optimized on client, and its final result is about 1.57Kb on client, and ridiculously 4.52 Kb on server, comments included :)
Here is the download, unpack them into your localhost, and go into phomet folder to view the first demo.
Compatibility? I've tested them with IE6, 7, 8, Opera 9, FireFox 1.5, 2, 3, Safari 3 windows but I am sure there are other browsers compatible.
I am waiting for your suggestions, bugs, opinions, whatever :D
Cheers, and please stay tuned for next Comet appointments :geek:
Instead of perform a lot of calls using Ajax (polling) the server is able to send to client, whenever it wants, a generic response.
Unfortunately in the PHP world there's no simple way to implement this kind of technique and I'll write more posts to explain better how to implement this library and what is generally possible to do, or not possible yet, with Comet idea inside a dedicated PHP environment.
At the moment, the only thing you can do is read documentation inside JavaScript and PHP files (truly few lines) and test the first basic example, a server side clock in less than 30 lines of mixed code.
As last information, Phomet comes with all necessary to be optimized on client, and its final result is about 1.57Kb on client, and ridiculously 4.52 Kb on server, comments included :)
Here is the download, unpack them into your localhost, and go into phomet folder to view the first demo.
Compatibility? I've tested them with IE6, 7, 8, Opera 9, FireFox 1.5, 2, 3, Safari 3 windows but I am sure there are other browsers compatible.
I am waiting for your suggestions, bugs, opinions, whatever :D
Cheers, and please stay tuned for next Comet appointments :geek:
Monday, April 14, 2008
Script Type PHP :)
Update 2008/03/15
I have removed preg_replace and added DOM classes to parse and manage, in a better way, script nodes that contain php code.
Everything inside a simple PHP 5 compatible class.
Finally, please remember that this is a layer between <?php ?> and JavaScript, and only an experiment ;)
Here you can read another example, where difference between server, output, and client, should be more clear than precedent one.
-------------------------------
This is a little experiment to emulate script tag with php.
The final result will be something like this one:
How can it be possible?
Of course, we need to include this file before we write a single character in the layout (spaces included), so basically to obtain the expected result, just save above code in a file called, for example, php_script_handler.php, and put them before the layout
The evil eval? Yes, absolutely ... but first of all, this is only a simple experiment, secondly, the page will not be sent before evaluation, so there's no way from the client side to inject malicious code.
The main problem is true interoperability between these two languages, JavaScript, and PHP, but did I say that this is only an experiment? :P
I have removed preg_replace and added DOM classes to parse and manage, in a better way, script nodes that contain php code.
Everything inside a simple PHP 5 compatible class.
Finally, please remember that this is a layer between <?php ?> and JavaScript, and only an experiment ;)
Here you can read another example, where difference between server, output, and client, should be more clear than precedent one.
<?php require 'PHPScriptHandler.php'; ?>
<html>
<head>
<title>Hello PHP World</title>
<script type="text/php" author="andr3a">
// here we are between the server and output, known as client
$hello = ucwords('hello php world');
// imagine that we would like to use a variable
// defined somewhere in the server
global $something;
// we could even include or require php files
// perform database operations and everything else
</script>
<script type="text/javascript">
onload = function(){
// here we are in the client, on window load event
alert($hello);
alert($something);
};
</script>
</head>
<body>
<?php
// here we are in the server side
// we could do what we do every day without problems
$something = '<div>Hello Body</div>';
echo $something;
?>
</body>
</html>
-------------------------------
This is a little experiment to emulate script tag with php.
The final result will be something like this one:
<html>
<head>
<title>Hello PHP World</title>
<script type="text/php">
// string
$hello = ucwords('hello php world');
// object
$o = new stdClass;
$o->test = 'hello again';
</script>
<script type="text/javascript">
onload = function(){
alert($hello);
alert($o.test);
};
</script>
</head>
<body>
</body>
</html>
How can it be possible?
<?php // 5 - PHP Script Handler Experiment - by Andrea Giammarchi
function php_script_handler($output){return stripos($output, 'type="text/php"') ? preg_replace_callback('#(?i)<script[[:space:]]+type="text/php"(.*?)>([^\a]+?)</script>#', 'php_script_parser', $output) : $output;}
function php_script_parser(){eval(end(func_get_arg(0)));return '<script type="text/javascript"'.next(func_get_arg(0)).'>'.PHP_EOL.php_script_vars(get_defined_vars()).PHP_EOL.'</script>';}
function php_script_vars($vars){foreach($vars as $key => $value)$vars[$key] = '$'.$key.'='.json_encode($value).';';return implode(PHP_EOL, $vars);}
ob_start('php_script_handler');
?>
Of course, we need to include this file before we write a single character in the layout (spaces included), so basically to obtain the expected result, just save above code in a file called, for example, php_script_handler.php, and put them before the layout
<?php require 'php_script_handler.php'; ?>
<html>
<head>
<title>Hello PHP World</title>
.... other stuff ....
The evil eval? Yes, absolutely ... but first of all, this is only a simple experiment, secondly, the page will not be sent before evaluation, so there's no way from the client side to inject malicious code.
The main problem is true interoperability between these two languages, JavaScript, and PHP, but did I say that this is only an experiment? :P
Friday, April 11, 2008
Io programming language List for JavaScript
Io is a small, prototype-based programming language. The ideas in Io are mostly inspired by Smalltalk (all values are objects, all messages are dynamic), Self (prototype-based), NewtonScript (differential inheritance), Act1 (actors and futures for concurrency), LISP (code is a runtime inspectable/modifiable tree) and Lua (small, embeddable).
This programming language is really interesting, starting from syntax, throw the entire guide.
One of its primitive type is called List, and this is a summary of this type:
A List is an array of references and supports all the standard array manipulation and enumeration methods.
It seems that List is all we need when we think about an Array of elements ... so why couldn't we have something similar in JavaScript?
// Io programming language List example
// followed by my JavaScript List implementation
a := List clone
a = List.clone()
a := list(33, "a")
a = list(33, "a")
a append("b")
a.append("b")
==> list(33, "a", "b")
a size
a.size
==> 3
a at(1)
a.at(1)
==> "a"
a atPut(2, "foo")
a.atPut(2, "foo")
==> list(33, "a", "foo", "b")
a atPut(6, "Fred")
a.atPut(6, "Fred")
==> Exception: index out of bounds
a remove("foo")
a.remove("foo")
==> list(33, "a", "b")
a atPut(2, "foo")
a.atPut(2, "foo")
==> list(33, "a", "foo", "56")
a := list(65, 21, 122)
a = list(65, 21, 122);
a foreach(i, v, write(i, ":", v, ", "))
a.foreach(function(i, v){alert(i + ":" + v + ", ")})
==> 0:65, 1:21, 2:122,
a foreach(v, v println)
a.foreach(function(v){document.writeln(v)})
==> 65
21
122
numbers := list(1, 2, 3, 4, 5, 6)
numbers = list(1, 2, 3, 4, 5, 6)
numbers select(x, x isOdd)
numbers.select(function isOdd(x){return !!(x%2)})
==> list(1, 3, 5)
numbers select(i, x, x isOdd)
numbers.select(function isOdd(i, x){return !!(x%2)})
==> list(1, 3, 5)
numbers map(x, x*2)
numbers.map(function(x){return x*2})
==> list(2, 4, 6, 8, 10, 12)
numbers map(i, x, x+i)
numbers.map(function(i, x){return x+i})
==> list(1, 3, 5, 7, 9, 11)
The map and select methods return new lists. To do the same operations in-place, you can use selectInPlace() and mapInPlace() methods.
and my implementation has mapInPlace and selectInPlace as well :)
Am I forgetting something? ... of course, the source!
P.S. because of nature of List, you can do stuff like this one:
list(1,2,3).append(4).remove(2).size;
// 3
an so on ;)
Wednesday, April 09, 2008
S.O.S. JavaScript - How to recover your stuff !!!
In this Ajax Web era there are a lot of sites that use JavaScript to perform simple or complex stuff.
Sometime, one of these site could be "not so well" programmed, specially during client-server interactions.
For example, it happens few days ago that while I was trying to post a message to another "friend", an error occurred during this operation.
The result was a beautiful fake popup with returned server error information and only a button to close them ... and I wondered what about my content? Can I try again to send them?
The answer was NO, because the SEND button has been disabled, and the worst thing is that the textarea with my message was disabled as well.
I wasn't able to get my message content again because of some client/server error and some bad logic in the client side. What could we do in these cases?
Reading the source? ... uhm, content wasn't there ...
Using firebug? Maybe, but content could not be there as well ...
Press F5 and reload the page? ... ok, but why should we loose our content in this way? What I mean, I wasted my time to write that message and why on heart should I spend twice ... ok, ok, here I come with these "stupid" links:
If you bookmark these links, dragging them in your Browser Bookmarks area, you will be able in 90% of cases to enable again the blocked page.
Basically, I created the first one (runtime and in few seconds), Enable Area, to get my content that was inside the disabled textarea, to refresh the page and try the entire operation without loosing whatever I wrote before.
The simple used code is this one:
and the difference between those links is only in the sent parameter, the first is the string textarea, the second is the string input, and finally the third one is the string button.
These links, and this code, are compatible with every browser that supports javascript uris (so, basically, every recent browser where recent means since some year ago ...)
Finally, in this way we use JavaScript to help us with pages that have problems with JavaScript, sounds weird? :D
Sometime, one of these site could be "not so well" programmed, specially during client-server interactions.
For example, it happens few days ago that while I was trying to post a message to another "friend", an error occurred during this operation.
The result was a beautiful fake popup with returned server error information and only a button to close them ... and I wondered what about my content? Can I try again to send them?
The answer was NO, because the SEND button has been disabled, and the worst thing is that the textarea with my message was disabled as well.
I wasn't able to get my message content again because of some client/server error and some bad logic in the client side. What could we do in these cases?
Reading the source? ... uhm, content wasn't there ...
Using firebug? Maybe, but content could not be there as well ...
Press F5 and reload the page? ... ok, but why should we loose our content in this way? What I mean, I wasted my time to write that message and why on heart should I spend twice ... ok, ok, here I come with these "stupid" links:
- Update
CTAPbIu_MABP gave me a suggestion to write an all in one version, keep it ;)
Enable All - Enable Areas
- Enable Inputs
- Enable Buttons
- Enable Select
If you bookmark these links, dragging them in your Browser Bookmarks area, you will be able in 90% of cases to enable again the blocked page.
Basically, I created the first one (runtime and in few seconds), Enable Area, to get my content that was inside the disabled textarea, to refresh the page and try the entire operation without loosing whatever I wrote before.
The simple used code is this one:
(function(A,G){A=document.getElementsByTagName(A);G=A.length;while(G--)A[G].disabled=!A})("textarea")
and the difference between those links is only in the sent parameter, the first is the string textarea, the second is the string input, and finally the third one is the string button.
These links, and this code, are compatible with every browser that supports javascript uris (so, basically, every recent browser where recent means since some year ago ...)
Finally, in this way we use JavaScript to help us with pages that have problems with JavaScript, sounds weird? :D
Tuesday, April 08, 2008
Famous documentation and the dark side of "this" !
The good thing of internet is that you can find a lot of free documentation.
At the same time, the bad thing of internet, is that this documentation is rarely updated.
It could be a "guru documentation" or it could be a newbie documentation, but in both cases, it doesn't matter because it is probably wrong, not updated, or too generic.
This post has not enough space to describe every error you can find on, and off line ... so let me start with some true example about a common misunderstood referer, the this one.
This page is famous enough, and I suppose that every true JavaScript developer has read them at least once.
The main error in that page is described in this sentence
We know, or maybe we don't, that everything without a prefix will be executed in the global scope or in nested closure, if any. But even if a function is created inside a method, it fortunately does not make sense to call a function that has not been assigned as instance method and find a this reference inside.
The main reason we do not need to use window when we call a global method, or function, is that everything in JavaScript is virtually executed like in a global window with statement (that's why write window.open is redundant and nothing else ... and Stargate code is totally redundant too :D).
Let's focus on the onload example in the middle ... ok? Who will be the this referer if we do not use call or apply Function.prototype methods? window, of course.
And as window has a self property, that a link to window itself, if we use alert(this === self); it will be true every time we will use onload();
If we assign onload function as object method
... we will read two alerts with two false instead of two true value.
This simply means that to use a function that has not been assigned as method, or better, that is not called from a method, the this reference will be the global object.
I do not really know why Doug defined this an error in ECMA Specification, but if it really is, what could be the logic behaviour, an "unpredictable" default this referer even if the nested function is not inside an instance constructor?
I don't think so.
Thanks to this "error", we could use a constructor in two ways or recognize when it has been called with new or as function.
If it is an error, it couldn't be possible to know this kind of useful information.
Anyway, as I wrote in my recent and updated documentation, that passed totally unobserved, we do not need a that variable for nested private function.
Finally, I have to admit that Douglas Crockford is my favourite JavaScript professor, and it's basically thanks to him that I know what I know about JavaScript. He wrote a lot of interesting JS stuff, and some document is truly updated, explaining for example errors wrote in old one.
Every programmer should evolve because in this sector knowledge is never enough. So thanks a lot Doug, but please update your 2001 doc writing something more about this, that, scope, injected this, and closures :D (a link to this post should be appreciated as well)
Differently, here we are in late 2007 ... December 2007
For some reason, few days ago someone posted again this book in Digg ... and for the first time, I read about them.
It seems to be really a good book, but without reading them, I've just downloaded examples trying to imagine what are these used for.
Fortunately, and thanks to Apress or authors decision, these sources are free and well organized inside chapter folders, each file with dedicated paragraph.
Well done ... but at the third chapter, I've read a pseudo "horror" in file 3.07 ...
Forgetting the missed = function, that could be a common error during quick development, getUPPER_BOUND is a privileged method of the global scope, aka window, and it is not static, it is like a window.getUPER_BOUND call, where this is obviously the window itself.
As I wrote few lines before, if we use this inside a function it will refer to window object. That's why after we can see a wrong example like this one:
I am pretty sure that if this code is the one showed to explain privileged, that chapter could be full of errors ... please update them putting correct code and free corrected page inside the zip ... otherwise, sorry for this correction.
Finally, Dustin and Ross are two JavaScript ninjas, and reading the rest of the code it seems that I absolutely need to find that book because I do like design patterns and I am so curious to know how are their implementation (good stuff guys!).
I am the first one that writes horrible code, and probably I've even forgot what I wrote one year ago and where ... so the only suggestion I could write is that if you find something interesting, or something that you did not know, look for something else and look every time for the date that document has been published.
Have fun with self instruction, and never stop ;)
At the same time, the bad thing of internet, is that this documentation is rarely updated.
It could be a "guru documentation" or it could be a newbie documentation, but in both cases, it doesn't matter because it is probably wrong, not updated, or too generic.
This post has not enough space to describe every error you can find on, and off line ... so let me start with some true example about a common misunderstood referer, the this one.
Douglas Crockford and Private Members in JavaScript
This page is famous enough, and I suppose that every true JavaScript developer has read them at least once.
The main error in that page is described in this sentence
By convention, we make a private that parameter. This is used to make the object available to the private methods. This is a workaround for an error in the ECMAScript Language Specification which causes this to be set incorrectly for inner functions.
We know, or maybe we don't, that everything without a prefix will be executed in the global scope or in nested closure, if any. But even if a function is created inside a method, it fortunately does not make sense to call a function that has not been assigned as instance method and find a this reference inside.
// guys, this function ...
window.testMe = function(){};
// is exactly the same of this one
function testMe(){};
// or this one in a global scope
var testMe = function(){};
The main reason we do not need to use window when we call a global method, or function, is that everything in JavaScript is virtually executed like in a global window with statement (that's why write window.open is redundant and nothing else ... and Stargate code is totally redundant too :D).
// this code ...
window.onload = function(){};
// is exactly the same of this one
onload = function(){};
onload();
// that is virtually similar to ...
with(window){
onload();
};
Let's focus on the onload example in the middle ... ok? Who will be the this referer if we do not use call or apply Function.prototype methods? window, of course.
And as window has a self property, that a link to window itself, if we use alert(this === self); it will be true every time we will use onload();
If we assign onload function as object method
onload = function(){
alert(this === self);
alert(this === window);
};
var o = {};
o.onload = onload;
... we will read two alerts with two false instead of two true value.
This simply means that to use a function that has not been assigned as method, or better, that is not called from a method, the this reference will be the global object.
onload = function(){
alert(this === window);
};
onload(); // true
var o = {onload:onload};
o.onload(); // false
function useCallback(callback){
callback();
};
useCallback(o.onload); // false again
I do not really know why Doug defined this an error in ECMA Specification, but if it really is, what could be the logic behaviour, an "unpredictable" default this referer even if the nested function is not inside an instance constructor?
I don't think so.
The intrinsic constructor Factory Design Pattern
Thanks to this "error", we could use a constructor in two ways or recognize when it has been called with new or as function.
If it is an error, it couldn't be possible to know this kind of useful information.
function Person(name, age){
// this is true only if we used
// new before Person constructor
if(this instanceof Person){
this.name = name;
this.age = age;
} else
// otherwise we used the constructor
// as factory design pattern (in this example)
return new Person(name, age);
};
// these two lines do the same thing: create a Person instance
var me = Person("Andrea", 29), // doyou like python style, don't you?
you = new Person("You", null);
alert(me instanceof Person); // true
alert(you instanceof Person); // true
Anyway, as I wrote in my recent and updated documentation, that passed totally unobserved, we do not need a that variable for nested private function.
function Person(name, age){
function setNameAndAge(){
this.name = name;
this.age = age;
};
// to call setNameAndAge as private
// method we do not need a that
// but only call or apply Function.prototype
// methods to inject instance as this referer
setNameAndAge.call(this);
};
alert(
(new Person("Andrea", 29)).name // Andrea
);
Finally, I have to admit that Douglas Crockford is my favourite JavaScript professor, and it's basically thanks to him that I know what I know about JavaScript. He wrote a lot of interesting JS stuff, and some document is truly updated, explaining for example errors wrote in old one.
My programming style has evolved since then, as any good programmer's should. I have learned to fully embrace prototypalism, and have liberated myself from the confines of the classical model.
Every programmer should evolve because in this sector knowledge is never enough. So thanks a lot Doug, but please update your 2001 doc writing something more about this, that, scope, injected this, and closures :D (a link to this post should be appreciated as well)
Ross and Dustin in Pro JavaScript Design Patterns
Differently, here we are in late 2007 ... December 2007
For some reason, few days ago someone posted again this book in Digg ... and for the first time, I read about them.
It seems to be really a good book, but without reading them, I've just downloaded examples trying to imagine what are these used for.
Fortunately, and thanks to Apress or authors decision, these sources are free and well organized inside chapter folders, each file with dedicated paragraph.
Well done ... but at the third chapter, I've read a pseudo "horror" in file 3.07 ...
var Class = (function() {
// Constants (created as private static attributes).
var UPPER_BOUND = 100;
// Privileged static method.
// ... that will never work, where is the function?
this.getUPPER_BOUND() {
return UPPER_BOUND;
}
// Return the constructor.
return function(constructorArgument) {
//
}
})();
Forgetting the missed = function, that could be a common error during quick development, getUPPER_BOUND is a privileged method of the global scope, aka window, and it is not static, it is like a window.getUPER_BOUND call, where this is obviously the window itself.
As I wrote few lines before, if we use this inside a function it will refer to window object. That's why after we can see a wrong example like this one:
var Class = (function() {
var constants = {
UPPER_BOUND: 100,
LOWER_BOUND: -100
}
// again ...
this.getConstant = function(name) {
return constants[name];
}
return function(constructorArgument) {
//...
}
})();
// anyway ... Error!!!
Class.getConstant('UPPER_BOUND');
alert(Class.getConstant); // undefined
alert(getConstant); // expected function
I am pretty sure that if this code is the one showed to explain privileged, that chapter could be full of errors ... please update them putting correct code and free corrected page inside the zip ... otherwise, sorry for this correction.
Finally, Dustin and Ross are two JavaScript ninjas, and reading the rest of the code it seems that I absolutely need to find that book because I do like design patterns and I am so curious to know how are their implementation (good stuff guys!).
Conclusion
I am the first one that writes horrible code, and probably I've even forgot what I wrote one year ago and where ... so the only suggestion I could write is that if you find something interesting, or something that you did not know, look for something else and look every time for the date that document has been published.
Have fun with self instruction, and never stop ;)
Monday, April 07, 2008
Natural JavaScript private methods
I've never seen this technique yet, but basically it allows us to create private methods, without privileged, and in an way that does not allow subclasses to inherit them ... does it sound interesting? ;)
As we can read in my JavaScript Prototypal Inheritance for Classical Emulation documentation, there is a way to easily create private methods without usage of privileged.
The advantage of this way is, as explained in my doc, is that JavaScript interpreter does not have to create many functions for each declared instance.
Here there is a basic example:
Function toString will be shared by prototype with every created instance for the simple reason that every instance will inherit prototype.toString method and, at the same time, it points to private scope where toString function has been defined.
Is everything ok? Perfect, because we have to comprehend quite perfectly above example to understand what we are going to do right now ( and if you do not understand, read my doc to know more :P )
What we have to do each time is to remember that when we need a private method, with our instance injected scope, we have to write in an unnatural way.
What I mean is that if we usually use the underscore prefix to define our virtually protected methods, why couldn't we use them to define a function for private stuff only?
The difference is basically in this line of code:
Please do not forget that these methods are private, so there is no way to use them in subclasses, if those are created in an external or different closure, and that is exactly an expected behaviour (these functions are private).
But at the same time, if a subclass call an inherited method that use inside the parent prototype the private underscore, it will work perfectly.
Finally, what we can do with this method, is to redefine them to allow us to overwrite private functions and/or use them without problems:
That's it :)
As we can read in my JavaScript Prototypal Inheritance for Classical Emulation documentation, there is a way to easily create private methods without usage of privileged.
The advantage of this way is, as explained in my doc, is that JavaScript interpreter does not have to create many functions for each declared instance.
Here there is a basic example:
// our constructor
function Person(name, age){
this.name = name;
this.age = age;
};
// prototype assignment
Person.prototype = (function(){
// we have a scope for private stuff
// created once and not for every instance
function toString(){
return this.name + " is " + this.age;
};
// create the prototype and return them
return {
// never forget the constructor ...
constructor:Person,
// "magic" toString method
toString:function(){
// call private toString method
return toString.call(this);
}
};
})();
// example
alert(
new Person("Andrea", 29)
); // Andrea is 29
Function toString will be shared by prototype with every created instance for the simple reason that every instance will inherit prototype.toString method and, at the same time, it points to private scope where toString function has been defined.
Is everything ok? Perfect, because we have to comprehend quite perfectly above example to understand what we are going to do right now ( and if you do not understand, read my doc to know more :P )
What we have to do each time is to remember that when we need a private method, with our instance injected scope, we have to write in an unnatural way.
What I mean is that if we usually use the underscore prefix to define our virtually protected methods, why couldn't we use them to define a function for private stuff only?
// our constructor
function Person(name, age){
this.name = name;
this.age = age;
};
// prototype assignment
Person.prototype = (function(){
// private stuff
function toString(){
return this.name + " is " + this.age;
};
// prototype
return {
constructor:Person,
toString:function(){
// call private toString method
// in a more natural way
return this._(toString)();
},
// define private methods dedicated one
_:function(callback){
// instance referer
var self = this;
// callback that will be used
return function(){
return callback.apply(self, arguments);
};
}
};
})();
// example
alert(
new Person("Andrea", 29)
); // Andrea is 29
The difference is basically in this line of code:
// instead of this way
return toString.call(this);
// we have this one
return this._(toString)();
Please do not forget that these methods are private, so there is no way to use them in subclasses, if those are created in an external or different closure, and that is exactly an expected behaviour (these functions are private).
But at the same time, if a subclass call an inherited method that use inside the parent prototype the private underscore, it will work perfectly.
// basic extend function
function extend(B, A){
function I(){};
I.prototype = A.prototype;
B.prototype = new I;
B.prototype.constructor = B;
B.prototype.parent = A;
};
// same stuff ...
function Person(name, age){
this.name = name;
this.age = age;
};
Person.prototype = (function(){
function toString(){
return this.name + " is " + this.age;
};
return {
constructor:Person,
toString:function(){
return this._(toString)();
},
_:function(callback){
var self = this;
return function(){
return callback.apply(self, arguments);
};
}
};
})();
// subclass
function Employee(company, name, age){
this.parent.call(this, name, age);
this.company = company;
};
extend(Employee, Person);
Employee.prototype.getFullDetails = function(){
// toString has been inherited from Person
// and it uses inside the private method
return this.toString() + " and works in " + this.company;
};
var other = new Employee("Mega Ltd", "Daniele", 26);
alert(
other.getFullDetails()
);
Finally, what we can do with this method, is to redefine them to allow us to overwrite private functions and/or use them without problems:
// above stuff + subclass
function Employee(company, name, age){
this.parent.call(this, name, age);
this.company = company;
};
extend(Employee, Person);
// extend prototype and return them
Employee.prototype = (function(proto){
function toString(){
return this.company;
};
proto.toString = function(){
return this.parent.prototype.toString.call(this) + " and works in " + this._(toString)();
};
proto._ = function(callback){
var self = this;
return function(){
return callback.apply(self, arguments);
};
};
return proto;
})(Employee.prototype);
alert(new Employee("Mega Ltd", "Daniele", 26));
// Daniele is 26 and works for Mega Ltd
That's it :)
Sunday, April 06, 2008
PHP - JavaScript like Object class
As I've wrote in last post, there's some JavaScript feature I would like to have in PHP too.
This time we will use a basic implementation of JavaScript Object constructor in PHP.
What we need to start is this class, based on SPL ArrayAccess interface.
The main goal of this class is to have a JS like literal object, and in this reduced version, with best possible performances for this kind of purpose.
Here is some example:
These instances are simple as useful and could be used instead of associative arrays.
The class contains 3 public static methods to perform common task during client/server interactions.
One of the common PHP error is to access to an associative array propery sending undefined constants instead of strings.
Of course, using associative wrong way to retrieve a property will cause a notice error again, but having the common instance "->" operator, why should we cause that notice?
Another interesting thing could be the usage of dynamic instances, and the ability to add methods (not possible with associative arrays) or use current one to share, save, or send these instances.
To have these functionalities in every day applications, we could think about this simple task:
Of course, you can find a lot of different common situation where this kind of class could be useful, don't you?
This time we will use a basic implementation of JavaScript Object constructor in PHP.
What we need to start is this class, based on SPL ArrayAccess interface.
class Object extends stdClass implements ArrayAccess {
// (C) Andrea Giammarchi - webreflection.blogspot.com - Mit Style License
// static public methods
static public function create(){
return new Object;
}
static public function parseJSON($json){
return self::create()->extend(json_decode($json));
}
static public function parseSource($source){
return self::create()->extend(unserialize($source));
}
// basic JavaScript like methods
public function extend(){
for($i = 0, $length = count($arguments = func_get_args()); $i < $length; $i++)
foreach($arguments[$i] as $key => $value)
$this->$key = $value;
return $this;
}
public function toJSONString(){
return json_encode($this);
}
public function toSource(){
return serialize($this);
}
// ArrayAccess interface methods
public function offsetExists($key){
return isset($this->$key);
}
public function offsetGet($key){
return $this->$key;
}
public function offsetSet($key, $value){
$this->$key = $value;
}
public function offsetUnset($key){
unset($this->$key);
}
}
The main goal of this class is to have a JS like literal object, and in this reduced version, with best possible performances for this kind of purpose.
Here is some example:
$o = new Object;
$o->test = "test";
echo $o->test === $o['test']; // 1
$o['other_test'] = 123;
echo $o->other_test; // 123
These instances are simple as useful and could be used instead of associative arrays.
The class contains 3 public static methods to perform common task during client/server interactions.
// factory pattern
$o = Object::create();
// factory with serialized string
$o = Object::parseSource(serialize(array('A'=>'A')));
echo $o->A; // A
// factory with JSON string
$o = Object::parseJSON('{"B":"B"}');
echo $o->B; // B
One of the common PHP error is to access to an associative array propery sending undefined constants instead of strings.
$a = array('A'=>'A');
echo $a[A]; // notice, defined constant possible ambiguity
// factory + extend
$o = Object::create()->extend($a);
// we have two ways to access to the same property
echo $o->A; // OK, output is A
echo $o['A']; // OK again ...
Of course, using associative wrong way to retrieve a property will cause a notice error again, but having the common instance "->" operator, why should we cause that notice?
Another interesting thing could be the usage of dynamic instances, and the ability to add methods (not possible with associative arrays) or use current one to share, save, or send these instances.
$me = new Object;
$me->name = 'Andrea';
$me->surname = 'Giammarchi';
$me->age = 29; // ... still ...
// simple interaction
echo '';';
foreach($me as $key => $value)
echo $key."\t".$value.PHP_EOL;
echo '
// or JSON / PHP serializzation
echo // {"name":"Andrea","surname":"Giammarchi","age":29}
$me->toJSONString().
PHP_EOL.
// O:6:"Object":3:{s:4:"name";s:6:"Andrea";s:7:"surname";s:10:"Giammarchi";s:3:"age";i:29;}
$me->toSource();
To have these functionalities in every day applications, we could think about this simple task:
$result = array();
$query = mysql_unbuffered_query(
'SELECT t.name AS "name", t.surname AS "surname", t.age AS "age" FROM table t',
$connection
);
while(@$row = mysql_fetch_assoc($query))
$result[] = Object::create()->extend($row);
echo 'First person name is '.$result[0]->name;
Of course, you can find a lot of different common situation where this kind of class could be useful, don't you?
Saturday, April 05, 2008
PHP - apply, call, and Callback class
The "news" is that while some developer is putting a lot of effort to emulate PHP functionalities with JavaScript, I would like to have JavaScript functionalities in PHP.
Nested functions, closures, and injected scope, are only some of JS cool stuff that's currently missing PHP (hoping that during this summer of code someone will implement at least one of them).
Today what I'm going to emulate is a partial implementation of apply and call Function.prototype methods, and this is the basic example:
As is for JavaScript, the main difference between these functions is that apply accept an array of arguments while call accepts an arbitrary number of arguments.
Simple, but not so useful yet.
Currently, these implementations are just shortcuts to call_user_func or call_user_func_array PHP native functions ... and these are not JavaScript style friendly ... so what could we do?
To have a JS style code we would like to be able to write something like this:
... and I suppose noone could say that this way couldn't be cool, isn't it?
To obtain above behavior all we need is a class, called for obvious reasons Callback, that will contain those 2 public static methods:
What we can do now, is to create every kind of function alias simply sending the name of the function or arguments and body for a runtime function creation.
The public name property will contain the string rappresenting the used function name (lambda too), while the magic __toString method will return the name using dedicated ReflectionFunction isntance method (note: lambda functions have everytime the same one: __lambda_func).
With a simple class like this one we are able to send or recieve callbacks between functions, methods, or whatever else ... have you never sent a function in this way?
The principal goal is to solve type checks and improve code portability ... but with another little piece of code, this stuff could be even funny!
With above function we are now able to do something like:
Or, to be extremely scriptish, something like:
Enjoy :)
Nested functions, closures, and injected scope, are only some of JS cool stuff that's currently missing PHP (hoping that during this summer of code someone will implement at least one of them).
Today what I'm going to emulate is a partial implementation of apply and call Function.prototype methods, and this is the basic example:
function apply($name, array $arguments = array()){
return call_user_func_array($name, $arguments);
}
function call(){
$arguments = func_get_args();
return call_user_func_array(array_shift($arguments), $arguments);
}
As is for JavaScript, the main difference between these functions is that apply accept an array of arguments while call accepts an arbitrary number of arguments.
echo call('md5', 'hello world');
// 5eb63bbbe01eeed093cb22bb8f5acdc3
echo apply('pow', array(2, 3));
// 8
Simple, but not so useful yet.
Currently, these implementations are just shortcuts to call_user_func or call_user_func_array PHP native functions ... and these are not JavaScript style friendly ... so what could we do?
To have a JS style code we would like to be able to write something like this:
$md5->call('hello world');
$pow->apply(array(2, 3));
... and I suppose noone could say that this way couldn't be cool, isn't it?
To obtain above behavior all we need is a class, called for obvious reasons Callback, that will contain those 2 public static methods:
class Callback{
// (C) webreflection.blogspot.com - Mit Style License
public $name; // name of the function
protected $_callback; // ReflectionFunction instance
public function __construct($arguments, $callback = ''){
$this->_callback = new ReflectionFunction(
0 < strlen($arguments) &&
strlen($callback) < 1 &&
is_callable($arguments) &&
function_exists($arguments) ?
$this->name = $arguments :
$this->name = ''.create_function($arguments, $callback)
);
}
public function __toString(){
return $this->_callback->getName();
}
public function apply(array $arguments){
return $this->_callback->invokeArgs($arguments);
}
public function call(){
// /* simple, unfornutatly with bad performances */ return $this->apply(func_get_args());
return $this->_callback->invokeArgs(func_get_args());
}
}
What we can do now, is to create every kind of function alias simply sending the name of the function or arguments and body for a runtime function creation.
$md5 = new Callback('md5');
$pow = new Callback('pow');
$sum = new Callback('$x, $y', 'return $x + $y;');
echo $md5->call('hello world').PHP_EOL; // 5eb63bbbe01eeed093cb22bb8f5acdc3
echo $pow->apply(array(2, 3)).PHP_EOL; // 8
echo $sum->call(2, 3).PHP_EOL; // 5
The public name property will contain the string rappresenting the used function name (lambda too), while the magic __toString method will return the name using dedicated ReflectionFunction isntance method (note: lambda functions have everytime the same one: __lambda_func).
With a simple class like this one we are able to send or recieve callbacks between functions, methods, or whatever else ... have you never sent a function in this way?
function hashMe($value, Callback $hash){
return $hash->call($value);
}
$md5 = new Callback('md5');
$sha1 = new Callback('sha1');
echo hashMe('hello world', $md5).
PHP_EOL.
hashMe('hello world', $sha1);
// 5eb63bbbe01eeed093cb22bb8f5acdc3
// 2aae6c35c94fcfb415dbe95f408b9ce91ee846ed
The principal goal is to solve type checks and improve code portability ... but with another little piece of code, this stuff could be even funny!
// Callback dedicated factory pattern function
function callback(){
static $Callback;
if(!isset($Callback))
$Callback = new ReflectionClass('Callback');
return $Callback->newInstanceArgs(func_get_args());
}
With above function we are now able to do something like:
echo callback('str_repeat')->call('hello world ', 2);
// hello world hello world
Or, to be extremely scriptish, something like:
// create a string with "callback" content
$F = 'callback';
// use them as a function
echo $F('str_repeat')->call('hello world ', 2);
echo $F('pow')->call(2, 3);
// but if we need better performances ...
$md5 = $F('md5');
while($i--)
echo $md5->call($container[$i]);
Enjoy :)
Subscribe to:
Posts (Atom)