Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.php > #10542 > unrolled thread
| Started by | Fiver <numeralfive@gmail.com> |
|---|---|
| First post | 2013-08-17 06:55 +0200 |
| Last post | 2013-08-17 13:28 -0400 |
| Articles | 15 on this page of 35 — 10 participants |
Back to article view | Back to comp.lang.php
switch with case 0 Fiver <numeralfive@gmail.com> - 2013-08-17 06:55 +0200
Re: switch with case 0 "J.O. Aho" <user@example.net> - 2013-08-17 08:35 +0200
Re: switch with case 0 The Natural Philosopher <tnp@invalid.invalid> - 2013-08-17 08:29 +0100
Re: switch with case 0 Luuk <luuk@invalid.lan> - 2013-08-17 09:51 +0200
Re: switch with case 0 Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> - 2013-08-17 13:16 +0200
Re: switch with case 0 "Peter H. Coffin" <hellsop@ninehells.com> - 2013-08-17 10:56 -0500
Re: switch with case 0 The Natural Philosopher <tnp@invalid.invalid> - 2013-08-17 17:45 +0100
Re: switch with case 0 Tim Streater <timstreater@greenbee.net> - 2013-08-17 18:58 +0100
Re: switch with case 0 The Natural Philosopher <tnp@invalid.invalid> - 2013-08-17 19:39 +0100
Re: switch with case 0 Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> - 2013-08-17 21:36 +0200
Re: switch with case 0 Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> - 2013-08-17 22:14 +0200
Re: switch with case 0 Norman Peelman <npeelman@cfl.rr.com> - 2013-08-17 13:56 -0400
Re: switch with case 0 Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> - 2013-08-17 21:55 +0200
Re: switch with case 0 The Natural Philosopher <tnp@invalid.invalid> - 2013-08-17 21:04 +0100
Re: switch with case 0 Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> - 2013-08-17 22:32 +0200
Re: switch with case 0 Richard Yates <richard@yatesguitar.com> - 2013-08-17 15:20 -0700
Re: switch with case 0 Fiver <numeralfive@gmail.com> - 2013-08-17 22:37 +0200
Re: switch with case 0 Norman Peelman <npeelman@cfl.rr.com> - 2013-08-17 19:26 -0400
Re: switch with case 0 The Natural Philosopher <tnp@invalid.invalid> - 2013-08-18 12:54 +0100
Re: switch with case 0 Norman Peelman <npeelman@cfl.rr.com> - 2013-08-17 20:23 -0400
Re: switch with case 0 Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> - 2013-08-18 15:22 +0200
Re: switch with case 0 Norman Peelman <npeelman@cfl.rr.com> - 2013-08-18 11:20 -0400
Re: switch with case 0 Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> - 2013-08-18 18:28 +0200
Re: switch with case 0 Norman Peelman <npeelman@cfl.rr.com> - 2013-08-18 15:16 -0400
Re: switch with case 0 Norman Peelman <npeelman@cfl.rr.com> - 2013-08-18 18:04 -0400
Re: switch with case 0 Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> - 2013-08-19 00:17 +0200
Re: switch with case 0 Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> - 2013-08-19 00:13 +0200
Re: switch with case 0 The Natural Philosopher <tnp@invalid.invalid> - 2013-08-19 00:35 +0100
Re: switch with case 0 Norman Peelman <npeelman@cfl.rr.com> - 2013-08-19 06:30 -0400
Re: switch with case 0 Norman Peelman <npeelman@cfl.rr.com> - 2013-08-18 22:13 -0400
Re: switch with case 0 Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> - 2013-08-19 19:55 +0200
Re: switch with case 0 Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-08-19 10:18 +0200
Re: switch with case 0 Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> - 2013-08-19 19:39 +0200
Re: switch with case 0 Fiver <numeralfive@gmail.com> - 2013-08-17 16:15 +0200
Re: switch with case 0 Norman Peelman <npeelman@cfl.rr.com> - 2013-08-17 13:28 -0400
Page 2 of 2 — ← Prev page 1 [2]
| From | Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> |
|---|---|
| Date | 2013-08-18 15:22 +0200 |
| Message-ID | <kuqhr8$csc$1@news.albasani.net> |
| In reply to | #10572 |
Norman Peelman schrieb:
> Why is it unreasonable? After all, FORM data is all strings to begin
> with. PHP will type juggle "12345" to 12345 just fine. The whole idea
> behind this after all is not about having strings like "2foo".
GET/POST data arrive as strings, yes. So the first thing one does in a
PHP script is to validate that data and convert it *explicitly* to the
correct type. One does not "leave" it as string and expect PHP to
convert it *implicitly* later on, because one may well have cases where
there is a string like "42" or "2foo" which is supposed to remain a
string and be treated as a string and not as a number.
> FORM data, GET/POST data, all strings...
I heard you the first time.
>>>>>> switch ($mode) {
>>>>>> case SORT_ASC:
>>>>>> case SORT_DESC:
>>>>>> case SORT_REGULAR:
>>>>>> case SORT_NUMERIC:
>>>>>> case SORT_STRING:
>>>>>> case SORT_LOCALE_STRING:
>>>>>> case SORT_NATURAL:
>>>>>> case SORT_FLAG_CASE:
>>>>>> break;
>>>>>> default:
>>>>>> throw new \InvalidArgumentException("invalid sort mode:
>>>>>> $mode");
>>>>>> }
>>>>
>> No I'm not assuming that. If all the SORT_* constants are integers, then
>> only the default branch should match in that case. It doesn't in PHP,
>> because PHP is made to implicitly convert strings to integers.
>
> No, the only time the default is reached is when $mode is outside 0-7
I wrote "in that case" referring to $mode = "foo".
> (I say that because i only have 6 of the 8, I haven't updated yet.) If
> $mode = E_ERROR it still validates. This code does nothing to ensure
> $mode is what it is supposed to be.
Yes, different constants could have the same value and there is no way
for PHP to tell which one was "used" to pass the value. So you could
pass E_ERROR instead of SORT_FOO if both happen to have the same value.
It would be nice, though, to be able to detect that.
>
> What about:
> -- code --
> $mode = setSortMode("SORT_NUMERIC");
> echo $mode."\n";
That would be a workaround to achieve the above. But I find it not very
elegant to use a string in this case.
> Technically speaking, the user should not be able to *choose* an
> invalid mode but if they somehow did, I believe it should default to
> some normal behavior (even if the result isn't what they wanted.) In
> other words, default to SORT_REGULAR (pick your poison) until another
> *valid* option is chosen.
Or the code should throw an exception if an invalid argument is passed.
(After all, it's the programmer's job to ensure no invalid arguments are
passed to any function, so if it happens, it's the programmer's fault
and must be fixed.)
>> I am aware of the fact that PHP will try to convert the string into a
>> number (even when this would not possibly make any sense).
>
> How do you know when it wouldn't make sense?
Trying to convert "foo" to a number doesn't make sense. It only makes
sense when the string contains the representation of a number. That
said, if there happened to be a defined constant foo = 42, then (int)
"foo" could reasonably result in int(42). But in any case, a conversion
from string to number should never happen implicitly -- only explicitly.
> FORMS, GET/POST data = strings...
I heard you the first time.
But just to be clear, let me repeat myself once more: *explicit*
conversion from string to number is okay as long as it returns `null`
(or some other appropriate indication) in case of the string not
representing a valid number. *Implicit* conversion from string to number
is bad. Whenever there's a string and a number and PHP is supposed to do
something with them (like comparing via `<=`), it should convert the
number to a string and not the other way round.
Greetings,
Thomas
--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
[toc] | [prev] | [next] | [standalone]
| From | Norman Peelman <npeelman@cfl.rr.com> |
|---|---|
| Date | 2013-08-18 11:20 -0400 |
| Message-ID | <kuqool$m0p$1@dont-email.me> |
| In reply to | #10574 |
On 08/18/2013 09:22 AM, Thomas Mlynarczyk wrote:
> Norman Peelman schrieb:
>
>> Why is it unreasonable? After all, FORM data is all strings to begin
>> with. PHP will type juggle "12345" to 12345 just fine. The whole idea
>> behind this after all is not about having strings like "2foo".
>
> GET/POST data arrive as strings, yes. So the first thing one does in a
> PHP script is to validate that data and convert it *explicitly* to the
PHP started *before* the big validation era...
> correct type. One does not "leave" it as string and expect PHP to
> convert it *implicitly* later on, because one may well have cases where
> there is a string like "42" or "2foo" which is supposed to remain a
> string and be treated as a string and not as a number.
>
PHP doesn't just randomly decide to type juggle, it does so in
context. If you want a string "42", you have it. PHP won't do anything
to it until you try to do some math with it (or explicitly ask it to do so.)
>> FORM data, GET/POST data, all strings...
>
> I heard you the first time.
>
>>>>>>> switch ($mode) {
>>>>>>> case SORT_ASC:
>>>>>>> case SORT_DESC:
>>>>>>> case SORT_REGULAR:
>>>>>>> case SORT_NUMERIC:
>>>>>>> case SORT_STRING:
>>>>>>> case SORT_LOCALE_STRING:
>>>>>>> case SORT_NATURAL:
>>>>>>> case SORT_FLAG_CASE:
>>>>>>> break;
>>>>>>> default:
>>>>>>> throw new \InvalidArgumentException("invalid sort mode:
>>>>>>> $mode");
>>>>>>> }
>>>>>
>
>>> No I'm not assuming that. If all the SORT_* constants are integers, then
>>> only the default branch should match in that case. It doesn't in PHP,
>>> because PHP is made to implicitly convert strings to integers.
>>
>> No, the only time the default is reached is when $mode is outside 0-7
>
> I wrote "in that case" referring to $mode = "foo".
>
>> (I say that because i only have 6 of the 8, I haven't updated yet.) If
>> $mode = E_ERROR it still validates. This code does nothing to ensure
>> $mode is what it is supposed to be.
>
> Yes, different constants could have the same value and there is no way
> for PHP to tell which one was "used" to pass the value. So you could
> pass E_ERROR instead of SORT_FOO if both happen to have the same value.
> It would be nice, though, to be able to detect that.
>
>>
>> What about:
>> -- code --
>> $mode = setSortMode("SORT_NUMERIC");
>> echo $mode."\n";
>
> That would be a workaround to achieve the above. But I find it not very
> elegant to use a string in this case.
>
>> Technically speaking, the user should not be able to *choose* an
>> invalid mode but if they somehow did, I believe it should default to
>> some normal behavior (even if the result isn't what they wanted.) In
>> other words, default to SORT_REGULAR (pick your poison) until another
>> *valid* option is chosen.
>
> Or the code should throw an exception if an invalid argument is passed.
> (After all, it's the programmer's job to ensure no invalid arguments are
> passed to any function, so if it happens, it's the programmer's fault
> and must be fixed.)
>
>>> I am aware of the fact that PHP will try to convert the string into a
>>> number (even when this would not possibly make any sense).
>>
>> How do you know when it wouldn't make sense?
>
> Trying to convert "foo" to a number doesn't make sense. It only makes
> sense when the string contains the representation of a number.
Thomas, methinks you've decided to be dense... PHP has to *look* at
the string to determine that.
> That said, if there happened to be a defined constant foo = 42, then (int)
> "foo" could reasonably result in int(42). But in any case, a conversion
There is no constant "foo". If created, it would be foo. So, no
(int)"foo" should not result in a constant foo value. constant("foo")
does that just fine.
> from string to number should never happen implicitly -- only explicitly.
>
PHP type juggles when you ask it to do so (right/wrong/mistake). If
it did it implicitly then it would happen before you ever got to the data.
>> FORMS, GET/POST data = strings...
>
> I heard you the first time.
>
> But just to be clear, let me repeat myself once more: *explicit*
> conversion from string to number is okay as long as it returns `null`
"foo" + 2 = 2
NULL + 2 = 2
> (or some other appropriate indication) in case of the string not
> representing a valid number. *Implicit* conversion from string to number
> is bad. Whenever there's a string and a number and PHP is supposed to do
> something with them (like comparing via `<=`), it should convert the
> number to a string and not the other way round.
>
> Greetings,
> Thomas
>
--
Norman
Registered Linux user #461062
-Have you been to www.php.net yet?-
[toc] | [prev] | [next] | [standalone]
| From | Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> |
|---|---|
| Date | 2013-08-18 18:28 +0200 |
| Message-ID | <kuqsnr$3gu$1@news.albasani.net> |
| In reply to | #10575 |
Norman Peelman schrieb:
> PHP started *before* the big validation era...
This may be true, but does that mean we should not validate in PHP? ;-)
> PHP doesn't just randomly decide to type juggle, it does so in
> context. If you want a string "42", you have it. PHP won't do anything
> to it until you try to do some math with it (or explicitly ask it to do
> so.)
Well, unfortunately, <, <=, >, >= and switch give you no possibility to
prevent unwanted string->int casts. For equality checks, you can use ===
and !==, but there are no corresponding operators for <, > etc. And
that's the problem.
>> Trying to convert "foo" to a number doesn't make sense. It only makes
>> sense when the string contains the representation of a number.
>
> Thomas, methinks you've decided to be dense... PHP has to *look* at
> the string to determine that.
Methinks differently, but... Of course, PHP has to look. Just looking is
okay. Messing up is not. But if PHP never tried to look at the string by
itself -- only when being told to -- things would be much better.
>> That said, if there happened to be a defined constant foo = 42, then
>> (int)
>> "foo" could reasonably result in int(42). But in any case, a conversion
> There is no constant "foo". If created, it would be foo. So, no
> (int)"foo" should not result in a constant foo value. constant("foo")
> does that just fine.
Oh come on, my English is certainly not perfect, but please -- just a
little effort trying to understand what I say...? Again:
Suppose you have a string "foo" and your task is to convert it to an
integer. Normally, you'd think there's no reasonable way to do that. But
if there happened to be a constant foo = 42 defined, it would seem
reasonable to assume that the string "foo" might refer to that constant
and therefore convert "foo" to 42. No, I'm not talking about what PHP
*is* currently doing in such a situation, I'm talking about how a
computer language should be designed to behave in such a situation.
> PHP type juggles when you ask it to do so (right/wrong/mistake). If it
> did it implicitly then it would happen before you ever got to the data.
With "foo" < 42, PHP will convert "foo" to 0 and then "do" 0 < 42.
That's what I call implicit conversion and please correct me if my usage
of that word happens to be wrong. Explicit would be (int) "foo" < 42.
> "foo" + 2 = 2
> NULL + 2 = 2
It boils down to this: "foo" + 2 doesn't mean anything. In order to mean
something, both operands must be of the same type. So, either
"foo" + (string) 2 = "foo" + "2" = "foo2"
as other languages would handle this, or
(int) "foo" + 2 = ??? + 2 = ???
or throw an exception to complain about incompatible operands.
If (int) $somevar yields 0 with $somevar = "foo", then I have no way of
knowing whether the 0 is the "legitimate" result of the cast or whether
it just means "couldn't cast that to a number, giving you back 0
instead". But if in case of failure `null` is returned, I can look at
the result of (int) $somevar and if it's `null` (and not an integer) I
know the cast failed and I can react accordingly.
Greetings,
Thomas
--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
[toc] | [prev] | [next] | [standalone]
| From | Norman Peelman <npeelman@cfl.rr.com> |
|---|---|
| Date | 2013-08-18 15:16 -0400 |
| Message-ID | <kur6jc$4om$1@dont-email.me> |
| In reply to | #10576 |
On 08/18/2013 12:28 PM, Thomas Mlynarczyk wrote:
> Norman Peelman schrieb:
>
>> PHP started *before* the big validation era...
>
> This may be true, but does that mean we should not validate in PHP? ;-)
>
By all means no...
>> PHP doesn't just randomly decide to type juggle, it does so in
>> context. If you want a string "42", you have it. PHP won't do anything
>> to it until you try to do some math with it (or explicitly ask it to
>> do so.)
>
> Well, unfortunately, <, <=, >, >= and switch give you no possibility to
> prevent unwanted string->int casts. For equality checks, you can use ===
> and !==, but there are no corresponding operators for <, > etc. And
> that's the problem.
>
$mode = "fop";
echo (($mode === "$mode") AND ($mode <= "foo")) ? "True\n" : "False\n";
>>> Trying to convert "foo" to a number doesn't make sense. It only makes
>>> sense when the string contains the representation of a number.
>>
>> Thomas, methinks you've decided to be dense... PHP has to *look* at
>> the string to determine that.
>
> Methinks differently, but... Of course, PHP has to look. Just looking is
> okay. Messing up is not. But if PHP never tried to look at the string by
> itself -- only when being told to -- things would be much better.
>
When you are comparing things, you are asking PHP to look at them...
>>> That said, if there happened to be a defined constant foo = 42, then
>>> (int)
>>> "foo" could reasonably result in int(42). But in any case, a conversion
>
>> There is no constant "foo". If created, it would be foo. So, no
>> (int)"foo" should not result in a constant foo value. constant("foo")
>> does that just fine.
>
> Oh come on, my English is certainly not perfect, but please -- just a
> little effort trying to understand what I say...?
I don't believe I misunderstood at all... (int)"???" could end up
matching any CONSTANT by accident. Talk about getting unknown
quantities... and your English is just fine. :)
> Again:
> Suppose you have a string "foo" and your task is to convert it to an
> integer. Normally, you'd think there's no reasonable way to do that. But
> if there happened to be a constant foo = 42 defined, it would seem
> reasonable to assume that the string "foo" might refer to that constant
> and therefore convert "foo" to 42. No, I'm not talking about what PHP
> *is* currently doing in such a situation, I'm talking about how a
> computer language should be designed to behave in such a situation.
>
>> PHP type juggles when you ask it to do so (right/wrong/mistake). If
>> it did it implicitly then it would happen before you ever got to the
>> data.
>
> With "foo" < 42, PHP will convert "foo" to 0 and then "do" 0 < 42.
> That's what I call implicit conversion and please correct me if my usage
> of that word happens to be wrong. Explicit would be (int) "foo" < 42.
>
>> "foo" + 2 = 2
>> NULL + 2 = 2
>
> It boils down to this: "foo" + 2 doesn't mean anything. In order to mean
> something, both operands must be of the same type. So, either
>
> "foo" + (string) 2 = "foo" + "2" = "foo2"
>
> as other languages would handle this, or
To me that's the same problem in reverse. + is math, . is
concatination. + needs/wants numbers, . needs/wants strings. You don't
ADD strings, you JOIN/CONCATINATE them.
>
> (int) "foo" + 2 = ??? + 2 = ???
>
= 0 + 2 = 2
"foo" . 2 = "foo2"
> or throw an exception to complain about incompatible operands.
>
> If (int) $somevar yields 0 with $somevar = "foo", then I have no way of
> knowing whether the 0 is the "legitimate" result of the cast or whether
> it just means "couldn't cast that to a number, giving you back 0
> instead". But if in case of failure `null` is returned, I can look at
> the result of (int) $somevar and if it's `null` (and not an integer) I
> know the cast failed and I can react accordingly.
>
Ok Thomas, lets think this through. If a string $somevar contains a
number, you get cast that number. If the cast results in 0 because
$somevar either does not contain a number or contains "0", does it
matter? If 0 is not an acceptable result, you the programmer should more
than likely be coding for that anyway.
> Greetings,
> Thomas
>
--
Norman
Registered Linux user #461062
-Have you been to www.php.net yet?-
[toc] | [prev] | [next] | [standalone]
| From | Norman Peelman <npeelman@cfl.rr.com> |
|---|---|
| Date | 2013-08-18 18:04 -0400 |
| Message-ID | <kurgec$4nd$1@dont-email.me> |
| In reply to | #10577 |
On 08/18/2013 03:16 PM, Norman Peelman wrote: > On 08/18/2013 12:28 PM, Thomas Mlynarczyk wrote: >> Norman Peelman schrieb: >> >>> PHP started *before* the big validation era... >> >> This may be true, but does that mean we should not validate in PHP? ;-) >> > > By all means no... > >>> PHP doesn't just randomly decide to type juggle, it does so in >>> context. If you want a string "42", you have it. PHP won't do anything >>> to it until you try to do some math with it (or explicitly ask it to >>> do so.) >> >> Well, unfortunately, <, <=, >, >= and switch give you no possibility to >> prevent unwanted string->int casts. For equality checks, you can use === >> and !==, but there are no corresponding operators for <, > etc. And >> that's the problem. >> > > $mode = "fop"; > echo (($mode === "$mode") AND ($mode <= "foo")) ? "True\n" : "False\n"; > Better I think: ((is_string($mode) AND is_string($var)) AND $mode <= $var) ? true : false ((is_int($mode) AND is_int($var)) AND $mode <= $var) ? true : false -- Norman Registered Linux user #461062 -Have you been to www.php.net yet?-
[toc] | [prev] | [next] | [standalone]
| From | Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> |
|---|---|
| Date | 2013-08-19 00:17 +0200 |
| Message-ID | <kurh5q$djk$2@news.albasani.net> |
| In reply to | #10578 |
Norman Peelman schrieb: > Better I think: > > ((is_string($mode) AND is_string($var)) AND $mode <= $var) ? true : false > > ((is_int($mode) AND is_int($var)) AND $mode <= $var) ? true : false Yes, that makes it much clearer. Still... in other languages, a simple $mode <= $var would suffice. And one must remember that it doesn't suffice in PHP. :-( Greetings, Thomas -- Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison! (Coluche)
[toc] | [prev] | [next] | [standalone]
| From | Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> |
|---|---|
| Date | 2013-08-19 00:13 +0200 |
| Message-ID | <kurguq$djk$1@news.albasani.net> |
| In reply to | #10577 |
Norman Peelman schrieb:
> $mode = "fop";
> echo (($mode === "$mode") AND ($mode <= "foo")) ? "True\n" : "False\n";
False. And no surprise. This is more fun:
// Transitivity...?
var_dump( "10" < "foo", "foo" < 2, "10" < 2 );
// Foo is both greater and smaller than 1?
var_dump( "1" == 1, "foo" > "1", "foo" < 1 );
// Appending the same character on both sides...
var_dump( "xe" > "x0", "xe2" > "x02" );
// ... should not change the result
var_dump( "1e" > "10", "1e2" > "102" );
Yes there are rules that PHP follows to create all this madness and it's
all documented. But why wasn't it made as simple and intuitive as in
other languages?
> When you are comparing things, you are asking PHP to look at them...
Yes. But PHP should not turn strings into numbers before doing the
comparison. It should rather turn numbers into strings, if necessary.
> To me that's the same problem in reverse. + is math, . is
> concatination. + needs/wants numbers, . needs/wants strings. You don't
> ADD strings, you JOIN/CONCATINATE them.
Okay, + wants numbers. So "foo" + 2 is an error. Silently turning "foo"
into 0 hides this error instead of slapping it into the programmer's face.
> Ok Thomas, lets think this through. If a string $somevar contains a
> number, you get cast that number. If the cast results in 0 because
> $somevar either does not contain a number or contains "0", does it
> matter?
Yes, I think it does matter. When I'm expecting something that resembles
a number and I get something that does not resemble a number, then
clearly there's something wrong and the situation should be handled in a
special way. There may be cases, where the silent conversion to 0 is
desirable, but the default behaviour should be an error.
> If 0 is not an acceptable result, you the programmer should more
> than likely be coding for that anyway.
Yes, I (as the programmer) should make sure not to try adding "foo" + 2.
But what about my var_dump() examples above? What if I want to compare
"1e2" > "102" as strings and not as numbers (100 > 102)? I'd have to
resort to substr_compare() to achieve that. With PHP, there's usually a
way to get what you want, but it's not always the simplest and most
obvious way. And thus one must be careful with this language to avoid
all the pitfalls. Once I wrote by mistake
if ( strlen( $string <= 64 ) ) // note the misplaced `)`
and it worked like a charm -- for months. Until a had $string values
starting with numbers... Did PHP complain? No. First it did its weird
comparison and then it passed the resulting boolean to strlen() and
strlen() didn't complain, converted the boolean to string, did its
stuff, returned an integer which got converted to a boolean to evaluate
the if condition. If you ever make a mistake and want to hide it -- put
it in a PHP script, it'll be safe there ;-)
Greetings,
Thomas
--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
[toc] | [prev] | [next] | [standalone]
| From | The Natural Philosopher <tnp@invalid.invalid> |
|---|---|
| Date | 2013-08-19 00:35 +0100 |
| Message-ID | <kurlnh$lkl$1@news.albasani.net> |
| In reply to | #10579 |
On 18/08/13 23:13, Thomas Mlynarczyk wrote: > No. First it did its weird comparison and then it passed the > resulting boolean to strlen() and strlen() didn't complain, converted > the boolean to string, did its stuff, returned an integer which got > converted to a boolean to evaluate the if condition. If you ever make > a mistake and want to hide it -- put it in a PHP script, it'll be safe > there ;-) > At least you only have ONE implementation of PHP to contend with. When I did similar in Javascript it took me TWO BLOODY DAYS to work out why exactly the same code worked in Firefox and not in IE6. And it was EXACTLY the same issue. comparing what I ASSUMED were numbers, but they got converted to strings by IE6, But not by firefox. It took me one and a half days to pin the thing down, and half a day to find a construct that actually did the same thing in both browsers. sheesh. I even looked up the spec. It didn't cover the case. casting is explicitly defined in ASSIGNMENTS, but not in COMPARISONS. > Greetings, > Thomas > > -- Ineptocracy (in-ep-toc’-ra-cy) – a system of government where the least capable to lead are elected by the least capable of producing, and where the members of society least likely to sustain themselves or succeed, are rewarded with goods and services paid for by the confiscated wealth of a diminishing number of producers.
[toc] | [prev] | [next] | [standalone]
| From | Norman Peelman <npeelman@cfl.rr.com> |
|---|---|
| Date | 2013-08-19 06:30 -0400 |
| Message-ID | <kuss3n$ofd$1@dont-email.me> |
| In reply to | #10581 |
On 08/18/2013 07:35 PM, The Natural Philosopher wrote: > On 18/08/13 23:13, Thomas Mlynarczyk wrote: >> No. First it did its weird comparison and then it passed the >> resulting boolean to strlen() and strlen() didn't complain, converted >> the boolean to string, did its stuff, returned an integer which got >> converted to a boolean to evaluate the if condition. If you ever make >> a mistake and want to hide it -- put it in a PHP script, it'll be safe >> there ;-) >> > > At least you only have ONE implementation of PHP to contend with. > > When I did similar in Javascript it took me TWO BLOODY DAYS to work out > why exactly the same code worked in Firefox and not in IE6. > > And it was EXACTLY the same issue. comparing what I ASSUMED were > numbers, but they got converted to strings by IE6, > > But not by firefox. > > It took me one and a half days to pin the thing down, and half a day to > find a construct that actually did the same thing in both browsers. > > sheesh. > > I even looked up the spec. It didn't cover the case. casting is > explicitly defined in ASSIGNMENTS, but not in COMPARISONS. > > That's part of the problem (that I just recently realized)... there are no STRING *comparators* in PHP, just STRING *functions*. -- Norman Registered Linux user #461062 -Have you been to www.php.net yet?-
[toc] | [prev] | [next] | [standalone]
| From | Norman Peelman <npeelman@cfl.rr.com> |
|---|---|
| Date | 2013-08-18 22:13 -0400 |
| Message-ID | <kurv04$1sk$1@dont-email.me> |
| In reply to | #10579 |
On 08/18/2013 06:13 PM, Thomas Mlynarczyk wrote:
> Norman Peelman schrieb:
>
>> $mode = "fop";
>> echo (($mode === "$mode") AND ($mode <= "foo")) ? "True\n" : "False\n";
>
> False. And no surprise. This is more fun:
>
> // Transitivity...?
> var_dump( "10" < "foo", "foo" < 2, "10" < 2 );
"10" < "foo" == TRUE - alphabetically numbers are lower than letters.
But "10" is shorter in length than "foo" so it is less than by default.
"foo" < 2 == TRUE - "foo" == 0 (since it isn't greater than 0). "foo" is
cast because of the integer 2.
"10" < 2 == FALSE - cast as above.
>
> // Foo is both greater and smaller than 1?
> var_dump( "1" == 1, "foo" > "1", "foo" < 1 );
"1" == 1 == TRUE - cast as above.
"foo" > "1" == TRUE - both alphabetically and length. no cast.
"foo" < 1 == TRUE - cast as above
>
> // Appending the same character on both sides...
> var_dump( "xe" > "x0", "xe2" > "x02" );
"xe" > "x0" == TRUE - alphabetically, no cast.
"xe2" > "x02" == TRUE - alphabetically, no cast.
> // ... should not change the result
> var_dump( "1e" > "10", "1e2" > "102" );
"1e" > "10" == TRUE - evaluated as strings because "1e" does not cast to
10 ("1e1" does though.)
"1e2" > "102" == FALSE - evaluated as numbers because both strings are
numerical. You have me on this one. I understand casting when at least
one side is INT/etc. but when both are strings they should be evaluated
as strings. That is implicit casting. And there is no reason for it. :)
>
> Yes there are rules that PHP follows to create all this madness and it's
> all documented. But why wasn't it made as simple and intuitive as in
> other languages?
>
>> When you are comparing things, you are asking PHP to look at them...
>
> Yes. But PHP should not turn strings into numbers before doing the
> comparison. It should rather turn numbers into strings, if necessary.
>
>> To me that's the same problem in reverse. + is math, . is
>> concatination. + needs/wants numbers, . needs/wants strings. You don't
>> ADD strings, you JOIN/CONCATINATE them.
>
> Okay, + wants numbers. So "foo" + 2 is an error. Silently turning "foo"
> into 0 hides this error instead of slapping it into the programmer's face.
We are going in circles at this point... PHP just isn't made that way
so I can't keep arguing about it. Again, I get the basic casting method
up but not including casting two strings to compare them as numbers. If
it's because functions like *strcmp()* are for strings then maybe *that*
should be handled silently:
"1e2" < "102" == strcmp("1e2","102") // dunno about that - seems clumsy
Technically speaking, there are only two STRING operators listed:
. concatenation
.= append
...everything else is function based for strings. You've partially
changed my mind Thomas. That you have.
>
>> Ok Thomas, lets think this through. If a string $somevar contains a
>> number, you get cast that number. If the cast results in 0 because
>> $somevar either does not contain a number or contains "0", does it
>> matter?
>
> Yes, I think it does matter. When I'm expecting something that resembles
> a number and I get something that does not resemble a number, then
> clearly there's something wrong and the situation should be handled in a
> special way. There may be cases, where the silent conversion to 0 is
> desirable, but the default behaviour should be an error.
>
>> If 0 is not an acceptable result, you the programmer should more than
>> likely be coding for that anyway.
>
> Yes, I (as the programmer) should make sure not to try adding "foo" + 2.
> But what about my var_dump() examples above? What if I want to compare
> "1e2" > "102" as strings and not as numbers (100 > 102)? I'd have to
> resort to substr_compare() to achieve that. With PHP, there's usually a
> way to get what you want, but it's not always the simplest and most
> obvious way. And thus one must be careful with this language to avoid
> all the pitfalls. Once I wrote by mistake
>
> if ( strlen( $string <= 64 ) ) // note the misplaced `)`
>
> and it worked like a charm -- for months. Until a had $string values
> starting with numbers... Did PHP complain? No. First it did its weird
> comparison and then it passed the resulting boolean to strlen() and
> strlen() didn't complain, converted the boolean to string, did its
> stuff, returned an integer which got converted to a boolean to evaluate
> the if condition. If you ever make a mistake and want to hide it -- put
> it in a PHP script, it'll be safe there ;-)
>
> Greetings,
> Thomas
>
>
I still think most of it when used properly can aid a programmer. A
big part of our discussion is actually two different things. You want
PHP to let you know up front like a compiler would. And i'm thinking
about how to use casting to my advantage. Might start a new topic about
that...
--
Norman
Registered Linux user #461062
-Have you been to www.php.net yet?-
[toc] | [prev] | [next] | [standalone]
| From | Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> |
|---|---|
| Date | 2013-08-19 19:55 +0200 |
| Message-ID | <kutm6f$hrn$1@news.albasani.net> |
| In reply to | #10582 |
Norman Peelman schrieb: > We are going in circles at this point... PHP just isn't made that way > so I can't keep arguing about it. Indeed. If I want PHP to change, I should file a feature request. But even if everyone else agreed with me, my request would be rejected "because it would break backwards compatibility". (An issue that might be solvable by introducing a "strict" mode in PHP.) > Technically speaking, there are only two STRING operators listed: > > . concatenation > .= append > > ...everything else is function based for strings. So, actually, operators like < or >= are not really meant for string comparisons. Neither is switch. And with that in mind, things start to look a bit clearer. Greetings, Thomas -- Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison! (Coluche)
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2013-08-19 10:18 +0200 |
| Message-ID | <31310115.f6C6Xg6MER@PointedEars.de> |
| In reply to | #10565 |
Thomas Mlynarczyk wrote:
> Norman Peelman schrieb:
>> That's why it says "foo" = 0. Now is "foo" really 0, no - but it sure
>> isn't greater than 0.
>
> In order to compare "foo" and 0 one would need either to convert the
> number 0 to a string ("0" would be the most reasonable result) or
> convert "foo" to a number (not reasonably possible). PHP, unfortunately,
> chooses the unreasonable alternative.
When you consider the possibility that a request parameter may or may not be
present, and you wanted an easy way to check this, like
if ($param)
{
// …
}
it does not look that unreasonable anymore.
The argument can be made that "0" is something, while "" is nothing. I
cannot find it reasonable by any measure that "foo" should be equal to 0.
"foo" certainly is something, while at the same time the argument can be
made that 0 is a mathematical “nothing” (the neutral element towards
addition).
But PHP, after all, also allows for strict comparison to avoid this problem.
Why do you not use it, and then complain about the language (with dubious
assertions about it, BTW)?
if ($param && $param !== "0")
{
// …
}
>> PHP looks at the string in question one character
>> at a time and builds a number until a non-numeric character is reached
>
> I am aware of all that. It was decided to make PHP work that way. I was
> merely pointing out that I consider it a very unfortunate decision to
> cast strings to numbers instead of the other way round.
I think it is the natural result of PHP being the *P*HP *H*ypertext
*P*reprocessor.
BTW, because of discussions like this one, switch-case has been either
removed in an early version from or is never going to be introduced into
Python, another programming language that uses dynamic type-checking (we
should lose the term “loose typing”, it is too loose to be useful). You
have to write
if foo == 1:
pass
elif foo == 2:
pass
elif foo == 3:
pass
else:
pass
and that is precisely what you should do in PHP if the type matters:
if ($foo === 1)
{
// …
}
else if ($foo === 2)
{
// …
}
else if ($foo === 3)
{
// …
}
else
{
/* default */
}
PointedEars
--
var bugRiddenCrashPronePieceOfJunk = (
navigator.userAgent.indexOf('MSIE 5') != -1
&& navigator.userAgent.indexOf('Mac') != -1
) // Plone, register_function.js:16
[toc] | [prev] | [next] | [standalone]
| From | Thomas Mlynarczyk <thomas@mlynarczyk-webdesign.de> |
|---|---|
| Date | 2013-08-19 19:39 +0200 |
| Message-ID | <kutl82$fph$1@news.albasani.net> |
| In reply to | #10583 |
Thomas 'PointedEars' Lahn schrieb:
> But PHP, after all, also allows for strict comparison to avoid this problem.
True, there are === and !==. Unfortunately, though, there are no
"strict" equivalents for <, <=, > and >=. That would be nice to have.
> BTW, because of discussions like this one, switch-case has been either
> removed in an early version from or is never going to be introduced into
> Python,
I think the original reason for switch was to evaluate the expression
only once and use the result as an offset in a "jump table". And
actually, the Pythonic equivalent of switch is not an if-elif-else
structure, but a dict of functions.
> and that is precisely what you should do in PHP if the type matters:
>
> if ($foo === 1)
> {
> // …
> }
> else if ($foo === 2)
> {
> // …
> }
> else if ($foo === 3)
> {
> // …
> }
> else
> {
> /* default */
> }
Indeed, you're right.
Greetings,
Thomas
--
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)
[toc] | [prev] | [next] | [standalone]
| From | Fiver <numeralfive@gmail.com> |
|---|---|
| Date | 2013-08-17 16:15 +0200 |
| Message-ID | <kuo0hn$vq0$1@dont-email.me> |
| In reply to | #10542 |
On 2013-08-17 06:55, Fiver wrote: > I know how to avoid the problem, I'm just wondering what kind of > comparison is used that makes "foo" equal to 0? The manual mentions > "loose comparison", but this is even looser than usual. Ah, please disregard. This is exactly how loose typing in PHP is supposed to work (for some reason). "foo" == 0 indeed evaluates to true. I work with a lot of different languages, often at the same time, so I sometimes get confused by the different type coercion rules in weakly typed languages. FWIW, in JavaScript, Python, Ruby, Bash and others this comparison would evaluate to false; Perl issues a warning; strongly typed languages like Java won't even compile it. For the record, I had changed the problematic switch() to in_array() with strict type checking before even posting the question. thanks, 5er
[toc] | [prev] | [next] | [standalone]
| From | Norman Peelman <npeelman@cfl.rr.com> |
|---|---|
| Date | 2013-08-17 13:28 -0400 |
| Message-ID | <kuobru$t9c$1@dont-email.me> |
| In reply to | #10542 |
On 08/17/2013 12:55 AM, Fiver wrote:
> This example
>
> switch ("foo") {
> case 0:
> echo "'foo' is 0\n";
> break;
> default:
> echo "'foo' is not 0\n";
> }
>
> will print: 'foo' is 0.
>
> I know how to avoid the problem, I'm just wondering what kind of
> comparison is used that makes "foo" equal to 0? The manual mentions
> "loose comparison", but this is even looser than usual.
>
Type juggling is done at every CASE statement, consider the following:
switch ("foo") {
case "foo":
echo "'foo' is 'foo'!\n";
//break;
case 0:
echo "'foo' is 0\n";
break;
default:
echo "'foo' is not 0\n";
}
switch ("2bar") {
case "bar":
echo "'bar' is 'bar'!\n";
//break;
case 0:
echo "'bar' is 0\n";
break;
default:
echo "'bar' is not 0\n";
}
> By the way, the original code was meant to validate SORT_* arguments.
> It's a little harder to spot here:
>
> switch ($mode) {
> case SORT_ASC:
> case SORT_DESC:
> case SORT_REGULAR:
> case SORT_NUMERIC:
> case SORT_STRING:
> case SORT_LOCALE_STRING:
> case SORT_NATURAL:
> case SORT_FLAG_CASE:
> break;
> default:
> throw new \InvalidArgumentException("invalid sort mode: $mode");
> }
>
> SORT_REGULAR is 0, so if the input is a string, this will break (literally).
>
>
No, it will just default to SORT_REGULAR if the string type juggling
results in 0.
--
Norman
Registered Linux user #461062
-Have you been to www.php.net yet?-
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | comp.lang.php
csiph-web