Hello,
I was just skimming through Traits RFC document on the wiki trying to find a
practical use for them. The first thing that comes to my mind is a Singleton
implementation - this is where I found myself literally "copying" most of
the code in the past. As far as I know there is no way to implement this
pattern properly in PHP without duplicate code (due to lack of multiple
inheritance/templating).
Unfortunately, the same RFC document mentions this for trait methods:
The static modifier is not supported, because it would change the methods
semantics and references to $this would break.
.. and that pretty much defeats Singleton-Trait implementation. Is there any
particular technical/design reasons why traits can't handle $this inside
static methods just like regular static methods do (with a fatal error)?
p.s. a Singleton-Trait implementation could look like:
trait Singleton {
public static function getInstance() { ... }
}
class Child extends Parent {
use Singleton;
}
Child::getInstance();
Hi Simas:
The first thing that comes to my mind is a Singleton
implementation - this is where I found myself literally "copying" most of
the code in the past. As far as I know there is no way to implement this
pattern properly in PHP without duplicate code (due to lack of multiple
inheritance/templating).Unfortunately, the same RFC document mentions this for trait methods:
The static modifier is not supported, because it would change the methods
semantics and references to $this would break.
.. and that pretty much defeats Singleton-Trait implementation. Is there any
particular technical/design reasons why traits can't handle $this inside
static methods just like regular static methods do (with a fatal error)?
Hm, good question. I don't recall any implementation details. Haven't touched the code for too long.
From the top of my head, I don't see why it should not work.
If I would have elaborated a bit more what I was thinking when I wrote that comment...
Following the motto 'it is just compiler assisted copy and paste' I think it should be implemented.
Best regards
Stefan
--
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: +32 2 629 2974
Fax: +32 2 629 3525
Hi Stefan,
Following the motto 'it is just compiler assisted copy and paste' I think
it should be implemented.
Alright then, I am sure someone will find more uses for static methods in
Traits like factories/utilities (especially if traits can be made to work
with late static binding).
I assume this will be implemented in one way or another before or after
first 5.4 alphas! :)
/Simas
Hi Simas:
Alright then, I am sure someone will find more uses for static methods in
Traits like factories/utilities (especially if traits can be made to work
with late static binding).I assume this will be implemented in one way or another before or after
first 5.4 alphas! :)
Send me the tests/phpt-files for it, and I will have a lock at it over the weekend.
Best regards
Stefan
--
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: +32 2 629 2974
Fax: +32 2 629 3525
Hi Simas:
Thanks for sending me the test cases.
I checked them in, and surprise surprise: it actually was already completely implemented. I didn't had to touch any code...
So the missing bit was being more explicit in the RFC.
I added a section and an example based on your Singleton code.
Now I also remember what the reference to the static modifier was about.
You cannot use it to change it for a standard method.
That means, if you have a normal method, you cannot make it static however, you can for instance make a public method private, or add an alias for it. That was what that statement was referring to.
http://wiki.php.net/rfc/horizontalreuse
Hope that helps
Best regards
Stefan
Hi Simas:
Alright then, I am sure someone will find more uses for static methods in
Traits like factories/utilities (especially if traits can be made to work
with late static binding).I assume this will be implemented in one way or another before or after
first 5.4 alphas! :)
Send me the tests/phpt-files for it, and I will have a lock at it over the weekend.Best regards
Stefan--
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: +32 2 629 2974
Fax: +32 2 629 3525--
--
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: +32 2 629 2974
Fax: +32 2 629 3525
Hello,
I was just skimming through Traits RFC document on the wiki trying to find
a
practical use for them. The first thing that comes to my mind is a
Singleton
implementation - this is where I found myself literally "copying" most of
the code in the past. As far as I know there is no way to implement this
pattern properly in PHP without duplicate code (due to lack of multiple
inheritance/templating).Unfortunately, the same RFC document mentions this for trait methods:
The static modifier is not supported, because it would change the methods
semantics and references to $this would break.
.. and that pretty much defeats Singleton-Trait implementation. Is there
any
particular technical/design reasons why traits can't handle $this inside
static methods just like regular static methods do (with a fatal error)?p.s. a Singleton-Trait implementation could look like:
trait Singleton {
public static function getInstance() { ... }
}class Child extends Parent {
use Singleton;
}Child::getInstance();
for reusable singleton pattern with php 5.3
http://www.slideshare.net/fabpot/design-patternrevisitedphp53
slide 11 and 12
Tyrael
for reusable singleton pattern with php 5.3
http://www.slideshare.net/fabpot/design-patternrevisitedphp53
slide 11 and 12Tyrael
The problem with the solution presented in the slides is that it
limits every singleton class to only ever be able to inherit from
Singleton, so we can't have a child class that is a singleton while
the parent is not. Something that having Traits would solve. Though
we'd still have singletons, which is a different problem.
-Tom
Hi Ferenc,
for reusable singleton pattern with php 5.3
http://www.slideshare.net/fabpot/design-patternrevisitedphp53
slide 11 and 12
As Tom already pointed out - there is that lock-down of your parent(s) to
singletons with this type of implementation and there are other shortcomings
when used with SPL, for example:
class Test extends ArrayObject { }
Without creating some sort of intermediate ArrayObjectSingleton class you
can't make Test a singleton (and traits would solve that).
/Simas
Am 16.11.2010 18:46, schrieb Simas Toleikis:
p.s. a Singleton-Trait implementation could look like:
trait Singleton {
public static function getInstance() { ... }
}class Child extends Parent {
use Singleton;
}Child::getInstance();
This is not really a good example as the getInstance() method alone is
not sufficient for a reusable implementation of the Singleton pattern.
A trait for a reusable implementation of the Singleton pattern should
look more like
trait Singleton
{
private static $uniqueInstance = NULL;
protected function __construct() {}
private final function __clone() {}
public static function getInstance()
{
if (self::$uniqueInstance === NULL) {
self::$uniqueInstance = new Singleton;
}
return self::$uniqueInstance;
}
}
which of course does not work as traits are stateless and
class MySingleton
{
use Singleton;
}
MySingleton::getInstance();
results in
Access to undeclared static property: MySingleton::$uniqueInstance
And rightfully so. Nobody should need a mechanism to make it as easy as
pie to clutter the code base with singletons ;-)
--
Sebastian Bergmann Co-Founder and Principal Consultant
http://sebastian-bergmann.de/ http://thePHP.cc/
Hi Sebastian,
This is not really a good example as the getInstance() method alone is
not sufficient for a reusable implementation of the Singleton pattern.
Yes, it was just a pseudo-code and not a true singleton implementation.
A trait for a reusable implementation of the Singleton pattern should
look more like
...
which of course does not work as traits are stateless and
Would it work if instance is saved inside a local static var like:
public static function getInstance() {
static $instance = NULL;
if (is_null($instance)) {
$instance = new self();
}
return $instance;
}
/Simas
Hi Simas:
Would it work if instance is saved inside a local static var like:
public static function getInstance() {
static $instance = NULL;
if (is_null($instance)) {
$instance = new self();
}return $instance;
}
http://svn.php.net/viewvc/php/php-src/trunk/Zend/tests/traits/language013.phpt?revision=300283&view=markup
The test case says it works ;)
Best regards
Stefan
--
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: +32 2 629 2974
Fax: +32 2 629 3525