Защо Perl смята, че -1 е вярно?

Това е част от общ примерен код:

while (1) { 
    print "foo\n"; 
}

който отпечатва 'foo' завинаги.

perl foo.pl
foo
foo
foo
...

и

while (0) { print "foo\n"; } 

умира тихо, както очаквате:

perl test.pl

Може ли някой да обясни защо това е полезна реализация на while? Това работи поне на 5.10, Unix и MacOS X:

while (-1) { print "foo\n"; }

което дава

foo
foo
foo
...

person shigeta    schedule 03.10.2011    source източник
comment
-1 се счита за истинска стойност на много езици.   -  person Quentin    schedule 03.10.2011
comment
В Perl 0 е невярно; всичко, което не е невярно, е истина.   -  person Kristofer Hoch    schedule 03.10.2011
comment
Интересно ми е какво доведе до този въпрос. Има ли език, който счита -1 за невярно?   -  person ikegami    schedule 03.10.2011
comment
Разгледах няколко примерни статии и нито една от тях не споменава отрицателни цели числа. Изглежда като нещо, което биха посочили.   -  person shigeta    schedule 03.10.2011
comment
Те го посочиха. В отговора на toolic има цитат от perlsyn, който ясно посочва, че всяка ненулева стойност се счита за вярна. Въпросът е защо решихте, че отрицателните цели числа са изключени?   -  person TLP    schedule 03.10.2011
comment
Спрете да гласувате против подобни въпроси! Отговорите и обясненията тук все още могат да бъдат ценни за начинаещи.   -  person Leonardo Herrera    schedule 03.10.2011
comment
Само за сравнение, ето какво казват K&R в The C Programming Language (второ издание, стр. 223): И в двете форми на оператора if се оценява, включително всички странични ефекти, и ако се сравни, не е равно на 0, първият подизраз се изпълнява. (Наблягането е добавено). Така че това е стандартният начин за правене на нещата на всеки език.   -  person frezik    schedule 03.10.2011
comment
@Leonardo За да бъда честен, в сегашната си форма това е лош въпрос (съжалявам, OP!). Започва от неоснователно, неразумно и необяснимо погрешно предположение и хвърля няколко погрешни схващания, без да стига до същината. Съгласен съм, че си струва да зададете свързан въпрос („какви стойности се считат за true и защо?“). Гласовете против тук, предполагам, са, защото това точно не се иска.   -  person Konrad Rudolph    schedule 03.10.2011
comment
@KonradRudolph - Разбирам какво имаш предвид. Но фалшивите и лоши предположения ще останат същите, докато не бъдат попитани и отговорени от тези, които знаят по-добре.   -  person Leonardo Herrera    schedule 04.10.2011
comment
Просто сменете заглавието на въпроса. Perl смята, че е истина, защото е истина. Ако имахте заглавие на въпроса Защо е -1 дефинирано като вярно в Perl, щяхте да получите това, което търсите по-бързо   -  person frankc    schedule 11.01.2012
comment
Дублиране на отговор, който ще работи най-добре тук е да посочите хак за реален perl true/false израз   -  person    schedule 15.01.2014


Отговори (7)


Ако не друго, може да се каже, че -1 е по-вероятно да е вярно, отколкото 1, тъй като -1 (111..111b) е побитово отрицание на нула (000..000b). BASIC и GW-BASIC използваха -1, когато трябваше да върнат истинска стойност.

Независимо от това, Perl реши, че стойностите, които означават "празно" или "нищо", са неверни. Повечето езици имат подобно мнение. По-конкретно, цяло число нула, нула с плаваща запетая, низът нула, празният низ и undef са неверни.

Това е документирано, въпреки че документацията е лошо формулирана. (Изброява () като стойност, която е невярна, но няма такава стойност.)

Освен последователността е много полезно да се приложи този подход. Например, позволява на човек да използва

if (@x)

вместо

if (@x != 0)
person ikegami    schedule 03.10.2011
comment
В контекста на списъка има стойност за празния списък, сравнете if (($x) = (undef)) { #true срещу if (($x) = ()) { #false. И в двата случая $x е зададено на undef, но истинността на израза се определя от броя на елементите в списъка, а не от стойностите на тези елементи. - person Ven'Tatsu; 03.10.2011
comment
@Ven'Tatsu, не, няма. Кодът, който публикувахте, тества върнатата стойност на присвояването, а не върнатата стойност на (). - person ikegami; 03.10.2011
comment
@Ven'Tatsu, в случай че сте любопитни, присвояването на списък в скаларен контекст връща броя на елементите, върнати от RHS. напр. say scalar( ($x)=(4,5) ); отпечатва 2 и say scalar( ($x)=() ); отпечатва 0.) - person ikegami; 03.10.2011

Всяко ненулево цяло число се оценява на true. И 0 винаги е false

person RiaD    schedule 03.10.2011
comment
тези отговори са тавтологични. не питах дали това е вярно, виждам го. въпросът е ЗАЩО това е вярно. Разгледах няколко статии, преди да публикувам това и всъщност този факт не се споменава, но мога да видя. положителни цели числа са всички примери, които обикновено се дават. - person shigeta; 03.10.2011
comment
11 гласа за.. =) Наистина лесните отговори са тези, които дават най-големите награди за репутация. - person TLP; 03.10.2011
comment
@shigeta - Това е лесен отговор: това е ‹i›по дефиниция‹/i›. Що се отнася до причината, поради която беше решено по този начин, има много обяснения, но беше най-вече за удобство (псевдокод: if val = 0 then ‹false› else ‹true›) - person Leonardo Herrera; 03.10.2011
comment
@shigeta Прегледах няколко статии....и всъщност този факт не се споменава, че виждам. Това е често срещана грешка за начинаещи: Търсене на отговори на грешното място. Прочетете документацията на Perl, която идва с Perl. perldoc.perl.org/perlsyn.html#Truth-and-Falsehood - person DavidO; 03.10.2011
comment
@shigeta - защото Лари каза това много назад. - person Bill Ruppert; 03.10.2011
comment
Нищо от това не дава сериозен отговор на въпроса. - person reinierpost; 04.10.2011
comment
@reinierpost, въпросът е някак непоследователен или в най-добрия случай безнадеждно двусмислен. Освен това бих предизвикал OP да намери един език за програмиране там, където последният пример във въпроса не е валиден. - person Richard Simões; 04.10.2011
comment
@reinierpost - това е сериозен отговор. Бихте ли уточнили защо мислите, че не е така? - person Leonardo Herrera; 04.10.2011
comment
Това е сериозно и уместно, но не е отговор на въпроса. - person reinierpost; 06.10.2011

От perldoc perlsyn (Истина и лъжа):

Числото 0, низовете '0' и '', празният списък () и undef са неверни в булев контекст. Всички други стойности са верни.

-1 се счита за вярно.

person toolic    schedule 03.10.2011
comment
Винаги съм смятал, че когато тествам списък в булев контекст, аз наистина косвено го тествам в скаларен контекст, който, когато е празен, дава нула, следователно невярно. Наистина ли е вярно, че списъкът има булева оценка на контекста, която не получава първо скаларното третиране? - person Joel Berger; 04.10.2011
comment
Това не отговаря на въпроса. - person reinierpost; 04.10.2011
comment
@Joel: По-вероятно празният списък е просто споменат, за да се избегне объркване. В скаларния контекст, празен масив се оценява на 0 (броя елементи), а празен списък се оценява на undef (последния му елемент), като и двата вече са фалшиви, без да се изисква логика на специални случаи, за да се справи с тях. - person Dave Sherohman; 04.10.2011
comment
@reinierpost - Въпросът посочва защо Perl смята, че -1 е вярно, а този отговор казва, че само a, b и c са верни, а всичко останало е невярно. Etailment прави този отговор напълно валиден. - person Leonardo Herrera; 04.10.2011
comment
Знам, че компютърните маниаци имат проблеми с въпросите "защо" и винаги се учат само за материални последици - аз самият съм такъв. Но наистина са различни неща. - person reinierpost; 06.10.2011

Въпросът е 'защо perl смята, че -1 е вярно?'.

Отговорът е, че когато perl беше разработен, беше решено, че определени стойности ще бъдат оценени като false. Това са:

  • 0
  • undef
  • '' (празен низ)

Това е всичко, за което се сещам за подходящ отговор на въпроса защо. Просто беше проектирано по този начин.

person cubabit    schedule 03.10.2011

Само цяло число 0 се счита за невярно. Всяко друго цяло число, различно от нула, се счита за вярно.

person Kirk    schedule 03.10.2011
comment
Не е вярно. "" връща нещо, което не е нито нула, нито вярно. - person ikegami; 03.10.2011

всяко цяло число ‹> 0 е вярно. 0 винаги е невярно.

person Apollo SOFTWARE    schedule 03.10.2011
comment
Нула, но вярно: perl -E 'say 0e0? True : False' Трябва да се прави разлика между низове и числа в език, който няма стриктна система за въвеждане. 0e0 може да бъде число, може да бъде низ (който дори се оценява на нула) и може да бъде истински низ (заради e). Една малка точка от случайно объркване. - person DavidO; 03.10.2011
comment
@DavidO, Вярно, но "0e0" не връща цяло число в смисъла на CS. - person ikegami; 03.10.2011

Perl взе това поведение от awk и C.

Защо C го прави е обяснено тук.

person reinierpost    schedule 04.10.2011