Monday, April 7, 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:


// 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 6, 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.

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 5, 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:

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 :)