Hello guys,
the attached patch closes one more __toString() part. It allows
to use objects that define __toString as indexes to arrays. What do
you guys think about this, should we add it or stay with the old
behavior that didn't allow objects as indexes at all.
--
Best regards,
Marcus mailto:mail@marcus-boerger.de
Hi,
Hello guys,
the attached patch closes one more __toString() part. It allows
to use objects that define __toString as indexes to arrays. What do
you guys think about this, should we add it or stay with the old
behavior that didn't allow objects as indexes at all.
$arr[new Test] = 'abc';
makes very little sense to me, as well as
$a = new Test; $arr[$a] = 'abc';
Do we really want to support that?
--Pierre
Hello Pierre,
ever thought that we use tests to check special behavior and that
those snippets have little to do with real applications? Obviously
not. The idea behind is that for instance you might use an array as
a translation and use an object to calculate the index.
Saturday, June 3, 2006, 2:40:29 PM, you wrote:
Hi,
Hello guys,
the attached patch closes one more __toString() part. It allows
to use objects that define __toString as indexes to arrays. What do
you guys think about this, should we add it or stay with the old
behavior that didn't allow objects as indexes at all.
$arr[new Test] = 'abc';
makes very little sense to me, as well as
$a = new Test; $arr[$a] = 'abc';
Do we really want to support that?
--Pierre
Best regards,
Marcus
Hello Pierre,
ever thought that we use tests to check special behavior and that
those snippets have little to do with real applications? Obviously
not. The idea behind is that for instance you might use an array as
a translation and use an object to calculate the index.
I understood that. The "magic" behind __toString was my point. However
adding it could help to be consistent with the other magic
operations...
--Pierre
Hi,
Is it really worth enabling a whole new area where problems could
occur just for this? Can you provide an example of where it might
actually be considered useful and not just being lazy?
-Rob
Hello Pierre,
ever thought that we use tests to check special behavior and that
those snippets have little to do with real applications? Obviously
not. The idea behind is that for instance you might use an array as
a translation and use an object to calculate the index.Saturday, June 3, 2006, 2:40:29 PM, you wrote:
Hi,
Hello guys,
the attached patch closes one more __toString() part. It allows
to use objects that define __toString as indexes to arrays. What do
you guys think about this, should we add it or stay with the old
behavior that didn't allow objects as indexes at all.$arr[new Test] = 'abc';
makes very little sense to me, as well as
$a = new Test; $arr[$a] = 'abc';
Do we really want to support that?
--Pierre
Best regards,
Marcus--
--
Xnyo - http://xnyo.odynia.org/
Hello Robert,
well lazy is a good point here but __toString is all about lazyness.
Then again as said you might want to have objects naturally convert
to strings whereever possible. Generally when providing a __toString
implementation you say that you want this. And then you might as well
expect that your objects can be used as index to arrays.
The example is as said an object that can be used to calculate the
index to an array. Assuming you deal with persons derived from
a database as classes, your person objects might be implmeneted so
that __toString simply returns the name of the persons. Now when your
application also has an array that stores more information about the
persons it would be nice if you could access that array direectly by
your peson objects.
best regards
marcus
Saturday, June 3, 2006, 2:55:00 PM, you wrote:
Hi,
Is it really worth enabling a whole new area where problems could
occur just for this? Can you provide an example of where it might
actually be considered useful and not just being lazy?
-Rob
Hello Pierre,
ever thought that we use tests to check special behavior and that
those snippets have little to do with real applications? Obviously
not. The idea behind is that for instance you might use an array as
a translation and use an object to calculate the index.Saturday, June 3, 2006, 2:40:29 PM, you wrote:
Hi,
Hello guys,
the attached patch closes one more __toString() part. It allows
to use objects that define __toString as indexes to arrays. What do
you guys think about this, should we add it or stay with the old
behavior that didn't allow objects as indexes at all.$arr[new Test] = 'abc';
makes very little sense to me, as well as
$a = new Test; $arr[$a] = 'abc';
Do we really want to support that?
--Pierre
Best regards,
Marcus--
--
Xnyo - http://xnyo.odynia.org/
Best regards,
Marcus
Thats fair, as long as it doesn't result in any unwanted behaviour then I'm +1.
-Rob
Hello Robert,
well lazy is a good point here but __toString is all about lazyness.
Then again as said you might want to have objects naturally convert
to strings whereever possible. Generally when providing a __toString
implementation you say that you want this. And then you might as well
expect that your objects can be used as index to arrays.The example is as said an object that can be used to calculate the
index to an array. Assuming you deal with persons derived from
a database as classes, your person objects might be implmeneted so
that __toString simply returns the name of the persons. Now when your
application also has an array that stores more information about the
persons it would be nice if you could access that array direectly by
your peson objects.best regards
marcusSaturday, June 3, 2006, 2:55:00 PM, you wrote:
Hi,
Is it really worth enabling a whole new area where problems could
occur just for this? Can you provide an example of where it might
actually be considered useful and not just being lazy?-Rob
Hello Pierre,
ever thought that we use tests to check special behavior and that
those snippets have little to do with real applications? Obviously
not. The idea behind is that for instance you might use an array as
a translation and use an object to calculate the index.Saturday, June 3, 2006, 2:40:29 PM, you wrote:
Hi,
Hello guys,
the attached patch closes one more __toString() part. It allows
to use objects that define __toString as indexes to arrays. What do
you guys think about this, should we add it or stay with the old
behavior that didn't allow objects as indexes at all.$arr[new Test] = 'abc';
makes very little sense to me, as well as
$a = new Test; $arr[$a] = 'abc';
Do we really want to support that?
--Pierre
Best regards,
Marcus--
--
Xnyo - http://xnyo.odynia.org/Best regards,
Marcus
--
Xnyo - http://xnyo.odynia.org/
Thats fair, as long as it doesn't result in any unwanted behaviour then I'm +1.
Good luck ;-)
--Pierre
Hello Robert,
well lazy is a good point here but __toString is all about lazyness.
Then again as said you might want to have objects naturally convert
to strings whereever possible. Generally when providing a __toString
implementation you say that you want this. And then you might as well
expect that your objects can be used as index to arrays.The example is as said an object that can be used to calculate the
index to an array. Assuming you deal with persons derived from
a database as classes, your person objects might be implmeneted so
that __toString simply returns the name of the persons. Now when your
application also has an array that stores more information about the
persons it would be nice if you could access that array direectly by
your peson objects.
Makes sense to me, so +1.
Derick
--
Derick Rethans
http://derickrethans.nl | http://ez.no | http://xdebug.org
Yes definitely, that functionality would be useful.
Regards,
Michael
Hi,
Hello guys,
the attached patch closes one more __toString() part. It allows
to use objects that define __toString as indexes to arrays. What do
you guys think about this, should we add it or stay with the old
behavior that didn't allow objects as indexes at all.$arr[new Test] = 'abc';
makes very little sense to me, as well as
$a = new Test; $arr[$a] = 'abc';
Do we really want to support that?
--Pierre
Hello guys,
the attached patch closes one more __toString() part. It allows
to use objects that define __toString as indexes to arrays. What do
you guys think about this, should we add it or stay with the old
behavior that didn't allow objects as indexes at all.
Like others who have contributed to the thread I agree that it would be
useful, but I think using __toString() wrong for this. There is a
confusion two ideas here:
1. The string representation of an object, probably human
readable, lucent string.
2. A unique hash of an object use to identify it programmatically,
and likely unique. Probably a non-human friendly, opaque value.
These are not the same thing. The latter is what, IMO, would be used
for an objects value as an index into an array, not the former.
The latter is available ... currently I do this like so:
class a{ public function __toString() { return 'an object';}}
$foo = new a;
$bar = new a;
$arr = new array()
$arr[(string)$foo] = $foo; // The index is "Object id #1"
$arr[(string)$bar] = $bar; // The index is "Object id #2"
Note that the __tostring method is not used in the cast - a spearate
issue, but needs to be pointed out for this issue.
Therefore my suggested alternative to Marcus' patch is:
When Objects are used in array index context, use the object ID or some
variation. And, possibly, provide a magic method, or interface to
generate an hash value of an object.
Regards,
Andrew
Andrew Yochum
Plexpod
andrew@plexpod.com
718-360-0879
Hello Andrew,
Saturday, June 3, 2006, 4:36:39 PM, you wrote:
Hello guys,
the attached patch closes one more __toString() part. It allows
to use objects that define __toString as indexes to arrays. What do
you guys think about this, should we add it or stay with the old
behavior that didn't allow objects as indexes at all.
Like others who have contributed to the thread I agree that it would be
useful, but I think using __toString() wrong for this. There is a
confusion two ideas here:
1. The string representation of an object, probably human
readable, lucent string.
2. A unique hash of an object use to identify it programmatically,
and likely unique. Probably a non-human friendly, opaque value.
These are not the same thing. The latter is what, IMO, would be used
for an objects value as an index into an array, not the former.
The latter is available ... currently I do this like so:
class a{ public function __toString() { return 'an object';}}
$foo = new a;
$bar = new a;
$arr = new array()
$arr[(string)$foo] = $foo; // The index is "Object id #1"
$arr[(string)$bar] = $bar; // The index is "Object id #2"
Note that the __tostring method is not used in the cast - a spearate
issue, but needs to be pointed out for this issue.
Therefore my suggested alternative to Marcus' patch is:
When Objects are used in array index context, use the object ID or some
variation. And, possibly, provide a magic method, or interface to
generate an hash value of an object.
We cannot use the object id since that is not necessarily unique.
For the same reason SplObjectStorage cannot be done in userland.
However what you mention here is right. Other languages offer to
magic functions. A stringify one and a hashing one. But then again
i don't think we should add yet another magic feature.
best regards
marcus
Generally I think it's a good thing to allow to use objects as array indexes.
There are really two ways of doing it:
a) Try and find a way to create unique ideas.
b) Support __toString() and leave it up to the author.
I have a bit of a hard time finding a solution to (a) unless the
unique id is a string. Not that I think having it as a string is
necessarily a bad thing but I'd be interested in hearing what others think.
Supporting __toString() is the easiest way to go, especially as it
wouldn't lead to BC breaks. It would be up to the author to make
that a unique key like "Db#Person#1" but then they couldn't use that
with "print" because the value the class author would want there
would probably not be the one he'd want in array access.
Anyone got any thoughts, how bad of a break it would be if we did
create a unique id of objects, whether string or int? That's
something we probably could do for PHP 6 esp. if string is acceptable.
Andi
At 09:38 AM 6/3/2006, Marcus Boerger wrote:
Hello Andrew,
Saturday, June 3, 2006, 4:36:39 PM, you wrote:
Hello guys,
the attached patch closes one more __toString() part. It allows
to use objects that define __toString as indexes to arrays. What do
you guys think about this, should we add it or stay with the old
behavior that didn't allow objects as indexes at all.Like others who have contributed to the thread I agree that it would be
useful, but I think using __toString() wrong for this. There is a
confusion two ideas here:
1. The string representation of an object, probably human
readable, lucent string.
2. A unique hash of an object use to identify it programmatically,
and likely unique. Probably a non-human friendly, opaque value.
These are not the same thing. The latter is what, IMO, would be used
for an objects value as an index into an array, not the former.The latter is available ... currently I do this like so:
class a{ public function __toString() { return 'an object';}}
$foo = new a;
$bar = new a;
$arr = new array()
$arr[(string)$foo] = $foo; // The index is "Object id #1"
$arr[(string)$bar] = $bar; // The index is "Object id #2"
Note that the __tostring method is not used in the cast - a spearate
issue, but needs to be pointed out for this issue.Therefore my suggested alternative to Marcus' patch is:
When Objects are used in array index context, use the object ID or some
variation. And, possibly, provide a magic method, or interface to
generate an hash value of an object.We cannot use the object id since that is not necessarily unique.
For the same reason SplObjectStorage cannot be done in userland.
However what you mention here is right. Other languages offer to
magic functions. A stringify one and a hashing one. But then again
i don't think we should add yet another magic feature.best regards
marcus
Hi,
Generally I think it's a good thing to allow to use objects as array
indexes. There are really two ways of doing it:
a) Try and find a way to create unique ideas.
b) Support __toString() and leave it up to the author.
I see a third choice, which I prefer:
c) leave the choice to the user, he knows better what to do with his
object (like implementing his own get(Hash|Key) method.
--Pierre
Yep that is also a choice, although it can be advantageous to have an
automatic (a) which people just now works, always...
I don't think it's a critical problem because as you pointed out
people can deal with it, but I think it'd be nice to provide some
tools to make life easier.
At 06:01 PM 6/3/2006, Pierre wrote:
Hi,
Generally I think it's a good thing to allow to use objects as array
indexes. There are really two ways of doing it:
a) Try and find a way to create unique ideas.
b) Support __toString() and leave it up to the author.I see a third choice, which I prefer:
c) leave the choice to the user, he knows better what to do with his
object (like implementing his own get(Hash|Key) method.--Pierre
$x = new Obj;
$y[$x]= 123;
That behaviour is going to be fun to document, and for people unfamilar
with it to find in the manual
-> php.net/array -> go to array syntax page -> read down to find about
objects as keys -> go to __toHash() page...
..whereas...
$x = new Obj;
$y[$x->toHash()]= 123;
they might have a chance to see instantly how that is supposed to work,
on the rare occasion that somebody needs this, is it really worth
building it into the langauge????
Regards
Alan
Andi Gutmans wrote:
Yep that is also a choice, although it can be advantageous to have an
automatic (a) which people just now works, always...
I don't think it's a critical problem because as you pointed out
people can deal with it, but I think it'd be nice to provide some
tools to make life easier.At 06:01 PM 6/3/2006, Pierre wrote:
Hi,
Generally I think it's a good thing to allow to use objects as array
indexes. There are really two ways of doing it:
a) Try and find a way to create unique ideas.
b) Support __toString() and leave it up to the author.I see a third choice, which I prefer:
c) leave the choice to the user, he knows better what to do with his
object (like implementing his own get(Hash|Key) method.--Pierre
Alan Knowles wrote:
$x = new Obj;
$y[$x]= 123;That behaviour is going to be fun to document, and for people unfamilar
with it to find in the manual
-> php.net/array -> go to array syntax page -> read down to find about
objects as keys -> go to __toHash() page.....whereas...
$x = new Obj;
$y[$x->toHash()]= 123;they might have a chance to see instantly how that is supposed to work,
on the rare occasion that somebody needs this, is it really worth
building it into the langauge????
In that case, why not just use the existing __toString explicitly with:
$x = new Obj;
$y[(string)$x] = 123;
This works today and basically gives you the same thing. The only thing
it doesn't do is separate an array index context from an output context
allowing you do different things in the two cases.
I think if we are going to add a toHash thing, it should trigger when
the object is used in a hash context, just like toString triggers when
it is used in a string context.
-Rasmus
On Sat, 03 Jun 2006 18:50:09 -0700
rasmus@lerdorf.com (Rasmus Lerdorf) wrote:
This works today and basically gives you the same thing. The only
thing it doesn't do is separate an array index context from an output
context allowing you do different things in the two cases.I think if we are going to add a toHash thing, it should trigger when
the object is used in a hash context, just like toString triggers
when it is used in a string context.
Agreed. this is the only solution to limit undesired behaviors, if we
add such magic method.
As well as raising warnings when an object is used as hash without
having this method defined.
-- Pierre
Hello Rasmus, Andi,
first to Andi, there is no BC involved beside the fact that this would
allow objects being used in arrays which wasn't possible before.
Now a hashing value can easily be generated:
char * hash;
int len = spprintf(&hash,0,"%p:%d",Z_OBJ_HT_P(zobj),Z_OBJ_HANDLE_P(zobj));
That said maybe it is enough to add a generic hash function either the
engine or SPL:
/* {{{ proto string spl_object_hash(object obj)
Return hash id for given object */
PHP_FUNCTION(spl_object_hash)
{
zval *obj;
int len;
char *hash;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) {
return;
}
len = spprintf(&hash, 0, "%p:%d", Z_OBJ_HT_P(obj), Z_OBJ_HANDLE_P(obj));
RETURN_STRINGL(hash, len, 0);
}
marcus@zaphod /usr/src/PHP_5_2 $ php -r 'var_dump(spl_object_hash(new stdClass));'
string(11) "0x87b6a40:1"
Maybe we want to scramble this with md5 or something alike:
/* {{{ proto string spl_object_hash(object obj)
Return hash id for given object */
PHP_FUNCTION(spl_object_hash)
{
zval *obj;
int len;
char *hash;
char md5str[33];
PHP_MD5_CTX context;
unsigned char digest[16];
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) {
return;
}
len = spprintf(&hash, 0, "%p:%d", Z_OBJ_HT_P(obj), Z_OBJ_HANDLE_P(obj));
md5str[0] = '\0';
PHP_MD5Init(&context);
PHP_MD5Update(&context, (unsigned char*)hash, len);
PHP_MD5Final(digest, &context);
make_digest(md5str, digest);
RETVAL_STRING(md5str, 1);
efree(hash);
}
marcus@zaphod /usr/src/PHP_5_2 $ php -r 'var_dump(spl_object_hash(new stdClass));'
string(32) "0bab1548e3b42acbcf1170617b5432ae"
For PHP 5.2 we could think about adding a hash handler to the object
handler table and provide the above as default implementation. That hash
handler would then be called when an object is being used as an offset.
Maybe later in PHP 6 we can also add an interface that allows to overload
that hash implementation. (If someone really wants that). Yet anything
the user can overload be it an interface or magic function (e.g. __hashOf)
seems to be too much for now.
Besides that i am meanwhile convinced that __toString shouldn't have to do
anything with objects as array offsets other then it can be requested by
the user thorugh a string cast (e.g.: $ar[(string)$obj]).
best regards
marcus
Sunday, June 4, 2006, 3:50:09 AM, you wrote:
Alan Knowles wrote:
$x = new Obj;
$y[$x]= 123;That behaviour is going to be fun to document, and for people unfamilar
with it to find in the manual
-> php.net/array -> go to array syntax page -> read down to find about
objects as keys -> go to __toHash() page.....whereas...
$x = new Obj;
$y[$x->toHash()]= 123;they might have a chance to see instantly how that is supposed to work,
on the rare occasion that somebody needs this, is it really worth
building it into the langauge????
In that case, why not just use the existing __toString explicitly with:
$x = new Obj;
$y[(string)$x] = 123;
This works today and basically gives you the same thing. The only thing
it doesn't do is separate an array index context from an output context
allowing you do different things in the two cases.
I think if we are going to add a toHash thing, it should trigger when
the object is used in a hash context, just like toString triggers when
it is used in a string context.
-Rasmus
Best regards,
Marcus
Hello,
Hello Rasmus, Andi,
marcus@zaphod /usr/src/PHP_5_2 $ php -r 'var_dump(spl_object_hash(new
stdClass));' string(32) "0bab1548e3b42acbcf1170617b5432ae"For PHP 5.2 we could think about adding a hash handler to the object
handler table and provide the above as default implementation. That
hash handler would then be called when an object is being used as an
offset. Maybe later in PHP 6 we can also add an interface that allows
to overload that hash implementation. (If someone really wants that).
Yet anything the user can overload be it an interface or magic
function (e.g. __hashOf) seems to be too much for now.
Do you mean to allow object as indices with this default
implementation? But this implementataion cannot be overloaded? I fail
to see the needs of such things in 5.x (or 6.x even with overload).
Adding another magic method __toHash is also not what I would like.
Adding a function hash_from_object() or spl_hash_from object() to ease
the generations of hashes is indeed a good idea. There is no impact in
the objects managements and people are free to use it or not (no magic
default behaviors).
--Pierre
Hello Pierre,
Sunday, June 4, 2006, 1:52:41 PM, you wrote:
Hello,
Hello Rasmus, Andi,
marcus@zaphod /usr/src/PHP_5_2 $ php -r 'var_dump(spl_object_hash(new
stdClass));' string(32) "0bab1548e3b42acbcf1170617b5432ae"For PHP 5.2 we could think about adding a hash handler to the object
handler table and provide the above as default implementation. That
hash handler would then be called when an object is being used as an
offset. Maybe later in PHP 6 we can also add an interface that allows
to overload that hash implementation. (If someone really wants that).
Yet anything the user can overload be it an interface or magic
function (e.g. __hashOf) seems to be too much for now.
Do you mean to allow object as indices with this default
implementation? But this implementataion cannot be overloaded? I fail
to see the needs of such things in 5.x (or 6.x even with overload).
Adding another magic method __toHash is also not what I would like.
Adding a function hash_from_object() or spl_hash_from object() to ease
the generations of hashes is indeed a good idea. There is no impact in
the objects managements and people are free to use it or not (no magic
default behaviors).
Hence i wrote "For PHP 5.2 we could think"...
Adding a function hash_from_object() or spl_hash_from object() to ease
the generations of hashes is indeed a good idea. There is no impact in
the objects managements and people are free to use it or not (no magic
default behaviors).Hence i wrote "For PHP 5.2 we could think"...
Yes, and what's the point of this answer?
You should have read my mail as:
-1 for any magic changes
+1 to keep $a[(string)$o]
-1 for __toHash/whatever will be the name of this method
+0 for an extra (and extern) function to get an unique hash of an object
--Pierre
Hello Pierre,
Sunday, June 4, 2006, 2:05:52 PM, you wrote:
Adding a function hash_from_object() or spl_hash_from object() to ease
the generations of hashes is indeed a good idea. There is no impact in
the objects managements and people are free to use it or not (no magic
default behaviors).Hence i wrote "For PHP 5.2 we could think"...
Yes, and what's the point of this answer?
You reply didn't sound like you understood what i wrote. Having a vote from
you makes your thoughts clear also i got it like that already.
And just in case anybody is interested in my voting:
~0 for any magic changes
~0 for __toHash/whatever will be the name of this method
+1 to keep $a[(string)$o]
+1 for an extra (and extern) function to get an unique hash of an object
I would suggest :
a) Make sure $arr[(string)$obj] works (I see no reason for it not to).
b) Look into how to support a unique identifier (-1 on a hash value).
Two main questions are how this thing looks like, and whether it's
explicit (you need to call some function/method to get it) or
implicit (e.g. $arr[$obj]).
A Unique indentifier could look something like "Classname#Object id"
e.g. "SimpleXMLElement#1".
Andi
P.S.-Yep, sticking to bullets keeps emails brief :)
I would suggest :
a) Make sure $arr[(string)$obj] works (I see no reason for it not to).
It already does, nothing needs to be changed or added.
Ilia
Hello Andi,
the classname has not make the id unique. In fact it has nothing to
do with a hash.
best regards
marcus
Sunday, June 4, 2006, 4:26:13 PM, you wrote:
I would suggest :
a) Make sure $arr[(string)$obj] works (I see no reason for it not to).
b) Look into how to support a unique identifier (-1 on a hash value).
Two main questions are how this thing looks like, and whether it's
explicit (you need to call some function/method to get it) or
implicit (e.g. $arr[$obj]).
A Unique indentifier could look something like "Classname#Object id"
e.g. "SimpleXMLElement#1".
Andi
P.S.-Yep, sticking to bullets keeps emails brief :)
Best regards,
Marcus
What extensions today have different objects with the same object ids
(inside a certain class)?
What do you mean it has nothing to do with hash? Don't understand
what you mean.
At 07:56 AM 6/4/2006, Marcus Boerger wrote:
Hello Andi,
the classname has not make the id unique. In fact it has nothing to
do with a hash.
best regards
marcusSunday, June 4, 2006, 4:26:13 PM, you wrote:
I would suggest :
a) Make sure $arr[(string)$obj] works (I see no reason for it not to).
b) Look into how to support a unique identifier (-1 on a hash value).
Two main questions are how this thing looks like, and whether it's
explicit (you need to call some function/method to get it) or
implicit (e.g. $arr[$obj]).A Unique indentifier could look something like "Classname#Object id"
e.g. "SimpleXMLElement#1".Andi
P.S.-Yep, sticking to bullets keeps emails brief :)
Best regards,
Marcus
Hello Andi,
it was your own argument that the id itself is not unique when some
time ago somebody wanted to have access to that id from userland. And
it is also the reason for SplObjectStorage the way it is today.
By 'it hash' nothing to do with hash' i mean that the classname does
not belong into a hash.
best regards
marcus
Sunday, June 4, 2006, 4:58:34 PM, you wrote:
What extensions today have different objects with the same object ids
(inside a certain class)?
What do you mean it has nothing to do with hash? Don't understand
what you mean.
At 07:56 AM 6/4/2006, Marcus Boerger wrote:
Hello Andi,
the classname has not make the id unique. In fact it has nothing to
do with a hash.
best regards
marcusSunday, June 4, 2006, 4:26:13 PM, you wrote:
I would suggest :
a) Make sure $arr[(string)$obj] works (I see no reason for it not to).
b) Look into how to support a unique identifier (-1 on a hash value).
Two main questions are how this thing looks like, and whether it's
explicit (you need to call some function/method to get it) or
implicit (e.g. $arr[$obj]).A Unique indentifier could look something like "Classname#Object id"
e.g. "SimpleXMLElement#1".Andi
P.S.-Yep, sticking to bullets keeps emails brief :)
Best regards,
Marcus
Best regards,
Marcus
At 08:08 AM 6/4/2006, Marcus Boerger wrote:
Hello Andi,
it was your own argument that the id itself is not unique when some
time ago somebody wanted to have access to that id from userland. And
it is also the reason for SplObjectStorage the way it is today.
The object id itself is not unique, but coupled with the class name
it is. All this means is that the unique id has to be a string and
not a number. I mentioned in the past that it'd be a problem to have
a number as the unique id.
By 'it hash' nothing to do with hash' i mean that the classname does
not belong into a hash.
My point is that the string "ClassName#id" is what would be the
unique identifier. e.g. that's what toKey() would return (assuming
we'd want such a method).
Andi
Hello Andi,
the classname doesn't help, it is the handler that you need. In theory
you can have two objects with the same id and classname but not with the
same id and handler table.
best regards
marcus
Sunday, June 4, 2006, 5:14:46 PM, you wrote:
At 08:08 AM 6/4/2006, Marcus Boerger wrote:
Hello Andi,
it was your own argument that the id itself is not unique when some
time ago somebody wanted to have access to that id from userland. And
it is also the reason for SplObjectStorage the way it is today.
The object id itself is not unique, but coupled with the class name
it is. All this means is that the unique id has to be a string and
not a number. I mentioned in the past that it'd be a problem to have
a number as the unique id.
By 'it hash' nothing to do with hash' i mean that the classname does
not belong into a hash.
My point is that the string "ClassName#id" is what would be the
unique identifier. e.g. that's what toKey() would return (assuming
we'd want such a method).
Andi
Best regards,
Marcus
MB>> the classname doesn't help, it is the handler that you need. In
MB>>theory you can have two objects with the same id and classname but not
MB>>with the same id and handler table.
Yes, theoretically you could have two modules returning same class names
for their objects, though it would be extremely bad practice to do it.
Bigger problem is, however, that object handler doesn't really have to
give you any meaningful class name at all - for all it worth it can always
return something like "No class name".
Stanislav Malyshev, Zend Products Engineer
stas@zend.com http://www.zend.com/ +972-3-6139665 ext.115
At 08:22 AM 6/4/2006, Stanislav Malyshev wrote:
MB>> the classname doesn't help, it is the handler that you need. In
MB>>theory you can have two objects with the same id and classname but not
MB>>with the same id and handler table.Yes, theoretically you could have two modules returning same class names
for their objects, though it would be extremely bad practice to do it.Bigger problem is, however, that object handler doesn't really have to
give you any meaningful class name at all - for all it worth it can always
return something like "No class name".
We should probably make this a requirement and I don't know of one
today that doesn't have an associated class name. I believe some
parts of PHP might blow up if this isn't supported.
Andi
AG>>We should probably make this a requirement and I don't know of one
AG>>today that doesn't have an associated class name. I believe some parts
AG>>of PHP might blow up if this isn't supported.
There are parts that can blow up if get_class_name is NULL
or returns NULL
(though good practice would be to filter such places out but I'm not sure
it was ever accomplished) - however it doesn't have to be NULL
to be a
problem. Imagine two extensions that bridge external objects - e.g., Java
and .Net one - that attempt to return real class of an object, but if it
doesn't succeed (e.g., internal reflection doesn't work for some reason)
they return "???" instead. It's not that good, but we can't catch it and
we can't even put up a requirement out saying "your 'don't know' value
should be different from other's" - how's one supposed to know what
other's value is? And if you don't do something very unrelated would break
in very strange ways - so it's be quite hard even point to what is the
cause.
So in fact classname here would not be a good idea for ID. Handler table,
however, combined with object handle seems to be good way to ID an object
- it's how the engine identifies them after all...
--
Stanislav Malyshev, Zend Products Engineer
stas@zend.com http://www.zend.com/ +972-3-6139665 ext.115
Hello Stanislav,
do you remember any reason why we have the current layout with the zval
pointing to a handler and that having a function which returns a pointer
to the class_entry as well as a function that returns the name?
struct _zend_object_handlers {
[...]
zend_object_get_class_entry_t get_class_entry;
zend_object_get_class_name_t get_class_name;
typedef struct _zend_object_value {
zend_object_handle handle;
zend_object_handlers *handlers;
} zend_object_value;
And wouldn't it be faster to drop both handlers from the table and
instead have zend_object_value have a pointer to zend_class_entry
and that a pounter to the handler table?
best regards
marcus
Sunday, June 4, 2006, 5:42:02 PM, you wrote:
AG>>>We should probably make this a requirement and I don't know of one
AG>>>today that doesn't have an associated class name. I believe some parts
AG>>>of PHP might blow up if this isn't supported.
There are parts that can blow up if get_class_name is
NULL
or returnsNULL
(though good practice would be to filter such places out but I'm not sure
it was ever accomplished) - however it doesn't have to beNULL
to be a
problem. Imagine two extensions that bridge external objects - e.g., Java
and .Net one - that attempt to return real class of an object, but if it
doesn't succeed (e.g., internal reflection doesn't work for some reason)
they return "???" instead. It's not that good, but we can't catch it and
we can't even put up a requirement out saying "your 'don't know' value
should be different from other's" - how's one supposed to know what
other's value is? And if you don't do something very unrelated would break
in very strange ways - so it's be quite hard even point to what is the
cause.
So in fact classname here would not be a good idea for ID. Handler table,
however, combined with object handle seems to be good way to ID an object
- it's how the engine identifies them after all...
Best regards,
Marcus
MB>>typedef struct _zend_object_value {
MB>> zend_object_handle handle;
MB>> zend_object_handlers *handlers;
MB>>} zend_object_value;
MB>>
MB>>And wouldn't it be faster to drop both handlers from the table and
MB>>instead have zend_object_value have a pointer to zend_class_entry
MB>>and that a pounter to the handler table?
Not quite - since not all objects have zend_class_entry for them so you
couldn't actually use it - unless you insert check each time and write
code to handle both cases - using zend_class_entry pointer and using
something else - so it's actually easier to do the right thing from the
start and use the handlers. Of course, you could "optimize" it for the
case zend_class_entry exists and add the zend_class_entry field into the
object value - but IMHO the resulting code and model complication would do
much more harm than speed improvement on saving one function call (which
I'm not sure is of any significance). Also, this would inevitably lead to
creating code which forgets to use handlers and breaks in all kinds of
funny ways on overloaded objects. My opinion is that it is better to have
one consistent API.
As for the question why there are two handlers - because class name is
useful in all kinds of contexts like backtaces, exceptions, messages, etc.
even though you may not have zend_class_entry - so it's a possibility for
the overloaded object to give maximum iformation there.
Stanislav Malyshev, Zend Products Engineer
stas@zend.com http://www.zend.com/ +972-3-6139665 ext.115
Yes, I realize that but it doesn't happen today and I don't think we
couldn't make this a rule (requiring extensions to have unique id's
per classes). In any case, we can always make it the following string:
"id=<ht table address in hex>#unique id"
Andi
At 08:18 AM 6/4/2006, Marcus Boerger wrote:
Hello Andi,
the classname doesn't help, it is the handler that you need. In theory
you can have two objects with the same id and classname but not with the
same id and handler table.best regards
marcusSunday, June 4, 2006, 5:14:46 PM, you wrote:
At 08:08 AM 6/4/2006, Marcus Boerger wrote:
Hello Andi,
it was your own argument that the id itself is not unique when some
time ago somebody wanted to have access to that id from userland. And
it is also the reason for SplObjectStorage the way it is today.The object id itself is not unique, but coupled with the class name
it is. All this means is that the unique id has to be a string and
not a number. I mentioned in the past that it'd be a problem to have
a number as the unique id.By 'it hash' nothing to do with hash' i mean that the classname does
not belong into a hash.My point is that the string "ClassName#id" is what would be the
unique identifier. e.g. that's what toKey() would return (assuming
we'd want such a method).Andi
Best regards,
Marcus
Yes, I realize that but it doesn't happen today and I don't think we couldn't
make this a rule (requiring extensions to have unique id's per classes). In
any case, we can always make it the following string:
"id=<ht table address in hex>#unique id"
And that is exactly what Marcus already suggested:
char * hash;
int len = spprintf(&hash,0,"%p:%d",Z_OBJ_HT_P(zobj),Z_OBJ_HANDLE_P(zobj));
regards,
Derick
--
Derick Rethans
http://derickrethans.nl | http://ez.no | http://xdebug.org
Again, I don't think we should have a hash but a unique id which can
be used as an array key and in other things. Difference. Hash implies
that it's not unique, I'm talking about unique. So yes, I'd take the
starting point of Marcus' proposal but:
a) Make the value start with a letter so that this isn't
autoconverted but taken as a literal string key. Again, something
like "id=%p:%d"
b) Not call it hash because I see this as a unique id and not as a
hash value which is not unique necessarily.
c) This should be something outside SPL and part of the engine.
Question is again, whether it's explicit or implicit (back to the
question I had earlier). Do you just want to add a function which
returns this thing or do you want $arr[$obj] to automatically ask for it.
These are valid questions and should be answered.
Andi
At 08:41 AM 6/4/2006, Derick Rethans wrote:
Yes, I realize that but it doesn't happen today and I don't think
we couldn't
make this a rule (requiring extensions to have unique id's per classes). In
any case, we can always make it the following string:
"id=<ht table address in hex>#unique id"And that is exactly what Marcus already suggested:
char * hash; int len =
spprintf(&hash,0,"%p:%d",Z_OBJ_HT_P(zobj),Z_OBJ_HANDLE_P(zobj));
regards,
Derick--
Derick Rethans
http://derickrethans.nl | http://ez.no | http://xdebug.org
Again, I don't think we should have a hash but a unique id which can be used
as an array key and in other things. Difference. Hash implies that it's not
unique, I'm talking about unique.
Instead of all those hacky ways to come up with IDs, why don't se simply
change the engine not to reuse those IDs in the first place? Seems to
solve quite a few problems.
Derick
--
Derick Rethans
http://derickrethans.nl | http://ez.no | http://xdebug.org
At 09:05 AM 6/4/2006, Derick Rethans wrote:
Again, I don't think we should have a hash but a unique id which
can be used
as an array key and in other things. Difference. Hash implies that it's not
unique, I'm talking about unique.Instead of all those hacky ways to come up with IDs, why don't se simply
change the engine not to reuse those IDs in the first place? Seems to
solve quite a few problems.
Because the idea is that each extension can control its own object
storage if needed. If it gets a centralized id with an arbitrary
limit (say 32bit) then they'd all have to use hashes for the storage
instead of arrays. It's actually a beneficial thing that we decoupled
the extensions.
There is no reason why a string key such as I suggested, wouldn't
solve your problems of lack of id...
Andi
Andi Gutmans wrote:
Again, I don't think we should have a hash but a unique id which can be
used as an array key and in other things. Difference. Hash implies that
it's not unique, I'm talking about unique. So yes, I'd take the starting
point of Marcus' proposal but:
a) Make the value start with a letter so that this isn't autoconverted
but taken as a literal string key. Again, something like "id=%p:%d"
b) Not call it hash because I see this as a unique id and not as a hash
value which is not unique necessarily.
c) This should be something outside SPL and part of the engine. Question
is again, whether it's explicit or implicit (back to the question I had
earlier). Do you just want to add a function which returns this thing or
do you want $arr[$obj] to automatically ask for it.These are valid questions and should be answered.
I think if we implement a way to get a hash from an object, or at least
a unique identifier that can be used as a hash, then it should be
implicit just like other things are implicitly converted when the
context is clear. Of course, you should also be able to force it
explicitly. And I don't think there is any point in doing this unless
we also implicitly go the other way. From unique identifier to object.
As in:
class foo { function bar($arg) { echo $arg; } }
$obj1 = new foo;
$obj2 = new foo;
$a = array($obj1=>1,$obj2=>2);
foreach($a as $k=>$v) {
$k->bar($v);
}
Unless this works, I am not sure there is any point to all this. To me
the end goal is to make it possible to use types other than strings and
numbers as array indices which to me also means we should look at doing
the same for arrays.
-Rasmus
Need to think about that but I remembered after I sent my email that
I was wrong about something like "num:num" (e.g. "3:4") requiring to
start with a letter in order not to be auto-converted to a numbered
index. The reason for the confusion is the behavior of strtol() in:
print "3:4" + 1;
Which will convert "3:4" to "3".
Anyway, will think a bit more about your email and hopefully have
some more ideas by tomorrow.
Thx.
Andi
At 09:17 AM 6/4/2006, Rasmus Lerdorf wrote:
Andi Gutmans wrote:
Again, I don't think we should have a hash but a unique id which
can be used as an array key and in other things. Difference. Hash
implies that it's not unique, I'm talking about unique. So yes, I'd
take the starting point of Marcus' proposal but:
a) Make the value start with a letter so that this isn't
autoconverted but taken as a literal string key. Again, something
like "id=%p:%d"
b) Not call it hash because I see this as a unique id and not as a
hash value which is not unique necessarily.
c) This should be something outside SPL and part of the engine.
Question is again, whether it's explicit or implicit (back to the
question I had earlier). Do you just want to add a function which
returns this thing or do you want $arr[$obj] to automatically ask for it.
These are valid questions and should be answered.I think if we implement a way to get a hash from an object, or at
least a unique identifier that can be used as a hash, then it should
be implicit just like other things are implicitly converted when the
context is clear. Of course, you should also be able to force it
explicitly. And I don't think there is any point in doing this
unless we also implicitly go the other way. From unique identifier
to object. As in:class foo { function bar($arg) { echo $arg; } }
$obj1 = new foo;
$obj2 = new foo;$a = array($obj1=>1,$obj2=>2);
foreach($a as $k=>$v) {
$k->bar($v);
}Unless this works, I am not sure there is any point to all this. To
me the end goal is to make it possible to use types other than
strings and numbers as array indices which to me also means we
should look at doing the same for arrays.-Rasmus
Hello Andi,
you don't read my proposals, do you? If you read them you will find
that i actually proposed to add a function that uses exactly what you
just wrote here.
best regards
marcus
Sunday, June 4, 2006, 5:35:25 PM, you wrote:
Yes, I realize that but it doesn't happen today and I don't think we
couldn't make this a rule (requiring extensions to have unique id's
per classes). In any case, we can always make it the following string:
"id=<ht table address in hex>#unique id"
Andi
At 08:18 AM 6/4/2006, Marcus Boerger wrote:
Hello Andi,
the classname doesn't help, it is the handler that you need. In theory
you can have two objects with the same id and classname but not with the
same id and handler table.best regards
marcusSunday, June 4, 2006, 5:14:46 PM, you wrote:
At 08:08 AM 6/4/2006, Marcus Boerger wrote:
Hello Andi,
it was your own argument that the id itself is not unique when some
time ago somebody wanted to have access to that id from userland. And
it is also the reason for SplObjectStorage the way it is today.The object id itself is not unique, but coupled with the class name
it is. All this means is that the unique id has to be a string and
not a number. I mentioned in the past that it'd be a problem to have
a number as the unique id.By 'it hash' nothing to do with hash' i mean that the classname does
not belong into a hash.My point is that the string "ClassName#id" is what would be the
unique identifier. e.g. that's what toKey() would return (assuming
we'd want such a method).Andi
Best regards,
Marcus
Best regards,
Marcus
Rasmus Lerdorf wrote:
I think if we are going to add a toHash thing, it should trigger when
the object is used in a hash context, just like toString triggers when
it is used in a string context.
This makes sense to me, too.
--
Sebastian Bergmann http://www.sebastian-bergmann.de/
GnuPG Key: 0xB85B5D69 / 27A7 2B14 09E4 98CD 6277 0E5B 6867 C514 B85B 5D69
Whichever way we go, the key would have to be either an integer or a
string (since that's what array indices can be), and going with an
integer here sounds like a really bad idea (chances of it colliding
with numeric indices are reasonably high on a 32-bit system). So if
we go with (a), it would definitely have to be a string as you
suggested. Not sure what's the best way to create a unique,
one-to-one mapped string representation of an object. If we can't
find a solution to that one, then it pretty much brings us to (b).
Zeev
At 03:57 04/06/2006, Andi Gutmans wrote:
Generally I think it's a good thing to allow to use objects as array indexes.
There are really two ways of doing it:
a) Try and find a way to create unique ideas.
b) Support __toString() and leave it up to the author.I have a bit of a hard time finding a solution to (a) unless the
unique id is a string. Not that I think having it as a string is
necessarily a bad thing but I'd be interested in hearing what others think.
Supporting __toString() is the easiest way to go, especially as it
wouldn't lead to BC breaks. It would be up to the author to make
that a unique key like "Db#Person#1" but then they couldn't use
that with "print" because the value the class author would want
there would probably not be the one he'd want in array access.Anyone got any thoughts, how bad of a break it would be if we did
create a unique id of objects, whether string or int? That's
something we probably could do for PHP 6 esp. if string is acceptable.Andi
At 09:38 AM 6/3/2006, Marcus Boerger wrote:
Hello Andrew,
Saturday, June 3, 2006, 4:36:39 PM, you wrote:
Hello guys,
the attached patch closes one more __toString() part. It allows
to use objects that define __toString as indexes to arrays. What do
you guys think about this, should we add it or stay with the old
behavior that didn't allow objects as indexes at all.Like others who have contributed to the thread I agree that it would be
useful, but I think using __toString() wrong for this. There is a
confusion two ideas here:
1. The string representation of an object, probably human
readable, lucent string.
2. A unique hash of an object use to identify it programmatically,
and likely unique. Probably a non-human friendly, opaque value.
These are not the same thing. The latter is what, IMO, would be used
for an objects value as an index into an array, not the former.The latter is available ... currently I do this like so:
class a{ public function __toString() { return 'an object';}}
$foo = new a;
$bar = new a;
$arr = new array()
$arr[(string)$foo] = $foo; // The index is "Object id #1"
$arr[(string)$bar] = $bar; // The index is "Object id #2"
Note that the __tostring method is not used in the cast - a spearate
issue, but needs to be pointed out for this issue.Therefore my suggested alternative to Marcus' patch is:
When Objects are used in array index context, use the object ID or some
variation. And, possibly, provide a magic method, or interface to
generate an hash value of an object.We cannot use the object id since that is not necessarily unique.
For the same reason SplObjectStorage cannot be done in userland.
However what you mention here is right. Other languages offer to
magic functions. A stringify one and a hashing one. But then again
i don't think we should add yet another magic feature.best regards
marcus
I think this is a potentially missing bit of functionality we
definitely need to consider including. There is really no technical
reason why $foo[new ToStringObject] = "bar"; cannot work or a reason
why it shouldn't as far as functionality goes.
Ilia Alshanetsky
Hello guys,
the attached patch closes one more __toString() part. It allows
to use objects that define __toString as indexes to arrays. What do
you guys think about this, should we add it or stay with the old
behavior that didn't allow objects as indexes at all.--
Best regards,
Marcus mailto:mail@marcus-boerger.de
<ze2-offset-obj-tostring-20060603.diff.txt
I don't understand why using the object as an index would trigger a
__toString() call. PHP's array indices are not defined to be strings,
so I don't see this as being a string context use and thus __toString()
shouldn't be called.
I also don't see why we need to make a distinction between the key and
the value here if there is any way we can avoid it.
For example, this obviously works:
class foo {
function a() { echo "a"; }
}
$a = new foo();
$b[1] = $a;
$b[1]->a();
Why shouldn't this?
$b[$a] = 1;
key($b)->a();
I have always looked a PHP array as having 2 places to store things.
You can store stuff in the key with the caveat/feature that it must be
unique and you can store whatever you want in the value part. Only
allowing strings and integers in the key seems like an arbitrary
restriction to me. As long as the key is something we can somehow
uniquely identify I think we should aim to support it.
-Rasmus
Ilia Alshanetsky wrote:
I think this is a potentially missing bit of functionality we definitely
need to consider including. There is really no technical reason why
$foo[new ToStringObject] = "bar"; cannot work or a reason why it
shouldn't as far as functionality goes.Ilia Alshanetsky
Hello guys,
the attached patch closes one more __toString() part. It allows
to use objects that define __toString as indexes to arrays. What do
you guys think about this, should we add it or stay with the old
behavior that didn't allow objects as indexes at all.--Best regards,
Marcus mailto:mail@marcus-boerger.de
<ze2-offset-obj-tostring-20060603.diff.txt
Hello Rasmus,
though you are probably right here your idea brought to it's full
extend will bring a major BC break. Just consider we had both key
and value as a zval then the current behavior would change for quite
a lot of situations including not only objects and resources but also
booleans, floats and NULL.
Right now everybody is used to the restiction that an array key can
only be a string or an integer and if not it is either not acceptable
as a key at all or is being converted to either one.
best regards
marcus
Saturday, June 3, 2006, 6:30:38 PM, you wrote:
I don't understand why using the object as an index would trigger a
__toString() call. PHP's array indices are not defined to be strings,
so I don't see this as being a string context use and thus __toString()
shouldn't be called.
I also don't see why we need to make a distinction between the key and
the value here if there is any way we can avoid it.
For example, this obviously works:
class foo {
function a() { echo "a"; }
}
$a = new foo();
$b[1] = $a;
$b[1]->a();
Why shouldn't this?
$b[$a] = 1;
key($b)->a();
I have always looked a PHP array as having 2 places to store things.
You can store stuff in the key with the caveat/feature that it must be
unique and you can store whatever you want in the value part. Only
allowing strings and integers in the key seems like an arbitrary
restriction to me. As long as the key is something we can somehow
uniquely identify I think we should aim to support it.
-Rasmus
Ilia Alshanetsky wrote:
I think this is a potentially missing bit of functionality we definitely
need to consider including. There is really no technical reason why
$foo[new ToStringObject] = "bar"; cannot work or a reason why it
shouldn't as far as functionality goes.Ilia Alshanetsky
Hello guys,
the attached patch closes one more __toString() part. It allows
to use objects that define __toString as indexes to arrays. What do
you guys think about this, should we add it or stay with the old
behavior that didn't allow objects as indexes at all.--Best regards,
Marcus mailto:mail@marcus-boerger.de
<ze2-offset-obj-tostring-20060603.diff.txt>--
Best regards,
Marcus
Right, just let me clarify. My point here was that if we are going to
make a change here, we should do it correctly and come up with a way to
create a unique hash of the object so it really can be used as an array
index. Magically calling __toString() in a case where we don't have an
explicit string context sounds half-assed and non-obvious to me. If you
want that ability, simply do: $a[(string)$obj] and it is obvious what
you are doing.
-Rasmus
Marcus Boerger wrote:
Hello Rasmus,
though you are probably right here your idea brought to it's full
extend will bring a major BC break. Just consider we had both key
and value as a zval then the current behavior would change for quite
a lot of situations including not only objects and resources but also
booleans, floats and NULL.Right now everybody is used to the restiction that an array key can
only be a string or an integer and if not it is either not acceptable
as a key at all or is being converted to either one.best regards
marcusSaturday, June 3, 2006, 6:30:38 PM, you wrote:
I don't understand why using the object as an index would trigger a
__toString() call. PHP's array indices are not defined to be strings,
so I don't see this as being a string context use and thus __toString()
shouldn't be called.I also don't see why we need to make a distinction between the key and
the value here if there is any way we can avoid it.For example, this obviously works:
class foo {
function a() { echo "a"; }
}
$a = new foo();
$b[1] = $a;
$b[1]->a();Why shouldn't this?
$b[$a] = 1;
key($b)->a();I have always looked a PHP array as having 2 places to store things.
You can store stuff in the key with the caveat/feature that it must be
unique and you can store whatever you want in the value part. Only
allowing strings and integers in the key seems like an arbitrary
restriction to me. As long as the key is something we can somehow
uniquely identify I think we should aim to support it.-Rasmus
Ilia Alshanetsky wrote:
I think this is a potentially missing bit of functionality we definitely
need to consider including. There is really no technical reason why
$foo[new ToStringObject] = "bar"; cannot work or a reason why it
shouldn't as far as functionality goes.Ilia Alshanetsky
Hello guys,
the attached patch closes one more __toString() part. It allows
to use objects that define __toString as indexes to arrays. What do
you guys think about this, should we add it or stay with the old
behavior that didn't allow objects as indexes at all.--Best regards,
Marcus mailto:mail@marcus-boerger.de
<ze2-offset-obj-tostring-20060603.diff.txt>--
Best regards,
Marcus
RL>>I don't understand why using the object as an index would trigger a
RL>>__toString() call. PHP's array indices are not defined to be strings,
RL>>so I don't see this as being a string context use and thus
RL>>__toString() shouldn't be called.
If so, what should be the actual key in the hash?
--
Stanislav Malyshev, Zend Products Engineer
stas@zend.com http://www.zend.com/ +972-3-6139665 ext.115
Stanislav Malyshev wrote:
RL>>I don't understand why using the object as an index would trigger a
RL>>__toString() call. PHP's array indices are not defined to be strings,
RL>>so I don't see this as being a string context use and thus
RL>>__toString() shouldn't be called.If so, what should be the actual key in the hash?
I am sure we could come up with some sort of hashing mechanism that
would uniquely identify an object. And perhaps even expose it to the
user with a __hashOf(). But again, I am not sure we want to open up
that can of worms. Like I said, I think this is the more correct
approach and that we shouldn't try to use a magic __toString() call here
to attempt to emulate this.
-Rasmus
RL>>I don't understand why using the object as an index would
trigger a RL>>__toString() call. PHP's array indices are not
defined to be strings, RL>>so I don't see this as being a string
context use and thus
RL>>__toString() shouldn't be called.
If so, what should be the actual key in the hash?
I am sure we could come up with some sort of hashing mechanism that
would uniquely identify an object. And perhaps even expose it to
the user with a __hashOf(). But again, I am not sure we want to
open up that can of worms. Like I said, I think this is the more
correct approach and that we shouldn't try to use a magic __toString
() call here to attempt to emulate this.
I'm new to this list, so I apologize if I'm out of line in commenting
here, but it's my opinion that the advantages offered by a __hash()
magic function would outweigh the inevitable complexity and issues
involved. I imagine that it would be a strict semantic: If the class
of the object being indexed into the array doesn't define a magic
__hash() function, it would be a warning or even fatal error; no
attempt would/should be made to calculate a hash based on anything
other than what the object is willing to call itself.
Gwynne
SkyTag Software
-----BEGIN PGP SIGNED MESSAGE-----
Hash: RIPEMD160
Gwynne wrote:
I'm new to this list, so I apologize if I'm out of line in commenting
here, but it's my opinion that the advantages offered by a __hash()
magic function would outweigh the inevitable complexity and issues
involved. I imagine that it would be a strict semantic: If the class of
the object being indexed into the array doesn't define a magic __hash()
function, it would be a warning or even fatal error; no attempt
would/should be made to calculate a hash based on anything other than
what the object is willing to call itself.
I would imagine that __hash() or whatever it is called would be defined
on all objects and implemented internally in PHP, and would simply
generate some internal hash that is unique for all objects.
Jasper Bryant-Greene
General Manager
Album Limited
http://www.album.co.nz/ 0800 4 ALBUM
jasper@album.co.nz 021 708 334
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.3 (MingW32)
iD8DBQFEgglOFfAeHhDzT4gRA2JtAKC3rkHI6QGo5yYQyHBbuZzG068D6wCgqej3
QqtgAcCeC5qo8ja2oCB4aUw=
=2C/T
-----END PGP SIGNATURE
I would imagine that __hash() or whatever it is called would be
defined
on all objects and implemented internally in PHP, and would simply
generate some internal hash that is unique for all objects.
That might work for initial testing, but applying that sort of hash
function to objects identified purely by strings, to take one
example, doesn't work. (in_array(new Str("A"), array(new Str("A")))
is one failure mode that comes instantly to mind. It's inevitable
that two non-identical objects would contain identical data. Think of
the reasons behind C++'s operator==, or for those of you familiar
with Carbon programming under MacOS, the hash callbacks provided by
CoreFoundation's various container types.
Gwynne
SkyTag Software
Gwynne wrote:
no attempt
would/should be made to calculate a hash based on anything other than
what the object is willing to call itself.
+1 here
oo people have a name for that.
and implement what's needed.
I'm surely out of talk , but please keep indexes scalar.
The toString way is anyway rotten.
The id way for an object is headaches.
toggg
Marcus Boerger wrote:
Hello guys,
the attached patch closes one more __toString() part. It allows
to use objects that define __toString as indexes to arrays. What do
you guys think about this, should we add it or stay with the old
behavior that didn't allow objects as indexes at all.
I prefer to require an explicit (string) cast to use an object as an
array index. The "can't use objects as array index" has actually helped
me catch many subtle bugs that were slipping through in earlier PHP
versions, I very much like this fatal error. I don't see this:
$a = $b[$c];
being much clearer to understand than:
$a = $b[$c];
or better yet
$a = $b[$c->person()];
which is by far the clearest and easiest to debug (and results in a
fatal error if $c is the wrong kind of object or the wrong string - even
better for debugging)
Thanks,
Greg
In case we can't find a solution Andi's (a) approach, I think I like
the explicit cast approach better than just implicitly converting to
string. Rasmus pointed out that it's not clear why of all types PHP
would implicitly convert the object to a string, and chances are that
he's not the only person that will be surprised by that behavior.
Zeev
At 06:20 04/06/2006, Greg Beaver wrote:
Marcus Boerger wrote:
Hello guys,
the attached patch closes one more __toString() part. It allows
to use objects that define __toString as indexes to arrays. What do
you guys think about this, should we add it or stay with the old
behavior that didn't allow objects as indexes at all.I prefer to require an explicit (string) cast to use an object as an
array index. The "can't use objects as array index" has actually helped
me catch many subtle bugs that were slipping through in earlier PHP
versions, I very much like this fatal error. I don't see this:$a = $b[$c];
being much clearer to understand than:
$a = $b[$c];
or better yet
$a = $b[$c->person()];
which is by far the clearest and easiest to debug (and results in a
fatal error if $c is the wrong kind of object or the wrong string - even
better for debugging)Thanks,
Greg
Marcus Boerger wrote:
Hello guys,
the attached patch closes one more __toString() part. It allows
to use objects that define __toString as indexes to arrays. What do
you guys think about this, should we add it or stay with the old
behavior that didn't allow objects as indexes at all.
-1 on automatic __toString()
+1 on explicit (string) cast (as it is now)
+0 on __toHash()/__toKey() (which must be implemented explicitly)
Rasmus' idea of changing the HashKey is... duh... at least something
to think some more time about.
Regards,
Michael
Marcus Boerger wrote:
Hello guys,
the attached patch closes one more __toString() part. It allows
to use objects that define __toString as indexes to arrays. What do
you guys think about this, should we add it or stay with the old
behavior that didn't allow objects as indexes at all.-1 on automatic __toString()
+1 on explicit (string) cast (as it is now)
+0 on __toHash()/__toKey() (which must be implemented explicitly)
I changed my mind :)
-1 on automatic __toString()
+1 on explicit (string) cast
-1 on __toHash/__toKey
+1 on unique object identifiers
regards,
Derick
There will be a BC problem with classes implementing ArrayAccess where the
array key is passed to offsetXXX methods as it is. And there we have objects
also allowed as parameters.
2006/6/3, Marcus Boerger mail@marcus-boerger.de:
Hello guys,
the attached patch closes one more __toString() part. It allows
to use objects that define __toString as indexes to arrays. What do
you guys think about this, should we add it or stay with the old
behavior that didn't allow objects as indexes at all.--
Best regards,
Marcus mailto:mail@marcus-boerger.de
I am sorry if I missed the whole thread. I think that using the
result of __toString() for indexing objects is a bad idea. If we want
to allow this behavior (which is actually useful in some situations),
I'd rather we had a __hash() method or something similar to what
Python does. The string representation of the object and its hashed
representation may be very different.
-Andrei
Hello guys,
the attached patch closes one more __toString() part. It allows
to use objects that define __toString as indexes to arrays. What do
you guys think about this, should we add it or stay with the old
behavior that didn't allow objects as indexes at all.--
Best regards,
Marcus mailto:mail@marcus-boerger.de
<ze2-offset-obj-tostring-20060603.diff.txt
I am sorry if I missed the whole thread. I think that using the
result of __toString() for indexing objects is a bad idea. If we want
to allow this behavior (which is actually useful in some situations),
I'd rather we had a __hash() method or something similar to what
Python does. The string representation of the object and its hashed
representation may be very different.
After sitting on the fence on this one for a few days, I agree with
Andrei.
For example, for an eBay Item object, my __toString() returns the
Title, but that's not unique, so my __toHash() returns the numeric ID,
which is.
Furthermore, if my __toString() was unique, and I was relying on that
for keys in an array, I would have to mark that method as final;
otherwise, someone might unknowingly destroy the uniqueness in a child
class and break my code. That's not ideal because there could
otherwise be many good reasons that someone would want to override
__toString().
In contrast, it's unlikely that you would override __toHash(), and
it's pretty obvious that you shouldn't do something that could cause
collisions.
The other proposal, where PHP generates a unique object id, would also
be fine. Even better, perhaps. I'm not sure what I think yet.
-adam
--
adam@trachtenberg.com | http://www.trachtenberg.com
author of o'reilly's "upgrading to php 5" and "php cookbook"
avoid the holiday rush, buy your copies today!
For example, for an eBay Item object, my __toString() returns the
Title, but that's not unique, so my __toHash() returns the numeric ID,
which is.
While I wouldn't be surprised if you completely ignore my opinion, however I
think the __toHash implementation should happen in an interface, rather than
happening automagically. That will make it just a little bit more
predicatable.
Michael
For example, for an eBay Item object, my __toString() returns the
Title, but that's not unique, so my __toHash() returns the numeric
ID,
which is.
While I wouldn't be surprised if you completely ignore my opinion,
however I
think the __toHash implementation should happen in an interface,
rather than
happening automagically. That will make it just a little bit more
predicatable.
+1 on that from me. There is definitely a use for a __toHash() magic
function WITHOUT it being automagical. An automagical one would
probably lead to a lot of confusion and odd behaviors. Let people use
the feature if they need it and ignore it otherwise.
However, if it was automagical, I'd agree with previous comments:
Make it a string based on the hash table pointer.
Gwynne
SkyTag Software
For example, for an eBay Item object, my __toString() returns the
Title, but that's not unique, so my __toHash() returns the numeric
ID,
which is.
While I wouldn't be surprised if you completely ignore my opinion,
however I
think the __toHash implementation should happen in an interface,
rather than
happening automagically. That will make it just a little bit more
predicatable.+1 on that from me. There is definitely a use for a __toHash() magic
function WITHOUT it being automagical. An automagical one would
probably lead to a lot of confusion and odd behaviors. Let people use
the feature if they need it and ignore it otherwise.
But enforcing it's use via an interface means class users that don't
want to use interfaces now need to use interfaces. Also the other
magical functions aren't linked to interfaces, why change tradition?
Cheers,
Rob.
.------------------------------------------------------------.
| InterJinn Application Framework - http://www.interjinn.com |
:------------------------------------------------------------:
| An application and templating framework for PHP. Boasting |
| a powerful, scalable system for accessing system services |
| such as forms, properties, sessions, and caches. InterJinn |
| also provides an extremely flexible architecture for |
| creating re-usable components quickly and easily. |
`------------------------------------------------------------'
the attached patch closes one more __toString() part. It allows
to use objects that define __toString as indexes to arrays. What do
you guys think about this, should we add it or stay with the old
behavior that didn't allow objects as indexes at all.
I use objects rarely, and am not sure I care all that much, but...
Seems to me that there is a REALLY good chance that there ARE scripts
"out there" that rely on current behaviour of:
$a = new Foo();
$arr[$a] = 42;
Never mind that that's a really dumb thing to have -- Somebody is
relying on it doing whatever it does...
Whether that is erroring out or just turning all objects into ""
doesn't matter. Somebody relies on it doing the same thing it always
did.
Don't break that, please, in 5.2 -- Do whatever you want in 6.0 on that.
This all seems like much ado about nothing to me. Anybody brainy
enough to NEED their objects as array indices can probably manage to
write a function to uniquely identify their/all objects.
Sorry if my votes aren't fitting into the schema of voting... I kinda
got glassy-eyed with this whole thread, to tell the truth.
--
Like Music?
http://l-i-e.com/artists.htm
As far as I can see, and I'm sure someone will be kind enough to correct me
if I'm wrong, but there is no current behaviour for it, it returns a
warning.
$a = new stdClass;
$b[$a] = 0;
Warning: Illegal offset type in t3.php on line 2
And results in an empty array (in this case) so it does nothing.
-bok
the attached patch closes one more __toString() part. It allows
to use objects that define __toString as indexes to arrays. What do
you guys think about this, should we add it or stay with the old
behavior that didn't allow objects as indexes at all.I use objects rarely, and am not sure I care all that much, but...
Seems to me that there is a REALLY good chance that there ARE scripts
"out there" that rely on current behaviour of:$a = new Foo();
$arr[$a] = 42;Never mind that that's a really dumb thing to have -- Somebody is
relying on it doing whatever it does...Whether that is erroring out or just turning all objects into ""
doesn't matter. Somebody relies on it doing the same thing it always
did.Don't break that, please, in 5.2 -- Do whatever you want in 6.0 on that.
This all seems like much ado about nothing to me. Anybody brainy
enough to NEED their objects as array indices can probably manage to
write a function to uniquely identify their/all objects.Sorry if my votes aren't fitting into the schema of voting... I kinda
got glassy-eyed with this whole thread, to tell the truth.--
Like Music?
http://l-i-e.com/artists.htm--
--
Xnyo - http://xnyo.odynia.org/
That IS a current behaviour.
Returns a warning and leaves the array un-modified.
As far as I can see, and I'm sure someone will be kind enough to
correct me
if I'm wrong, but there is no current behaviour for it, it returns a
warning.$a = new stdClass;
$b[$a] = 0;Warning: Illegal offset type in t3.php on line 2
And results in an empty array (in this case) so it does nothing.
-bok
the attached patch closes one more __toString() part. It allows
to use objects that define __toString as indexes to arrays. What
do
you guys think about this, should we add it or stay with the old
behavior that didn't allow objects as indexes at all.I use objects rarely, and am not sure I care all that much, but...
Seems to me that there is a REALLY good chance that there ARE
scripts
"out there" that rely on current behaviour of:$a = new Foo();
$arr[$a] = 42;Never mind that that's a really dumb thing to have -- Somebody is
relying on it doing whatever it does...Whether that is erroring out or just turning all objects into ""
doesn't matter. Somebody relies on it doing the same thing it
always
did.Don't break that, please, in 5.2 -- Do whatever you want in 6.0 on
that.This all seems like much ado about nothing to me. Anybody brainy
enough to NEED their objects as array indices can probably manage to
write a function to uniquely identify their/all objects.Sorry if my votes aren't fitting into the schema of voting... I
kinda
got glassy-eyed with this whole thread, to tell the truth.--
Like Music?
http://l-i-e.com/artists.htm--
--
Xnyo - http://xnyo.odynia.org/
--
Like Music?
http://l-i-e.com/artists.htm
-----BEGIN PGP SIGNED MESSAGE-----
Hash: RIPEMD160
All I've got to say on the matter is that if anyone is relying on that
kind of behaviour for something serious, then their code deserves to break.
Jasper
Richard Lynch wrote:
That IS a current behaviour.
Returns a warning and leaves the array un-modified.
As far as I can see, and I'm sure someone will be kind enough to
correct me
if I'm wrong, but there is no current behaviour for it, it returns a
warning.$a = new stdClass;
$b[$a] = 0;Warning: Illegal offset type in t3.php on line 2
And results in an empty array (in this case) so it does nothing.
-bok
the attached patch closes one more __toString() part. It allows
to use objects that define __toString as indexes to arrays. What
do
you guys think about this, should we add it or stay with the old
behavior that didn't allow objects as indexes at all.
I use objects rarely, and am not sure I care all that much, but...Seems to me that there is a REALLY good chance that there ARE
scripts
"out there" that rely on current behaviour of:$a = new Foo();
$arr[$a] = 42;Never mind that that's a really dumb thing to have -- Somebody is
relying on it doing whatever it does...Whether that is erroring out or just turning all objects into ""
doesn't matter. Somebody relies on it doing the same thing it
always
did.Don't break that, please, in 5.2 -- Do whatever you want in 6.0 on
that.This all seems like much ado about nothing to me. Anybody brainy
enough to NEED their objects as array indices can probably manage to
write a function to uniquely identify their/all objects.Sorry if my votes aren't fitting into the schema of voting... I
kinda
got glassy-eyed with this whole thread, to tell the truth.--
Like Music?
http://l-i-e.com/artists.htm--
--
Xnyo - http://xnyo.odynia.org/
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFEhJWZFfAeHhDzT4gRA82mAJ4xoaVLaWdN98sgiKBLoI2BNVlqNQCgw6tb
8sayHh6bHy+540r+gYMwxwk=
=10rp
-----END PGP SIGNATURE
You miss the point. The warning that is helpful in debugging, it has
nothing to do with designing things to break, it has to do with
unintentional bugs. If in 1 case of 1000 in a loop, there is an object
instead of a string used as a key due to a bug (one example: this can
easily happen if you forget to check for a PEAR_Error on return from a
legacy PEAR class), a warning is printed. With some kind of magic
conversion, this warning will instead translate into a magic conversion
to string, causing unpredictable and very difficult-to-track-down behavior.
Greg
Jasper Bryant-Greene wrote:
All I've got to say on the matter is that if anyone is relying on that
kind of behaviour for something serious, then their code deserves to break.Jasper
Richard Lynch wrote:
That IS a current behaviour.
Returns a warning and leaves the array un-modified.
As far as I can see, and I'm sure someone will be kind enough to
correct me
if I'm wrong, but there is no current behaviour for it, it returns a
warning.$a = new stdClass;
$b[$a] = 0;Warning: Illegal offset type in t3.php on line 2
And results in an empty array (in this case) so it does nothing.
-bok
the attached patch closes one more __toString() part. It allows
to use objects that define __toString as indexes to arrays. Whatdo
you guys think about this, should we add it or stay with the old
behavior that didn't allow objects as indexes at all.I use objects rarely, and am not sure I care all that much, but...
Seems to me that there is a REALLY good chance that there ARE
scripts
"out there" that rely on current behaviour of:$a = new Foo();
$arr[$a] = 42;Never mind that that's a really dumb thing to have -- Somebody is
relying on it doing whatever it does...Whether that is erroring out or just turning all objects into ""
doesn't matter. Somebody relies on it doing the same thing it
always
did.Don't break that, please, in 5.2 -- Do whatever you want in 6.0 on
that.This all seems like much ado about nothing to me. Anybody brainy
enough to NEED their objects as array indices can probably manage to
write a function to uniquely identify their/all objects.Sorry if my votes aren't fitting into the schema of voting... I
kinda
got glassy-eyed with this whole thread, to tell the truth.--
Like Music?
http://l-i-e.com/artists.htm--
--
Xnyo - http://xnyo.odynia.org/
Marcus Boerger wrote:
the attached patch closes one more __toString() part. It allows
to use objects that define __toString as indexes to arrays. What do
you guys think about this, should we add it or stay with the old
behavior that didn't allow objects as indexes at all.
+1
--
Sebastian Bergmann http://www.sebastian-bergmann.de/
GnuPG Key: 0xB85B5D69 / 27A7 2B14 09E4 98CD 6277 0E5B 6867 C514 B85B 5D69
We probably should support this, but not only for __toString().
Objects may also have internal get() (not __get()) and cast() handlers that
should be supported too.
Also usage of cast() in context of array offset don't say what do we like
"int" or "string".
Thanks. Dmitry.
-----Original Message-----
From: Marcus Boerger [mailto:mail@marcus-boerger.de]
Sent: Saturday, June 03, 2006 3:42 PM
To: internals@lists.php.net
Cc: Dmitry Stogov; Andi Gutmans; Zeev Suraski; Ilia Alshanetsky
Subject: [PHP-DEV] Missing __toString() partHello guys,
the attached patch closes one more __toString() part. It
allows to use objects that define __toString as indexes to
arrays. What do you guys think about this, should we add it
or stay with the old behavior that didn't allow objects as
indexes at all.--
Best regards,
Marcus mailto:mail@marcus-boerger.de