ugrás a tartalomhoz

Argumentumok átadása név szerint

Török Gábor · 2006. Jan. 18. (Sze), 15.30
A PHP fejlesztői listán merült fel, hogy a PHP 6-ban bevezessék a paraméterek név szerinti átadásának lehetőségét. Maga az ötlet nem új, például Pythonban, vagy az egyre népszerűbb Ruby-ban is megtalálható ez a lehetőség (és a Perl 6-ba is tervezik). Segítségével beszédesebbé tehetők a függvények argumentumlistái, illetve így akár megengedhető lenne a paraméterek tetszőleges sorrendű átadása, nem kellene mindig a régebben használt függvények miatt a kézikönyveket és referenciákat bújni. A kód maga szolgáltatná a saját API-ját.

Jared White felvetése szerint tehát a PHP elbírná a következő kifejezést:
  1. <?php adduser(username: 'root', password: 'abcdefg', superuser: true); ?>  
A vitafonal Jared levelével indul. A nevesített paraméterátadás ugyan konkrét új funkciót nem nyújt, de rugalmasabbá teheti az opcionális paraméterek használatát, kényelmesebbé és szebbé teheti a kódot. Hasonlít arra, mintha egy asszociatív tömböt adnánk át, de a "fogadó oldalon", vagyis a függvény definíciójánál, illetve az átadott paraméterek felhasználásakor további a nyelv által biztosított automatikus lehetőségeket biztosít, szemben például egy általunk megvalósítandó feltétel halmazzal.
 
1

Ha valaki nagyon ragaszkodik hozzá...

tiny · 2006. Jan. 18. (Sze), 15.53
Ha valaki nagyon ragaszkodik hozzá, most is megoldható, bár nem éppen ezzel a szintaktikával. Nekem nem hiányzik, mert abc sorrendbe szoktam tenni :)
Mr.Tiny [http://tiny.uw.hu]
2

Perl

ralesk · 2006. Jan. 18. (Sze), 18.48
A Perl 5-ben is megoldható, sőt, sokan előszeretettel használják is – nem mondhatni teljesen „tiszta” megoldásnak ez sem, de nemigen látom értelmét annak, hogy ez „jobban” legyen támogatva. Elvégre most is működik, mégpedig nagyon megbízhatóan.

Az egésznek az alapja az, hogy a Perl hash-ek igazából megadhatók mint egy lista, aminek a párosadik (ugye nullával kezdve számozunk) elemei a kulcsok, páratlanadik elemei az értékek. Egy szubrutin paraméterei pedig lista.

A lényeg egy függvény elkészítésekor, hogy ezt a konverziót elvégezzük. Ez egyetlen sor az elején:
sub függvényem {
  my %args = @_;
  # $args{$_[0]} = $_[1], $args{$_[2]} = $_[3], stb. innentől

  # ...
}
A szubrutint pedig ezek után meg lehet hívni például így:
függvényem( 'gyümölcs' => 'alma', 'user' => 'józsi' );
3

beépített támogatás

Balogh Tibor · 2006. Jan. 18. (Sze), 21.15
A natív támogatás ennél tovább mutatna. A belső függvényeken is lehetne alkalmazni ezt a szintaxist. Ellenkező esetben nem sok értelme lenne.
  1. <?php  
  2.    in_array($ertek$tomb);  
  3.    in_array(needle: $ertek, haystack: $tomb);  
  4.    in_array(haystack: $tomb, needle: $ertek);  
  5.   
  6.    header(string: 'Location: blabla.html', http_response_code: 301);  
  7. ?>  
4

<Nincs cím>

ralesk · 2006. Jan. 18. (Sze), 23.43
Perlben egy csomó CPAN modul rutinja ilyen, attól függetlenül, hogy nem éppen natív a hash-átadás támogatása.

Gondolok itt a CGI modulra (ha már azt felvetetted):

print CGI::header(-type  =>  'text/html',
                  -cost  =>  'Three smackers',
                  -annoyance_level => 'high',
                  -complaints_to   => 'bit bucket');
Mondjuk szerintem az in_array($val,$arr) és egy csomó más belső függvénynél egyszerűen nincs értelme a hash-es átadásnak, de persze ki hogy szereti :) Szerintem csak felesleges gépelés – szóval remélem azért nem cserélik le a mindent ilyenre, hanem ésszel lesznek.

A PHP-ről nincsenek túl mély ismereteim, de tiny fent említette, hogy most is megoldható, hogy a saját függvényeid valami ilyesmit támogassanak – ebből én azt a következtetést vontam le, hogy ha a PHP készítői nagyon akarnák, az alap függvényekbe akár most is beletehetnék az ilyen paraméterátadást, anélkül, hogy egy új szintaktikai elemet bevezetnének. Az egész csak azon áll, hogy bele akarják-e írni az alap librarykba ezt vagy nem.
5

Gyakorlati haszon?

saxus · 2006. Jan. 19. (Cs), 01.07
Van azért gyakorlati haszna is a kényelmi funkciókon fellül. Például van egy ilyenem:

function akarmi($elso='', $masodik='valami', $harmadik=false) { ... }


És ha nekem csak az első és a harmadik paraméter értékét kell megadnom, amúgy jó lesz az alapértelmezett, akkor jól jön, feltéve, ha jól értelmeztem, mire jó.

akarmi(elso: 'nemtudom', harmadik: true );


A gyakorlat az, hogy ilyen viszonylag ritkábban kell, mint az, hogy az összes paramétert megadjuk. Persze ha kell jól jön bármi :-). Csak nekem van egy olyan gyanum, hogy ha bekerül a PHP6-ba, ez a gyakorlatban legtöbbször kényelmi szempontból fog megnyilvánulni és csak a kódmennyiséget növeli. Bár egy részről olvashatóbbá teszi a paraméterek listáját.

De mi van akkor, ha valaki vegyesen használja?
10

Alternatív megoldás

Anonymous · 2006. Jan. 20. (P), 13.52
A saját programjaimban én is törekszem arra, hogy jól olvasható legyen a kód. Ezért a példában szereplő fgvhívást én így csinálom:
  1. <?php  
  2. $password = "abcdefg";  
  3. $username = "root";  
  4. adduser( $username$password );  
Tény, hogy ez nem teszi lehetővé a paraméterek sorrendváltoztatását és opcionálissá tételét; kizárólag a paraméterátadás olvashatóbbá tétele érdekében csinálom így. Bár bevált az eddigi módszer, mégis támogatom a bevezetni kívánt új jelölésmódot.

Ha nem akarod, nem írod ki a "paraméternév:"-ot, ha akarod, akkor pedig kiírod. Még a szövegterpesztő is támogathatja egy "show parameter names" gombocskával, hogy ezeket megmutassa-e vagy sem. Én kiírnám mindenhova, ahol nem egyértelmű, és elrejtetném a texteditorral, ha zavar a sok szöveg.
12

Felesleges pluszok

saxus · 2006. Jan. 20. (P), 22.44
Mondjuk ez magánvélemény, de én azért nem szeretem az ilyen megadásokat, (régebben használtam ilyet itt-ott, most már csak ott, ahol tényleg úgy gondolom, hogy érdemes) mert szerintem ezért felesleges külön lefoglaltatni egy-egy változót, és plusz műveleteket végrehatjani, hogy olvashatóbb kód legyen. Mondjuk lehet, hogy minimális, amit lassít, de én nem szeretem. Ez magánvélemény akart lenni. :)
13

Mas

sajt · 2006. Jan. 23. (H), 16.55
Mondjuk az ilyen hozzaadasok altalaban, peldaul valamilyen inputbol jonnek, igy a dolog valahogy igy valtozik:
  1. <?php  
  2. adduser($_POST['username'], $_POST['password']);  
  3. ?>  
Ahol pedig konstansok vannak, ott pedig erdemes ugye konstansokat valasztani.

--
Ámon Tamás - http://amon.hu
6

hason ló

bbalint · 2006. Jan. 19. (Cs), 02.25
hasonló szintakszist most is lehet; bár az alapértékek beállítása "hülyén néz ki":
  1. <?php  
  2.   //  a megadott tömb n-edik eleme legyen a kulcs, az n+1-edik  
  3.   // pediglen az érték a visszaadott tömbben; aholis n egy kettővel  
  4.   // maradék nélkül osztható szám => a paraméterben megadott tömb  
  5.   // elemeinek száma legyen páros  
  6.   function párosít($args){  
  7.     $r = array();  
  8.     reset($args);  
  9.     while((list(, $kulcs) = each($args))  
  10.        && list(, $ertek) = each($args))  
  11.       $r[$kulcs] = $ertek;  
  12.       
  13.     return($r);  
  14.   }  
  15.     
  16.   // teszt PHP  
  17.     
  18.   error_reporting(error_reporting() & ~E_NOTICE);  
  19.     
  20.   function a(){  
  21.     // alapértékek  
  22.     $a = 1;  
  23.     $b = 'false';  
  24.       
  25.     // "varázs"-kód  
  26.     extract(párosít(${microtime()}=func_get_args()), EXTR_OVERWRITE);  
  27.       
  28.     // nézzük meg a változók  
  29.     print('$a = '.$a.chr(10));  
  30.     print('$b = '.$b.chr(10));  
  31.   }  
  32.     
  33.   a();  
  34.   a(a, 12);  
  35.   a(b, 'true');  
  36.   a(b, 'null', a, 112);  
  37. ?>  
a magam részéről egy naplo() nevű függvénynél vettem eddig hasznát, aholis sok paramétert magától kitalál, viszont vannak esetek, amikor azokat azér' fölül kell írni.

megjegyzés: a példa-kódban a ${microtime()} = func_get_args()-ra azért volt szükség, mivel a PHP dokumentáció szerint
Ez a függvény [func_get_args()] nem használható közvetlenül függvény paramétereként
...az általam tesztelt PHP verziókkal (4.2.2 és 5.1.1) helyesen működött, ha elhagytam ezt az értékadást.
így csak a rend kedvéért szerepel ott

bbalint
9

Ugh!

ralesk · 2006. Jan. 19. (Cs), 17.42
Hát… ez elég csúnyán néz ki PHP-ben :) Lehet, hogy mégis csak jó ötlet kicsit natívabbá tenni ezt?
7

JS-ben, ha nagyon kell nagyon hasonló megoldás:

sly · 2006. Jan. 19. (Cs), 17.20
Gyorsan öszedobtam egy JavaScript megvalosítást is, ha valakinek szüksége lenne ilyenre. Végülis többféle képpen is meg lehet valosítani, de szerintem ez a legegyszerübb.
  1. <script type="text/javascript">  
  2. function ar(STarg) {  
  3.   var ARtmp = STarg.split(',');  
  4.   var ARreturn = new Array();  
  5.   for (i=0;i<ARtmp.length;i++) {  
  6.     eval('ARreturn.'+ARtmp[i].substring(0,ARtmp[i].indexOf(':'))+'='+ARtmp[i].substring(ARtmp[i].indexOf(':')+1));  
  7.   }  
  8.   return ARreturn;  
  9. }  
  10.   
  11. function func1(arg) {  
  12.   alert(arg.username+','+arg.password+','+arg.superuser);  
  13. }  
  14.   
  15. func1(ar("username: 'root', password: 'abcdefg', superuser: true"));  
  16. </script>  
.
8

Nem tudom

Bártházi András · 2006. Jan. 19. (Cs), 17.26
Nem mernék megesküdni rá, de mintha natívan lenne ilyen JavaScriptben. Ez a string megoldás azért elég ronda...

[...]

Ha nincs is, de a hash-es PHP-s megoldáshoz hasonlóan (egy jóval szebb, mint a stringben átadjuk megoldás):
http://www.javascriptkit.com/javatutors/namedfunction.shtml

Illetve JavaScript 2.0:
http://www.mozilla.org/js/language/js20/rationale/named.html

-boogie-
11

Tombok

sajt · 2006. Jan. 20. (P), 15.42
Ugye lehet tomboket is atadni. Ilyenekre jo peldak a smarty pld.:
  1. <?php  
  2. function valami($args) {  
  3.   /* alapertekek */  
  4.   $elso     = 1;  
  5.   $masodik  = 2;  
  6.   $harmadik = 3;  
  7.   /*feluliras a tombben levovel*/  
  8.   extract($args)  
  9. }  
  10.   
  11. valami (array('elso' => 2, 'harmadik' => -4));  
  12. ?>  
--
Ámon Tamás - http://amon.hu
14

Nekem kell a régi mód

Anonymous · 2006. Feb. 2. (Cs), 02.55
Felőlem jöhet, de maradjon meg a régi mód is, amikor nem kell leírni a formális paramétert. Épp elég programon kellett végiggyúrnom magam (Ada), amiben - előírás miatt - minden paramétert formális hivatkozással adtak át. Rendesen megnöveli a kódot => kevesebbet látsz át adott idő alatt. Néha persze jól jön, csak erőszakolni nem lenne jó.

Most itt a fönti példákon ugyan nem az látszik, hogy az idegeidre fog menni, sőt, ránézve logikus, hogy átláthatóbb az az _egy_ hívás. De az _egész_ program...

C-ben meg évekig programoztam, megvagyok default paraméterek nélkül. Ha kellenek, azt
- meg lehet oldani jelzőváltozókkal (igazán nem bonyolult)
- a sor végére lehet tenni (PHP-ban)
- vagy rendben, vezessük be ezt az újítást (valóban így a legszebb), csak ne kötelezően.

Én jobban örülnék, ha már olyanokkal foglalkoznának, hogy pl. bevezetnének a perl ,,use strict''-jéhez valami hasonló dolgot, amit ha bekapcsolsz, akkor deklarálod kell minden változót. Nem deklarált változókra álljon le értelmezési hibával. Nagyobb program esetén sokkal több segítség, mint ráfordítás - gondoljunk bele, egy apró elírás a változónévben, aminek pont új értéket adsz; és ahelyett, hogy rád szólna a PHP, hogy ,,Öreg, ezt ne csináld már...'', ahelyett misztikus hibákat fog produkláni a programod. :)

--
Kiskübi
15

E_NOTICE, E_STRICT

Hojtsy Gábor · 2006. Feb. 2. (Cs), 12.43
A PHP-ben eléggé régóta van E_NOTICE, ami a változó problémádat megoldja. Nem értelmezési hibát ad, valóban, de mivel dinamikusan bármikor előjöhetnek változónevek, ez talán logikus is. Az E_STRICT pedig PHP 5-ben egy még korlátozóbb hibaszint. Megjegyzem, ez itt teljesen offtopic.
16

E_NOTICE

Anonymous · 2006. Feb. 4. (Szo), 01.17
Valóban, ámbár az összes nem definiált sztringkonstansomért is hisztizik, amiket egyszer használok, és nem akarom külön leírni, meg egyéb dolgok miatt...
Azért köszönöm a hasznos infót, és bocs a ,,teljesen offtopic'' miatt. :)

--
Kiskübi