# new overloading feature?

- Thread: https://externals.io/message/13731
- Original archive: https://news-web.php.net/php.internals/13731
- Started by Derrell.Lipman@UnwiredUniverse.com on 2004-11-05T15:55:51+00:00
- Messages: 27
- Page 1 of 2: messages 1 to 25 (25 per page, add `?page=N` to the URL)
- Next page: https://externals.io/message/13731.md?page=2
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #13731 — Derrell.Lipman@UnwiredUniverse.com — 2004-11-05T15:55:51+00:00

URL: https://externals.io/message/13731#13731

I came across an interesting desire today.  I'd like to create a new class
instance if an only if a "key" value does not already exist.  This key value
could be looked up in a database, in an array, etc.

The following contrived example shows use of a proposed __new() overload
function which would be called BEFORE the constructor, and could chose to
return a newly constructed object (by calling __construct()) or to return an
already existing object.

One could certainly call a function which searched for the key value and only
instantiated a new object if the existing one was not found, but this seems
cleaner.

Thoughts?

<?php

class X
{
    static          $allX = array();
    var             $val;

    function __construct($val)
    {
        $this->val = $val;
        X::$allX[] =& $this;
    }

    function __new($val)
    {
        foreach (X::$allX as $x)
        {
            if ($x->val == $val)
            {
                return $x;
            }
        }

        return __construct($val);
    }
}

$try1 = new X(23);              /* would return $allX[0] reference */
$try2 = new X(42);              /* woudl return $allX[1] reference */
$try3 = new X(23);              /* would return $allX[0] reference */
?

---

## #13732 — Andrey Hristov — 2004-11-05T16:28:06+00:00

URL: https://externals.io/message/13731#13732 · In reply to: #13731

Why not using Singleton for multiple objects with getInstance() ?

Andrey

Derrell.Lipman@UnwiredUniverse.com wrote:
> I came across an interesting desire today.  I'd like to create a new class
> instance if an only if a "key" value does not already exist.  This key value
> could be looked up in a database, in an array, etc.
> 
> The following contrived example shows use of a proposed __new() overload
> function which would be called BEFORE the constructor, and could chose to
> return a newly constructed object (by calling __construct()) or to return an
> already existing object.
> 
> One could certainly call a function which searched for the key value and only
> instantiated a new object if the existing one was not found, but this seems
> cleaner.
> 
> Thoughts?
> 
> <?php
> 
> class X
> {
>     static          $allX = array();
>     var             $val;
> 
>     function __construct($val)
>     {
>         $this->val = $val;
>         X::$allX[] =& $this;
>     }
> 
>     function __new($val)
>     {
>         foreach (X::$allX as $x)
>         {
>             if ($x->val == $val)
>             {
>                 return $x;
>             }
>         }
> 
>         return __construct($val);
>     }
> }
> 
> $try1 = new X(23);              /* would return $allX[0] reference */
> $try2 = new X(42);              /* woudl return $allX[1] reference */
> $try3 = new X(23);              /* would return $allX[0] reference */
> ?

---

## #13733 — Derrell.Lipman@UnwiredUniverse.com — 2004-11-05T17:10:09+00:00

URL: https://externals.io/message/13731#13733 · In reply to: #13732

Andrey Hristov <php@hristov.com> writes:

>  Why not using Singleton for multiple objects with getInstance() ?

Yeah, it's not quite a Singleton pattern.  I've seen references to what I'm
talking about as a Pool pattern.  That's basically what I described here:

> > […]

There are absolutely ways to do this purely at the application level.  It just
seems that it'd be a really clean, easy to program, easy to understand
methodology to pass the key value to the request for a new instance, and get
back either a new instance, or a previously existing one with that key value.

In fact, the proposed __new() feature could provide an automatic Singleton
capability without the caller needing to worry about (or even know) that it's
dealing with a Singleton.  The class defines a __new() function that always
returns its one and only instance (instantiating it the very first time), and
the application can always use 'new' without worrying about the internal
implementation.

Derrell

---

## #13734 — Andrey Hristov — 2004-11-05T17:14:49+00:00

URL: https://externals.io/message/13731#13734 · In reply to: #13733

Derrell.Lipman@UnwiredUniverse.com wrote:
> Andrey Hristov <php@hristov.com> writes:
> 
> 
> > […]
> 
> 
> Yeah, it's not quite a Singleton pattern.  I've seen references to what I'm
> talking about as a Pool pattern.  That's basically what I described here:
> 

Yes, Pool. I just said that it is Singleton for multiple objects which
in fact is pool.

> > […]
> 
> 
> There are absolutely ways to do this purely at the application level.  It just
> seems that it'd be a really clean, easy to program, easy to understand
> methodology to pass the key value to the request for a new instance, and get
> back either a new instance, or a previously existing one with that key value.
> 
> In fact, the proposed __new() feature could provide an automatic Singleton
> capability without the caller needing to worry about (or even know) that it's
> dealing with a Singleton.  The class defines a __new() function that always
> returns its one and only instance (instantiating it the very first time), and
> the application can always use 'new' without worrying about the internal
> implementation.
> 
> Derrell
> 

The thing I find nice in the current way of implementing it with getInstance()
and a static class variable is that it is like it is defined in GoF. People
can easily understand what's going on. Otherwise it is too much of magic to me:)


Andrey

---

## #16181 — Derrell.Lipman@UnwiredUniverse.com — 2005-05-09T16:17:32+00:00

URL: https://externals.io/message/13731#16181 · In reply to: #13731

Derrell.Lipman@UnwiredUniverse.com writes:

Leonardo Pedretti <lpedretti@suserver.com> writes:

> I would like (for code cleanliness purposes) to make 'new' return a
> reference to an already created object under certain circumstances without
> using a factory, is it possible?

A number of months ago, I proposed a similar feature, implemented as
overloading a __new() function.  At the time, it seemed I was the only one who
wanted it, but your request is for a feature identical to my request.  Here's
my previous message.  (The whole thread can be found under the subject "new
overloading feature?" from 5 Nov 2004).  I'd love for this to be revisited now
that there's someone else with a similar desire.

My previous proposal:

> I came across an interesting desire today.  I'd like to create a new class
> instance if an only if a "key" value does not already exist.  This key value
> could be looked up in a database, in an array, etc.
>
> The following contrived example shows use of a proposed __new() overload
> function which would be called BEFORE the constructor, and could chose to
> return a newly constructed object (by calling __construct()) or to return an
> already existing object.
>
> One could certainly call a function which searched for the key value and only
> instantiated a new object if the existing one was not found, but this seems
> cleaner.
>
> Thoughts?
>
> <?php
>
> class X
> {
>     static          $allX = array();
>     var             $val;
>
>     function __construct($val)
>     {
>         $this->val = $val;
>         X::$allX[] =& $this;
>     }
>
>     function __new($val)
>     {
>         foreach (X::$allX as $x)
>         {
>             if ($x->val == $val)
>             {
>                 return $x;
>             }
>         }
>
>         return __construct($val);
>     }
> }
>
> $try1 = new X(23);              /* would return $allX[0] reference */
> $try2 = new X(42);              /* woudl return $allX[1] reference */
> $try3 = new X(23);              /* would return $allX[0] reference */
> ?

---

## #16182 — George Schlossnagle — 2005-05-09T18:05:50+00:00

URL: https://externals.io/message/13731#16182 · In reply to: #16181

Derrell.Lipman@UnwiredUniverse.com wrote:

>Derrell.Lipman@UnwiredUniverse.com writes:
>
>Leonardo Pedretti <lpedretti@suserver.com> writes:
>
>  
>
> > […]
>
>A number of months ago, I proposed a similar feature, implemented as
>overloading a __new() function.  At the time, it seemed I was the only one who
>wanted it, but your request is for a feature identical to my request.  Here's
>my previous message.  (The whole thread can be found under the subject "new
>overloading feature?" from 5 Nov 2004).  I'd love for this to be revisited now
>that there's someone else with a similar desire.
>  
>

I'm not an OO expert, but doesn't this break a fundamental semantic of 
OOP -- namely that new() returns a new object of the specified class.  
Isn't this the whole reason that the Singleton pattern exists?

George

---

## #16186 — Lukas Smith — 2005-05-09T20:36:33+00:00

URL: https://externals.io/message/13731#16186 · In reply to: #16182

George Schlossnagle wrote:

> I'm not an OO expert, but doesn't this break a fundamental semantic of 
> OOP -- namely that new() returns a new object of the specified class.  
> Isn't this the whole reason that the Singleton pattern exists?

yeah I would agree that we should always try to find a non magic 
solution and in this case a singleton seems to be the obvious choice. 
however currently its kinda hard to write a singleton that will work 
even if you inherit from the base class that implements the singleton 
due to:
http://bugs.php.net/bug.php?id=30235

regards,
Lukas

---

## #16188 — Sebastian Bergmann — 2005-05-10T05:26:19+00:00

URL: https://externals.io/message/13731#16188 · In reply to: #16186

Lukas Smith wrote:
> http://bugs.php.net/bug.php?id=30235

 I agree with Marcus: self is bound at runtime, so the behaviour is
 correct. If you do not like this late binding just do not use self but
 the name of the class.

-- 
Sebastian Bergmann                      http://www.sebastian-bergmann.de/
GnuPG Key: 0xB85B5D69 / 27A7 2B14 09E4 98CD 6277 0E5B 6867 C514 B85B 5D69

---

## #16189 — Markus Fischer — 2005-05-10T06:31:05+00:00

URL: https://externals.io/message/13731#16189 · In reply to: #16188

Sebastian Bergmann wrote:
> Lukas Smith wrote:
> 
> > […]
> 
> 
>  I agree with Marcus: self is bound at runtime, so the behaviour is
>  correct. If you do not like this late binding just do not use self but
>  the name of the class.

Sorry to jump in the middle, but I've similiar question to constants 
defined in classes.

When the class is named SomeLongNameBecauseWedontHaveNamespaces and I 
define a SELF_EXPLAINING_CONSTANT_NUMBER_ONE I've to write 
SomeLongNameBecauseWedontHaveNamespaces::SELF_EXPLAINING_CONSTANT_NUMBER_ONE 
to access it from within the class itself.

Is there a way to reference constants from the same class (or dervived 
class) in a friendlier way?

thanks for listening,

- Markus

---

## #16192 — Marcus Boerger — 2005-05-10T08:03:56+00:00

URL: https://externals.io/message/13731#16192 · In reply to: #16189

Hello Markus,

Tuesday, May 10, 2005, 8:31:05 AM, you wrote:

> Sebastian Bergmann wrote:
> > […]

> Sorry to jump in the middle, but I've similiar question to constants 
> defined in classes.

> When the class is named SomeLongNameBecauseWedontHaveNamespaces and I 
> define a SELF_EXPLAINING_CONSTANT_NUMBER_ONE I've to write 
> SomeLongNameBecauseWedontHaveNamespaces::SELF_EXPLAINING_CONSTANT_NUMBER_ONE
> to access it from within the class itself.

> Is there a way to reference constants from the same class (or dervived 
> class) in a friendlier way?

We're not going to change the language for that, sorry.



-- 
Best regards,
 Marcus                            mailto:mail@marcus-boerger.de

---

## #16191 — Markus Fischer — 2005-05-10T08:20:56+00:00

URL: https://externals.io/message/13731#16191 · In reply to: #16192

Marcus Boerger wrote:
> > […]
> 
> > […]
> 
> 
> > […]
 >
> We're not going to change the language for that, sorry.

I didn't request any change ;) Just wanted to know if there's a current 
better practice. If not, then not.

thanks,

- Mar'k'us

---

## #16193 — Jason Sweat — 2005-05-10T11:27:53+00:00

URL: https://externals.io/message/13731#16193 · In reply to: #16189

> When the class is named SomeLongNameBecauseWedontHaveNamespaces and I
> define a SELF_EXPLAINING_CONSTANT_NUMBER_ONE I've to write
> SomeLongNameBecauseWedontHaveNamespaces::SELF_EXPLAINING_CONSTANT_NUMBER_ONE
> to access it from within the class itself.
> 
> Is there a way to reference constants from the same class (or dervived
> class) in a friendlier way?

Hi Markus,

I often use self::SELF_EXPLAINING_CONSTANT_NUMBER_ONE when in context
of a class method itself.

HTH
 
Regards,
Jason
http://blog.casey-sweat.us/

---

## #16194 — Markus Fischer — 2005-05-10T11:32:58+00:00

URL: https://externals.io/message/13731#16194 · In reply to: #16193

Jason Sweat wrote:
> > […]
> 
> I often use self::SELF_EXPLAINING_CONSTANT_NUMBER_ONE when in context
> of a class method itself.

I forgot to add that I mean in static methods ..

but thanks,
- Markus

---

## #16195 — Lukas Smith — 2005-05-10T12:57:56+00:00

URL: https://externals.io/message/13731#16195 · In reply to: #16188

Sebastian Bergmann wrote:
> Lukas Smith wrote:
> 
> > […]
> 
> 
>  I agree with Marcus: self is bound at runtime, so the behaviour is
>  correct. If you do not like this late binding just do not use self but
>  the name of the class.

So please explain to me how you would write a singleton static method 
for a base class from which you can inherite. Suddenly the idea with 
using the class name becomes less useful.

The late binding seems to be a nice performance tweak, but it means that 
in many situations you end up having to do cut and paste in combination 
with inheritance. Doesnt seem very OOP to me, altough I fear Java 
behaves the same way. So all I am asking for is an easy way to call a 
static method in the current context (without having to go through the 
reflection API, having to store the class name in a static property etc).

regards,
Lukas

---

## #16196 — Lukas Smith — 2005-05-10T13:40:51+00:00

URL: https://externals.io/message/13731#16196 · In reply to: #16195

Lukas Smith wrote:
> Sebastian Bergmann wrote:
> 
> > […]
> 
> 
> So please explain to me how you would write a singleton static method 
> for a base class from which you can inherite. Suddenly the idea with 
> using the class name becomes less useful.
> 
> The late binding seems to be a nice performance tweak, but it means that 
> in many situations you end up having to do cut and paste in combination 
> with inheritance. Doesnt seem very OOP to me, altough I fear Java 
> behaves the same way. So all I am asking for is an easy way to call a 
> static method in the current context (without having to go through the 
> reflection API, having to store the class name in a static property etc).

Johannes reminded me that I should probably also mention this weekly 
news item on the topic:
http://www.zend.com/zend/week/week219.php#Heading5

regards,
Lukas

---

## #16200 — ondrej@kmit.sk — 2005-05-10T14:56:11+00:00

URL: https://externals.io/message/13731#16200 · In reply to: #16195

Lukas Smith wrote:
> So please explain to me how you would write a singleton static method
> for a base class from which you can inherite. Suddenly the idea with
> using the class name becomes less useful.

IMHO, you need singleton factory :)

Inheritance is very strong relationship between classes. For example I
have base class 'Animal' and derived classes 'Dog' and 'Cat'. I can find
similarity between 'Dog' and 'Cat'. (They are animals)

If I have base class Singleton and derived classes 'MyCar' and 'MyCat'.
I can't find similarity between this classes.

Solutions is:

class SingletonFactory {
	private $instances;

	__construct() {
		$this->instances = array();
	}

	function getInstance($name) {
		if(is_a($this->instances[$name], $name) === false) {
			$this->instances[$name] = new $name;
		}
		
		return $this->instances[$name];
	}
}

FYI: SingletonFactory can be a pure static class.

-- 
Ondrej Ivanic
(ondrej@kmit.sk)

---

## #16203 — Lukas Smith — 2005-05-10T15:49:26+00:00

URL: https://externals.io/message/13731#16203 · In reply to: #16200

Ondrej Ivanič wrote:

> class SingletonFactory {
> 	private $instances;
> 
> 	__construct() {
> 		$this->instances = array();
> 	}
> 
> 	function getInstance($name) {
> 		if(is_a($this->instances[$name], $name) === false) {
> 			$this->instances[$name] = new $name;
> 		}
> 		
> 		return $this->instances[$name];
> 	}
> }
> 
> FYI: SingletonFactory can be a pure static class.
> 

yes it just doesnt work if you normally already use a factory ..because 
then you cant do $name::factory();

regards,
Lukas

---

## #16205 — Alex Knaub — 2005-05-10T16:33:55+00:00

URL: https://externals.io/message/13731#16205 · In reply to: #16188

2005/5/10, Sebastian Bergmann <sb@sebastian-bergmann.de>:
> Lukas Smith wrote:
> > […]
> 
>  I agree with Marcus: self is bound at runtime, so the behaviour is
>  correct. If you do not like this late binding just do not use self but
>  the name of the class.

I don't agree with Marcus. Singleton or the name of the class are ugly
workarounds for this bug. Every genuine OOP and dynamic language
(ObjC, Ruby, Smalltalk) bounds self at runtime.

---

## #16208 — Thomas Richter — 2005-05-11T09:34:09+00:00

URL: https://externals.io/message/13731#16208 · In reply to: #16203

Lukas Smith wrote:

> > […]
> 
> yes it just doesnt work if you normally already use a factory ..because 
> then you cant do $name::factory();

call_user_func(array($name,"Factory")); ??

thomas

---

## #16233 — Lukas Smith — 2005-05-12T20:39:15+00:00

URL: https://externals.io/message/13731#16233 · In reply to: #16208

Thomas Richter wrote:
> Lukas Smith wrote:
> 
> > […]
> 
> 
> call_user_func(array($name,"Factory")); ??

that works if you store the class name for every child of the parent 
class into a static property.

the problem is that unless you copy paste, maintain the class name in a 
static property for every child class you have a problem. both options 
seem to be rather clumsy and un-OOP. so it would be nice to have some 
way of getting the class name that is being called upon statically.

regards,
Lukas

---

## #16234 — Marcus Boerger — 2005-05-12T21:48:16+00:00

URL: https://externals.io/message/13731#16234 · In reply to: #16205

Hello Alex,

  but PHP is a class based langauage which is very much different from
prototype based langauages. Apart from that i already said that it would be
possible to add a special 'called_self' (or better name) syntax to support
what you want - only that would slow doen execution even if you won't use
it. And since what you want is not the correct way of doing it in a class
based language i don't think we should add it.

regards
marcus

Tuesday, May 10, 2005, 6:33:55 PM, you wrote:

> 2005/5/10, Sebastian Bergmann <sb@sebastian-bergmann.de>:
> > […]

> I don't agree with Marcus. Singleton or the name of the class are ugly
> workarounds for this bug. Every genuine OOP and dynamic language
> (ObjC, Ruby, Smalltalk) bounds self at runtime.

> --
> 
> 




-- 
Best regards,
 Marcus                            mailto:mail@marcus-boerger.de

---

## #16238 — Alex Knaub — 2005-05-13T15:18:43+00:00

URL: https://externals.io/message/13731#16238 · In reply to: #16234

2005/5/12, Marcus Boerger <mail@marcus-boerger.de>:
> Hello Alex,
> 
>   but PHP is a class based langauage which is very much different from

what is a class based language?

> prototype based langauages. Apart from that i already said that it would be
> possible to add a special 'called_self' (or better name) syntax to support
> what you want - only that would slow doen execution even if you won't use
> it. And since what you want is not the correct way of doing it in a class

that is the only correct way to use factories in a dynamic language,
everything else
leads to code duplication and / or crapy code.

---

## #16239 — Marcus Boerger — 2005-05-13T15:35:47+00:00

URL: https://externals.io/message/13731#16239 · In reply to: #16238

Hello Alex,

Friday, May 13, 2005, 5:18:43 PM, you wrote:

> 2005/5/12, Marcus Boerger <mail@marcus-boerger.de>:
> > […]

> what is a class based language?

 It means the language is based around the idea that all objects refer to a
 certain class and you cannot dynamically add, change or remove members
 (though php allows to dynamically add properties).

> > […]

> that is the only correct way to use factories in a dynamic language,
> everything else
> leads to code duplication and / or crapy code.

Yes but for php supporting this would means that we'd need to make php
slower. And where is the problem in a little code duplication? Maybe you
want templates? Maybe you're in the wrong language.

-- 
Best regards,
 Marcus                            mailto:mail@marcus-boerger.de

---

## #16240 — Alex Knaub — 2005-05-13T16:22:24+00:00

URL: https://externals.io/message/13731#16240 · In reply to: #16239

Hello Marcus,

2005/5/13, Marcus Boerger <mail@marcus-boerger.de>:
> > […]
> 
>  It means the language is based around the idea that all objects refer to a
>  certain class and you cannot dynamically add, change or remove members
>  (though php allows to dynamically add properties).

ok, this makes the hole thing clearer. Now i understand the idea behind the
php object model.

thank you.

---

## #16245 — Justin Hannus — 2005-05-14T01:55:54+00:00

URL: https://externals.io/message/13731#16245 · In reply to: #13731

My thoughts are:

1. Adding to many __methods is ugly.

2. Interesting subject though. Not to add to the flame but I've seen the 
need for more advanced overloading features in allot of the code I've 
been writing with PHP5. Consider the following example (C++ almost like, 
may slow down the engine but seems like a cleaner idea):


class StringObject
{
   public $val = '';

   public function __construct($str = '')
   {
     $this->val = $str;
   }

   public function __operator($operator, &$lOperand, &$rOperand,
     &$returnValue)
   {
     switch ($operator) {
       case T_CONCAT_EQUALS:
         if ($rOperand instanceof StringObject &&
           $lOperand instanceof StringObject) {
           $returnValue = $lOperand->val . $rOperand->val;
           // or something?
           return true; // use operator handler;
         }

       // ...other operators that are supported by this object
       // can be defined here...

     }
     return false; // normal operation takes place;
   }
}

$str1 = new StringObject("hello ");
$str2 = new StringObject("world!");

str1 .= $str2;


This would be very useful and very clean but seems like if defined would 
really slow down the engine. But, i think this could work well in many, 
many different situations. Maybe only a subset of operators are 
overloadable with this method.

-Justin

Derrell Lipman wrote:
> I came across an interesting desire today.  I'd like to create a new class
> instance if an only if a "key" value does not already exist.  This key value
> could be looked up in a database, in an array, etc.
> 
> The following contrived example shows use of a proposed __new() overload
> function which would be called BEFORE the constructor, and could chose to
> return a newly constructed object (by calling __construct()) or to return an
> already existing object.
> 
> One could certainly call a function which searched for the key value and only
> instantiated a new object if the existing one was not found, but this seems
> cleaner.
> 
> Thoughts?
> 
> <?php
> 
> class X
> {
>     static          $allX = array();
>     var             $val;
> 
>     function __construct($val)
>     {
>         $this->val = $val;
>         X::$allX[] =& $this;
>     }
> 
>     function __new($val)
>     {
>         foreach (X::$allX as $x)
>         {
>             if ($x->val == $val)
>             {
>                 return $x;
>             }
>         }
> 
>         return __construct($val);
>     }
> }
> 
> $try1 = new X(23);              /* would return $allX[0] reference */
> $try2 = new X(42);              /* woudl return $allX[1] reference */
> $try3 = new X(23);              /* would return $allX[0] reference */
> ?

---

Next page: https://externals.io/message/13731.md?page=2
