RE: [PHP-DEV] [patch] Late static bindings (LSB)

2007-10-01 Thread Dmitry Stogov
Hi Robin,

Thank you for catching this issue.
static:: make no sense in compile-time constants.
I've just forbidden it there.

Thanks. Dmitry.



 -Original Message-
 From: Robin Fernandes [mailto:[EMAIL PROTECTED] 
 Sent: Friday, September 28, 2007 6:45 PM
 To: internals@lists.php.net
 Cc: Stanislav Malyshev; Baptiste Autin; Zoe Slattery; Dmitry 
 Stogov; Marcus Boerger; Lukas Kahwe Smith; Michael Lively; 
 Etienne Kneuss; Andi Gutmans
 Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB)
 
 
 Sorry to persist with this, but I think it could be really 
 useful to clarify the meaning of static:: outside of method 
 bodies... particularly since parent:: and self:: can already 
 behave very strangely in such scenarios (see 
 http://news.php.net/php.internals/32443 ).
 
 For example, I find the following behaviour with the current patch
 counter-intuitive:
 
 ?php
 // NOTE: X is not related to A.
 class X  {
   const MY_CONST = I am completely unrelated to class A.;
   static function createA() {
 new A;  // triggers initialiser evaluation
   }
 }
 
 class A {
   const MY_CONST = const A;
   public $p = static::MY_CONST;
   static function getInstance() {
 return new A;
   }
 }
 
 // First instantiate A inside X. This causes A's properties'
 // default values to be evaluated within X's scope. X::createA();
 
 // Now that A's default values have been evaluated,
 // behaviour is as if any new instance of A treats
 // the occurrence of static:: on line 12 to mean X.
 
 // Instantiate A inside A:
 $a = A::getInstance();
 var_dump($a-p);// has value of X::MY_CONST.
 
 // Instantiate A at global scope:
 $a = new A();
 var_dump($a-p);// has value of X::MY_CONST.
 ?
 
 Actual output:
 string(37) I am completely unrelated to class A.
 string(37) I am completely unrelated to class A.
 
 
 Some thoughts:
  - static:: could simply be forbidden in all class 
 property/constant default values.
  - Any occurrences of static:: in instance property default 
 values could behave as if they were in the constructor, but 
 be forbidden in static property and constant initialisers.
  - Other ideas?
 
 
 Also, there are some questions around reflection. All of the following
 A::reflect*() calls cause a fatal error like:
   PHP Fatal error:  Undefined class constant 'MY_CONST' in %s 
 on line %d
 
 ?php
 class A {
   const MY_CONST = const A;
   const C1 = static::MY_CONST;
 
   static function f($a = static::MY_CONST) {
 return $a;
   }
 
   static function f2() {
 static $x = static::MY_CONST;
   }
 
 
   static function reflectConst() {
 $rc = new ReflectionClass('A');
 var_dump($rc-getConstant('C1'));
   }
 
   static function reflectArg() {
 $rm = new ReflectionMethod('A::f');
 $rps = $rm-getParameters();
 var_dump($rps[0]-getDefaultValue());
   }
 
   static function reflectStat() {
 $rm = new ReflectionMethod('A::f2');
 var_dump($rm-getStaticVariables());
   }
 
 }
 
 A::reflectConst(); // fatal error
 A::reflectArg();   // fatal error
 A::reflectStat();  // fatal error
 ?
 
 Is this desirable? One could argue that the reflection calls 
 emanate from A::, so static:: could be resolved accordingly. 
 This test case suggests that static:: is in fact being bound 
 to the ReflectionClass class itself (since 
 ReflectionClass::IS_FINAL===64) :
 
 ?php
 class A {
   const IS_FINAL = This string is not integer sixty-four;
   const C1 = static::IS_FINAL;
 }
 
 $rc = new ReflectionClass('A');
 $rc-getConstant('C1');  // trigger evaluation of A::C1
 
 var_dump(A::C1);
 ?
 
 Actual output:
 int(64)
 
 
 Kind regards,
 Robin
 
 On 27/09/2007, Jingcheng Zhang [EMAIL PROTECTED] wrote:
  Hello,
  static methods seem exactly like dynamic binded methods now, is 
  there any chance that abstract static function being 
 restored from 
  E_STRICT limitation? Currently it is allowed in interfaces, but 
  forbidden in abstract class, I don't know why php 
 implements static 
  method in this way, this seems strange.. Thanks!
 
  On 9/27/07, Stanislav Malyshev [EMAIL PROTECTED] wrote:
  
So, if I understand you well, Stanislas, you are personally not 
much
   into
static:: but more into making that sort of code working :
   
interface iC {
  public $structure;
}
abstract class A implements iC {
  public function display() {
  echo self::$structure;
  }
}
class B extends A {
  static public $structure = This is a string.;
}
$b = new B();
$b-display();
  
   No, I don't think we should make interfaces with 
 variables, I'm just 
   telling that the code before had API that not allowed correctly 
   enforce its requirements.
   --
   Stanislav Malyshev, Zend Software Architect
   [EMAIL PROTECTED]   http://www.zend.com/
   (408)253-8829   MSN: [EMAIL PROTECTED]
  
   --
   PHP Internals - PHP Runtime Development Mailing List
   To unsubscribe, visit: http://www.php.net/unsub.php

Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-28 Thread Robin Fernandes
Sorry to persist with this, but I think it could be really useful to
clarify the meaning of static:: outside of method bodies...
particularly since parent:: and self:: can already behave very
strangely in such scenarios (see
http://news.php.net/php.internals/32443 ).

For example, I find the following behaviour with the current patch
counter-intuitive:

?php
// NOTE: X is not related to A.
class X  {
  const MY_CONST = I am completely unrelated to class A.;
  static function createA() {
new A;  // triggers initialiser evaluation
  }
}

class A {
  const MY_CONST = const A;
  public $p = static::MY_CONST;
  static function getInstance() {
return new A;
  }
}

// First instantiate A inside X. This causes A's properties'
// default values to be evaluated within X's scope.
X::createA();

// Now that A's default values have been evaluated,
// behaviour is as if any new instance of A treats
// the occurrence of static:: on line 12 to mean X.

// Instantiate A inside A:
$a = A::getInstance();
var_dump($a-p);// has value of X::MY_CONST.

// Instantiate A at global scope:
$a = new A();
var_dump($a-p);// has value of X::MY_CONST.
?

Actual output:
string(37) I am completely unrelated to class A.
string(37) I am completely unrelated to class A.


Some thoughts:
 - static:: could simply be forbidden in all class property/constant
default values.
 - Any occurrences of static:: in instance property default values
could behave as if they were in the constructor, but be forbidden in
static property and constant initialisers.
 - Other ideas?


Also, there are some questions around reflection. All of the following
A::reflect*() calls cause a fatal error like:
  PHP Fatal error:  Undefined class constant 'MY_CONST' in %s on line %d

?php
class A {
  const MY_CONST = const A;
  const C1 = static::MY_CONST;

  static function f($a = static::MY_CONST) {
return $a;
  }

  static function f2() {
static $x = static::MY_CONST;
  }


  static function reflectConst() {
$rc = new ReflectionClass('A');
var_dump($rc-getConstant('C1'));
  }

  static function reflectArg() {
$rm = new ReflectionMethod('A::f');
$rps = $rm-getParameters();
var_dump($rps[0]-getDefaultValue());
  }

  static function reflectStat() {
$rm = new ReflectionMethod('A::f2');
var_dump($rm-getStaticVariables());
  }

}

A::reflectConst(); // fatal error
A::reflectArg();   // fatal error
A::reflectStat();  // fatal error
?

Is this desirable? One could argue that the reflection calls emanate
from A::, so static:: could be resolved accordingly. This test case
suggests that static:: is in fact being bound to the ReflectionClass
class itself (since ReflectionClass::IS_FINAL===64) :

?php
class A {
  const IS_FINAL = This string is not integer sixty-four;
  const C1 = static::IS_FINAL;
}

$rc = new ReflectionClass('A');
$rc-getConstant('C1');  // trigger evaluation of A::C1

var_dump(A::C1);
?

Actual output:
int(64)


Kind regards,
Robin

On 27/09/2007, Jingcheng Zhang [EMAIL PROTECTED] wrote:
 Hello,
 static methods seem exactly like dynamic binded methods now, is there
 any chance that abstract static function being restored from E_STRICT
 limitation? Currently it is allowed in interfaces, but forbidden in abstract
 class, I don't know why php implements static method in this way, this
 seems strange.. Thanks!

 On 9/27/07, Stanislav Malyshev [EMAIL PROTECTED] wrote:
 
   So, if I understand you well, Stanislas, you are personally not much
  into
   static:: but more into making that sort of code working :
  
   interface iC {
 public $structure;
   }
   abstract class A implements iC {
 public function display() {
 echo self::$structure;
 }
   }
   class B extends A {
 static public $structure = This is a string.;
   }
   $b = new B();
   $b-display();
 
  No, I don't think we should make interfaces with variables, I'm just
  telling that the code before had API that not allowed correctly enforce
  its requirements.
  --
  Stanislav Malyshev, Zend Software Architect
  [EMAIL PROTECTED]   http://www.zend.com/
  (408)253-8829   MSN: [EMAIL PROTECTED]
 
  --
  PHP Internals - PHP Runtime Development Mailing List
  To unsubscribe, visit: http://www.php.net/unsub.php
 
 


 --
 Best regards,
 Jingcheng Zhang
 Room 304, Dormitory 26 of Yuquan Campus, Zhejiang University
 P.R.China


-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



RE: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-26 Thread Baptiste Autin
People generally prefer compile-time 
control which is derived from definition rather than per-instance 
runtime control (implementing interface vs. checking each time if class 
has certain methods).

It's me again, sorry.
So, if I understand you well, Stanislas, you are personally not much into
static:: but more into making that sort of code working :

interface iC {
public $structure;
}
abstract class A implements iC {
public function display() {
echo self::$structure;
}
}
class B extends A {
static public $structure = This is a string.;
}
$b = new B();
$b-display();


If so, what's the problem?
Is there a technical difficulty of implementation behind?
Or is it because we are unsure whether all the people asking for LSB would
be satisfied with that way?

BTW, here's a funny sort of polymorphism with static members that already
runs great with the actual PHP release:

interface iC {
function getStructure();
}
abstract class A implements iC {
public function display() {
echo $this-getStructure();
}
}
abstract class B extends A {
static public $structure = This is a string from B.;
}
class C extends B {
static public $structure = This is a string from C.;
public function getStructure() {
return self::$structure;
}
}
$c = new C();
$c-display();

Remove the definition of $structure in C, and the one in B will apply.
I suppose Michael Lively's example would be solved (the one with the
TableSelectQueries), if it could work the same way in a fully static context
(and without the help of an additional method like getStructure)
... Right ?

Baptiste

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-26 Thread Etienne Kneuss
Hello,

if I understand you correctly, you want to radically change the behavior of
self:: ?

This is not doable as it would break tons of scripts!

Regards

On 9/27/07, Baptiste Autin [EMAIL PROTECTED] wrote:

 People generally prefer compile-time
 control which is derived from definition rather than per-instance
 runtime control (implementing interface vs. checking each time if class
 has certain methods).

 It's me again, sorry.
 So, if I understand you well, Stanislas, you are personally not much into
 static:: but more into making that sort of code working :

 interface iC {
 public $structure;
 }
 abstract class A implements iC {
 public function display() {
 echo self::$structure;
 }
 }
 class B extends A {
 static public $structure = This is a string.;
 }
 $b = new B();
 $b-display();


 If so, what's the problem?
 Is there a technical difficulty of implementation behind?
 Or is it because we are unsure whether all the people asking for LSB
 would
 be satisfied with that way?

 BTW, here's a funny sort of polymorphism with static members that already
 runs great with the actual PHP release:

 interface iC {
 function getStructure();
 }
 abstract class A implements iC {
 public function display() {
 echo $this-getStructure();
 }
 }
 abstract class B extends A {
 static public $structure = This is a string from B.;
 }
 class C extends B {
 static public $structure = This is a string from C.;
 public function getStructure() {
 return self::$structure;
 }
 }
 $c = new C();
 $c-display();

 Remove the definition of $structure in C, and the one in B will apply.
 I suppose Michael Lively's example would be solved (the one with the
 TableSelectQueries), if it could work the same way in a fully static
 context
 (and without the help of an additional method like getStructure)
 ... Right ?

 Baptiste

 --
 PHP Internals - PHP Runtime Development Mailing List
 To unsubscribe, visit: http://www.php.net/unsub.php





-- 
Etienne Kneuss
http://www.colder.ch

Men never do evil so completely and cheerfully as
when they do it from a religious conviction.
-- Pascal


RE: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-26 Thread Baptiste Autin
You mean, tons of PHP scripts?
It would just allow some non-working code (fatal error) to run, by extending
the scope of self::. So what could it break?
And if you add the obligation to implement an interface (probably under-used
in PHP), it is even less likely that it raises side effects.
No ?


-Original Message-
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Etienne
Kneuss
Sent: jeudi 27 septembre 2007 01:11
To: Baptiste Autin
Cc: Stanislav Malyshev; Zoe Slattery; Dmitry Stogov; Marcus Boerger; Lukas
Kahwe Smith; Michael Lively; internals@lists.php.net; Andi Gutmans
Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB)

Hello,

if I understand you correctly, you want to radically change the behavior of
self:: ?

This is not doable as it would break tons of scripts!

Regards

On 9/27/07, Baptiste Autin [EMAIL PROTECTED] wrote:

 People generally prefer compile-time
 control which is derived from definition rather than per-instance
 runtime control (implementing interface vs. checking each time if class
 has certain methods).

 It's me again, sorry.
 So, if I understand you well, Stanislas, you are personally not much into
 static:: but more into making that sort of code working :

 interface iC {
 public $structure;
 }
 abstract class A implements iC {
 public function display() {
 echo self::$structure;
 }
 }
 class B extends A {
 static public $structure = This is a string.;
 }
 $b = new B();
 $b-display();


 If so, what's the problem?
 Is there a technical difficulty of implementation behind?
 Or is it because we are unsure whether all the people asking for LSB
 would
 be satisfied with that way?

 BTW, here's a funny sort of polymorphism with static members that already
 runs great with the actual PHP release:

 interface iC {
 function getStructure();
 }
 abstract class A implements iC {
 public function display() {
 echo $this-getStructure();
 }
 }
 abstract class B extends A {
 static public $structure = This is a string from B.;
 }
 class C extends B {
 static public $structure = This is a string from C.;
 public function getStructure() {
 return self::$structure;
 }
 }
 $c = new C();
 $c-display();

 Remove the definition of $structure in C, and the one in B will apply.
 I suppose Michael Lively's example would be solved (the one with the
 TableSelectQueries), if it could work the same way in a fully static
 context
 (and without the help of an additional method like getStructure)
 ... Right ?

 Baptiste

 --
 PHP Internals - PHP Runtime Development Mailing List
 To unsubscribe, visit: http://www.php.net/unsub.php





-- 
Etienne Kneuss
http://www.colder.ch

Men never do evil so completely and cheerfully as
when they do it from a religious conviction.
-- Pascal

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-26 Thread Stanislav Malyshev

So, if I understand you well, Stanislas, you are personally not much into
static:: but more into making that sort of code working :

interface iC {
public $structure;
}
abstract class A implements iC {
public function display() {
echo self::$structure;
}
}
class B extends A {
static public $structure = This is a string.;
}
$b = new B();
$b-display();


No, I don't think we should make interfaces with variables, I'm just 
telling that the code before had API that not allowed correctly enforce 
its requirements.

--
Stanislav Malyshev, Zend Software Architect
[EMAIL PROTECTED]   http://www.zend.com/
(408)253-8829   MSN: [EMAIL PROTECTED]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-26 Thread Jingcheng Zhang
Hello,
static methods seem exactly like dynamic binded methods now, is there
any chance that abstract static function being restored from E_STRICT
limitation? Currently it is allowed in interfaces, but forbidden in abstract
class, I don't know why php implements static method in this way, this
seems strange.. Thanks!

On 9/27/07, Stanislav Malyshev [EMAIL PROTECTED] wrote:

  So, if I understand you well, Stanislas, you are personally not much
 into
  static:: but more into making that sort of code working :
 
  interface iC {
public $structure;
  }
  abstract class A implements iC {
public function display() {
echo self::$structure;
}
  }
  class B extends A {
static public $structure = This is a string.;
  }
  $b = new B();
  $b-display();

 No, I don't think we should make interfaces with variables, I'm just
 telling that the code before had API that not allowed correctly enforce
 its requirements.
 --
 Stanislav Malyshev, Zend Software Architect
 [EMAIL PROTECTED]   http://www.zend.com/
 (408)253-8829   MSN: [EMAIL PROTECTED]

 --
 PHP Internals - PHP Runtime Development Mailing List
 To unsubscribe, visit: http://www.php.net/unsub.php




-- 
Best regards,
Jingcheng Zhang
Room 304, Dormitory 26 of Yuquan Campus, Zhejiang University
P.R.China


Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-25 Thread Robin Fernandes
On 20/09/2007, Stanislav Malyshev [EMAIL PROTECTED] wrote:

 I think we better spend time on figuring out the concept and then do the
 patch than first do the patch and then discover we don't know how it was
 supposed to work :)

Here's a question that I think hasn't been discussed and isn't covered
by the test cases in the patch: will static:: have a meaning in
property and constant declarations? e.g.:

?
class A {
 const MY_CONST = const A;
 public $p = static::MY_CONST;
}
class B extends A {
 const MY_CONST = const B;
}
$a = new A();
$b = new B();
var_dump($a::p, $b::p);
?

One reason I ask is that in php5.2, self:: and parent:: can (imho) act
counter-intuitively in property declarations. They do not always
behave as if they were bound at compile time. See test case below and
http://news.php.net/php.internals/31961 for more details.

(if these inconsistencies are bugs, please let me know and I'll
happily raise them on bugzilla)

?php
class A {
   const MY_CONST  = 'MY_CONST_A';
   public static $inheritedStatic = self::MY_CONST;
   public $inheritedProp = self::MY_CONST;
   const INHERITED_CONST = self::MY_CONST;
   public static function inheritedStaticMethod() {
  return self::MY_CONST;
   }
   public function inheritedMethod() {
  return self::MY_CONST;
   }
}
class B extends A {
   const MY_CONST  = 'MY_CONST_B';
}
echo \n Static Properties:\n;
new B; // !!! Removing this line changes behaviour !!!
echo- In A: ; var_dump(A::$inheritedStatic);
echo- In B: ; var_dump(B::$inheritedStatic);
echo \n Instance Properties\n;
$a = new A;
$b = new B;
echo- In A: ; var_dump($a-inheritedProp);
echo- In B: ; var_dump($b-inheritedProp);
echo \n Constants:\n;
echo- In A: ; var_dump(A::INHERITED_CONST);
echo- In B: ; var_dump(B::INHERITED_CONST);
echo \n Static call:\n;
echo- From A: ; var_dump(A::inheritedStaticMethod());
echo- From B: ; var_dump(B::inheritedStaticMethod());
echo \n Instance call:\n;
echo- From A: ; var_dump($a-inheritedMethod());
echo- From B: ; var_dump($b-inheritedMethod());
?


-- Actual Output on php5 --

 Static Properties:
  - In A: string(10) MY_CONST_B
  - In B: string(10) MY_CONST_B
 Instance Properties
  - In A: string(10) MY_CONST_A
  - In B: string(10) MY_CONST_B
 Constants:
  - In A: string(10) MY_CONST_A
  - In B: string(10) MY_CONST_B
 Static call:
  - From A: string(10) MY_CONST_A
  - From B: string(10) MY_CONST_A
 Instance call:
  - From A: string(10) MY_CONST_A
  - From B: string(10) MY_CONST_A


-- Expected output assuming self:: is bound at compile time --

 Static Properties:
  - In A: string(10) MY_CONST_A
  - In B: string(10) MY_CONST_A
 Instance Properties
  - In A: string(10) MY_CONST_A
  - In B: string(10) MY_CONST_A
 Constants:
  - In A: string(10) MY_CONST_A
  - In B: string(10) MY_CONST_A
 Static call:
  - From A: string(10) MY_CONST_A
  - From B: string(10) MY_CONST_A
 Instance call:
  - From A: string(10) MY_CONST_A
  - From B: string(10) MY_CONST_A



Kind regards,
Robin Fernandes

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-24 Thread Alexey Zakhlestin
On 9/24/07, Michael Lively [EMAIL PROTECTED] wrote:
 The very phrase late static binding is an oxymoron of sorts :)

that's because the term we use is not correct… :)
it would be better to say late binding of static methods

-- 
Alexey Zakhlestin
http://blog.milkfarmsoft.com/


RE: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-23 Thread Baptiste Autin

If you mean Client's $structure, the you have to use static::$structure 
and it should work. However it's quite a bad design here since you have 
no way to ensure class inheriting from Entity would have $structure.

Couldn't I write: isset(static::$structure) ?

BTW, sorry for my recent vulgar intrusions on PHP internal forum.
I know I am not skilled enough for it, I should have read more carefully
some previous posts, and I am just a big redneck.
Mea culpa :)

So this will be my very last (and so much naïve) question: do you know how
people cope with it in other OO languages?

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-23 Thread Stanislav Malyshev

Couldn't I write: isset(static::$structure) ?


You could, but that's only runtime. People generally prefer compile-time 
control which is derived from definition rather than per-instance 
runtime control (implementing interface vs. checking each time if class 
has certain methods).



So this will be my very last (and so much naïve) question: do you know how
people cope with it in other OO languages?


AFAIK there are not many languages which allow you to do non-static 
static calls... I see no way of doing it in Java or C++ - please correct 
me if I'm wrong.

--
Stanislav Malyshev, Zend Software Architect
[EMAIL PROTECTED]   http://www.zend.com/
(408)253-8829   MSN: [EMAIL PROTECTED]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-23 Thread Michael Lively


- Original Message - 
From: Stanislav Malyshev [EMAIL PROTECTED]

To: Baptiste Autin [EMAIL PROTECTED]
Cc: 'Zoe Slattery' [EMAIL PROTECTED]; 'Dmitry Stogov' 
[EMAIL PROTECTED]; 'Marcus Boerger' [EMAIL PROTECTED]; 'Lukas Kahwe Smith' 
[EMAIL PROTECTED]; 'Michael Lively' [EMAIL PROTECTED]; 'Etienne 
Kneuss' [EMAIL PROTECTED]; internals@lists.php.net; 'Andi Gutmans' 
[EMAIL PROTECTED]

Sent: Sunday, September 23, 2007 3:39 PM
Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB)



Couldn't I write: isset(static::$structure) ?


You could, but that's only runtime. People generally prefer compile-time 
control which is derived from definition rather than per-instance runtime 
control (implementing interface vs. checking each time if class has 
certain methods).


So this will be my very last (and so much naïve) question: do you know 
how

people cope with it in other OO languages?


AFAIK there are not many languages which allow you to do non-static static 
calls... I see no way of doing it in Java or C++ - please correct me if 
I'm wrong.


The only languages I have seen that allow things like this seem to trend 
more towards prototype based languages. Though it may very well be that I 
don't know what terminology to look for. The very phrase late static binding 
is an oxymoron of sorts :). In any case I do want to be sure to say that 
just because the exact concept is lacking in Java and C++ that is not a 
reason to discount it entirely.



--
Stanislav Malyshev, Zend Software Architect
[EMAIL PROTECTED]   http://www.zend.com/
(408)253-8829   MSN: [EMAIL PROTECTED]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php




--
No virus found in this incoming message.
Checked by AVG Free Edition. Version: 7.5.488 / Virus Database: 
269.13.30/1025 - Release Date: 9/23/2007 1:53 PM





--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-22 Thread Stanislav Malyshev

Like that one, ridiculous:

static private function getStruct($class) {
if(!(is_array(Entity::$struct)  array_key_exists($class,
Entity::$struct))) {
eval(if(!isset(.$class.::\$structure))
self::array2xml('.$class.'););
eval(Entity::\$struct[\$class] = new SimpleXMLElement(
.$class.::\$structure););
}
return Entity::$struct[$class];
}

Do you understand what it does? Do you find it readable? Clean? I don't.
Yet that's what I have to write in PHP.


What you were trying to do I wonder?


Maybe the problem arises in PHP because, as far as I know, there is no way
to define a function as virtual, like in C++, and so you can't choose
between static lookup or dynamic lookup.


In C++, as far as I know, there's no such thing as static virtual function.
--
Stanislav Malyshev, Zend Software Architect
[EMAIL PROTECTED]   http://www.zend.com/
(408)253-8829   MSN: [EMAIL PROTECTED]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



RE: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-21 Thread Dmitry Stogov
You could see about 20 tests with the latest patch.
2 of them especially to show inheritance problem.

Thanks. Dmitry.

 -Original Message-
 From: Zoe Slattery [mailto:[EMAIL PROTECTED] 
 Sent: Thursday, September 20, 2007 10:54 PM
 To: Stanislav Malyshev
 Cc: Dmitry Stogov; 'Marcus Boerger'; 'Lukas Kahwe Smith'; 
 'Michael Lively'; 'Etienne Kneuss'; internals@lists.php.net; 
 'Andi Gutmans'
 Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB)
 
 
 Stanislav Malyshev wrote:
  So we have at least three different views on concept.
  It seems that patch will be delayed again. :(
 
  I think we better spend time on figuring out the concept and then do
  the patch than first do the patch and then discover we 
 don't know how 
  it was supposed to work :)
 How about writing the test cases first - and then the patch?
 
 -- 
 PHP Internals - PHP Runtime Development Mailing List
 To unsubscribe, visit: http://www.php.net/unsub.php
 

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-21 Thread Stanislav Malyshev

class TableSelectExplainBuilder  extends TableSelectBuilder
{
   static protected function buildSelectQuery()
   {
   return EXPLAIN .parent::buildSelectQuery();
   }
}


Why not do static:: instead of parent:: here?
--
Stanislav Malyshev, Zend Software Architect
[EMAIL PROTECTED]   http://www.zend.com/
(408)253-8829   MSN: [EMAIL PROTECTED]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-21 Thread Stanislav Malyshev

Now, let's say the base class is called Entity.
And let's say I have an inherited class called Client:

Abstract Class Entity {
function read()
{}
function delete()
{}
...
}

Class Client extends Entity
{
public $id;
public $first_name;
public $last_name;
static public $structure = ? structure of Client ?;
}

Now, imagine you are programming the delete function in class Entity.
And you have to use the $structure variable.


If you mean Client's $structure, the you have to use static::$structure 
and it should work. However it's quite a bad design here since you have 
no way to ensure class inheriting from Entity would have $structure.



Since all the objects you are manipulating are Client objects (or other
inherited table objects), it would be logical to write:
parent::$structure


It won't be since Entity has no parent, so delete() in Entity definitely 
can't use this keyword.



Personally, I think one should give the programmer the choice, exactly like
the programmer is given the choice between __CLASS__ (now, like it is
written steadily in the code) and get_parent_class() (at run time, like
objects are really instantiated).


__CLASS__ returns name of the class, get_parent_class() is the name of 
parent class, those are entirely different things, nothing to do with 
compiler/run time. Class always has one name and one parent or none.



I may be wrong, but I think LSB occurs every time you need to do something
in a RELATIVE way (get_parent_class(), parent::), because there is an


What do you mean by RELATIVE?


ambiguity upon what you consider as your reference, when you write something
like parent::$structure.


There's no any ambiguity - parent:: always means the name of the class 
you wrote after the keyword extends.

--
Stanislav Malyshev, Zend Software Architect
[EMAIL PROTECTED]   http://www.zend.com/
(408)253-8829   MSN: [EMAIL PROTECTED]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



RE: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-21 Thread Dmitry Stogov
With static:: you are not able to call method of parent with the same name.

Dmitry.


 -Original Message-
 From: Stanislav Malyshev [mailto:[EMAIL PROTECTED] 
 Sent: Friday, September 21, 2007 12:03 PM
 To: Michael Lively
 Cc: Dmitry Stogov; 'Marcus Boerger'; 'Lukas Kahwe Smith'; 
 'Etienne Kneuss'; internals@lists.php.net; 'Andi Gutmans'
 Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB)
 
 
  class TableSelectExplainBuilder  extends TableSelectBuilder
  {
 static protected function buildSelectQuery()
 {
 return EXPLAIN .parent::buildSelectQuery();
 }
  }
 
 Why not do static:: instead of parent:: here?
 -- 
 Stanislav Malyshev, Zend Software Architect
 [EMAIL PROTECTED]   http://www.zend.com/
 (408)253-8829   MSN: [EMAIL PROTECTED]
 

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-21 Thread Marcus Boerger
Hello Dmitry,

  this is a good idea imo. It sounds like the most natural solution - to me.

marcus

Thursday, September 20, 2007, 12:04:04 PM, you wrote:

 From technical point of view it is possible to propagate LSB with self::,
 parent::, and static:: and not with CLASS::.
 I think it may be a good compromise.

 Thanks. Dmitry.

 -Original Message-
 From: Stefan Walk [mailto:[EMAIL PROTECTED] 
 Sent: Thursday, September 20, 2007 1:10 PM
 To: Dmitry Stogov; internals@lists.php.net
 Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB)
 
 
 Is it possible or feasible to distinguish betwenn parent:: 
 and NameOfParentClass::? That would allow to push a call up 
 while preserving the called name while not making Class:: 
 mean different things depending on the location of the call, 
 which is a very bad thing IMO (it's an effect that may not be 
 desired).
 
 Regards,
 Stefan
 




Best regards,
 Marcus

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



RE: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-21 Thread Baptiste Autin
__CLASS__ returns name of the class, get_parent_class() is the name of 
parent class, those are entirely different things, nothing to do with 
compiler/run time. Class always has one name and one parent or none.

Sorry, I meant:
__CLASS__
and
get_class($this)
They are both different things, and they can return different values. 
Like someone said it earlier, __CLASS__ is deterministic: you know its value
at compile.
get_class($this) is not : you cannot guess its value before run time.


What do you mean by RELATIVE?

I mean, when you want to go upwards, to reach an ancestor class.
I think there is an ambiguity: for you, ::parent always means the parent of
__CLASS__
But it could also mean: the parent of get_class($this), in the mind of a
programmer.
And under certain conditions, like the one I explained, you cannot use
parent:: for that ; I must use a lot of get_class() and laborious
turnarounds to get what I want.

Baptiste

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-21 Thread Stanislav Malyshev

I mean, when you want to go upwards, to reach an ancestor class.


You can't go upwards, because there's no upwards for classes. You can 
use the information you already have, via static:: and function that is 
analogous to it for static and get_parent_class for non-static.



But it could also mean: the parent of get_class($this), in the mind of a
programmer.


Then you can use get_parent_class($this) I guess.
--
Stanislav Malyshev, Zend Software Architect
[EMAIL PROTECTED]   http://www.zend.com/
(408)253-8829   MSN: [EMAIL PROTECTED]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-21 Thread Stanislav Malyshev

With static:: you are not able to call method of parent with the same name.


Ah, I see you point. I'm starting to dislike all this idea of let's 
have an object without really having an object... It's becoming messy 
now - we now need to start to invent all kinds of complex propagation 
rules for it in parallel with the true object propagation rules. Why not 
just have an object then?

--
Stanislav Malyshev, Zend Software Architect
[EMAIL PROTECTED]   http://www.zend.com/
(408)253-8829   MSN: [EMAIL PROTECTED]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



RE: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-21 Thread Baptiste Autin
It's becoming messy now - we now need to start to invent all kinds of
complex propagation rules for it in parallel with the true object
propagation rules. Why not just have an object then?

Because if you could only see the incredible number of get_class($this)
and of if(__CLASS__!=get_class($this)) do this or that
and of $t = get_parent_class($class); return ($t!=__CLASS__ ? $t :
$class)'
and other special unreadable hacks I have to imagine in order to get what I
want.

Like that one, ridiculous:

static private function getStruct($class) {
if(!(is_array(Entity::$struct)  array_key_exists($class,
Entity::$struct))) {
eval(if(!isset(.$class.::\$structure))
self::array2xml('.$class.'););
eval(Entity::\$struct[\$class] = new SimpleXMLElement(
.$class.::\$structure););
}
return Entity::$struct[$class];
}

Do you understand what it does? Do you find it readable? Clean? I don't.
Yet that's what I have to write in PHP.

And when you have 20 methods in a class, 3 or 4 levels of inheritance, and
you constantly have to manipulate get_parent_class($this) and other
get_class($this) and other eval($class::..), it becomes impossible.

There must be a cleaner way to express what you want to write.
Maybe the problem arises in PHP because, as far as I know, there is no way
to define a function as virtual, like in C++, and so you can't choose
between static lookup or dynamic lookup.

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



RE: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-20 Thread Dmitry Stogov
So we have at least three different views on concept.
It seems that patch will be delayed again. :(

Thanks. Dmitry.

 -Original Message-
 From: Stanislav Malyshev [mailto:[EMAIL PROTECTED] 
 Sent: Wednesday, September 19, 2007 8:51 PM
 To: Dmitry Stogov
 Cc: 'Marcus Boerger'; 'Lukas Kahwe Smith'; 'Michael Lively'; 
 'Etienne Kneuss'; internals@lists.php.net; 'Andi Gutmans'
 Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB)
 
 
  So to clarify the question...
  
  ?php
  class A {
  function foo() {
  return get_called_class();
  }
  }
  class B extends A {
  function bar() {
  return A::foo();
  }
  }
  class C extensa A {
  function bar() {
  return B::bar();
  }
  }
  echo B::foo(); // this must return B. This is not a question, the 
  question is in the following two lines... echo B::bar(); // 
 this must 
  return B, because B::bar() calls to A::foo() and A is 
 parent of B, 
  so late static binding still the same
 
 I don't understand this. How comes you called A::foo() and you get B? 
 Doesn't make sense to me. If you call A::foo, you are 
 supposed to get A. 
 It looks like your intent is that A::foo() returns different things 
 depending on where it is called, which is not good.
 
  echo C::bar(); // this must return B too, because C:bar() 
 calls to 
  B::bar(), but B is not the parent of C, so the call to B::bar() is 
  handled in the same way as in the previous line.
 
 This should give the same as previous, of course, since in both cases 
 B::bar() is called.
 
  Is this the expected behavior? (I would prefer it. My 
 previous patches 
  worked in this way).
 
 I don't think it's good.
 
  Or may be both lines must return A? (like Etienne's 
 patches do, and 
  like my latest path does)
 
 Yes.
 -- 
 Stanislav Malyshev, Zend Software Architect
 [EMAIL PROTECTED]   http://www.zend.com/
 (408)253-8829   MSN: [EMAIL PROTECTED]
 
 -- 
 PHP Internals - PHP Runtime Development Mailing List
 To unsubscribe, visit: http://www.php.net/unsub.php
 

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



RE: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-20 Thread Dmitry Stogov
From technical point of view it is possible to propagate LSB with self::,
parent::, and static:: and not with CLASS::.
I think it may be a good compromise.

Thanks. Dmitry.

 -Original Message-
 From: Stefan Walk [mailto:[EMAIL PROTECTED] 
 Sent: Thursday, September 20, 2007 1:10 PM
 To: Dmitry Stogov; internals@lists.php.net
 Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB)
 
 
 Is it possible or feasible to distinguish betwenn parent:: 
 and NameOfParentClass::? That would allow to push a call up 
 while preserving the called name while not making Class:: 
 mean different things depending on the location of the call, 
 which is a very bad thing IMO (it's an effect that may not be 
 desired).
 
 Regards,
 Stefan
 

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-20 Thread Stefan Walk
Is it possible or feasible to distinguish betwenn parent:: and
NameOfParentClass::? That would allow to push a call up while
preserving the called name while not making Class:: mean different
things depending on the location of the call, which is a very bad thing
IMO (it's an effect that may not be desired).

Regards,
Stefan

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-20 Thread Stanislav Malyshev

So we have at least three different views on concept.
It seems that patch will be delayed again. :(


I think we better spend time on figuring out the concept and then do the 
patch than first do the patch and then discover we don't know how it was 
supposed to work :)

--
Stanislav Malyshev, Zend Software Architect
[EMAIL PROTECTED]   http://www.zend.com/
(408)253-8829   MSN: [EMAIL PROTECTED]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-20 Thread Stanislav Malyshev

Is it possible or feasible to distinguish betwenn parent:: and
NameOfParentClass::? That would allow to push a call up while


I'm not sure I understand - what's the difference? Can you give an example?

--
Stanislav Malyshev, Zend Software Architect
[EMAIL PROTECTED]   http://www.zend.com/
(408)253-8829   MSN: [EMAIL PROTECTED]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-20 Thread Zoe Slattery

Stanislav Malyshev wrote:

So we have at least three different views on concept.
It seems that patch will be delayed again. :(


I think we better spend time on figuring out the concept and then do 
the patch than first do the patch and then discover we don't know how 
it was supposed to work :)

How about writing the test cases first - and then the patch?

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-20 Thread Stanislav Malyshev

How about writing the test cases first - and then the patch?


I'm fine with that - that's why I asking people for examples of what 
they want to do with it.

--
Stanislav Malyshev, Zend Software Architect
[EMAIL PROTECTED]   http://www.zend.com/
(408)253-8829   MSN: [EMAIL PROTECTED]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



RE: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-20 Thread Baptiste Autin
I hope I won't bother you with obvious things, but I think Stefan has
pointed out something important about LSB: the importance of the relative
access (like parent::), and the ambiguity of the context. It's not a problem
of static data.
Let me give an example, from my present real-life.

I am writing an ORM in PHP, and I really need LSB.
The principle is simple: to each table of the DB corresponds a class (a PHP
class). One table = one class. One column = one attribute.
All my PHP classes inherit from an abstract base class, who owns the main
abstract methods (of access to the DB, like selects, inserts, etc). The
structure of a table (which datatypes, keys, etc.) is represented through an
XML string, in a static variable, in the corresponding PHP class.
It is static because all the instances of a same class (= of a same table)
share the same structure of course; but it could be defined as not static as
well.

Now, let's say the base class is called Entity.
And let's say I have an inherited class called Client:

Abstract Class Entity {
function read()
{}
function delete()
{}
...
}

Class Client extends Entity
{
public $id;
public $first_name;
public $last_name;
static public $structure = ? structure of Client ?;
}

Now, imagine you are programming the delete function in class Entity.
And you have to use the $structure variable.
Since all the objects you are manipulating are Client objects (or other
inherited table objects), it would be logical to write:
parent::$structure
and not:
self::$structure, because Entity has no $structure variable.
The structures belong to the table classes, not to Entity.
But parent::$structure has no meaning at compilation time in Entity.

There is no way for PHP to guess what you want to do: do you mean now, or
do you mean at run time?
Personally, I think one should give the programmer the choice, exactly like
the programmer is given the choice between __CLASS__ (now, like it is
written steadily in the code) and get_parent_class() (at run time, like
objects are really instantiated).

I may be wrong, but I think LSB occurs every time you need to do something
in a RELATIVE way (get_parent_class(), parent::), because there is an
ambiguity upon what you consider as your reference, when you write something
like parent::$structure.
There relies the problem; it's not a question of static or not static. The
problem just frequently occurs with static variables.

Anyway, I do agree with Stanislav when he writes I think we better spend
time on figuring out the concept.
And sorry for my commonplace prose. :)


Baptiste Autin
http://www.baptisteautin.com/


-Original Message-
From: Stanislav Malyshev [mailto:[EMAIL PROTECTED] 
Sent: jeudi 20 septembre 2007 20:58
To: Zoe Slattery
Cc: Dmitry Stogov; 'Marcus Boerger'; 'Lukas Kahwe Smith'; 'Michael Lively';
'Etienne Kneuss'; internals@lists.php.net; 'Andi Gutmans'
Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB)

 How about writing the test cases first - and then the patch?

I'm fine with that - that's why I asking people for examples of what 
they want to do with it.
-- 
Stanislav Malyshev, Zend Software Architect
[EMAIL PROTECTED]   http://www.zend.com/
(408)253-8829   MSN: [EMAIL PROTECTED]

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php


-Original Message-
From: Stanislav Malyshev [mailto:[EMAIL PROTECTED] 
Sent: jeudi 20 septembre 2007 20:58
To: Zoe Slattery
Cc: Dmitry Stogov; 'Marcus Boerger'; 'Lukas Kahwe Smith'; 'Michael Lively';
'Etienne Kneuss'; internals@lists.php.net; 'Andi Gutmans'
Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB)

 How about writing the test cases first - and then the patch?

I'm fine with that - that's why I asking people for examples of what 
they want to do with it.
-- 
Stanislav Malyshev, Zend Software Architect
[EMAIL PROTECTED]   http://www.zend.com/
(408)253-8829   MSN: [EMAIL PROTECTED]

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-20 Thread Michael Lively

From technical point of view it is possible to propagate LSB with self::,
parent::, and static:: and not with CLASS::.
I think it may be a good compromise.


I am very much in favor of this. I think it allows the greatest amount of 
control. If you need a specific class's static method called then passing 
that class' name is the best idea. i would question wether it is a good idea 
to make self:: work like that though.





Thanks. Dmitry.


-Original Message-
From: Stefan Walk [mailto:[EMAIL PROTECTED]
Sent: Thursday, September 20, 2007 1:10 PM
To: Dmitry Stogov; internals@lists.php.net
Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB)


Is it possible or feasible to distinguish betwenn parent::
and NameOfParentClass::? That would allow to push a call up
while preserving the called name while not making Class::
mean different things depending on the location of the call,
which is a very bad thing IMO (it's an effect that may not be
desired).

Regards,
Stefan



--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php




--
No virus found in this incoming message.
Checked by AVG Free Edition.
Version: 7.5.487 / Virus Database: 269.13.21/1010 - Release Date: 
9/15/2007 7:54 PM





--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-20 Thread Michael Lively
Do you have any ideas on how to allow this to be at all useful with 
inheritance and overriding? If the patch is left to where these examples 
would all return 'A' and something wasn't put in place to allow 
overloading a static function  AND forward on the original called class


What do you mean by overloading a static function? What you are trying 
to do?


I have explained this on list twice already...but here it goes again, maybe 
a slightly more concrete example will help:


Say I have a class that is used to generate queries based on the values of 
certain static properties.


?php

class TableSelectBuilder
{
   static protected $tableName;
   static protected $tableColumns;

   static protected function buildSelectQuery()
   {
   return SELECT .implode(', ', static::$tableColumns). FROM 
.static::$tableName;

   }
}

class TestTableSelectBuilder extends TableSelectBuilder
{
   static protected $tableName = 'test';
   static protected $tableColumns = array('col1', 'col2', 'col3');

   static public function test()
   {
   return self::buildSelectQuery();
   }
}

echo TestTableQueryBuilder::test().\n;

?

Running this  script using the latest patch by Dmitry or Etienne will echo 
SELECT col1, col2, col3 FROM test. This is perfect, I love it. Now I want 
to extend TableSelectBuilder to prepend EXPLAIN to a query. I then want to 
change TestTableSelectBuilder to extend that class instead


?php

class TableSelectBuilder
{
   static protected $tableName;
   static protected $tableColumns;

   static protected function buildSelectQuery()
   {
   return SELECT .implode(', ', static::$tableColumns). FROM 
.static::$tableName;

   }
}

class TableSelectExplainBuilder  extends TableSelectBuilder
{
   static protected function buildSelectQuery()
   {
   return EXPLAIN .parent::buildSelectQuery();
   }
}

class TestTableQueryBuilder extends TableSelectExplainBuilder
{
   static protected $tableName = 'test';
   static protected $tableColumns = array('col1', 'col2', 'col3');

   static public function test()
   {
   return self::buildSelectQuery();
   }
}

echo TestTableQueryBuilder::test().\n;

?

This now echos EXPLAIN SELECT  FROM. This is obviously not what is 
desired. Changing parent:: to static:: will cause a segfault due to infinite 
recursion as will self::. So in short there is absolutely no way to make 
TableSelectExplainBuilder useful in the current patch without duplicating 
the parent class code. This limitation is part of the problem that lsb is 
supposed to solve.




to the parent class then usefulness of late static binding is php is 
going to be diminished.


Usefulness for what?
--
Stanislav Malyshev, Zend Software Architect
[EMAIL PROTECTED]   http://www.zend.com/
(408)253-8829   MSN: [EMAIL PROTECTED]




--
No virus found in this incoming message.
Checked by AVG Free Edition. Version: 7.5.487 / Virus Database: 
269.13.21/1010 - Release Date: 9/15/2007 7:54 PM





--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



RE: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-19 Thread Dmitry Stogov
Hi Michael,

Good catch.
You can get the behavior that you expect by enabling (#ifdef ZEND_LSB2) in
my patch.
Tests lsb_018.phpt and lsb_019.phpt are especially for this behavior.

I am not sure which behavior shouldbe in final patch.
It seems like support for inheritance provides more flixebility, but makes
concept harder to understand.

Thanks. Dmitry.

 -Original Message-
 From: Michael Lively [mailto:[EMAIL PROTECTED] 
 Sent: Wednesday, September 19, 2007 8:34 AM
 To: Dmitry Stogov; 'Etienne Kneuss'
 Cc: internals@lists.php.net; Stanislav Malyshev; Andi Gutmans
 Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB)
 
 
 There is a serious problem with both of these patches as they are now.
 
 I understand the principal behind
 ?
 
 class A {
 static public function test() { echo get_called_class() }
 }
 
 class B extend A {
 static public function test2() { A::test(); }
 }
 
 B::test2()
 
 ?
 
 Returning 'A'. But I don't think that it is wise making this 
 change without 
 providing a way to still allow LSB to work further down an 
 inheritance 
 structure.
 
 The whole purpose behind late static binding is to offer 
 greater flexibility 
 when dealing with inheritance of static functions. I 
 understand that the 
 aspect of the original patch returning 'B' for the code above 
 is incorrect. 
 However, consider the following scenario.
 
 ?php
 
 class A {
 static public function test() {
 echo get_called_class().\n;
 }
 }
 
 class B {
 static public function test() {
 // Performing additional needed tasks.
 parent::test();
 }
 }
 
 ?
 
 In class B it is impossible to perform additional work in 
 ::test() and allow 
 class A to still do it's work while still being able to 
 identify the class 
 that originated the set of calls. I don't think it can be 
 denied that this 
 is incredibly inflexible and is somewhat against the reason 
 for introducing 
 late static binding.
 
 I think it is important that a solution is found to this 
 problem, whether it 
 is allowing parent:: to forward on the 'called class' or 
 introducing a new 
 keyword:: that will forward on the 'called class'.
 
 Also, just as a somewhat obvious side note I think the 
 ability to do what I 
 have mentioned will be expected by the OO programmers (which 
 is who lsb is 
 for):
 ?php
 
 class A
 {
 public function test()
 {
 echo get_class($this);
 }
 }
 
 class B extends A
 {
 public function test()
 {
 // Performing additional needed tasks.
 parent::test();
 }
 }
 
 $b = new B();
 $b-test();
 ?
 
 Returns 'B' with no problem
 
 
 - Original Message - 
 From: Dmitry Stogov [EMAIL PROTECTED]
 To: 'Etienne Kneuss' [EMAIL PROTECTED]
 Cc: internals@lists.php.net; Stanislav Malyshev 
 [EMAIL PROTECTED]; Andi 
 Gutmans [EMAIL PROTECTED]
 Sent: Tuesday, September 18, 2007 5:59 AM
 Subject: RE: [PHP-DEV] [patch] Late static bindings (LSB)
 
 
 Hi Etienne,
 
 At first thank you for catching the issue.
 
 I deside not to delay review of your patch and found only one 
 serious bug. It doesn't handle nested calls (test 
 lsb_017.phpt in my patch).
 
 --TEST--
 ZE2 nested calls
 --FILE--
 ?php
 class A {
 public static function test($x=null) {
 if (!is_null($x)) {
 echo $x\n;
 }
 return get_caller_class();
 }
 }
 
 class B extends A {
 }
 class C extends A {
 }
 class D extends A {
 }
 
 echo A::test(B::test(C::test(D::test(.\n;
 ?
 ==DONE==
 --EXPECT--
 D
 C
 B
 A
 ==DONE==
 
 Your patch outputs 4 D.
 
 BTW I like other aspects of your patch.
 I think your get_called_class() is better than my 
 get_caller_class(). (I changed this in my new patch).
 
 I also made the same behavior that you maintained in private 
 email. I didn't removed the corresponding code yet but 
 wrapped it with #ifdef ZEND_LSB2. (tests lsb_018.phpt and 
 test_019.phpt must be failed without it).
 
 I also made several optimizations.
 
 The latest version of my patch is attached.
 I think if you fix the bug that I maintained before our 
 patches will near identical. BTW may be your patch will be 
 better, so please make a mixture of our patches. I assume 
 they have exactly the same behavior, so we need the fastest one.
 
 Thanks. Dmitry.
 
  -Original Message-
  From: Etienne Kneuss [mailto:[EMAIL PROTECTED]
  Sent: Sunday, September 16, 2007 8:18 PM
  To: Dmitry Stogov
  Cc: internals@lists.php.net
  Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB)
 
 
  Hello,
 
  I made the update anyway as it looked like it wouldn't take 
 much time.
 
  Attached is a updated version of my patch, along with all the tests 
  related to it: 
  
 http://patches.colder.ch/Zend/late_static_bindings_take7.patch?markup
 
  --
  Etienne Kneuss
  http://www.colder.ch
 
  Men never do evil so completely and cheerfully as
  when they do it from a religious conviction.
  -- Pascal

Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-19 Thread Lukas Kahwe Smith

Dmitry Stogov wrote:


I am not sure which behavior shouldbe in final patch.
It seems like support for inheritance provides more flixebility, but makes
concept harder to understand.


Well inheritance is an advanced OO concept. As such its something that 
requires a bit of getting into. But making it inconsistent will not help 
ease of use.


regards,
Lukas

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-19 Thread Marcus Boerger
Hello Lukas,

  right, we already have inheritance all over so we should do it here as
  well. Nice work so far.

marcus

Wednesday, September 19, 2007, 9:07:16 AM, you wrote:

 Dmitry Stogov wrote:

 I am not sure which behavior shouldbe in final patch.
 It seems like support for inheritance provides more flixebility, but makes
 concept harder to understand.

 Well inheritance is an advanced OO concept. As such its something that 
 requires a bit of getting into. But making it inconsistent will not help 
 ease of use.

 regards,
 Lukas




Best regards,
 Marcus

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



RE: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-19 Thread Dmitry Stogov
So to clarify the question...

?php
class A {
function foo() {
return get_called_class();
}
}
class B extends A {
function bar() {
return A::foo();
}
}
class C extensa A {
function bar() {
return B::bar();
}
}
echo B::foo(); // this must return B. This is not a question, the question
is in the following two lines...
echo B::bar(); // this must return B, because B::bar() calls to A::foo()
and A is parent of B, so late static binding still the same
echo C::bar(); // this must return B too, because C:bar() calls to
B::bar(), but B is not the parent of C, so the call to B::bar() is handled
in the same way as in the previous line.
?

Is this the expected behavior? (I would prefer it. My previous patches
worked in this way).

Or may be both lines must return A? (like Etienne's patches do, and like
my latest path does)

Thanks. Dmitry.

 -Original Message-
 From: Marcus Boerger [mailto:[EMAIL PROTECTED] 
 Sent: Wednesday, September 19, 2007 12:43 PM
 To: Lukas Kahwe Smith
 Cc: Dmitry Stogov; 'Michael Lively'; 'Etienne Kneuss'; 
 internals@lists.php.net; 'Stanislav Malyshev'; 'Andi Gutmans'
 Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB)
 
 
 Hello Lukas,
 
   right, we already have inheritance all over so we should do 
 it here as
   well. Nice work so far.
 
 marcus
 
 Wednesday, September 19, 2007, 9:07:16 AM, you wrote:
 
  Dmitry Stogov wrote:
 
  I am not sure which behavior shouldbe in final patch.
  It seems like support for inheritance provides more 
 flixebility, but 
  makes concept harder to understand.
 
  Well inheritance is an advanced OO concept. As such its 
 something that
  requires a bit of getting into. But making it inconsistent 
 will not help 
  ease of use.
 
  regards,
  Lukas
 
 
 
 
 Best regards,
  Marcus
 
 -- 
 PHP Internals - PHP Runtime Development Mailing List
 To unsubscribe, visit: http://www.php.net/unsub.php
 

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-19 Thread Alexey Zakhlestin
oh… I guess I see it somehow the third way

class A
{
   function foo()
   {
  return get_called_class();
   }
}

class B extends A
{
   function bar1()
   {
  return self::foo(); // it is called using inheritance-rules
   }

   function bar2()
   {
  return A::foo(); // it is called directly!
   }
}

echo B::bar1(); // B
echo B::bar2(); // A



On 9/19/07, Dmitry Stogov [EMAIL PROTECTED] wrote:
 So to clarify the question...

 ?php
 class A {
 function foo() {
 return get_called_class();
 }
 }
 class B extends A {
 function bar() {
 return A::foo();
 }
 }
 class C extensa A {
 function bar() {
 return B::bar();
 }
 }
 echo B::foo(); // this must return B. This is not a question, the question
 is in the following two lines...
 echo B::bar(); // this must return B, because B::bar() calls to A::foo()
 and A is parent of B, so late static binding still the same
 echo C::bar(); // this must return B too, because C:bar() calls to
 B::bar(), but B is not the parent of C, so the call to B::bar() is handled
 in the same way as in the previous line.
 ?

 Is this the expected behavior? (I would prefer it. My previous patches
 worked in this way).

 Or may be both lines must return A? (like Etienne's patches do, and like
 my latest path does)

 Thanks. Dmitry.

-- 
Alexey Zakhlestin
http://blog.milkfarmsoft.com/


Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-19 Thread Marcus Boerger
Hello Dmitry,

  personally I'd argue with the stayed in same hierarchy. So all return B.

macus

Wednesday, September 19, 2007, 12:48:06 PM, you wrote:

 So to clarify the question...

 ?php
 class A {
 function foo() {
 return get_called_class();
 }
 }
 class B extends A {
 function bar() {
 return A::foo();
 }
 }
 class C extensa A {
 function bar() {
 return B::bar();
 }
 }
 echo B::foo(); // this must return B. This is not a question, the question
 is in the following two lines...
 echo B::bar(); // this must return B, because B::bar() calls to A::foo()
 and A is parent of B, so late static binding still the same
 echo C::bar(); // this must return B too, because C:bar() calls to
 B::bar(), but B is not the parent of C, so the call to B::bar() is handled
 in the same way as in the previous line.
?

 Is this the expected behavior? (I would prefer it. My previous patches
 worked in this way).

 Or may be both lines must return A? (like Etienne's patches do, and like
 my latest path does)

 Thanks. Dmitry.

 -Original Message-
 From: Marcus Boerger [mailto:[EMAIL PROTECTED] 
 Sent: Wednesday, September 19, 2007 12:43 PM
 To: Lukas Kahwe Smith
 Cc: Dmitry Stogov; 'Michael Lively'; 'Etienne Kneuss'; 
 internals@lists.php.net; 'Stanislav Malyshev'; 'Andi Gutmans'
 Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB)
 
 
 Hello Lukas,
 
   right, we already have inheritance all over so we should do 
 it here as
   well. Nice work so far.
 
 marcus
 
 Wednesday, September 19, 2007, 9:07:16 AM, you wrote:
 
  Dmitry Stogov wrote:
 
  I am not sure which behavior shouldbe in final patch.
  It seems like support for inheritance provides more 
 flixebility, but 
  makes concept harder to understand.
 
  Well inheritance is an advanced OO concept. As such its 
 something that
  requires a bit of getting into. But making it inconsistent 
 will not help 
  ease of use.
 
  regards,
  Lukas
 
 
 
 
 Best regards,
  Marcus
 
 -- 
 PHP Internals - PHP Runtime Development Mailing List
 To unsubscribe, visit: http://www.php.net/unsub.php
 



Best regards,
 Marcus

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



RE: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-19 Thread Dmitry Stogov
Do you like to make it work for self::foo() and/or static::foo(), but not
for parent::foo() and NAME::foo()?
From my point of view it is little bit inconsistent, but anyway thank you
for idea.

Dmitry.


 -Original Message-
 From: Alexey Zakhlestin [mailto:[EMAIL PROTECTED] 
 Sent: Wednesday, September 19, 2007 3:26 PM
 To: Dmitry Stogov
 Cc: Marcus Boerger; Lukas Kahwe Smith; Michael Lively; 
 Etienne Kneuss; internals@lists.php.net; Stanislav Malyshev; 
 Andi Gutmans
 Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB)
 
 
 oh. I guess I see it somehow the third way
 
 class A
 {
function foo()
{
   return get_called_class();
}
 }
 
 class B extends A
 {
function bar1()
{
   return self::foo(); // it is called using inheritance-rules
}
 
function bar2()
{
   return A::foo(); // it is called directly!
}
 }
 
 echo B::bar1(); // B
 echo B::bar2(); // A
 
 
 
 On 9/19/07, Dmitry Stogov [EMAIL PROTECTED] wrote:
  So to clarify the question...
 
  ?php
  class A {
  function foo() {
  return get_called_class();
  }
  }
  class B extends A {
  function bar() {
  return A::foo();
  }
  }
  class C extensa A {
  function bar() {
  return B::bar();
  }
  }
  echo B::foo(); // this must return B. This is not a question, the 
  question is in the following two lines... echo B::bar(); // 
 this must 
  return B, because B::bar() calls to A::foo() and A is 
 parent of B, 
  so late static binding still the same echo C::bar(); // this must 
  return B too, because C:bar() calls to B::bar(), but B is not the 
  parent of C, so the call to B::bar() is handled in the same 
 way as in 
  the previous line. ?
 
  Is this the expected behavior? (I would prefer it. My 
 previous patches 
  worked in this way).
 
  Or may be both lines must return A? (like Etienne's 
 patches do, and 
  like my latest path does)
 
  Thanks. Dmitry.
 
 -- 
 Alexey Zakhlestin
 http://blog.milkfarmsoft.com/
 

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-19 Thread Stanislav Malyshev

So to clarify the question...

?php
class A {
function foo() {
return get_called_class();
}
}
class B extends A {
function bar() {
return A::foo();
}
}
class C extensa A {
function bar() {
return B::bar();
}
}
echo B::foo(); // this must return B. This is not a question, the question
is in the following two lines...
echo B::bar(); // this must return B, because B::bar() calls to A::foo()
and A is parent of B, so late static binding still the same


I don't understand this. How comes you called A::foo() and you get B? 
Doesn't make sense to me. If you call A::foo, you are supposed to get A. 
It looks like your intent is that A::foo() returns different things 
depending on where it is called, which is not good.



echo C::bar(); // this must return B too, because C:bar() calls to
B::bar(), but B is not the parent of C, so the call to B::bar() is handled
in the same way as in the previous line.


This should give the same as previous, of course, since in both cases 
B::bar() is called.



Is this the expected behavior? (I would prefer it. My previous patches
worked in this way).


I don't think it's good.


Or may be both lines must return A? (like Etienne's patches do, and like
my latest path does)


Yes.
--
Stanislav Malyshev, Zend Software Architect
[EMAIL PROTECTED]   http://www.zend.com/
(408)253-8829   MSN: [EMAIL PROTECTED]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-19 Thread Michael Lively
Or may be both lines must return A? (like Etienne's patches do, and 
like

my latest path does)


Yes.


Do you have any ideas on how to allow this to be at all useful with 
inheritance and overriding? If the patch is left to where these examples 
would all return 'A' and something wasn't put in place to allow overloading 
a static function  AND forward on the original called class to the parent 
class then usefulness of late static binding is php is going to be 
diminished.



--
Stanislav Malyshev, Zend Software Architect
[EMAIL PROTECTED]   http://www.zend.com/
(408)253-8829   MSN: [EMAIL PROTECTED]




--
No virus found in this incoming message.
Checked by AVG Free Edition. Version: 7.5.487 / Virus Database: 
269.13.21/1010 - Release Date: 9/15/2007 7:54 PM





--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-19 Thread Stanislav Malyshev
Do you have any ideas on how to allow this to be at all useful with 
inheritance and overriding? If the patch is left to where these examples 
would all return 'A' and something wasn't put in place to allow 
overloading a static function  AND forward on the original called class 


What do you mean by overloading a static function? What you are trying 
to do?


to the parent class then usefulness of late static binding is php is 
going to be diminished.


Usefulness for what?
--
Stanislav Malyshev, Zend Software Architect
[EMAIL PROTECTED]   http://www.zend.com/
(408)253-8829   MSN: [EMAIL PROTECTED]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-18 Thread Michael Lively

There is a serious problem with both of these patches as they are now.

I understand the principal behind
?

class A {
   static public function test() { echo get_called_class() }
}

class B extend A {
   static public function test2() { A::test(); }
}

B::test2()

?

Returning 'A'. But I don't think that it is wise making this change without 
providing a way to still allow LSB to work further down an inheritance 
structure.


The whole purpose behind late static binding is to offer greater flexibility 
when dealing with inheritance of static functions. I understand that the 
aspect of the original patch returning 'B' for the code above is incorrect. 
However, consider the following scenario.


?php

class A {
   static public function test() {
   echo get_called_class().\n;
   }
}

class B {
   static public function test() {
   // Performing additional needed tasks.
   parent::test();
   }
}

?

In class B it is impossible to perform additional work in ::test() and allow 
class A to still do it's work while still being able to identify the class 
that originated the set of calls. I don't think it can be denied that this 
is incredibly inflexible and is somewhat against the reason for introducing 
late static binding.


I think it is important that a solution is found to this problem, whether it 
is allowing parent:: to forward on the 'called class' or introducing a new 
keyword:: that will forward on the 'called class'.


Also, just as a somewhat obvious side note I think the ability to do what I 
have mentioned will be expected by the OO programmers (which is who lsb is 
for):

?php

class A
{
   public function test()
   {
   echo get_class($this);
   }
}

class B extends A
{
   public function test()
   {
   // Performing additional needed tasks.
   parent::test();
   }
}

$b = new B();
$b-test();
?

Returns 'B' with no problem


- Original Message - 
From: Dmitry Stogov [EMAIL PROTECTED]

To: 'Etienne Kneuss' [EMAIL PROTECTED]
Cc: internals@lists.php.net; Stanislav Malyshev [EMAIL PROTECTED]; Andi 
Gutmans [EMAIL PROTECTED]

Sent: Tuesday, September 18, 2007 5:59 AM
Subject: RE: [PHP-DEV] [patch] Late static bindings (LSB)


Hi Etienne,

At first thank you for catching the issue.

I deside not to delay review of your patch and found only one serious bug.
It doesn't handle nested calls (test lsb_017.phpt in my patch).

--TEST--
ZE2 nested calls
--FILE--
?php
class A {
public static function test($x=null) {
if (!is_null($x)) {
echo $x\n;
}
return get_caller_class();
}
}

class B extends A {
}
class C extends A {
}
class D extends A {
}

echo A::test(B::test(C::test(D::test(.\n;
?
==DONE==
--EXPECT--
D
C
B
A
==DONE==

Your patch outputs 4 D.

BTW I like other aspects of your patch.
I think your get_called_class() is better than my get_caller_class(). (I
changed this in my new patch).

I also made the same behavior that you maintained in private email. I didn't
removed the corresponding code yet but wrapped it with #ifdef ZEND_LSB2.
(tests lsb_018.phpt and test_019.phpt must be failed without it).

I also made several optimizations.

The latest version of my patch is attached.
I think if you fix the bug that I maintained before our patches will near
identical.
BTW may be your patch will be better, so please make a mixture of our
patches.
I assume they have exactly the same behavior, so we need the fastest one.

Thanks. Dmitry.


-Original Message-
From: Etienne Kneuss [mailto:[EMAIL PROTECTED]
Sent: Sunday, September 16, 2007 8:18 PM
To: Dmitry Stogov
Cc: internals@lists.php.net
Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB)


Hello,

I made the update anyway as it looked like it wouldn't take much time.

Attached is a updated version of my patch, along with all the tests
related to it:
http://patches.colder.ch/Zend/late_static_bindings_take7.patch?markup

--
Etienne Kneuss
http://www.colder.ch

Men never do evil so completely and cheerfully as
when they do it from a religious conviction.
-- Pascal










--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php






No virus found in this incoming message.
Checked by AVG Free Edition.
Version: 7.5.487 / Virus Database: 269.13.21/1010 - Release Date: 9/15/2007 
7:54 PM


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-17 Thread Stanislav Malyshev

Since the call A::foo() is completely defined and that no fall back
occurs, I guess A is more expected as a result of this script.
Your patch will return B. I discussed this matter quite heavily on
#php.pecl and the expectations were also that A should get returned here.


I think you are right, static:: is supposed to mean the context of the 
call, so if A::foo() is called then static means A.



--
Stanislav Malyshev, Zend Software Architect
[EMAIL PROTECTED]   http://www.zend.com/
(408)253-8829   MSN: [EMAIL PROTECTED]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-16 Thread Etienne Kneuss

Hi Dmitry,

your patch fails with one test of mine. It may show a difference in the
conception we have of LSB's usage, consider the following snip:

--%-
?php

class A {
   public static function foo() {
   static::who();
   }

   public static function who() {
   echo __CLASS__.\n;
   }
}

class B extends A {
   public static function test() {
   A::foo();
   }

   public static function who() {
   echo __CLASS__.\n;
   }
}
B::test();

--%-

Since the call A::foo() is completely defined and that no fall back
occurs, I guess A is more expected as a result of this script.
Your patch will return B. I discussed this matter quite heavily on
#php.pecl and the expectations were also that A should get returned here.

Now if returning A is what we really want for PHP's LSB, I'm not sure
whether it's easily doable with your patch. To bring my patch up
to date with the latest functionalities like constants access through
constant()/defined() and callbacks wouldn't require much work.

But if my patch, which uses a slightly different approach (which seems
to be simpler according to patch size), have no way to go in anyway, I'd
like to know it before
I start wasting time on it again.

Thanks in advance.

--
Etienne Kneuss
http://www.colder.ch

Men never do evil so completely and cheerfully as
when they do it from a religious conviction.
-- Pascal

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-16 Thread Etienne Kneuss

Hello,

I made the update anyway as it looked like it wouldn't take much time.

Attached is a updated version of my patch, along with all the tests 
related to it:

http://patches.colder.ch/Zend/late_static_bindings_take7.patch?markup

--
Etienne Kneuss
http://www.colder.ch

Men never do evil so completely and cheerfully as 
when they do it from a religious conviction.

-- Pascal

? tests/classes/hooks_byref.phpt
? tests/classes/lsb
Index: Zend/zend_API.c
===
RCS file: /repository/ZendEngine2/zend_API.c,v
retrieving revision 1.443
diff -u -p -r1.443 zend_API.c
--- Zend/zend_API.c 31 Aug 2007 12:36:00 -  1.443
+++ Zend/zend_API.c 16 Sep 2007 16:11:35 -
@@ -2860,6 +2860,10 @@ ZEND_API zend_bool zend_is_callable_ex(z
lcname_len == 
sizeof(parent)-1 

ZEND_U_EQUAL(Z_TYPE_PP(obj), lcname, lcname_len, parent, sizeof(parent)-1)) 
{
ce = 
EG(active_op_array)-scope-parent;
+   } else if (EG(active_op_array) 
 EG(active_op_array)-scope 
+   lcname_len == 
sizeof(static)-1 
+   
ZEND_U_EQUAL(Z_TYPE_PP(obj), lcname, lcname_len, static, sizeof(static)-1)) 
{
+   ce = 
zend_fetch_class_lsb(EG(active_op_array)-scope TSRMLS_CC);
} else if 
(zend_u_lookup_class(Z_TYPE_PP(obj), Z_UNIVAL_PP(obj), Z_UNILEN_PP(obj), pce 
TSRMLS_CC) == SUCCESS) {
ce = *pce;
}
Index: Zend/zend_builtin_functions.c
===
RCS file: /repository/ZendEngine2/zend_builtin_functions.c,v
retrieving revision 1.352
diff -u -p -r1.352 zend_builtin_functions.c
--- Zend/zend_builtin_functions.c   11 Sep 2007 11:35:46 -  1.352
+++ Zend/zend_builtin_functions.c   16 Sep 2007 16:11:38 -
@@ -44,6 +44,7 @@ static ZEND_FUNCTION(define);
 static ZEND_FUNCTION(defined);
 static ZEND_FUNCTION(get_class);
 static ZEND_FUNCTION(get_parent_class);
+static ZEND_FUNCTION(get_called_class);
 static ZEND_FUNCTION(method_exists);
 static ZEND_FUNCTION(property_exists);
 static ZEND_FUNCTION(class_exists);
@@ -104,6 +105,7 @@ static zend_function_entry builtin_funct
ZEND_FE(defined,NULL)
ZEND_FE(get_class,  NULL)
ZEND_FE(get_parent_class,   NULL)
+   ZEND_FE(get_called_class,   NULL)
ZEND_FE(method_exists,  NULL)
ZEND_FE(property_exists,NULL)
ZEND_FE(class_exists,   NULL)
@@ -658,6 +660,30 @@ ZEND_FUNCTION(get_parent_class)
 }
 /* }}} */
 
+/* {{{ proto string get_called_class() U
+   Retrieves the class name that were initially called. @see static:: */
+ZEND_FUNCTION(get_called_class)
+{
+   zend_class_entry *lsb_scope;
+
+   if (ZEND_NUM_ARGS()) {
+   ZEND_WRONG_PARAM_COUNT();
+   }
+   
+   if (!EG(scope)) {
+   RETURN_FALSE;
+   }
+
+   lsb_scope = zend_fetch_class_lsb(EG(scope) TSRMLS_CC);
+
+   if (lsb_scope) {
+   RETURN_TEXTL(lsb_scope-name, lsb_scope-name_length, 1);
+   } else {
+   RETURN_FALSE;
+   }
+}
+/* }}} */
+
 static void is_a_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool only_subclass) 
/* {{{ */
 {
zval **obj, **class_name;
Index: Zend/zend_compile.c
===
RCS file: /repository/ZendEngine2/zend_compile.c,v
retrieving revision 1.767
diff -u -p -r1.767 zend_compile.c
--- Zend/zend_compile.c 5 Sep 2007 07:24:52 -   1.767
+++ Zend/zend_compile.c 16 Sep 2007 16:11:47 -
@@ -1701,6 +1701,7 @@ void zend_do_fetch_class(znode *result, 
fetch_type = 
zend_get_class_fetch_type(Z_TYPE(class_name-u.constant), 
Z_UNIVAL(class_name-u.constant), Z_UNILEN(class_name-u.constant));
switch (fetch_type) {
case ZEND_FETCH_CLASS_SELF:
+   case ZEND_FETCH_CLASS_LATE:
case ZEND_FETCH_CLASS_PARENT:
SET_UNUSED(opline-op2);
opline-extended_value = fetch_type;
@@ -3178,7 +3179,9 @@ void zend_do_begin_class_declaration(zno
 
if ((lcname_len == sizeof(self)-1 
 ZEND_U_EQUAL(Z_TYPE(class_name-u.constant), lcname, lcname_len, 
self, sizeof(self)-1)) ||
-   (lcname_len == sizeof(parent)-1 
+   (lcname_len == sizeof(static)-1 
+ZEND_U_EQUAL(Z_TYPE(class_name-u.constant), lcname, lcname_len, 
static, sizeof(static)-1)) 

Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-16 Thread Michael Lively

Since the call A::foo() is completely defined and that no fall back
occurs, I guess A is more expected as a result of this script.
Your patch will return B. I discussed this matter quite heavily on
#php.pecl and the expectations were also that A should get returned 
here.


I've taken a look at this patch and for the most part I agree that your code 
SHOULD return 'A'. However, one thing that I think is very important is that 
you are able to somehow pass-thru who the caller is when dealing with 
inheritance.


For instance:

?php

class Foo
{
   const TEST_CONST = 'foo';

   public function test()
   {
   return static::TEST_CONST;
   }
}

class Bar extends Foo
{
   const TEST_CONST = 'bar';
}

echo Foo::test().\n;
echo Bar::test().\n;

?

This works as expected outputting:
foo
bar

However, this concept becomes very inflexible when dealing with some aspects 
of inheritance. Consider a child class that needs to do additional work in 
its test() method and then called the parent test() method to do the normal 
work.


?php

class Bar2 extends Foo
{
   const TEST_CONST = 'bar2';

   public function test()
   {
   //do class specific things
   //try to continue the function chain
   return parent::test();
   }
}

?

This will also output 'foo'. While I agree that in this case this concept 
does make sense, I do think it is important for there to be a way to have 
this function return 'bar2'. The way that would most make sense to me and 
still somewhat follow the rules is to change the return to static::test(); 
However this causes a seg fault in your current patch. I will do a little 
more checking to see why you are segfaulting here.


In either case without having some way to chain callers this is going to 
become a very annoying problem when utilizing inheritance with late static 
binding.


--

Mike Lively
http://www.ds-o.com 


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-16 Thread Michael Lively


- Original Message - 
From: Etienne Kneuss [EMAIL PROTECTED]

To: internals@lists.php.net
Sent: Sunday, September 16, 2007 10:50 AM
Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB)


However this causes a seg fault in your current patch. I will do a little 
more checking to see why you are segfaulting here.



That's an endless recursion, hence the segfault ;)


Yah, quickly found that out after running gdb



In either case without having some way to chain callers this is going to 
become a very annoying problem when utilizing inheritance with late 
static binding.

I aggree that it could be a problem indeed, but you usually use LSB to
avoid having to redeclare static functions in child classes, if you do
anyway, LSB looses its interest.


You of course wouldn't HAVE to redeclare the static function. Occasionally 
you just need to do a little extra in a child class and if this breaks lsb 
(or makes it innefective) with no work around (static::) then that would be 
no good.


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-16 Thread Etienne Kneuss

Michael Lively wrote:

Since the call A::foo() is completely defined and that no fall back
occurs, I guess A is more expected as a result of this script.
Your patch will return B. I discussed this matter quite heavily on
#php.pecl and the expectations were also that A should get returned 
here.


I've taken a look at this patch and for the most part I agree that 
your code SHOULD return 'A'. However, one thing that I think is very 
important is that you are able to somehow pass-thru who the caller is 
when dealing with inheritance.


For instance:

?php

class Foo
{
   const TEST_CONST = 'foo';

   public function test()
   {
   return static::TEST_CONST;
   }
}

class Bar extends Foo
{
   const TEST_CONST = 'bar';
}

echo Foo::test().\n;
echo Bar::test().\n;

?

This works as expected outputting:
foo
bar

However, this concept becomes very inflexible when dealing with some 
aspects of inheritance. Consider a child class that needs to do 
additional work in its test() method and then called the parent test() 
method to do the normal work.


?php

class Bar2 extends Foo
{
   const TEST_CONST = 'bar2';

   public function test()
   {
   //do class specific things
   //try to continue the function chain
   return parent::test();
   }
}

?

This will also output 'foo'. While I agree that in this case this 
concept does make sense, I do think it is important for there to be a 
way to have this function return 'bar2'. The way that would most make 
sense to me and still somewhat follow the rules is to change the 
return to static::test(); However this causes a seg fault in your 
current patch. I will do a little more checking to see why you are 
segfaulting here.



That's an endless recursion, hence the segfault ;)

In either case without having some way to chain callers this is going 
to become a very annoying problem when utilizing inheritance with late 
static binding.

I aggree that it could be a problem indeed, but you usually use LSB to
avoid having to redeclare static functions in child classes, if you do
anyway, LSB looses its interest.

Regards


--

Mike Lively
http://www.ds-o.com



--
Etienne Kneuss
http://www.colder.ch

Men never do evil so completely and cheerfully as
when they do it from a religious conviction.
-- Pascal

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



RE: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-10 Thread Dmitry Stogov
Attached.

Thanks. Dmitry.

 -Original Message-
 From: Etienne Kneuss [mailto:[EMAIL PROTECTED] 
 Sent: Sunday, September 09, 2007 11:02 PM
 To: Dmitry Stogov
 Cc: internals@lists.php.net
 Subject: Re: [PHP-DEV] [patch] Late static bindings (LSB)
 
 
 Hello,
 
 sorry for the late reply, I am on vacations these weeks and 
 only have a 
 sparse access to web.
 I was aware that my patch missed supports for callbacks, and 
 let it that 
 way on purpose as I
 planned to do some cleanup work on callbacks.
 
 It looks like you placed the work necessary to have LSB in a 
 different 
 place than mine,
 generating more occurences and hence a quite bigger patch 
 size. I'd like 
 to see what implications it has.
 
 Sadly, the patch you gave me is not easily patchable with the current 
 HEAD, do you have an up to date version ?
 
 Thanks in advance
 
 Dmitry Stogov wrote:
  Hi Etienne,
 
  We already have patch for late static binding that is very 
 similar to 
  yours. If you have time, please compare them.
  From quick look I see that our patch more accurate (it supports 
  constants
  and runtime function calls)
  Does our patch miss something that your patch does?
 
  Thanks. Dmitry.
 

  -Original Message-
  From: Etienne Kneuss [mailto:[EMAIL PROTECTED]
  Sent: Friday, August 24, 2007 5:19 PM
  To: internals@lists.php.net
  Subject: [PHP-DEV] [patch] Late static bindings (LSB)
 
 
  Hi internals,
 
  here is a patch that implements Late static bindinds in a way that
  minimizes the performance hits that were feared.
  There is no significant slowdown or memory usage increase 
  when running 
  Zend/bench.php, which I assume is a
  good enough bench for that kind of matter, as it involves a stupid 
  amount of (recursive) function calls.
 
  You can also find the patch here:
  
 http://patches.colder.ch/Zend/late_static_bindings_take6.patch?markup
 
  Here is a document that describes its usage:
  http://colder.ch/news/08-24-2007/28/late-static-bindings-expl.html
 
  Regards,
 
  --
  Etienne Kneuss
  http://www.colder.ch
 
  Men never do evil so completely and cheerfully as
  when they do it from a religious conviction.
  -- Pascal
 
 
  
 
 
 -- 
 Etienne Kneuss
 http://www.colder.ch
 
 Men never do evil so completely and cheerfully as 
 when they do it from a religious conviction.
 -- Pascal
 
 -- 
 PHP Internals - PHP Runtime Development Mailing List
 To unsubscribe, visit: http://www.php.net/unsub.php
 
Index: Zend/zend_API.c
===
RCS file: /repository/ZendEngine2/zend_API.c,v
retrieving revision 1.443
diff -u -p -d -r1.443 zend_API.c
--- Zend/zend_API.c 31 Aug 2007 12:36:00 -  1.443
+++ Zend/zend_API.c 10 Sep 2007 07:59:35 -
@@ -2860,6 +2860,9 @@ ZEND_API zend_bool zend_is_callable_ex(z
lcname_len == 
sizeof(parent)-1 

ZEND_U_EQUAL(Z_TYPE_PP(obj), lcname, lcname_len, parent, sizeof(parent)-1)) 
{
ce = 
EG(active_op_array)-scope-parent;
+   } else if (lcname_len == 
sizeof(static)-1 
+   
ZEND_U_EQUAL(Z_TYPE_PP(obj), lcname, lcname_len, static, sizeof(static)-1)) 
{
+   ce = EG(caller_scope);
} else if 
(zend_u_lookup_class(Z_TYPE_PP(obj), Z_UNIVAL_PP(obj), Z_UNILEN_PP(obj), pce 
TSRMLS_CC) == SUCCESS) {
ce = *pce;
}
Index: Zend/zend_builtin_functions.c
===
RCS file: /repository/ZendEngine2/zend_builtin_functions.c,v
retrieving revision 1.350
diff -u -p -d -r1.350 zend_builtin_functions.c
--- Zend/zend_builtin_functions.c   30 Aug 2007 07:43:53 -  1.350
+++ Zend/zend_builtin_functions.c   10 Sep 2007 07:59:35 -
@@ -43,6 +43,7 @@ static ZEND_FUNCTION(error_reporting);
 static ZEND_FUNCTION(define);
 static ZEND_FUNCTION(defined);
 static ZEND_FUNCTION(get_class);
+static ZEND_FUNCTION(get_caller_class);
 static ZEND_FUNCTION(get_parent_class);
 static ZEND_FUNCTION(method_exists);
 static ZEND_FUNCTION(property_exists);
@@ -103,6 +104,7 @@ static zend_function_entry builtin_funct
ZEND_FE(define, NULL)
ZEND_FE(defined,NULL)
ZEND_FE(get_class,  NULL)
+   ZEND_FE(get_caller_class,   NULL)
ZEND_FE(get_parent_class,   NULL)
ZEND_FE(method_exists,  NULL)
ZEND_FE(property_exists,NULL)
@@ -614,6 +616,26 @@ ZEND_FUNCTION(get_class)
 }
 /* }}} */
 
+/* {{{ proto string get_caller_class()
+   Retrieves the class name

Re: [PHP-DEV] [patch] Late static bindings (LSB)

2007-09-09 Thread Etienne Kneuss

Hello,

sorry for the late reply, I am on vacations these weeks and only have a 
sparse access to web.
I was aware that my patch missed supports for callbacks, and let it that 
way on purpose as I

planned to do some cleanup work on callbacks.

It looks like you placed the work necessary to have LSB in a different 
place than mine,
generating more occurences and hence a quite bigger patch size. I'd like 
to see what implications it has.


Sadly, the patch you gave me is not easily patchable with the current 
HEAD, do you have an up to date version ?


Thanks in advance

Dmitry Stogov wrote:

Hi Etienne,

We already have patch for late static binding that is very similar to yours.
If you have time, please compare them.
From quick look I see that our patch more accurate (it supports constants
and runtime function calls)
Does our patch miss something that your patch does?

Thanks. Dmitry.

  

-Original Message-
From: Etienne Kneuss [mailto:[EMAIL PROTECTED] 
Sent: Friday, August 24, 2007 5:19 PM

To: internals@lists.php.net
Subject: [PHP-DEV] [patch] Late static bindings (LSB)


Hi internals,

here is a patch that implements Late static bindinds in a way that 
minimizes the performance hits that were feared.
There is no significant slowdown or memory usage increase 
when running 
Zend/bench.php, which I assume is a
good enough bench for that kind of matter, as it involves a stupid 
amount of (recursive) function calls.


You can also find the patch here: 
http://patches.colder.ch/Zend/late_static_bindings_take6.patch?markup


Here is a document that describes its usage: 
http://colder.ch/news/08-24-2007/28/late-static-bindings-expl.html


Regards,

--
Etienne Kneuss
http://www.colder.ch

Men never do evil so completely and cheerfully as 
when they do it from a religious conviction.

-- Pascal






--
Etienne Kneuss
http://www.colder.ch

Men never do evil so completely and cheerfully as 
when they do it from a religious conviction.

-- Pascal

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



RE: [PHP-DEV] [patch] Late static bindings (LSB)

2007-08-24 Thread Dmitry Stogov
Hi Etienne,

We already have patch for late static binding that is very similar to yours.
If you have time, please compare them.
From quick look I see that our patch more accurate (it supports constants
and runtime function calls)
Does our patch miss something that your patch does?

Thanks. Dmitry.

 -Original Message-
 From: Etienne Kneuss [mailto:[EMAIL PROTECTED] 
 Sent: Friday, August 24, 2007 5:19 PM
 To: internals@lists.php.net
 Subject: [PHP-DEV] [patch] Late static bindings (LSB)
 
 
 Hi internals,
 
 here is a patch that implements Late static bindinds in a way that 
 minimizes the performance hits that were feared.
 There is no significant slowdown or memory usage increase 
 when running 
 Zend/bench.php, which I assume is a
 good enough bench for that kind of matter, as it involves a stupid 
 amount of (recursive) function calls.
 
 You can also find the patch here: 
 http://patches.colder.ch/Zend/late_static_bindings_take6.patch?markup
 
 Here is a document that describes its usage: 
 http://colder.ch/news/08-24-2007/28/late-static-bindings-expl.html
 
 Regards,
 
 -- 
 Etienne Kneuss
 http://www.colder.ch
 
 Men never do evil so completely and cheerfully as 
 when they do it from a religious conviction.
 -- Pascal
 
 
Index: Zend/zend_API.c
===
RCS file: /repository/ZendEngine2/zend_API.c,v
retrieving revision 1.442
diff -u -p -d -r1.442 zend_API.c
--- Zend/zend_API.c 20 Aug 2007 09:48:41 -  1.442
+++ Zend/zend_API.c 24 Aug 2007 16:50:13 -
@@ -2836,6 +2836,9 @@ ZEND_API zend_bool zend_is_callable_ex(z
lcname_len == 
sizeof(parent)-1 

ZEND_U_EQUAL(Z_TYPE_PP(obj), lcname, lcname_len, parent, sizeof(parent)-1)) 
{
ce = 
EG(active_op_array)-scope-parent;
+   } else if (lcname_len == 
sizeof(static)-1 
+   
ZEND_U_EQUAL(Z_TYPE_PP(obj), lcname, lcname_len, static, sizeof(static)-1)) 
{
+   ce = EG(caller_scope);
} else if 
(zend_u_lookup_class(Z_TYPE_PP(obj), Z_UNIVAL_PP(obj), Z_UNILEN_PP(obj), pce 
TSRMLS_CC) == SUCCESS) {
ce = *pce;
}
Index: Zend/zend_builtin_functions.c
===
RCS file: /repository/ZendEngine2/zend_builtin_functions.c,v
retrieving revision 1.349
diff -u -p -d -r1.349 zend_builtin_functions.c
--- Zend/zend_builtin_functions.c   24 Aug 2007 13:50:52 -  1.349
+++ Zend/zend_builtin_functions.c   24 Aug 2007 16:50:13 -
@@ -43,6 +43,7 @@ static ZEND_FUNCTION(error_reporting);
 static ZEND_FUNCTION(define);
 static ZEND_FUNCTION(defined);
 static ZEND_FUNCTION(get_class);
+static ZEND_FUNCTION(get_caller_class);
 static ZEND_FUNCTION(get_parent_class);
 static ZEND_FUNCTION(method_exists);
 static ZEND_FUNCTION(property_exists);
@@ -103,6 +104,7 @@ static zend_function_entry builtin_funct
ZEND_FE(define, NULL)
ZEND_FE(defined,NULL)
ZEND_FE(get_class,  NULL)
+   ZEND_FE(get_caller_class,   NULL)
ZEND_FE(get_parent_class,   NULL)
ZEND_FE(method_exists,  NULL)
ZEND_FE(property_exists,NULL)
@@ -614,6 +616,26 @@ ZEND_FUNCTION(get_class)
 }
 /* }}} */
 
+/* {{{ proto string get_caller_class()
+   Retrieves the class name */
+ZEND_FUNCTION(get_caller_class)
+{
+   int dup;
+
+   if (!ZEND_NUM_ARGS()) {
+   if (EG(caller_scope)) {
+   RETURN_TEXTL(EG(caller_scope)-name, 
EG(caller_scope)-name_length, 1);
+   } else {
+   zend_error(E_ERROR, get_caller_class() called from 
outside a class);
+   }
+   } else {
+   ZEND_WRONG_PARAM_COUNT();
+   RETURN_FALSE;
+   }
+}
+/* }}} */
+
+
 /* {{{ proto string get_parent_class([mixed object]) U
Retrieves the parent class name for object or class or current scope. */
 ZEND_FUNCTION(get_parent_class)
Index: Zend/zend_compile.c
===
RCS file: /repository/ZendEngine2/zend_compile.c,v
retrieving revision 1.765
diff -u -p -d -r1.765 zend_compile.c
--- Zend/zend_compile.c 24 Aug 2007 13:50:52 -  1.765
+++ Zend/zend_compile.c 24 Aug 2007 16:50:13 -
@@ -1702,6 +1702,7 @@ void zend_do_fetch_class(znode *result, 
switch (fetch_type) {
case ZEND_FETCH_CLASS_SELF:
case ZEND_FETCH_CLASS_PARENT:
+   case