Thursday, March 22, 2007

PHP 5 static keyword feature - Part 2

To explain better what did I mean when I talked about static keyword problems, here is some code examples (same result with different languages)

C# (Console Application)

using System;
namespace ConsoleApplication1{

public class StaticString{
private String str;
public StaticString(String str){
this.str = str;
}
public String getString(){
return str;
}
public void write(){
str += " from instance";
StaticString.write(this);
}
public static void write(StaticString what){
Console.WriteLine(what.getString());
}

}

class Program{
static void Main(string[] args){
StaticString ss = new StaticString("Hello World!");
StaticString.write(ss); // I have a static method to do something
ss.write(); // and an instance method to do something else
Console.ReadLine();
}
}
}


ActionScript 2.0

class StaticString { // StaticString.as

// generic public instance method
public function getString(Void):String {
return str;
}

// generic public class static method (correctly not inherited)
public static function write(what:StaticString):Void {
trace(what.getString());
}

/*
// AS 2.0 doesn't accept methods overload
// ... however, this is not a method overload
// this should be an instance method (not a class method)
public function write(Void):Void {
StaticString.write(this);
}
// */

// You could solve this problem ... how ?
// Using a sort of bug (lol)

public var str:String;

// public constructor
public function StaticString(str:String) {
this.str = str;

// AS 2 "bug"
this["write"] = function(Void):Void{
StaticString.write(this);
}
}
}
/* // Test them!
import StaticString
var ss:StaticString = new StaticString('Hello World!');
StaticString.write(ss);
ss["write"]();
// */


JavaScript (!!!)

function StaticString(str){
this.getString = function(){
return str;
};
this.write = function(){
str += " from instance";
StaticString.write(this);
};
if(!StaticString.write)
StaticString.write = function(StaticString){
alert(StaticString.getString())
};
}(new StaticString);

ss = new StaticString("Hello World!");
StaticString.write(ss);
ss.write();


And finally ... what I was doing with PHP before the feature

class StaticString{
private $str;
public final function __construct($str){
$this->str = $str;
}
public final function __call($method, $values){
switch($method) {
case 'write':
$this->str .= ' from instance';
StaticString::write($this);
break;
}
}
public function getString(){
return $this->str;
}
public static function write(StaticString $what){
echo $what->getString(), '<br />';
}
}

$ss = new StaticString("Hello World!");
StaticString::write($ss);
$ss->write(); // Catchable fatal error:
// Argument 1 passed to StaticString::write() must be an instance of StaticString
// none given (hey PHP, I didn't call static class method !)


C++ should be able to do the same thing using overload as C# example.
Instances will inherit static method too but this will not be a problem.

Probably Java and many other languages can do something like these example ... while with PHP You can't.

I don't know about Python overload and specific problem solution, I think Python will have a solution.

Finally, this limit is efficent and simple way to code ... as PHP 5 developers said ... come on guys, I like very much PHP since version 4, but if You implement something, please, do it correctly!

No comments:

Post a Comment