|
Posted by james.gauth on 06/25/07 08:27
On 22 Jun, 02:15, Jerry Stuckle <jstuck...@attglobal.net> wrote:
> james.ga...@googlemail.com wrote:
> > I agree with Gosha Bine, PHP prides itself with maintaining backward
> > compatibility (so much so that there's an unbelievable amount of cruft
> > in the language) yet they choose to break backward compatibility with
> > something like this? Why not allow a way to extend the base object
> > prototype to reproduce the old behaviour (or a more descriptive
> > behaviour)? Or why not, if a __toString() method isn't found, print
> > 'Object' instead of throwing an exception?
>
> No, PHP has been lousy at maintaining backward compatibility.
Well, since you're using such a convincing argument here, I'll just go
ahead and refute your statement shall I? Here's the entire list of
backward incompatible changes made from a MAJOR revision in PHP (4-5):
http://uk.php.net/manual/en/migration5.incompatible.php
Almost all PHP4 code works perfectly in PHP5. I have to say, that's
definitely lousy backward compatibility isn't it?
> > Even the manual still states:
> > Objects are always converted to the string "Object". If you would like
> > to print out the member variable values of an object for debugging
> > reasons, read the paragraphs below. If you would like to find out the
> > class name of which an object is an instance of, use get_class(). As
> > of PHP 5, __toString() method is used if applicable.
>
> Which version are you looking at? I don't see this in my 5.2.21
> version. But it's not unusual for doc to lag the actual code changes, -
> in PHP or any other product.
I'm looking at the online version, the version you'd expect to be up-
to-date. The paragraph is contained here:
http://uk3.php.net/manual/en/language.types.string.php#language.types.string.casting
PHP 5.2 was introduced on the 2nd of November 2006. I hope you're not
suggesting that the online manual is suffering from 7 months of lag.
> Irregardless, they do say they will use the __tostring() method, if
> available.
They say 'if applicable'. In addition to being vague, it infers that
there might be cases where __toString() isn't used. Cases where the
default 'Object' casting would be used can reasonably be assumed to
be: IN CASES WHERE __toString() IS NOT DEFINED.
> Good programmers wouldn't leave something like this to the
> compiler/interpreter; they'd define it themselves, anyway. Otherwise
> you're just asking for bugs.
Good programmers might not leave it up to the compiler/interpreter,
but then again, good programmers could do this before they made it
fatal. You could always check a variable's type before using it in a
string context, there's no reasonable gain in usability by forcing it
on you. As a side note, breaking backward compatibility is just asking
for bugs too.
> > No warning is given that if a __toString() method isn't defined it'll
> > throw an exception and handily fatal for you (since PHP 5.2). They
> > even state that a __toString() method is used 'if applicable'. I'm
> > guessing 'if applicable' in this case actually means 'without question
> > and will cause a fatal error in your scripts if you don't define it
> > when casting an object to a string'.
>
> Gee, just like any other missing method. Again - EXACTLY which version
> of the doc are you using?
The crux of this argument is that __toString() shouldn't have to be
defined, therefore it wouldn't be a missing method. Again, the ONLINE
version. Would you like me to paste the URL again? I'll do that:
http://uk3.php.net/manual/en/language.types.string.php#language.types.string.casting
> > You *do* gain something from an implicit conversion to 'Object', you
> > gain the sure knowledge that string type-casting will work in *all*
> > cases regardless of variable type. You do not have to check what the
> > type of a variable is every time you would like to use it in a string
> > capacity. It's as if PHP is desperately trying to not be a loosely
> > typed language any more. The half-baked type-hinting feature is a
> > great example of this.
>
> You gain a FALSE COMFORT that a string casting will work in some usable
> manner.
Converting to the string 'Object' is perfectly usable for me. It's
certainly not harmful. It'd be a FALSE COMFORT if there was a REAL
DANGER in converting an object to 'Object' but there isn't. My code
doesn't suddenly become HIGHLY UNSTABLE if I define __toString()
methods which return 'Object'.
> > You lose far more from having your language behave inconsistently
> > between releases than you gain from forcing mandatory redundant coding
> > constructs. No mention is made in the change log with regards to what
> > is a reasonably intrinsic change to the language (type-casting should
> > be set in stone, or people should at least be made aware of it if it's
> > changed).
>
> You gain consistency - because now you are defining the __tostring()
> method in a manner which makes sense to your program (and your class).
> Not something PHP has to guess at.
You lose consistency - because whereas previously you could use any
variable type in a string context, you can no longer do that. The old
behaviour was not guesswork, you supplied an object in a string
context, it became 'Object'.
> In case you don't get it - I'm all for this change. I think one of
> their more serious mistakes was to implement to implicit string
> conversion for user-defined objects in the first place. It just
> encourages more sloppy programming.
I think one of your more serious mistakes is believing that an $object
variable is anything other than the internal type 'Object'. There is
no magical difference between the conversion of an array, a resource
or an object to a string. They all (or used to) return results
consistent with each other. Why doesn't PHP fatal on the following
code?
<code>
$a = new StdClass();
$b = new StdClass();
$c = $a + $b; // $c is now 2
</code>
PHP casts an object to an integer because it maintains the 'everything
can cast to an integer' premise.
Here's some more if you like:
<code>
$a = new StdClass();
$a->foo = 'bar';
var_dump($a);
var_dump((int)$a);
var_dump((bool)$a);
var_dump((float)$a);
var_dump((array)$a);
var_dump((object)$a);
var_dump((string)$a); // WHOOPS! FATAL
</code>
Now tell me that PHP causing a fatal unless you write __toString()
handlers improves consistency.
[Back to original message]
|