LINUXSOFT.cz Přeskoč levou lištu
Uživatel: Heslo:  
   CZUKPL

> Perl (5) - Podmínky

Perl Ukážeme si jeden z prostředků, který je nezbytný v každém menším programu. Díky podmínkám se lze v jistém bodě vykonávání programu rozhodnout mezi různými větvemi, kudy se dál budeme ubírat.

24.3.2005 15:00 | Jiří Václavík | Články autora | přečteno 41346×

Podmínka rozhoduje, kudy se má skript vykonávat. Díky podmínkám nemusejí příkazy probíhat od prvního k poslednímu, ale lze části vynechávat. Podmínka tedy určuje, zda má být určitý příkaz nebo blok kódu (dále v článku) vykonán. Spojením několika podmínek pak získáváme různé programové větve, z nichž se provede pouze jedna.

Uvedeme si na začátek příklad podmínky v našem jazyce, která by mohla názorněji osvětlit jejich smysl.

#!/usr/bin/nase_rec

........ (nějaký kód) ........

jestliže (bylo hlasováno){
    Tiskni "Již jste hlasoval!";
}

jestliže (nebylo hlasováno){
    Tiskni "Ok, můžete hlasovat:";
    ........ (formulář na hlasování) ........
}
........ (nějaký další kód) ........

Zde je pochopení intuitivní. Cílem programu je zabezpečit, aby nehlasoval jeden člověk vícekrát. Proto si program nejdříve musí zkonrolovat, zda už stejný člověk nehlasoval. Pokud zjistí že ano, vypíše program Již jste hlasoval!. V opačném případě zobrazí hlasovací lístek.

Tak funguje podmínka i v Perlu. Stačí se jen naučit, jak ji přeložit do jeho syntaxe.

Blok příkazů

Ještě předtím ale vysvětleme pojem blok příkazů. Jeho význam tkví v seskupení několika příkazů tak, abychom s nimi mohli najednou pohodlně nakládat. Označuje se složenými závorkami a struktura vypadá takto:

{
    příkaz1;
    příkaz2;
    příkaz3;
    ...
    příkazn;
}

Za posledním příkazem bloku je středník nepovinný (středník odděluje, nikoliv zakončuje příkazy), ale je dobré ho psát pro případ, že bychom ho někdy chtěli editovat. Za složenou koncovou závorku se středník nepíše.

Blok je nyní pro nás skupina příkazů, které budou podmínkou (později poznáme jiné strukturované příkazy, pro které se blok také používá) vykonány. Bezprostředně za podmínkou (testem) jestliže (bylo hlasováno) v příkladu můžeme právě takový blok nalézt. Vše, co je mezi { a } bude vykonáno, byl-li test úspěšný. V opačném případě bude blok přeskočen a skript pokračuje za ním.

Pravda (true) a nepravda (false)

Z každého výrazu, to jest z každé hodnoty po průchodu libovolnou operací, získáme nějakou hodnotu novou. Tato výsledná hodnota může být dvou typů. Buď true nebo false. Podle typu hodnoty se pak vyhodnocuje například právě test podmínky.

V našem příkladu jsme za klíčové slovo jestliže napsali do jednoduchých závorek test. Co to ale test je a jak je vyhodnocován?

Již bylo naznačeno, jak tyto dvě informace souvisí. Je-li výsledek testu pravdivý (true), bude následující blok příkazů vykonán. Bude-li výsledkem false, bude naopak přeskočen.

Jaká jsou pravidla pro určování, kterého typu je výraz (nebo-li hodnota nebo test)? Podmínka je false v případě, že je test (ještě jednou připomeňme, že to je prostě nějaký výraz) vyhodnocen jako:

  • prázdný řetězec ("")
  • nula (ať 0 nebo "0"), což je díky konverzi totéž
  • nedefinovaná hodnota (když je testem proměnná, do které jsme buď nic nepřiřazovali nebo přiřazovali nedefinovanou hodnotu)

Ve všech ostatních případech je test vyhodnocen jako true.

Podmínka if

Už víme, kdy je test vyhodnocován jako true a kdy jako false. Poslední informací, kterou potřebujeme je, že podmínku zapisujeme slovem if. Nyní se můžeme podívat na několik příkladů podmínek.

if (0){
    print "1. blok nebude vykonán: 0 je vyhodnocena jako false\n";
}

if (""){
    print "2. blok nebude vykonán: prázdný řetězec je vyhodnocen jako false\n";
}

if (1){
    print "3. blok bude vykonán: 1 je vyhodnocena jako true\n";
}

if ("nejaky text"){
    print "4. blok bude vykonán: neprázdný (nenulový) řetězec je vyhodnocen jako true\n";
}

if (1 + 2){
    print "5. blok bude vykonán: 1 + 2 = 3 je vyhodnoceno jako true\n";
}

if ($promenna_do_ktere_jsme_nic_nepriradili){
    print "6. blok nebude vykonán: proměnná, o které jsme se nikde nezmínili má nedefinovanou hodnotu\n";
}

$promenna = 2005;

if ($promenna){
    print "7. blok bude vykonán: v proměnné je uložena hodnota 2005, která je true\n";
}

Uložme si tento kód do souboru a zkusme spustit. Tam, kde jsou testy pravdivé, budou vytišteny příslušné zprávy.

Podmínka s alternativou if...else

Konstrukce if...else se používá k vytváření podmínek s dvěma větvemi - if větev a else větev.

Pokud je pomínka vyhodnocena jako false, automaticky se provede blok kódu, uvedený za else. Pokud je test true, vykoná se blok kódu za if a druhý blok se již nevykoná.

$promenna = 2005;

if ($promenna){
    print '1. blok bude vykonán, pokud je $promenna vyhodnocena jako true';
}
else{
    print '2. blok bude vykonán, nebude-li vykonán blok 1. (to nastane nebude-li
$promenna vyhodnocena jako true, ale jako false)';
}

Tento kód bychom mohli ekvivalentně přepsat jen pomocí jednoduchých podmínek. Poznamenejme, že uvedení vykřičníku obrací typ hodnoty.

$promenna = 2005;

if ($promenna){
    print '1. blok bude vykonán, pokud je $promenna vyhodnocena jako true';
}
if (!$promenna){
    print '2. blok bude vykonán, nebude-li vykonán blok 1. (to nastane nebude-li
$promenna vyhodnocena jako true, ale jako false)';
}

Z tohoto přepisu je vidět, co se stane, zkusíme-li změnit hodnotu testované proměnné na false.

Podmínka if...n*elsif...(else)

Fakticky ale můžeme do podmínky přidat libovolný počet větví. V takovém případě se prostřední větve uvádějí za slovo elsif.

Jak probíhá vyhodnocování? Nejprve se testuje hodnota v testu za if. Není-li true (blok se nevykoná), vyhodnotí Perl test za prvním slovem elsif. Není-li ani ten úspěšný, vyhodnocuje Perl další větev elsif a takto pokračuje, dokud není některý test vyhodnocen jako true. Stane-li se tak, je následující blok vykonán a ostatní větve přeskočeny. Větví elsif můžete použít libovolné množství. A jestliže testy ve všech větvích dopadnou jako false, vykoná se blok za větví else (pokud je uvedená).

Podívejme se opět na úsek kódu.

$definovana_promenna = 2005;

if ($nejaka_promenna){
    print "1. blok nebude vykonán: proměnná není definována\n";
}
elsif($dalsi_promenna){
    print "2. blok nebude vykonán: ani tato proměnná není definavána\n";
}
elsif($jeste_dalsi_nedefinovana_promenna){
    print "3. blok nebude vykonán: co dodat\n";
}
elsif($definovana_promenna){
    print "4. blok bude vykonán: test byl vyhodnocen jako true\n";
}
elsif(0){
    print "5. blok nebude vykonán: všechny větve za úspěšně vykonaným
4. blokem budou předskočeny, navíc 0 je false\n";
}
elsif(3.1416){
    print "6. blok nebude vykonán: i přesto, že test by byl true. Je
totiž také přeskočen\n";
}

Pro úplnost ještě uveďme příklad s přítomnou větví else:

$definovana_promenna = 2005;

if ($nejaka_promenna){
    print "1. blok nebude vykonán: proměnná není definována\n";
}
elsif($dalsi_promenna){
    print "2. blok nebude vykonán: ani tato proměnná není definavána\n";
}
elsif(""){
    print "3. blok nebude vykonán: ještě jednou false\n";
}
else{
    print "4. blok bude vykonán: to proto, že doteď žádný test nebyl
vyhodnocen jako true\n";
}

Podmínkový operátor ?...:

Podmínkový operátor dělá totéž jako podmínková konstrukce. Hodí se na spíše u konstruování výrazů (než příkazy) a zejména u krátkých podmínek se tento zápis velmi často používá. Je to často kvůli přehlednosti výhodnější než podmínková konstrukce a lze pomocí něj simulovat i celou konstrukci if...n*elsif...(else). Obecný zápis vypadá takto:

test ? příkaz_v_případě_true : příkaz_v_případě_false;
test ? výraz_v_případě_true : výraz_v_případě_false;

Pro srovnání, if funguje takto:

if (test){
    příkaz_v_případě_true;
}else{
    příkaz_v_případě_false;
}

Lze konstruovat i více podmínkových větví, což se nezřídka používá.

test1 ? výraz_v_případě_test1 : 
test2 ? výraz_v_případě_test2 :
test3 ? výraz_v_případě_test3 :
        výraz_jinak
        ;

Uveďme dva konkrétní příklady, které dělají totéž. První není příliš vhodně napsaný, protože pro podmiňování příkazů působí podmínkový operátor dost neohrabaně. Zato v tom druhém tiskneme návratovou hodnotu operátoru, což se obvykle očekává.

1 ? print "TRUE" :  print "FALSE";
print  1 ? "TRUE" :  "FALSE";

Protože 1 je true, vytiskne se TRUE. Teď ještě ukažme něco méně samoúčelného. Sice zatím neznáme klíčové slovo return, avšak často se tento operátor využívá právě tam.

return $jmenovatel ? $citatel / $jmenovatel
     : undef
     ;

Podmínka unless...(n*elsif)...(else)

Mimo výše zmiňovaných existuje podmínka s opačným významem než má if a příkazy s podmínkou na konci. Na začátku řekněme, že většinou nebývá dobrým nápadem tyto konstrukce používat, protože často zbytečně znečitelňují program. Zbytek článku klidně přeskočte. Obzvlášť pro začínající je možná lepší, když tyto konstrukce znát nebudou.

Podmínka unless je negované if. Česky se dá if vyjádřit slovem jestliže, unless slovy jestliže ne. Kód ve větvi unless se provede, vyhodnotí-li se test jako false. unless vzniklo jako zjednodušení pro if, kdy testujeme nějaký negovaný výraz.

V těle unless lze použít jak elsif, tak else. Použití elsif může být poněkud matoucí. unless totiž provede blok, je-li test false, a elsif ho provede, je-li test true.

Podívejme se na příklad použití unless, který se ovšem dá jednoduše převést na konstrukci if...else):

$definovana_promenna = 2005;

unless ($definovana_promenna){
    print "1. blok nebude vykonán: test vrátí true (proměnná je
definována) a vykonává se větev else\n";
}
else{
    print "2. blok bude vykonán\n";
}

Na závěr ještě jednou varujme před používáním unless. V naprosté většině případů je použití matoucí a je lepší dát přednost klasickému if.

Podmínka za příkazem

Syntakticky je správně též prohození bloku příkazů a podmínky. Následující kód bude fungovat.

$bylo_hlasovano = 1;

print "Díky za hlas!" if ($bylo_hlasovano);
print "Nehlasoval jste!" unless ($bylo_hlasovano);

I na tomto místě je třeba důrazně upozornit, že nebývá vhodné umístit podmínku za příkaz. Tento typ podmínky se používá výlučně pro příkazy typu last, next, redo a občas return. V jakémkoliv jiném případě je mnohem lepší použít klasické podmínky.

Podmínka za blokem

Stejné jako podmínka za příkazem až na to, že se místo jednoho příkazu vykoná celý blok. Před blok musíme uvést klíčové slovo do. Lze použít jak konstrukci do...if, tak i do...unless.

do{
    $x = 2 ** 10;
    print $x;
}if (1);

Za testem musí být středník. To proto, že za ním už není blok, ale následují další příkazy.

I tento odstavec je pouze informativní a z důvodu přehlednosti bychom neměli takové konstrukce používat, i když je to možné.

Podmínka case a switch

Jednou z mála běžných konstrukcí, které Perl standardně nenabízí je case, která testuje týž výraz na různé hodnoty. Lze ji ale napsat řadou způsobů pomocí operátorů. Operátorové konstrukce se dají často použít ve speciálních případech místo konstrukce if...mnoho*elsif...(else), která nebývá příliš šťastným řešením.

$p = 2;

CASE:{
    $p == 1 and do{print '$p je jedna!'; last CASE;};
    $p == 2 and do{print '$p je dva!';   last CASE;};
    $p == 3 and do{print '$p je tři!';   last CASE;};
    $p == 4 and do{print '$p je čtyři!'; last CASE;};
    do{print '$p není 1, 2, 3 ani 4!';}; #Tento do blok bude
proveden v případě, že nevyhověla žádná předešlá podmínka
}

Platí-li pravdivostní výraz na začátku řádku, vykoná se blok za klíčovým slovem do a dál program pokračuje za blokem označeným CASE. Využíváme zde triku s operátorem and, který nevyhodnocuje druhý operand, pokud již po vyhodnocení prvního je jasné, že výsledkem bude false. Značení bloků a klíčové slovo last probereme až v některém z dalších dílů.

Ani předchozí postup však není zrovna nejpohodlnější. Dalším a nejjednodušším způsobem zavedení této funkcionality je proto použití pragmy feature.

use feature qw(switch);

Po uvedení takového příkazu získáme novou konstrukci given...when. Stačí nám tak napsat následující.

given ($p) {
    when(1){
        print '$p je jedna!';
    }
    when(2){
        print '$p je dva!';
    }
    when(3){
        print '$p je tři!';
    }
    when($_ > 3){
        print '$p je větší než 3!';
    }
    default{
        print '$p je něco jiného!';
    }
}

Verze pro tisk

pridej.cz

 

DISKUZE

Nejsou žádné diskuzní příspěvky u dané položky.



Příspívat do diskuze mohou pouze registrovaní uživatelé.
> Vyhledávání software
> Vyhledávání článků

14.11.2017 16:56 /František Kučera

Máš rád svobodný software a hardware nebo se o nich chceš něco dozvědět? Zajímá tě DIY, CNC, SDR nebo morseovka? Přijď na sraz spolku OpenAlt – tradičně první čtvrtek před třetím pátkem v měsíci: 16. listopadu od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5).


Přidat komentář

12.11.2017 11:06 /Redakce Linuxsoft.cz
PR: 4. ročník odborné IT konference na téma Datová centra pro business proběhne již ve čtvrtek 23. listopadu 2017 v konferenčním centru Vavruška, v paláci Charitas, Karlovo náměstí 5, Praha 2 (u metra Karlovo náměstí) od 9:00. Konference o návrhu, budování, správě a efektivním využívání datových center nabídne odpovědi na aktuální a často řešené otázky, např Jaké jsou aktuální trendy v oblasti datových center a jak je využít pro vlastní prospěch? Jak zajistit pro firmu či jinou organizaci odpovídající služby datových center? Podle jakých kritérií vybrat dodavatele služeb? Jak volit součásti infrastruktury při budování či rozšiřování vlastního datového centra? Jak efektivně spravovat datové centrum? Jak eliminovat možná rizika? apod.
Přidat komentář

13.9.2017 8:00 /František Kučera
Máš rád svobodný software a hardware nebo se o nich chceš něco dozvědět? Zajímá tě DIY, CNC, SDR nebo morseovka? Přijď na sraz spolku OpenAlt – tentokrát netradičně v pondělí: 18. září od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5).
Přidat komentář

3.9.2017 20:45 /Redakce Linuxsoft.cz
PR: Dne 21. září 2017 proběhne v Praze konference "Mobilní řešení pro business". Hlavní tématy konference budou: nejnovější trendy v oblasti mobilních řešení pro firmy, efektivní využití mobilních zařízení, bezpečnostní rizika a řešení pro jejich omezení, správa mobilních zařízení ve firmách a další.
Přidat komentář

15.5.2017 23:50 /František Kučera
Máš rád svobodný software a hardware nebo se o nich chceš něco dozvědět? Zajímá tě DIY, CNC, SDR nebo morseovka? Přijď na sraz spolku OpenAlt, který se bude konat ve čtvrtek 18. května od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5).
Přidat komentář

12.5.2017 16:42 /Honza Javorek
PyCon CZ, česká konference o programovacím jazyce Python, se po dvou úspěšných ročnících v Brně bude letos konat v Praze, a to 8. až 10. června. Na konferenci letos zavítá např. i Armin Ronacher, známý především jako autor frameworku Flask, šablon Jinja2/Twig, a dalších projektů. Těšit se můžete na přednášky o datové analytice, tvorbě webu, testování, tvorbě API, učení a mentorování programování, přednášky o rozvoji komunity, o použití Pythonu ve vědě nebo k ovládání nejrůznějších zařízení (MicroPython). Na vlastní prsty si můžete na workshopech vyzkoušet postavit Pythonem ovládaného robota, naučit se učit šestileté děti programovat, efektivně testovat nebo si v Pythonu pohrát s kartografickým materiálem. Kupujte lístky, dokud jsou.
Přidat komentář

2.5.2017 9:20 /Eva Rázgová
Putovní konference československé Drupal komunity "DrupalCamp Československo" se tentokrát koná 27. 5.2017 na VUT FIT v Brně. Můžete načerpat a vyměnit si zkušenosti z oblasti Drupalu 7 a 8, UX, SEO, managementu týmového vývoje, využití Dockeru pro Drupal a dalších. Vítáni jsou nováčci i experti. Akci pořádají Slovenská Drupal Asociácia a česká Asociace pro Drupal. Registrace na webu .
Přidat komentář

1.5.2017 20:31 /Pavel `Goldenfish' Kysilka
PR: 25.5.2017 proběhne v Praze konference na téma Firemní informační systémy. Hlavními tématy jsou: Informační systémy s vlastní inteligencí, efektivní práce s dokumenty, mobilní přístup k datům nebo využívání cloudu.
Přidat komentář

   Více ...   Přidat zprávičku

> Poslední diskuze

18.9.2017 14:37 / Rojas
high security vault

15.9.2017 7:33 / Wilson
new zealand childcare jobs

31.8.2017 12:11 / Jaromir Obr
Re: ukůládání dat ze souboru

30.7.2017 11:12 / Jaromir Obr
Národní znaky

27.7.2017 12:24 / Jaromir Obr
Cteni/zapis

Více ...

ISSN 1801-3805 | Provozovatel: Pavel Kysilka, IČ: 72868490 (2003-2017) | mail at linuxsoft dot cz | Design: www.megadesign.cz | Textová verze