|
Posted by Jerry Stuckle on 06/27/07 13:32
james.gauth@googlemail.com wrote:
> On 26 Jun, 23:29, Jerry Stuckle <jstuck...@attglobal.net> wrote:
>> james.ga...@googlemail.com wrote:
>>> On 22 Jun, 02:15, Jerry Stuckle <jstuck...@attglobal.net> wrote:
>> I know PHP is in transition - and many of these changes needed to be
>> made. But they required major rewrites of code. They wouldn't have if
>> the language had been better planned from the start.
>
> This is exactly the point, better planning. A half-baked operator
> overloading scheme which breaks backward compatibility is not
> evolution, it's feature creep.
>
> There are two better options that they could've considered:
> a) Implement operator overloading in its entirety and allow the base
> object prototype to be overloaded
That would be a major change to the language. Not that I'm against it -
I love it in C++ and miss it in Java. But I've also seen it abused more
than used (properly, that is).
> b) Implement this system but only issue a notice or a warning when a
> __toString() method is not found
>
And do what when the method is not found? I prefer the "clean cut".
You only need to change things once, and people won't forget about it in
new code.
Your way people will just ignore the notice and at some later time will
get caught.
>
>>>>> 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.
>> Yes, but you took the statement out of context. When it says it will
>> use the __tostring() method if applicable, it is talking about if that
>> is an object vs. some other type. It says nothing about whether the
>> system provides a __tostring() function or not.
>
> The documentation is already marked as a bug here so I guess the
> designers agree that it's vague:
> http://bugs.php.net/bug.php?id=41750
>
OK, I don't read it that way. But OTOH I grew up in the IBM world,
where such doc is the norm :-)
>
>>>> 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.
>> As I said above, there are numerous instances of much more severe
>> changes which break backward compatibility.
>
> The numerous instances you mentioned all had very long deprecation
> periods and a way to turn the old functionality back on again. If we
> change our APIs we notify our clients and provide them a sufficient
> amount of time to change their code. No notification was made and no
> deprecation period was given.
>
You didn't say anything about "very long deprecation periods". You
spoke only of incompatibilities. I mentioned several which required
major rewrites of the code.
IMHO It would have been much better to make a clean cut on each of
these, also. Just search through the forum here. There are all kinds
of examples of people writing NEW CODE requiring register_globals to be
on. The same is true with short tags, for instance.
Creating a long deprecation period doesn't solve the problem - it just
delays it. And since new code also uses those deprecated features, the
longer the deprecation period the worse the problem gets.
>
>>> 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'.
>> Fine, then create a __tostring() function which returns an Object.
>
> Try doing that with StdClass.
>
Why?
Actually, it would be incorrect to have a __tostring() function which
returns an object. It needs to return a string.
>
>>>>> 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'.
>> Sure you can - as long as you define a __tostring() function for the
>> class. No problem. Are you saying this is too hard for you to do?
>
> You can't define __toString() methods for PHP built-in objects. You
> can't fill an array with a mixed set of variables and pass it to
> implode() if it contains a PHP built-in object.
>
Gee, you know, the same is true for C++ and Java. But you can extend a
PHP built-in object and add your own __tostring() function to it.
Pretty simple.
> I'm saying that in some dark recess of some dark hole there's bound to
> be a library which I have no control over which makes use of an object
> in a string context and causes a fatal error in a place where it would
> be innocuous to simply convert it to 'Object'. Here we go, here's some
> code in WURFL (wurfl.sourceforge.net):
>
> function _toLog($func, $text, $requestedLogLevel=LOG_NOTICE){
> global $wurfl_conf;
>
> if ( !defined('LOG_LEVEL') || LOG_LEVEL == 0 ) {
> return;
> }
> if ( $requestedLogLevel == LOG_ERR ) {
> $warn_banner = 'ERROR: ';
> } else if ( $requestedLogLevel == LOG_WARNING ) {
> $warn_banner = 'WARNING: ';
> } else {
> $warn_banner = '';
> }
> //echo "Opening ".$wurfl_conf['WURFL_LOG_FILE']."<br/>\n";
> $uname = posix_uname();
> $_textToLog = date('r')." [".$uname['nodename']."
> ".posix_getpid()."]"."[$func] ".$warn_banner . $text;
> $_logFP = fopen($wurfl_conf['WURFL_LOG_FILE'], "a+");
> fputs($_logFP, $_textToLog."\n");
> fclose($_logFP);
> return;
> }
>
> Which is more appropriate: Breaking code like this (leading to
> possible database inconsistency, or any other amount of problems from
> a mid-execution fatal) or issuing a warning and retaining the old
> functionality?
>
I would much rather see the error so I could fix the problem properly.
But where is this using a predefined __tostring() function, anyway? I
don't see it. So the question is irrelevant.
>
>> An array or a resource are PHP-defined types. A
>> user-defined object is not. Huge difference. The PHP compiler can
>> handle PHP defined types.
>
> An instantiation of a user defined class is a variable of the type
> 'Object'. It's still a PHP-defined type, just because you populate an
> object with data or attach functions to a class doesn't change that.
> Explain the huge difference because I really must be missing something
> here.
>
No, it is no longer a PHP-defined type. It is a user-defined type. It
may be derived from a PHP-defined type, but that does not make it
PHP-defined.
>
>>> <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.
>> Your fatal error looks perfectly fine to me. Maybe eventually they will
>> fix the other errors which allow invalid casting, also.
>
> Yeah, and maybe eventually they'll drop the whole loosely typed
> façade, implement namespaces and rename the language Java.
>
What an asinine comment.
--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstucklex@attglobal.net
==================
[Back to original message]
|