David Majda mi poslal v komentářích výborný odkaz na svůj článek, kde upoutává na přestřelku dvou (zřejmě významných) programátorů na téma „výjimky vs. návratové kódy“.
U toho se musím zastavit. A už teď je mi jasné, že se tento seriál trošku protáhne.
Joel vs. Ned vs. dgx
Joel Spolsky tvrdí, že návratové kódy jsou dobré, protože výjimky jsou z nejrůznějších důvodů špatné. Ned Batchelder oponuje, že výjimky jsou kůl, protože návratové kódy jsou fuj.
Pokud trošku „děláte do demagogie“, tak vám z uvedeného je jasné, že taková diskuze je pouhý flame, neb se implikuje nesmyslně. Totiž názor, že něco je špatné, není možné použít jako argument, že něco jiného (a nikoliv doplňkového) je dobré. Či alespoň lepší. To by se mohli hádat donekonečna. Svou pravdu mají oba a jen těžko mohou vyvrátit pravdu toho druhého.
Jak návratové kódy, tak výjimky, mají obrovské nedostatky. Ano, řekl bych, že špatné je obojí. A nemá smysl řešit, co víc. Naopak má smysl nad celou situací trošku popřemýšlet, pokusit se celý problém abstrahovat a najít uspokojivé řešení. A pak se ho pokusit zrealizovat v programovacím jazyce.
No, takže teď už alespoň víte, že tohle není jen další článek na téma Abc je lepší než Xyz 😉
Abstrakce problému
Minule jsem tu naznačoval určitý mechanismus správy chyb, ve kterém hrály hlavní roli tři pojmy: funkce, chyby a varování. Když tak se na to ještě mrkněte.
- Funkce – základní jednotka programu
- Chyba – stav, kdy funkce nedosáhne svého cíle. Informace o chybě se předá volající funkci (je ve tvaru, aby ji funkce dovedla pochopit)
- Varování – informace určená programátorům. Nezpůsobí ukončení funkce, program na ni nereaguje.
Logickou jednotkou programu je tedy funkce. Ta se buď zdárně vykoná a vrátí výslednou hodnotu, nebo dojde k chybě a s tím se funkce ukončí. Volající funkce je o chybě informována a nějakým způsobem ji ošetří. Třeba také vyvolá chybu, nebo varování, či pokračuje po určité větvi vykonávání dále. Nebo ji prostě ignoruje! Ano, ošetření ignorováním je zcela legitimní způsob ošetření.
V reálném světě je tomu stejně. Pokud se drobně škrábneme, nejedeme kvůli tomu do nemocnice, ale problém ignorujeme. V této analogii se výjimky chovají tak, že pokud se dostatečně škrábnutí nebudeme věnovat, dojde k odumření orgánu či dokonce okamžité smrti. Pro návratové kódy by zase sedělo, že sice škrábnutí umí v pohodě přejít, ale ignorují také uříznutí nohy cirkulárkou, neboť obojí jen stěží rozliší.
Volba mezi výjimkami a návratovým kódem je tedy volba mezi rychlou smrtí a postupným vykrvácením, dojde-li k neštěstí. Obojí má své zastánce 🙂
No, a teď zase vážně.
Problematika výjimek
Zatímco minule jsem si stěžoval, jak ubohou informační hodnotu má tzv.
chybový návratový kód false
, dnes se podívejme, jaké úskalí
nám umí přichystat výjimky.
Představme si, že by v PHP najednou všechny funkce začaly namísto
chybových kódů (jakým bývá často false
) vracet výjimky.
Položím vám otázku: co udělá (resp. může udělat) tento kód?
// korektně zjisti jméno uživatele
$user = isset($_GET['user']) && is_string($_GET['user'])
? $_GET['user']
: '';
// ořízni na max. délku
$user = substr($user, 0, 30);
// pokusíme se zalogovat
try {
$logged = in_array($user, myGetAllowedUsers(), true);
} catch (Exception $e) {
die('Nelze pokračovat.');
}
...
Komentáře
KLoK #1
neosetreni navratoveho kodu v pripade ze neni uzivatel v poly $allowedUsers. Dojde k prihlaseni i presto, ze logged je false.
Ale to je spise logicka chyba nez neosetreni vyjimky
error414 #2
Nevim co muze kod udelat. Ale je blbost aby funkce kdyz uz by vyhazovala vyjimku in_array tak aby ji vyhazovala kdyz by nenalezla prvek v poli.
To uz se zabredavame do rizeni toku programu pomoci vyjimek.
Hlavne by me zajimalo co bude v promene $logged? Kdyz funkce vyhodi vyjimku tak co nacpe do vystupu?
David Grudl #3
#1 KLoKu, lehce jsem to upravil, aby kód dával smysl. Přesto háček je jinde a je to tak trošku chyták…
no chyták – prostě je to zcela regulérní problém výjimek.
Ivan #4
Osobně bych považoval vyhození výjimky ve funkci in_array za poněkud nevhodné. Myslím, že výjimka se vyhazuje ke zpracování nahoru proto, že si s uvedenou situací neumí funkce sama poradit. V tomto případě tedy pokud by in_array neuměla rozhodnout zda v uvedeném poli proměnná je nebo není.
Naproti tomu, pokud mám metodu, která mi má vrátit pole objektů, které konstruuje podle databáze, byla by od té metody svévole, vyřešit pád databáze vrácením prázdného pole – tady je použití výjimky dle mého názoru oprávněné.
Nebo jsem něco totálně nepochopil?
Ivan #5
Jo totálně jsem nepochopi :) Předchozí příspěvek je mimo.
Ivan #6
Ale příběh toho kódu je prapodivný… Já ošetřuji blokem try funkci myGetAllowedUsers() a zároveň návratovou hodnotu in_array?
Ivan #7
Neboli – Access denied, vole právě tehdy když nemohu zjistit jací jsou povolení uživatelé ⇒ mě nezajímá, jestli jsi povolenej, pokud já znám své povolené, tak buď vítán :)
David Grudl #8
#7 Ivane, ok, změníme hlášku z ‚Access Denied‘ na ‚Nelze pokračovat‘.
Zároveň také můžete psát návrhy, jak kód z hlediska návrhu vylepšit.
error414 #9
výjimky končí až s jejich ošetřením. dam ruku do ohne ze to ma co delat stimhle
Ivan #10
#1 KLoKu, #3 David Grudl $allowedUsers :) tak ono se mi to takhle změnilo pod rukama. Odvolávám co jsem #5 Ivan odvolal :) A už si raději počkám na pointu.
Charlie #11
Funkce
in_array
má návratovou hodnotuboolean
, když uživatele nenajde, jednoduše vrátífalse
a bloktry
proběhne korektně. Nikdy tak nedojde k zachycení výjimky, protože jí funkce nevyhodí.Jediná šance, jak zachytit výjimku, je vyhodit ji ve funkci, která vrací pole uživatelů – to by pak ale byla chyba zdroje dat, nikoliv autentizace uživatele.
error414 #12
#11 Charlie, Představme si, že by v PHP najednou všechny funkce začaly namísto
chybových kódů (jakým bývá často false) vracet výjimky.
vice cist
David Grudl #13
#12 error414, Ale zrovna v případě in_array(), které vrací typ boolean, není false chybovým kódem. Nicméně jsi blízko.
Ivan #14
Za předpokladu, že se má výjimka šířit z myGetAllowedUsers(), tak chybí před try
$logged=false;
a na konciif($logged)...
.Inu catch nemusí být vždy koš na vše.
Pokud bylo myšleno, že se výjimka šíří z in_array tak si stojím za #4 Ivan
Charlie #15
#12 error414, Pardon, nějak jsem to přehlédl.
Pak se ale naskýtá otázka, co se stane, když bude vyhozena vyjímka dříve, než dojde ke zpracování té předešlé. Když by všechny funkce vyhazovali
Exception
místo navrácenífalse
, jednoduše by se tak mohlo stát, že by se skript přehltil vyjímkami.David Grudl #16
#15 Charlie, Výjimka automaticky přeskočí k „nejbližšímu“ místu zpracování. To je právě pro výjimky charakteristické. Pokud žádné takové místo není, dojde k fatální chybě skriptu.
KLoK #17
Ale porad tam zustava ten logicky problem. Je jedno jestli pole uzivatelu je v promenne nebo funkci.
Jde o to ze kdyz uzivatel v poli nebude, tak in_array vrati false. A logika algoritmu veli osetrit navratovou hodnotu zpusobem „in_array() or die“.
Pokud ti jde o to die() v catch bloku, tak tam by mohl byt zakopan pudl. Ja jsem odkojen C++ a tam kdyz zavolas exit() ve vyjimce tak je to proste exit(). Podle toho na co narazis bych tipoval ze PHP to neudela.
Ebo #18
nejlepší je, když se to kousne.. howg 😛
Jakub Podhorský #19
halvní problém tohodle kódu vydím to že zachycuješ nejnižší možnou vyjímu čili Exception…ve vyjímkách vidím tu obrovskou výhodu v jejich dědičnosti že si můžeš udělat jejich obrovskou hiearchii a tudíž by zde nemusel být jenom jeden catch…třeba by zde byla vyjímka na neexistující prvek v tom poli a nebo nějaká na odchycení chybového stavu v myGetAllowedUsers() atd. osobně na tom nevidím nic špatného jen to že zde se mi zdá spíš vhodnější kontrola true a false pro funkci in_array() a pro myGetAllowedUsers() nejspíš blok try…chatch
#9 error414, to je logické po bloku try musí ihned následovat blok catch takhle je to ve všech jazycích které podporují vyjímky
error414 #20
#19 Jakube Podhorský, to nerikej me ale Davidovi, to mela byt citace z predchoziho clanku.
dond #21
Nebudu komentovat PHP, ten „jazyk“ mi k srdci nepřirostl nikdy a v posledních letech mám to štěstí, že v něm nemusím nic dělat, ale co se týče řízení běhu programu, je to známý problém mnoha jazyků (výjimky vs. návratové hodnoty vs. globální proměnné vs. další obskurnosti).
IMHO obecné řešení neexistuje. Podívejte se, jak se větvení kódu řeší ve funkcionálních jazycích a třeba v zásobníkových jazycích (vlastně nevím, esli se to tak jmenuje, mám na mysli třeba Forth). Obvykle je totiž potřeba se rozhodnout podle konkrétní situace, který způsob je lepší. Jenže to by si člověk musel všechno psát sám a to není in…
Lando Mata #22
#19 Jakube Podhorský, „to je logické po bloku try musí ihned následovat blok catch takhle je to ve všech jazycích které podporují vyjímky“
No, ono to není úplně pravda. Např. v C# můžeš používat i
try...finally
bezcatch
. C++ má i další modifikace. Ale to jen na okraj .. 😉David Grudl #23
Tak tedy:
Kdo by to od substr() čekal, že? Je to však zdokumentované chování a musí se s ním počítat.
Nářků, proč tvůrci PHP s příchodem PHP5 nenahradili všechny chybové kódy za výjimky, jsem slyšel docela dost. V tomto příkladě by vyhodilo výjimku mimo blok try … catch.
Mohli bychom samozřejmě blok rozšířit:
Jenže co si tím pomůžeme? V bloku catch budeme muset jednak identifikovat zdroj chyby a ačkoliv ji vyhodnotíme jako banální, těžko budeme v započatém logování pokračovat.
Tak co zkusit třeba:
Ovšem tady už nám výjimky začínají být na obtíž…
Veena #24
No ale co s tím jinak? Ono:
neni taky nic parádního.
Hlavně je to opruz, pokud má člověk snahu o jiné ošetření chyb nebo větvení programu než die(). To by podle mě mohly (sám jsem ješte nedostal odvahu je v php používat) právě vyjímky zajišťovat, tuším.
Kvituju tvoji snahu se chybovýma stavama probrat a zjistit jak na ně nejlépe.
martin #25
#23 Davide Grudle, zacnem komentar od poslednej casti – preco si myslis, ze v tomto pripade su na obtiz. su predsa uplne rovnako na obtiz, ako kontrolovanie navratovej hodnoty, nie (alebo vadi ten jeden riadok naviac) ?
vyhoda vyjimiek (neviem, ako je to presne v php, ale runtime-ovych v jave) je ta, ze sa daju odchytavat na ktorejkolvek urovni zanorenia programu. t.j. su chyby, s ktorymi si volajuci kod vie poradit a tie by mal osetrit. tie, ktore osetrit nechce necha prebublat vyssie. a na niektorej urovni sa pravdepodobne odchytia vsetky dovtedy nezpracovane chyby – coz ma vo web aplikaciach potom za nasledok zobrazenie stranky s chybovou hlaskou typu „nastala chyba pri spracovavani poziadavku, skuste poziadavok neskor“. a naviac vyjimka so sebou nesie stack trace, takze pri zalogovani chyby na ktorejkolvek urovni je relativne lahko dohladatelny zdroj chyby. takze osobne si myslim, ze kod vobec nemusi osetrovat vsetky chyby, ktore mozu vzniknut vo funkciach, ktore vola, ale aplikacia by mala byt pisana tak, aby si vedela na niektorej urovni z vynimkou poradit.
Pavel #26
Já bych to napsal takto:
Ale myslím si, že Davidovi jde o tu výjimku vyhazovanou funkcí substring(), která by se musela na každém místě ošetřovat (ať tak či onak). Výjimky se „dle doporučení“ mají používat s rozvahou a metoda na vybrání podřetězce by podle mě „checkovanou“ výjimku rozhodně produkovat neměla…
marco #27
trochu offtopic: $_GET[‚user‘] je vzdy string ak je definovana, cize druha polovica podmienky je zbytocna
pok #28
No, pokud by všechny funkce vyhazovaly jen vyjímky, tak by stačilo tohle ne?
Zalogování je přeci operace ve stylu „povede se všechno a já se přihlásím“, nebo „smůla“. Myslím, že nevýhoda vyjímek na kterou se snažíš upozornit je že jejich nahození ukončí daný blok programu.
Ivan #29
#23 Davide Grudle, Hm, kdo by to čekal… Že
subStr('a', 0, 30) == 'a'
, alesubStr('', 0, 30) === false
:(V jiných jazycích to funguje dle mého názoru logičtěji:
''[:30]
vrací '' (python),''[0...30]
také vrací '' (ruby)Takže dle mého spíše ne všechno automaticky na výjimky, ale domyslet vhodnost.
David Majda #30
S případnou vyjímkou v substr() počítat v kódu NEMUSÍME z toho důvodu, že se jí lze na 100% vyhnout správným použitím té funkce. V tomto případě je jasně definováno, kdy ze substr() ta vyjímka vypadne a lze to při volání zařídit tak, aby tato situace nenastala. Je to úplně totéž, jako kdybys chtěl ošetřovat catch-blokem každé dělení, protože to má taky nedefinované případy (dělení nulou).
V Javě analogie této funkce (String.subString) ) vyhazuje IndexOutOfBoundsException, což je unchecked vyjímka, tedy její ošetření není povinné. V PHP jsou unchecked všechny vyjímky, takže tady není co řešit. V Javě je právě třeba často hlídat, zda se uživatel funkce může vyjímce vyhnout, a podle toho vyhazovat buď unchecked nebo checked exception. Ale to už trochu odbočuju.
Suma sumárum, myslím, že jsi zvolil špatný příklad.
Lokutus #31
#23 Davide Grudle,
No jistě, co bych taky měl očekávat jiného v proměnné typu strring.
Uff, díky bohu, že jde PHP úplně mimo mě.
Lokutus #32
#31 Lokutusi, Hele, já myslel, že když zmáčknu tady to čudlítko s nápisem CODE, tak se ta ohraničená část textu zformátuje. A ono prd. Nebo jsem to zmáčknul blbě?
Mordae #33
To, že
substr()
vůbec vrací false je chyba PHP, ne výjimek. Správné chování je IMO vrátit text nalezený do 30 znaků, nebo konce textu (co přijde dříve), stejně, jako při čtení ze streamu.Kód by měl při správné implementaci vypadat asi takto:
martin #34
#33 Mordae, a ako ste prisiel na to, ze substr nemoze failnut? napada ma celkom dost dovodov, ktore moze zapricinit vyhodenie vyjimky v metode substr
Ivan #35
#34 martine, Můžete důvody konkretizovat?
martin #36
#35 Ivane, napr. null ako prvy parameter, nieco ine ako retazec ako 1. prarmeter, nieco ine ako cislo ako dalsie 2 argumenty. 2. argument vacsi ako dlzka retazca. 2. alebo 3. argument negativny…
martin #37
#30 Davide Majdo, hmmm, IndexOutOfBounds ale musis (mal by si) tiez niekde osetrovat. pravdepodobne (skoro urcite) nie hned pri volani danej fcie, ale na urcitej urovni by osetrena mala byt – teda pokial nechces, aby ti to sundalo celu jvm – coz ja vacsinou nechcem :)
Ivan #38
#36 martine,
$user = substr($user, 0, 30);
– 2. a 3. parametr jsou tady mimo hru.$user = Script::getStringArgument('user');
– tady bych řekl, že to bude vracet string. Ale obecně máte pravdu – a je to slabina (?) slabě typových jazyků. (tedy, co se stane když bude např. 2 parametr ‚abc‘? Nefailne to, ale bude tam 0 – inu php :) Pokud byste v kódu připustil možnost zmatení parametrů, byla by výjimka na místě (podle mě mnohem lepší než vyhodit notice a zkusit pokračovat – jak to je teď).martin #39
#38 Ivane, ale vy sa pozerate na konkretne pouzitie. 2. a 3. argument nemusia byt staticke, ako v tomto priklade. mozu byt vypocitane, a vypocitane nespravne. preto by ich funkcia substr mala kontrolovat a vracat chybu (ci uz vynimku alebo false) v pripade nespravneho pouzitia. rovnake veci platia aj pre prvy parameter. ale ako som pisal aj v prispevku #37 martin, netreba tieto chyby riesit hned v kode, ktory metodu vola – staci na istej urovni osetrit vacsinu takychto typov chyb (v jave runtime-ovych) naraz.
raver #40
#27 marco, a co taketo url:
Ivan #41
#39 martine, Máte pravdu. Asi se nebudeme dál přít konkrétní x obecně…
Adam Hošek #42
#36 martine, To je demagogie. Pokud jde o PHP, pak by se někde uvnitř té fce mohlo převést přetypování (které snad žádné chyby nehází) a tudíž by prvním argumentem byl vždy string a další by byly vždy čísla (i kdyby 0). Jediný stav, kdy by ta fce mohla něco házet, je hodnota
null
. Nevim, jak se v tomhle případě PHP chová… snad převede hodnotu na"(null)"
nebo co já vim.V silně typových jazycích jiné typy, než definované hlavičkou funkce, použít nejde už v době kompilace a
null
je často odchytáván běhovou výjimkouNullPointerException
nebo něčím podobným.#38 Ivane, Přetypování
(int)"abc"
na 0 je samozřejmě to, na čem PHP stojí a padá… bohužel nebo bohudík 🙂.#39 martine, Zase narážíme na to, jak je PHP stavěné a jak se chová a co z toho pro programátory plyne. Buď ta fce vrací to své univerzální
false
nebo může házet (pokud se má vše vyhazovat)IllegalArgumentException
. No a je to zase zde – takhle by se mohla chovat každá funce v PHP. Pak si ale představme, jaký by byl svět peklo… na každém kroku ošetřování legálnosti argumentů… Kontrovat Javou asi neni úplně to nejlepší, co tady můžeme dělat……mám totiž pocit, že David se snaží rozebrat problematiku výjimek v PHP a ne jinde. I když srovnání má svou váhu.
Podle mě situace, aby ve slabě typovém jazyce (PHP) byly hojně užívány výjimky, je cesta do pekel. Navíc implementace té které funkce může být různá a dá se říct, že si v jednom jazyce můžu napsat pět různých implementací např. fce `substring() ` tak, abych pokryl všechny možné způsoby návratu chyby včetně všech možných typů chyb… no možná by těch implementací bylo víc 😉. Pak si můžu vybrat, jaké chyby chci dostat a použít konkrétní implementaci… srandičky 😉.
Vyčítat výjimkám jejich náročnou implementaci (bylo myšleno jako implementace ze strany jazyka/překladače/běhového prostředí nebo ze strany jejich používání? – komentuji první variantu) a snižování výkonu podle mě nemá smysl. Je to jedna z vlastností daného jazyka, která je implementovaná jednou a kvalitně (co do omezení chyb v implementaci) a která má svůj účel – ulehčit práci při běžném programování tak, aby programátor psal s pomocí těch konstrukcí programy s menším výskytem logických chyb, resp. aby bylo možné tyto chyby snadno lokalizovat a jednoduše ošetřit (pokud je to možné). Pokud mi jde o výkon, můžu programovat v C/C++ a kašlat na OOP, výjimky a všechna ta cukrátka, díky nimž lze dnes programovat pohodlněji.
Uff a howg! 🙂
Adam Hošek #43
A jsem tedyk zvědav na pokračování 🙂.
David Grudl #44
#28 poku, v podstatě jsi na to kápl. Vyhození vyjímky mě teleportuje pryč do míst, odkud se jen těžko budu vracet do započaté práce.
Ošetřit a rozhodnout se, zda (či kudy) pokračovat – tak to mám rád.
Bohužel u výjimek mě jímá paranoa, protože nevím, co všechno ji může vyhodit. Nevím, kde všude je skryté „goto“.
Ono se nedá říci, že logování je operace, kdy buť všechno proběhne nebo nic. Jako programátor chci sám určovat váhu jednotlivým operacím. A drobná chyba substr() vs. nemožnost zjistit pole uživatelů je podstatný rozdíl.
(tím nechci říct, že lze přehlížet problém se substr (tedy v PHP možná i lze, ale není to čisté))
#42 Adame Hošku, připouštím, že tyhle úvahy jsou velmi silně spjaty právě s PHP.
David Grudl #45
#25 martine, zcela s tebou souhlasím. Co může být horšího, než klasická PHP chybová hláška, neobsahující stacktrace a kterou lze buď utlmunit, nebo logout a pak pracně zkoumat původ.
Přesto vidím na výjimkách i negativa.
Adam Hošek #46
#45 Davide Grudle, A jak se jednou člověk sžije s něčím jako je např. (tolikrát přirovnávaná) Java, PHP pak dokáže být noční můrou. Občas ta hlášení chyb jsou tak nejasná, že člověk stejně matně tápe, kde je skutečný původ té chyby. (Mám na mysli víceméně běhové chyby.) A co je nejhorší: když je chyba v eval()'d kódu… no ale to už asi nakusuju téma
eval() || !eval()?
😉.martin #47
#44 Davide Grudle, „Ošetřit a rozhodnout se, zda (či kudy) pokračovat“ – mozno to je presne ono – mne sa prave nechce po pri volani kazdej metody riesit chybovy stav – chcem si vyberat miesta, kde tie chyby riesit budem – a casto na jednom mieste riesit chyby z vacsej sady volanych funkcii.
Adam Hošek #48
#47 martine, To je fajn, to nepopírám, dokonce souhlasim. Ale co když mezi jednotlivými úkony, z nichž touto metodou sbírám „odezvy“, je nějaký silnější vztah? Závislost, která mě nutí řešit problém před provedením dalšího úkonu? Je pravda, že série příkazů, kdy každý krok je zvlášť šetřen (jakoukoli z metod – výjimky, chybové kódy), aby bylo možné rozhodovat, jestli nadále můžu provést krok následující i při výskytu ošetřitelné chyby, je otravná na psaní i čtení.
Pokud je jakékoli selhání kritické pro další operace, je uvedení celého bloku úkonů do try-catch bloku celkem vhodné, přehledné atd. Otázkou je, jestli a za jakých chybových stavů je potřeba pokračovat v původním plánu? Proto se také doporučuje používat výjimky jen pro skutečně vyjímečné stavy. A to i v ohledu na výkon výjimek.
Např. u fce substr() je házení někde výše zmíněné výjimky typu IndexOutOfBoundsException (nebo nevím, jak tomu v tomhle případě říkat) docela trefné. Přecejen ten interval, který chceme vycucnout, většinou vypočítáme předem a obvykle v závislosti na délce cucaného řetězu. (Omlouvám se za slovník 😁.) Tj. pokud by zde došlo k chybě, asi bude oprávněně výjimečná a určitě běhová.
piler #49
Zdravim, trosku mimo temu, ale viete mi poradit, ci dat alebo nedat objekt do session?
Viete o nejakych nebezpecenstvach alebo o niecom inom, kvoli comu by sa objekt v session nemal prenasat?
dik ;)
marco #50
ok, beriem spat ;)
martin #51
#48 Adame Hošku, mno ja na vyjimkach vidim prave tu vyhodu, ze pokial chcem, tak problem mozem osetrit hned na mieste (po volani funkcie), alebo jeho osetrenie mozem nechat na nejake spolocne osetrenie. to je prave ta vyhoda, ze sice sa musim rozhodovat, ci vyjimku chybu vo funkcii osetrovat alebo nie, ale nemusim ju osetrovat hned, na rozdiel od navratovych kodov.
#49 piler jediny problem, co ma napada, je velkost objektu a jeho pripadna serializacia a replikovanie pri pouziti clusteru.
Adam Hošek #52
#51 martine, Samozřejmě… možnost nechat „odvést“ výjimky na nějakou vyšší úroveň jsem při psaní toho komentáře asi opomněl. To jednoznačně výhodou je. Zvláště když to umí programátor dobře používat.
llook #53
Ok, let's flame.
Připomněl bych tři způsoby zpracování výjimečných stavů, zmíněné v předchozím článku:
Osobně preferuju všechny tři, v různých situacích přijdou vhod různá řešení.
Výjimky jsou bezva ve dvou případech:
Globální proměnné či funkce jsou nejmocnější ve spojení s návratovými hodnotami. Příklad:
V praxi by
něcoUdělej
mohlo býtPDO::query
aposledníChybovka
potomPDO::errorCode
, třeba.Moje stanovisko: „v některých situacích to throw exceptions!“
kolemjdoucí #54
Mně se zdá, že objevujete Ameriku. Někdy je třeba ošetřit chybu hned – pak jsou výjimky opruz. Někdy je lepší ošetřit chybu později a jinde – pak jsou opruz návratové kódy. Takže částečným řešením je pořádně přemýšlet při návrhu, ale stejně se nezavděčíte všem ve všech situacích.
Miloslav Ponkrác #55
Používám výjimky řadu let v různých jazycích. Dgx se dostává do problémů proto, že se snaží věci dělat ad absurdum.
Některé věci je lépe ošetřit hned, jiné vyhozením výjimky, další třeba návratovou hodnotou, něco prostě není vůbec chyba, jen speciální stav, jindy je lépe svést chyby pomocí goto do jednoho místa. Některým chybám lze předejít testováním stavů a podmínek. Taky se může hodit nastavit globální proměnnou, nebo zalogovat, atd..
Všechno chce cit pro situaci a používat výjimky všude a za každou cenu je prostě blbost. Důsledkem je, že pokud používáte knihovnu od někoho, kdo neumí s výjimkami zacházet a přesto je používá, je to příšerná věc a pak je lepší, když se takovému člověku výjimky zakážou úplně. Nadělá pak méně škody.
Tedy závěr: Výjimky jsou JEDNÍM Z MNOHA prostředků, jak se vypořádat s neovyklými stavy (záměrně nepíšu s chybami, protože výjimky nejsou na chyby). Výjimky jsou skvělá věc, já programovací jazyk bez výjimek považuji za nedokonalý, ale ošetřovat vše jen pomocí výjimek je blbost. Navíc je potřeba říci, že výjimky jsou sice velmi luxusní prostředek, ale také velmi pomalý, pokud nastane vyjímečná událost. Pokud v programu lítá milióny vyhozených výjimek za sekundu, pak takový program bude zpravidla velmi pomalý. Tedy všeho s mírou.
martin #56
#55 Miloslave Ponkráci, milion neobvyklych stavov za sekundu, to chce programatora frajera :))
Kamzik II #57
No ja newim, podstatou vyjimek by melo bejt reagovani na stav, kterej by se mel nejak osetrit 😉
takze pokud se jedna o prihlasovani, tak mi urcite neni
jedno, ze se nekdo pokousi prihlasit pod ne-existujicim uzivatelskym jmenem – proste vyhodim vyjimku, a „pak“ se s tim proste nejak (treba vypisu chybovou hlasku) poperu. Pokud by byl celej system byl psan objektove, tak by tady ten problem, alespon si myslim, nebyl. Svet by byl jednodussi a vyjimky by nam ulehcovali a zprehlednovali zivot. Doufam, ze sem se vyjadril spravne…
Kamzik II 😉
Miloslav Ponkrác #58
To není až tak nemyslitelné, záleží co kdo považuje za hodné výjimky. Ale to se stává jen těm, kteří výjimky dotahují absolutně do absurdna.
Miloslav Ponkrác #59
Výjimky a objektové programování spolu až tak moc nesouvisí. Výjimky lze používat velmi úspěšně i bez objektů, třeba jádro Windows vyhazuje výjimky, ač je psané v C, které podporu pro objekty postrádá.
Objektové programování není jediný existující styl programování a jediné paradigma. Výjimky nepotřebují objekty, nejsou na objektech nikterak závislé. A to i když v mnoha jazycích se vyhazují instance objektů, ale není to podmínkou.
Kamzik II #60
#59 Miloslave Ponkráci, No ja bych rekl, ze pouzivani vyjimek bez oop je prasarna, ne?
Kamzik II #61
#60 Kamziku II, Mozna neni 😉 A co se tyce clanku, tak bych se priklonil k vyhazovani vyjimek 😉
llook #62
#60 Kamziku II, Mě to připadá, že si říkáš o přizvukování. Aby ti někdo napsal, že „výjimky bez OOP jsou prasárna, s tím rozhodně souhlasím“. To ti nenapíšu, radši se zeptám:
Proč myslíš, že výjimky bez OOP jsou prasárna? A proč by ses v článku přiklonil k vyhazování výjimek?
Kamzik II #63
#62 llooku, Ono slo spis o to, ze jsem napsal blbost, uvedomil jsem si to, tak sem se opravil 😉 A jinak ja vyhazuju vyjimky kde to jde, protoze to podle meho nazoru prispiva k logice a k prehlednosti kodu. A zatim me jeste nikdo nepresvedcil o opaku, muzes byt prvni :)
Tento článek byl uzavřen. Už není možné k němu přidávat komentáře.