Тупняк php

kruzer25

Ищу тут у себя в коде глюк - по пути узнал, что, оказывается, сейчас false==0, false==array но 0!=array!
Неужели нет никакого способа изменить это тупое поведение, какой-нибудь настройкой в ини-файле, к примеру?

Dasar

вроде все логично, что не понятно?

artimon

Нет.
Ботай наизусть таблицу http://www.php.net/manual/en/types.comparisons.php
или пользуйся ===

artimon

Ну, называть отсутствие транзитивности логичным поведением я бы не стал.

kruzer25

Где логичность? a==b, b==c, но a!=c - это, по-твоему, логично?

kruzer25

Надо, чтобы именно нестрогое сравнение было...
http://www.php.net/manual/en/types.comparisons.php
Ну, собственно, именно в мануале я это и увидел, когда устал искать у себя ошибку...
А если попробовать преобразовать оба значения в строку перед сравнением, это поможет? Транзитивность уж точно будет, а если $x==false, то (string)$x==""?

artimon

Должно помочь. Но надо точно представлять во что будут преобразованы разные типы данных. См. мануал, да и var_dump никто не отменял.
Кстати, преобразование массива в строку генерит Notice.

Dasar

> Ну, называть отсутствие транзитивности логичным поведением я бы не стал.
дык, оператор == не является математической операций "эквивалентно", соответственно не обязан быть транзитивным.
а все логично, потому что false используется как синоним слова "пусто".
соответственно 0 - это пусто, array - это пусто, но 0 != array
ps
житейская аналогия
лошадь = конь, лошадь=кобыла, но конь != кобыла
т.е. есть три терма: один нечеткий(более обобщенный) и два четких - соответственно нечеткий терм можно считать равным каждому из двух четких, но четкие термы между собой уже не равны.

wwoland

ну по крайней мере это не единичный случай.
А почему вообще должнв быть транзитивность?

kruzer25

житейская аналогия
лошадь = конь, лошадь=кобыла, но конь != кобыла
Нет.
in_array(конь, лошади); in_array(кобыла, лошади) - и вполне естественно, что конь!=кобыла.
Оператор == же используется для сравнения, а не проверки принадлежности. И мне, как разработчику, хочется, чтобы из того, что (без учёта типа) с b совпадает как a, так и c, следовало, что a совпадает с c (тоже без учёта типа, конечно).
Может, ещё и из a==b необязательно должно следовать b==a?

artimon

ОК, в этом есть какой-то смысл.

wwoland

никто никому ничего не должен

kruzer25

Ага, и вообще, тут перцы из php подумали-подумали, и решили, что в следующей версии + будет работать как умножение, * как сложение, а "==" будет означать присваивание - вот народ повеселится!

Dasar

к счастью, реальный мир намного богаче, чем математика, соответственно не всегда получается реальный мир засунуть в прокрустовое ложе математики.
здесь как раз именно такая ситуация, и соответственно вот в этом частном случае не получилось соблюсти транзитивность.

wwoland

а как должен работать + и как * ?
По моему они могут совершенно по разному работать.

kruzer25

Всё-таки, тебе не кажется, что php - это язык программирования, и сделан он для программистов, которым иногда транзитивность бывает важнее, чем какая-то заумная философия о том "0 ложно, Array тоже ложно, но, тем не менее, они не совпадают"? Я сейчас не говорю про true - это ещё с древних времён всё либо ложно, либо истинно, а ложны только всякие там нули и пустые строки.
ЗЫ: Это у меня в табличке опечатка, или "php"==0? Это-то с какого перепою? Я, конечно, понимаю, что (int)"php"==0, но вот "php"==0 - это как-то слишком...

wwoland

ну типа пхп - куйня =)

kruzer25

исправил

wwoland

просто может быть (boolean)array = falseboolean)0 = false;
а вот что к чему преобразуется в случае 0=array - хз, то есть я вообще пхп не знаю,но это мое предположение,что просто ту по разному преобразование типов идет,и в последнем случае,например,вообще преобразование провести невозможно и потому выдается автоматом false.
Хотя не удите строго этот бред =)

kruzer25

Ну типа это всё равно, что 1.5==1.
ВОобще, моё видение операции == - по идее, она возвращает true, когда
1) Обе сравниваемые величины - false (то есть, это false, 0, "", Array итп)
2) Обе сравниваемые величины - true, и при приведении величины более простого типа к более сложному (bool<int<float<string) - совпадают (то есть, если их типы различаются, и у одной из них тип не является ни bool, ни int, ни float, ни string - результат сравнения должен быть заведомо false, за исключением пункта 1)
Довольно логично, на мой взгляд...
Единственная проблема при этом - "0", но она уже решена - в php и так "0"==false.

Dasar

> сделан он для программистов, которым иногда транзитивность бывает важнее
дык, как раз транзитивность операции '==' - это какая-то заумная хрень.
а вот это реальный часто встречающийся код

number = 0
if (number) {}

items = array
if (items){}

kruzer25

Нет, всё было бы хорошо, проблема именно в том, что есть как бы довольно ограниченное количество объектов, которые false, даже конечное (всего-то false, NULL, 0, "0", "", 0.0, Array уж не помню, как там насчёт пустых объектов) - и было бы как раз очень логично, чтобы все эти "пустые" и "нулевые" объекты совпадали, если не смотреть на типы.
ЗЫ: Кстати, а почему в табличке нет "" (пустой строки)?

kruzer25

Ну он и у меня часто встречается.
И?
Смысл в том, чтобы, если уж обязательно требуется операция сравнения с чем-то вещественным, можнео было написать вместо if($x) - if($x=="" или if($x==0 итп.

Dasar

и какой будет полный список правил для предложенной тобой фичи?
ps
для текущей ситуации список правил - простой, про него как раз счетчик писал.
правила:
если тип совпадает, то сравнить значения
иначе если и там, и там числа, то привести оба значения к более общему типу числа и сравнить,
иначе если один из типов bool, то привести и второе значение к bool и сравнить
иначе если один из типов строка, то привести и второе значение к строке и сравнить
и т.д.

Dasar

> и было бы как раз очень логично, чтобы все эти "пустые" и "нулевые" объекты совпадали, если не смотреть на типы
ты кстати в курсе, что у тебя транзитивность тоже будет нарушена?
т.к. у тебя получится:
0 == "0"
0 == ""
но "" != "0"

kruzer25

ты кстати в курсе, что у тебя транзитивность тоже будет нарушена?
т.к. у тебя получится:
0 == "0"
0 == ""
но "" != "0"
Всё отлично, и "", и "0" - false, так что они подпадают под первый пункт правила (а значит, ""=="0")

kruzer25

У меня список правил простой.
Два значения равны, если они оба - false, или (они оба - не false, и их приведения к более общему типу совпадают).

Dasar

тогда нарушается закон непрерывности
"1" != ""
"2" != ""
"a" != ""
но "0" == ""

Dasar

если они оба - false
т.е. и "0" == "00"?

kruzer25

А "00"!=false.
$x==false тогда и только тогда, когда $x===NULL || $x===false || $x===0 || $x===0.0 || $x==="" || $x==="0" || $x===Array

kruzer25

Какой-какой закон нарушается?
Не вижу тут никаких нарушений.
А ещё "1"!=0, 1!=0, но "0"==0, прикинь?

Dasar

> $x==false тогда и только тогда, когда $x===NULL || $x===false || $x===0 || $x===0.0 || $x==="" || $x==="0" || $x===Array
т.е. каждый == заменяется на такую херотень?
а полезную работу программа когда будет выполнять?

wwoland

Возможно ботание теории компиляции даст ответ на вопрос,почему сделано так,а не иначе.

bleyman

а значит, ""=="0"
Сам-то не умер бы от программирования на таком? Это всё-таки разные строки.
Языку ПХП - зачот.

bobby

а вот это реальный часто встречающийся код
number = 0
if (number) {}

items = array
if (items){}
Чтобы была возможность писать такой код, в язык не обязательно вводить 0 == false и/или array == false. Посмотри на Python, например. Ещё есть какие-то доводы, зачем нужно отсутствие транзитивности операции == ?

Dasar

> в язык не обязательно вводить 0 == false и/или array == false. Посмотри на Python, например.
приведи свое понимание, а не на авторитеты ссылайся.
есть еще и такой код
if (!number)
if(!items)
и такой
var b = !number;
if (b)
 out(b);
var b = !items;
 if (b)
  out(b);

bobby

Код:
if 0:              print "0"
if 1: print "1"
if 2: print "2"
if []: print "[]"
if [1, 2]: print "[1, 2]"
if "": print '""'
if "a": print '"a"'
print
if not 0: print "not 0"
if not 1: print "not 1"
if not 2: print "not 2"
if not []: print "not []"
if not [1, 2]: print "not [1, 2]"
if not "": print 'not ""'
if not "a": print 'not "a"'
print
if 0 == False: print "0 == False"
if 1 == True: print "1 == True"
if 2 == True: print "2 == True"
if [] == False: print "[] == False"
if [1, 2] == True: print "[1, 2] == True"
if "" == False: print '"" == False'
if "a" == True: print '"a" == True'
print
print "not 0 = %s" % (not 0)
print "not 1 = %s" % (not 1)
print "not 2 = %s" % (not 2)
print "not [] = %s" % (not [])
print "not [1, 2] = %s" % (not [1, 2])
print 'not "" = %s' % (not "")
print 'not "a" = %s' % (not "a")
Вывод:
1
2
[1, 2]
"a"

not 0
not []
not ""

0 == False
1 == True

not 0 = True
not 1 = False
not 2 = False
not [] = True
not [1, 2] = False
not "" = True
not "a" = False
Тоже не идеал, я бы предпочел, чтобы строк "0 == False" и "1 == True" не было, хотя это уже, скорее, дело вкуса. В своих классах логическое значение объектов можно определять самостоятельно.
Проще всего (из того, что я видел на мой взгляд, в Ruby, где для логических (и условных) операций nil и false имеют значение "ложь", а все остальные объекты - "истина". При этом твой код не напишешь, но такое, по-моему, даже более наглядно:
if items.empty?
# blah-blah
end

if something.size.zero?
# blah
end

Dasar

Тоже не идеал
и чем это сильно отличается от php?
например, неявное приведение пустого массива к false все равно же есть.
единственное отличие, что в правилах для == неявное приведение не используется.
зы
кстати что выводит
print 0 == "0"
print True == "True"
> При этом твой код не напишешь, но такое, по-моему, даже более наглядно:
а если items или something в том числе могут быть и nil?

bobby

print 0 == "0"
print True == "True"
выводит
False
False

Отличие в том, что операция == транзитивна. Это её свойство для меня весьма привычно.
а если items или something в том числе могут быть и nil?
Ну, если нужно, можно определить методы empty?, zero? в NilClass:
irb> class NilClass
irb> def zero?
irb> true
irb> end
irb> end
=> nil

irb> nil.zero?
=> true

bobby

а если items или something в том числе могут быть и nil?
Но вообще, чтобы такого не было, обычно пишут:
items = obj.method(param1, param2) || []

Marinavo_0507

Всем отлично известно, что php сосёт.
Но пока лемминги изучают его вместо более достойных языков, нам с этим жить.

kruzer25

вместо более достойных языков
Вместо перла? Или С? Не смеши мои тапочки.

Marinavo_0507

Это все названия языков, которые ты слышал?

kruzer25

Дело не в том, что я слышал. Дело в том, какие названия языков слышал, например, какой-нибудь masterhost.
Для себя-то можно, конечно, и лисп понять и что-то на нём делать.

kruzer25

Сам-то не умер бы от программирования на таком? Это всё-таки разные строки.
false и "0" - ещё более разные вещи. И что?

Marinavo_0507

Про perl все слышали. И он лучше, по крайней мере нет такой хуйни, и библиотек разных побольше.

kruzer25

и библиотек разных побольше
Что, действительно?
А какие именно библиотеки есть в перле, но отсутствуют в пхп?
Судя по мануалу, всё, что мне только может понадобитсья (и очень много того, что не может) в пхп уже есть.

Andbar

Я бы с радостью забыл php и перешел на питон.
Однако программировать на питоне именно под веб не очень удобно. Вот если будет питон в виде модуля под апач и добавится соответствующий API, тогда можно будет задуматься.

bobby

Я бы с радостью забыл php и перешел на питон.
Однако программировать на питоне именно под веб не очень удобно. Вот если будет питон в виде модуля под апач и добавится соответствующий API, тогда можно будет задуматься.
Для Python есть куча веб-фреймворков разного калибра, они тебя все не устраивают? Работают через mod_python или FastCGI.

Marinavo_0507

А какие именно библиотеки есть в перле, но отсутствуют в пхп?
У меня были следующие случаи:
1. разбор и создание mailbox'ов разных форматов, разбор mime-структуры сообщений
2. калькулятор IP-адресов и префиксов (включая оптимизированный lookup по множеству префиксов)

kruzer25

разбор и создание mailbox'ов разных форматов, разбор mime-структуры сообщений
php.net/imap?

Marinavo_0507

и где там мейлбоксы разных форматов, чудо?

kruzer25

Что ты имеешь в виду, говоря "разных форматов"?

Marinavo_0507

ну хотя бы классический mbox
Оставить комментарий
Имя или ник:
Комментарий: