Přetěžování operátorů
Školení, která pořádám
Sara Golemon je u mě jeden z největších expertů na jádro PHP, z příslušnic něžného pohlaví určitě. Stačí se podívat, za jakými rozšířeními stojí (classkit, parsekit, runkit, …) a jistě mi dáte za pravdu. To ona do jazyka přidala operátor goto, prý jako domácí cvičení.
Další rozšíření, které jde až k samému jádru jazyka, je operator. Slouží k přetěžování více než 30 operátorů tak, aby se daly přímo používat pro práci s objekty. Přetěžování operátorů je velice oblíbené v jazyce C++, kde řadu věcí může skutečně značně zpřehlednit, do samotného PHP se ale asi nikdy nedostane, protože se na první pohled chová až příliš mysteriózně. Nicméně, pokud se někdo vyžívá v přetěžování přístupu k proměnným a volání funkcí a implementaci rozhraní pro práci s objekty jako s poli, dostává tímto rozšířením do ruky další mocnou zbraň.
<?php
class foo {
private $value;
function __add($val) {
return $this->value + $val;
}
function __construct($init) {
$this->value = $init;
}
}
$c = new foo(7);
var_dump($c + 3); // int(10)
?>
Diskuse
Jen doufám, že některá rozšíření Sary Golemon zůstanou i nadále domácím cvičením, nejlépe dobře ukrytým na jejím harddisku..
Ondra:
A teď tu všichni, kdo souhlasíte, napište "Souhlas" případně "Souhlasím".
OMG.
anode:
Souhlas. Vlastně ne, myslím, že jsem chtěl říct spíš něco jako "souhlasím". :)
Teď vážně, pokud se používají opravdu s rozumem, jsou runkit a podobné docela užitečné. Mně se třeba runkit docela hodí pro testování tříd a funkcí...
vd:
Souhlas, případně souhlasím, s tvojím souhlasem na souhlas, případně souhlasím.
Mordae:
Ted jsem `pecl install operator` a musim rici, ze to rozsireni rozhodne neni spatne. Jedine, co mi na nem chybi je (snad jen zatim) nemoznost pretizit i [], tj. pristup k prvkum pole. Jinac je to moc pekna vec.
Mordae:
Pravda, zapomel jsem. To by slo.
Michal Stankoviansky:
Čo je zlé na preťažovaní operátorov? Skvelá vec je to napríklad pri práci s dátumami. Vytvorím si nejaký objekt Date, k nemu pripočítam napr. konštantu 10 a výsledkom bude dátum o 10 dní väčší reprezentovaný objektom Date. Pomerne elegantné, či nie?
dgx:
Je to otázka přístupu. Pro mě osobně má obrovskou váhu to, že pohledem na kus zdrojového kódu jsem schopen pochopit jeho smysl a odhalit chyby. Kód obsahuje výrazy, podmínky, volání funkcí. Výřez kódu je jasný sám o sobě - jen neznám-li nějakou funkci a nepochopím její význam z názvu, dohledám si její implementaci.
Jinak je tomu ale při použití přetěžování a některých podobných technik. Najednou nelze z kousku kódu vyčíst s jistotou vůbec nic, tedy pokud perfektně neznám celek. Každý výraz musím složitě dešifrovat, jestli některý operátor nemá pozměněný význam. Chyby přestávají být zřetelné. Pochopení cizích aplikací se šíleně ztíží.
dgx:
To je něco jiného, uvažoval jsem v rovině syntaxe jazyka, ne knihoven funkcí.
On i overloading v podání PHP je sám o sobě zdrojem obrovských komplikací v chápání kódu. Příjemnější by byla striktnější implementace vlastností (property, viz http://www.dgx.cz/trine/item/property-setters-…-final-solution), už kvůli jejich přehlednému výčtu v kódu, který by šel navíc opatřit komentářem phpDoc.
A současný overloading nechat jako eventualitu pro specifické případy, jako je třeba SimpleXML.
@ss@ssIn:
IMHO by pretazovanie operatorov malo zostat v C++, ale ked uz tak jedno pravidlo [ekd sa ho drzis, tak nic nepokazis]
"Pretizene operatory by nemali popierat svoju inutitivnu funkciu."
Mordae:
To je jednim slovem GENIALNI ;]
Sakra, zase to tak o 50% zjednodusi praci s objekty a konecne bude mozne dopsat skutecnou tridu String.
Pavel Zbytovský:
Jenže při vytvoření takové třídy bychom museli předělat všechny funkce, které řetězce dostávají v parametru, ne? Moc se mi líbí jak je tohle všechno uděláno třeba v javascriptu, "To je jednim slovem GENIÁLNÍ ;]". :-)
Mordae:
No, kdyby nekdo primo v enginu zavedl __toString (nekdo chce, nekdo ne). Jo a taky automaticky ""->String('')...
Hodne funkci pro praci s retezci se stejne musi aliasovat ve tride String, substr(), tolower(), toupper() atd., takze to neni az tak hrozne.
Predesly post byl ale jen takovy maly nadseny vykrik. Zrovinka tedko me spis nez operatory stve absence pretezovani metod. Sakra, maj type-hinting, ale tohle neni. Da se to nahrubo napsat pres __call(), ale jsou s tim moc velke komplikace a je moc velky overhead. Kez by na tom makli a pridali take hinting zakladnich typu...
dgx:
Od 5.1 existuje hinting pro typ Array. Ale mám pocit, že hintování skalárních typů není péhápéčková cesta. Odlišení 1) pole, 2) objekty a 3) sklaráry mi docela vyhovuje.
Jakub Vrána :
Potvrzuji, mezi vývojáři se to nedávno probíralo. Absence hintování skalárních typů není chápána jako nedostatek, ale jako vlastnost jazyka.
Mordae:
Jenze ono tady to odliseni neni :-/, jenom pole/objekt/cokoliv...
Diskuse je zrušena z důvodu spamu.