ugrás a tartalomhoz

Névtelen függvények PHP-ben

Török Gábor · 2007. Dec. 4. (K), 19.39
Mióta túlnyomórészt ELisp és JavaScript nyelveken fejlesztek, egyre jobban hiányoznak a funkcionális programozásban megszokott lehetőségek. Így történt ma, hogy egy probléma megoldásának PHP alapú kivitelezése során szerettem volna névtelen függvényeket használni. Várakozásaimmal ellentétben rendelkezik a PHP is egyfajta tálalással, habár ez nem az a vonás, amire különösebben büszkék lehetnénk.

$sum = create_function('$a, $b', 'return $a + $b;');
echo $sum(4, 5); //9
A create_function()-nel többek között az a baj, hogy a névtelen függvény deklarációjának explicit kivédése megfoszt a fejlesztőkörnyezetünk valamennyi funkciójának használatától, de hogy ne szaladjunk túlságosan előre, egyszerűen a kódszínezés hiányában is nehezebben emészthető programot kapunk. Az implementáció másik hiányossága, hogy míg egy névvel definiált függvény esetén a függvény kódjában a __FUNCTION__ állandóval tudunk hivatkozni magára a függvényre, addig valamennyi névtelen függvénynél ez a __lambda_func szövegliterárt adja vissza, így például rekurzív névtelen függvények csak explicit argumentum átadással lehetségesek. De vannak vele egyéb gondok is.

Még márciusban terjesztett egy patch-et Wez Furlong a közösség elé, amely valódibb névtelen függvényekkel vértezi fel az értelmezőt, mellőzve a create_function()-ös – ahogy ő fogalmaz – paródiát. A Wez által bevezetett jelölés kisértetiesen hasonlít a JavaScriptes névtelen függvények deklarációjára:

$foo = function() {};
A megvalósítás erőssége azonban nem ebben jelentkezik. Wez implementációja automatikusan idézőjelezi a szükséges kifejezéseket, tehát nem kell külön a teljes függvénytörzset aposztrófok közé szorítani, egyszerűen úgy kódolhatunk, ahogy az természetes, és egyúttal a teljes kifejezést közvetlenül argumentumként is átadhatjuk.

$data = array('állatkert', 'narancs', 'autó', 'citrom', 'alma');
usort($data, function($a, $b) {return strcmp($a, $b);});
var_dump($data); //Az adatok immáron ábécé rendben
Így már klassz.
 
1

Jó lenne

Bártházi András · 2007. Dec. 4. (K), 21.07
Pont tegnap találkoztam én is a PHP ezen "feature"-jével. A paródia enyhe kifejezés. Örülök, hogy történik ezen a szinten is előrelépés. A JavaScript (és egyebek) után én is nagyon sokszor hatalmas visszalépésnek érzem a PHP-t.
2

Csatlakozom.

Fraki · 2007. Dec. 4. (K), 22.38
Csatlakozom. (Ugyanezt éreztem másfél éve, amikor megismerkedtem a nyelvvel.) A php és a metaprogramozás...

BTW, csodálkozom, hogy ilyen rövidke patch-csel megoldható az ügy.
3

And the real WTF is...

Wabbitseason · 2007. Dec. 5. (Sze), 11.09
Ha már március óta létezik ez a patch, akkor vajon miért nem kerül bele a hivatalos PHP-ba?

Ördögi dolog ez...
4

"no way in PHP to access the parent scope"

Török Gábor · 2007. Dec. 5. (Sze), 11.24
A Zend Developer Zone-ban találtam egy részletes elemzését a problémának.
5

ez fogalmazodott meg bennem is

Adam · 2007. Dec. 5. (Sze), 11.25
hogy vajon mikor ohajtjak majd betenni a hivatalos agba, hogy egyszeru halando fejlesztok tudjuk hasznalni :)
7

Fontosabb fejlesztések

Török Gábor · 2007. Dec. 5. (Sze), 11.33
Jó dolog volna, de azért vannak fontosabb területek is, amit érdemes hangsúlyosabban kezelni (pl. namespace támogatás). Mindezek mellett szerintem nyitott a közösség arra, hogy bárki végigvihesse a problémát (:
8

kicsit vilagosabb igy

Adam · 2007. Dec. 5. (Sze), 12.29
Az altalad adott linken leirtak elegge szemleletesen bemutatjak, hogy ezt bizony erosen at kell gondolni. Mivel a PHPt abszolut nem ilyenek megvalositasara terveztek, valoszinu a teljes PHP scope kezelest ujra kellene gondolni/irni, az meg megintcsak egy nagy ugras lenne...

A kozosseg termeszetesen nyitott, ellenben az ilyen marginalis valtoztatasokat nem feltetel nelkul veszik be, es van, hogy jopar felevnek kell eltelnie, mire megvitatjak egy-egy dolog alkalmazhatosagat, implementalasat, lasd anno a goto vita.
6

Nem üdvös

vbence · 2007. Dec. 5. (Sze), 11.32
Ez a patch ahogy én látom max arra jó, hogy a jó megoldás illúzióját keltse. Így is futásidőben értelmeződik, nem cache-elhető a fügvény, és így sem működik a __FUNCTION__ féle hivatkozás. Csak így nehezebb lesz rájönni, hogy miért nem...