Prototype based PHP
Another proof of concept, using PHP this time :
class Proto {
private $elems;
private $proto;
function __construct($proto = null) {
$this->elems = array ();
$this->proto = $proto;
}
function __set($name, $value) {
$this->elems[$name] = $value;
}
function __get($name) {
if ($this->elems[$name])
return $this->elems[$name];
else
if ($this->proto)
return $this->proto->$name;
else
return null;
}
function __call($name, $args) {
if ($this->elems[$name] && is_callable($this->elems[$name]))
{
array_unshift($args, $this);
return call_user_func_array($this->elems[$name], $args);
}
else
return null;
}
}
?>
The idead is completely different from the OCaml implementation. This time we use the magical methods to do whatever we want. Here is yesterday's example :
function write ($s) { echo $s; }
function method ($args,$body) { return create_function('$self,'.$args, $body); }
header('Content-Type:text/plain');
$p = new Proto;
$p->foo = 'p.foo';
$p->baz = 'p.baz';
$o = new Proto($p);
$o->foo = 'o.foo';
$o->bar = method('$f', '$f($self->baz);');
echo $p->foo, "\n";
echo $p->baz, "\n";
echo $o->foo, "\n";
$o->bar('write');
?>
There are several differences here too. First, echo is a statement, not a function, so it can't be passed to a function. This is why I use this workaround with the write function. Next, because of PHP's scoping, there is no direct access to the global variable $foo without calling global $foo;), I decided to $self as the first argument of all methodes and to bind it to the current element (this is actually how JavaScript works);
There are not much differences though…
Leave a Reply