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)
?>
Jakub Vrána, Seznámení s oblastí, 26.6.2006, diskuse: 20 (nové: 0)

Diskuse

ikona dgx:

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..

taurendil:

souhlas

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í...

ikona llook:

Souhlas, případně souhlasím!

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.

ikona Jakub Vrána OpenID:

Pro přístup k prvkům pole se dá použít rozhraní ArrayAccess, viz http://php.net/spl.

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?

ikona 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íží.

ikona Jakub Vrána OpenID:

Totéž se dá říct i o použití složitých frameworků. Pro příležitostné čtenáře přidávám odkaz na mírně filozofický pohled na tento problém: http://php.vrana.cz/lokalni-psani-kodu.php

ikona 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...

ikona 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.

ikona Jakub Vrána OpenID:

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.

avatar © 2005-2024 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.