Předávání pravdivostních parametrů
Školení, která pořádám
Někdy je funkci potřeba předat pravdivostní parametr, třeba jestli má v průběhu své činnosti něco tisknout nebo ne:
<?php
function process($print = false) {
if ($print) {
echo "průběžné informace\n";
}
// ...
}
?>
Pokud tuto funkci zavoláme jako process(true)
, je to značně nečitelný zápis, protože není na první pohled patrné, co to true
znamená. Já jsem si proto zvyknul používat zápis process("print")
. Jiná možnost je definovat si konstanty a pak volat process(PRINT)
, s tím je ale samozřejmě trochu práce navíc.
Diskuse
Michal:
Programuju v PHP už 5 let, ale nějak jsem nepochopil, co tímto chtěl autor říct?
houba:
Pravděpodobně chtěl autor říct, že lepší než nazvat funkci pořádně, aby každý pochopil co dělá nebo může dělat, tak si raději odvyknu používat proměnné typu Boolean (jejichž zpracování je velmi rychlé) a vše budu smolit pomocí řetězců...
O pojmenování funkce tady vůbec nejde. Jde o to, že když funkce dostává volitelné parametry, které mohou nabývat hodnot true/false, je čitelnější volání:
process($normalni_parametr, "no_print", "debug");
než
process($normalni_parametr, false, true);
Ve spoustě případů zcela nepodstatné snížení výkonnosti nehraje žádnou roli. Pokud roli hraje, je zmíněna možnost definice konstant.
jenže
process($normalni_parametr, "no_print", "debug");
znamená
process($normalni_parametr, true, true);
Trochu představivosti... V prvním případě může být funkce deklarovaná jako <?php process($x, $no_print = false, $debug = false) ?>, v druhém jako <?php process($x, $print = true, $debug = false) ?>.
Případně lze mít funkci deklarovanou takto:
<?php
function process($x, $print = null, $debug = null)
{
if (!isset($print)) $print = false;
if (!isset($debug)) $debug = false;
}
?>
To se hodí v případě, kdy jedna funkce s volitelnými parametry volá druhou, tedy např.:
<?php
function process2($x, $print = null, $debug = null)
{
return process(2*$x, $print, $debug);
}
?>
Výchozí hodnoty volitelných parametrů je potom možné mít pouze na jednom místě.
Mimochodem, ta vlna nesouhlasných reakcí se zvedla proto, že jsem to napsal nepochopitelně nebo to považujete za naprostou blbost? Jak to řešíte vy?
spíš jde o to, že pravdivostní hodnota řetětce je až na dvě výjimky vždycky true, tedy můžu napsat process("print", "debug"), ale process("no_print", "debug") bude totéž. Tedy musím psát process(false, "debug") a jaksi efekt je fuč, dokonce v tom vzniká jistý zmatek.
Tuhle myšlenku nezatracuju a pokud Ti vyhovuje, je to jen dobře. Osobně to používat nebudu, vidím v tom krok zpátky.
Krok zpátky oproti čemu? Co třeba pole s parametry, jako jsem viděl myslím v JpGraph?
<?php
function process($x, $params = array()) {
if (!isset($params["debug"])) $params["debug"] = false;
}
process($x, array("debug" => true));
?>
taky je možné, že jsem to zcela správně nepochopil...
Jakub Podhorský:
no tak tohle se mi nezdá jako nejlepší řešení...
buď si nazvu funkci pořádně abych na první pohled věděl co dělá
a nebo používám editor který podporuje PHPDoc a přidává ho při doplňování funkcí jako nápovědu...tuším že tohle umí phpEd a myslím že i Zend Studio
halogan:
Je to dobra idea, sam jsem driv delal metody ve tridach, ktere se volaly treba takto:
$t->input("Jmeno", 20, true, false, false, true);
Ted si to zpetne uvedomuji.
Jakub Podhorsky: Ano, ZDE to umi.
Tomáš (ATom):
Ano, čitelné je to lépe, ale kdo si bude pamatovat, co tam mám psát. Když nad tu funkci najedu v ZendStudiu, tak se zobrazí bublina s definici jednotlivých parametrů a jásně vidím, co kam mám dát, kdybych tam dával řetězece, tak to musím složitěji popisovat, co který řětězec znamená a hlavně ten řětězec musím psát, což může vést k překplepům. To už jsou lepší ty konstanty, nebo ještě lépe statické proměnné třídy.
Ale něčemu jako
$t->input("Jmeno", 20, true, false, false, true);
je fakt lepší se vyhnout
Od toho je to přece OOP, aby šlo:
$t->setMaxLenght(20);
$t->activateCheck(true);
$t->input("Jmeno");
halogan:
Jiste, to je dobre, ale pak formular s dvaceti inputy bude bordel...
llook:
Zajímavý nápad, ale připadá mi, že to je vlastně jen zvláštní poznámka. Asi jako /* print = */ true. Já bych to psal spíš takhle:
<?php
process(true); // print=true
?>
Třeba v Pythonu to řeší tzv. keyword argumenty. Když má funkce pět volitelných argumentů a já chci explicitně určit jen ten poslední, uvedu jeho název, např.:
frame = wx.Frame(title = "Hello world");
ia:
imho je najlepsie pouzit konstanty, ked nam ti TRUE/FALSE tak vadi, je to ovela efektnejsie a efektivnejsie...
tie konstanty mozme definovat akurat nad tou ktorou funkciou napriklad...
Jakub Vrána :
Nevím co máš na mysli "konstantami definovanými nad tou kterou funkcí". Mohl bys to nějak vysvětlit?
ia:
define ('DEBUG', TRUE);
define ('NO_DEBUG', FALSE); <- toto som myslel tym 'dan funkciou' :) proste ze su napisane pri funkcii.
function blabla ($debug)
{
if ( $debug )
{
// nieco zrob
}
}
Ale jak na to pozeram, tiez to nieje bohvieaka vyhra...
Jakub Podhorský:
já si myslím že se takhle akorát zbytečně vytvářejí konstanty a zbytečně tak zaberou místo v paměti
Jakub Vrána :
Kolik bys řekl, že zabírá paměti konstantní řetězec? Bez detailních znalostí toho, jak PHP vevnitř funguje není vhodné takové soudy vynášet.
Vozka:
Ahoj, trochu to na me pusobi jako proc delat veci jednoduse kdyz to jde slozite. Zcela bez pochyby se nejedna o nic sloziteho, ale zanasi to do kodu dalsi logiku nad kterou bude muset nekdo (nebo i ty sam) pozdeji premyslet. Proc proste nepouzit komentar a nenapsat si ze predni parametr je print a druhy debug, pokud to chci mit prehledne...
Nasledne kdokoliv prijde tak vidi jednoduchou funkci bez balastu a nastavovani konstant a ucel to splnilo take?
Nebo uz dneska neni v mode psat komentare?
V
Jakub Vrána :
Nejspíš jsi článek nepochopil. Parametry zůstávají stejné, pouze při volání se použije process("print") místo process(true). Vnitřek funkce se nijak nemění.
msx:
A prečo nevyužiť JavaDoc, či ako sa to volá? Ja by som radšej, pri volaní funkcie použil $print = true. Síce sa zbytočne Inicializuje premená, ale bude to prehľadnejsie.
Diskuse je zrušena z důvodu spamu.