Автор Тема: [PHP] Условности 2  (Прочетена 42846 пъти)

VladSun

  • Moderator
  • Участник
  • *****
  • Публикации: 2166
    • Профил
[PHP] Условности 2
« -: Mar 17, 2010, 14:14 »
Тъй като е свързано с темата, мисля да ви "погъделичкам" още малко ...

Задачка: Без да изпълнявате скрипта в PHP, какъв мислите ще е изходът от този скрипт:

Код
GeSHi (PHP):
  1. function foo($v)
  2. {
  3.    echo $v ? 'true ' : 'false ';
  4.    return !$v;
  5. }
  6.  
  7. function bar($v)
  8. {
  9.    echo !$v ? 'true ' : 'false ';
  10.    return $v;
  11. }
  12.  
  13. $v = true;
  14. echo ($v = foo($v) or bar($v)) ?  'true ' : 'false ';

 >:D >:D >:D
« Последна редакция: Mar 17, 2010, 14:37 от VladSun »
Активен

KISS Principle ( Keep-It-Short-and-Simple )
http://openfmi.net/projects/flattc/
Има 10 вида хора на този свят - разбиращи двоичния код и тези, които не го разбират :P

VladSun

  • Moderator
  • Участник
  • *****
  • Публикации: 2166
    • Профил
Re: [PHP] Условности 2
« Отговор #1 -: Mar 17, 2010, 14:36 »
false
false
false


Нещо омазах разделянето на темата :(
Активен

KISS Principle ( Keep-It-Short-and-Simple )
http://openfmi.net/projects/flattc/
Има 10 вида хора на този свят - разбиращи двоичния код и тези, които не го разбират :P

VladSun

  • Moderator
  • Участник
  • *****
  • Публикации: 2166
    • Профил
Re: [PHP] Условности 2
« Отговор #2 -: Mar 17, 2010, 14:38 »
Ще изчакам и другите да дадат отговори ;)
Активен

KISS Principle ( Keep-It-Short-and-Simple )
http://openfmi.net/projects/flattc/
Има 10 вида хора на този свят - разбиращи двоичния код и тези, които не го разбират :P

gat3way

  • Участник
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Re: [PHP] Условности 2
« Отговор #3 -: Mar 17, 2010, 15:04 »
true
(не съм убеден, вероятно false)
false

Активен

"Knowledge is power" - France is Bacon

neter

  • Global Moderator
  • Участник
  • *****
  • Публикации: 3408
  • Distribution: Debian, SailfishOS, CentOS
  • Window Manager: LXDE, Lipstick
    • Профил
    • WWW
Re: [PHP] Условности 2
« Отговор #4 -: Mar 17, 2010, 16:01 »
Хехе, тъй като съвсем наскоро в миналата тема за условностите си играх със задаване на стойности на променливи в структурата на други елементи, нямаше как да се излъжа:
Цитат
true
true
false
Обяснявам защо. Редът
Код
GeSHi (PHP):
  1. $v = foo($v)
не е проверка на стойност, а е задаване на променлива (обърнете внимание на броя на знаците "=" - имаме само 1, а не 2 или 3), и въпреки това, че се намира в структурата на if, задаването на променливата се изпълнява. Така че, при изпълнението на реда
Код
GeSHi (PHP):
  1. echo ($v = foo($v) or bar($v)) ?  'true ' : 'false ';
първо имаме задаване на променливата $v да бъде равна на резултата от функцията foo($v). При изпълнението на тази функция, на екрана се принтира "true", тъй като текущо $v е true, а функцията връща стойност false (обратното на стойността на $v), което застава като стойност на $v. Т.е., оттук нататък $v е false. При изпълнението на bar($v) имаме принтиране на "true", тъй като $v текущо е false. Така, в крайна сметка в if-а остава "false or false", което изкарва на екрана "false". Много интересно ми стана напоследък задаването на стойности на променливи на нестандартни места [_]3
« Последна редакция: Mar 17, 2010, 16:04 от neter »
Активен

"Да си добре приспособен към болно общество не е признак за добро здраве" - Джиду Кришнамурти

gat3way

  • Участник
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Re: [PHP] Условности 2
« Отговор #5 -: Mar 17, 2010, 16:09 »
Не е толкова логично първо да е "равно", после да е "или". Замени "or" с "||" и ще се изненадаш от резултата :)

Обаче тази дребна особеност съм я срещал преди :)
Активен

"Knowledge is power" - France is Bacon

neter

  • Global Moderator
  • Участник
  • *****
  • Публикации: 3408
  • Distribution: Debian, SailfishOS, CentOS
  • Window Manager: LXDE, Lipstick
    • Профил
    • WWW
Re: [PHP] Условности 2
« Отговор #6 -: Mar 17, 2010, 18:01 »
Това вече е интересно. Значи "or" не е пълен alias на "||". Стигнах до тези заключения. Когато се използва "or", стойността на променливата се задава веднага, и участва в следващите проверки на if-a. Но когато се използва "||", стойността на променливата започва да действа след приключването на if-а. И още нещо. Когато се използва "or", стойността на променливата се приема такава, каквато се задава (числова, булева...), но когато се използва "||", стойността на променливата се приема булева (ако зададеш "5", променливата става равна на "true", а не на "5"). В крайна сметка, при задаването на променливата и в двата случая в if-а остава булева стойност, на мястото на задаването на променливата, но при различните случаи имаме различна стойност на променливата и различен момент на нейното реално задаване. Цялата тази схема важи и за "&&" и неговия alias "and". Много интересно :)
Активен

"Да си добре приспособен към болно общество не е признак за добро здраве" - Джиду Кришнамурти

gat3way

  • Участник
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Re: [PHP] Условности 2
« Отговор #7 -: Mar 17, 2010, 18:31 »
Да, аз съм се чудил защо по дяволите в PHP има два еквивалентни набора логически оператора. В C примерно няма такива неща. Не че някои неща в PHP не ми изглеждат безкрайно странни, обаче това ми се видя абсолютно безсмислено. После се оказа че имало все пак разлика в приоритетите им :)

Иначе за вторият true/false имах съмнения в това дали "!" има приоритет пред съкратените if глупости и понеже видях, че нещата се въртят около тези проблеми, реших че Vladsun е заложил някакъв капан и там :) ама не съм познал.

Някъде дали няма нещо като таблица кое с по-голям приоритет в PHP?
Активен

"Knowledge is power" - France is Bacon

pikimos

  • Участник
  • *****
  • Публикации: 49
  • Distribution: Kubuntu 9.10
    • Профил
Re: [PHP] Условности 2
« Отговор #8 -: Mar 17, 2010, 18:43 »
Дайте нещо и за C++ :)
Активен

VladSun

  • Moderator
  • Участник
  • *****
  • Публикации: 2166
    • Профил
Re: [PHP] Условности 2
« Отговор #9 -: Mar 17, 2010, 19:05 »
Всичко произтича от два факта:

1) or/and операторите са с по-нисък приоритет от оператора за присвояване "=";
2)  >:D българската версия на PHP ръководството пропуска "минорни" забележки - сравнете http://www.php.net/manual/bg/language.operators.logical.php и http://bg.php.net/manual/en/language.operators.logical.php

Иначе в таблицата за приоритетите е ясно: http://www.php.net/manual/en/language.operators.precedence.php

Т.е. нашата задачка се развива във:

Код
GeSHi (PHP):
  1. $v =
  2. (
  3.  (
  4.     $v = foo($v)
  5.   )
  6.   or
  7.   bar($v)
  8. )

Активен

KISS Principle ( Keep-It-Short-and-Simple )
http://openfmi.net/projects/flattc/
Има 10 вида хора на този свят - разбиращи двоичния код и тези, които не го разбират :P

neter

  • Global Moderator
  • Участник
  • *****
  • Публикации: 3408
  • Distribution: Debian, SailfishOS, CentOS
  • Window Manager: LXDE, Lipstick
    • Профил
    • WWW
Re: [PHP] Условности 2
« Отговор #10 -: Mar 17, 2010, 20:27 »
Добре, ясно защо моментът на задаване на променливата е различен при различните двойки оператори - следваме списъка на приоритетите. Но нещо не можах да си отговоря защо при различните двойки оператори имаме различна крайна стойност на променливата? В тази задача така или иначе задаваме булева стойност на променливата и не си личи, но ако зададем числова (например "5"), защо при "and/or" имаме $v=5, а при "&&/||" имаме $v=true? Аналогично, ако зададем $v=0, то при "and/or" имаме $v=0, а при "&&/||" получаваме $v=false ???
Активен

"Да си добре приспособен към болно общество не е признак за добро здраве" - Джиду Кришнамурти

VladSun

  • Moderator
  • Участник
  • *****
  • Публикации: 2166
    • Профил
Re: [PHP] Условности 2
« Отговор #11 -: Mar 17, 2010, 23:30 »
@neter

Имаш предвид защо:
Код
GeSHi (PHP):
  1. $v = 5 or 4;
  2.  
  3. $v = 5 || 4;
  4.  
ще изкара :
Код:
int 5
boolean true
ли?

Пак заради приоритетите - при едното имаме
($v=5) or 4    => $v === 5

при второто имаме
$temp = (5 || 4), операторът || връща *винаги* булева стойност => $temp === true => $v = true

Най-лесно е да видиш изхода от:
Код
GeSHi (PHP):
  1. $v = (5 or 4);
=>
Код:
boolean true

Освен това, изразът "4" в първия пример изобщо не се взима под внимание заради short-circuit evaluation-а
« Последна редакция: Mar 17, 2010, 23:33 от VladSun »
Активен

KISS Principle ( Keep-It-Short-and-Simple )
http://openfmi.net/projects/flattc/
Има 10 вида хора на този свят - разбиращи двоичния код и тези, които не го разбират :P

neter

  • Global Moderator
  • Участник
  • *****
  • Публикации: 3408
  • Distribution: Debian, SailfishOS, CentOS
  • Window Manager: LXDE, Lipstick
    • Профил
    • WWW
Re: [PHP] Условности 2
« Отговор #12 -: Mar 18, 2010, 00:47 »
Да, сега вече ми стана ясно. Аз гледах на приоритетите като отделни точки на изпълнение, въобще не се сетих да ги погледна като части на "изречение" :) Много благодаря за разяснението, отвори ми се играчка на тема приоритети [_]3
Активен

"Да си добре приспособен към болно общество не е признак за добро здраве" - Джиду Кришнамурти

VladSun

  • Moderator
  • Участник
  • *****
  • Публикации: 2166
    • Профил
Re: [PHP] Условности 2
« Отговор #13 -: Mar 18, 2010, 13:18 »
Да, аз съм се чудил защо по дяволите в PHP има два еквивалентни набора логически оператора. В C примерно няма такива неща. Не че някои неща в PHP не ми изглеждат безкрайно странни, обаче това ми се видя абсолютно безсмислено. После се оказа че имало все пак разлика в приоритетите им :)

Въпреки (и заради) разликата в приоритетите, за мене е абсолютна глупост съществуването на OR/AND операторите :)
Активен

KISS Principle ( Keep-It-Short-and-Simple )
http://openfmi.net/projects/flattc/
Има 10 вида хора на този свят - разбиращи двоичния код и тези, които не го разбират :P

neter

  • Global Moderator
  • Участник
  • *****
  • Публикации: 3408
  • Distribution: Debian, SailfishOS, CentOS
  • Window Manager: LXDE, Lipstick
    • Профил
    • WWW
Re: [PHP] Условности 2
« Отговор #14 -: Mar 18, 2010, 13:56 »
Въпреки (и заради) разликата в приоритетите, за мене е абсолютна глупост съществуването на OR/AND операторите :)
Защо? Дава се свобода на програмиста. Досега не ми се е налагало да се възползвам от тази свобода, но никак не е изключено някой път да ми се наложи, и, ако я няма тази свобода, ще трябва да загрозявам кода, вместо просто да заменя оператора (сигурно може да се измисли и по-солидно тюхкане, но не ми се мисли за такова сега). Гледам, че тази свобода я има и в javascript. Ако човек не иска да рискува да обърка нещо в логиката на кода, в резултат на едновременното използване на двете двойки оператори, може просто винаги да ползва едната двойка, и да е спокоен - това, че втората двойка съществува, не го обвързва по никакъв начин. Пък нека я има свободата за тези, на които тази свобода ще е от полза. Ако тази свобода по някакъв начин задължи тези, които не я използват, да указват допълнителни неща, заради съществуването й, и да се обвързват по някакъв начин, тогава и аз бих се възпротивил.
Активен

"Да си добре приспособен към болно общество не е признак за добро здраве" - Джиду Кришнамурти