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

<?php
   in_array($ertek, $tomb);
   in_array(needle: $ertek, haystack: $tomb);
   in_array(haystack: $tomb, needle: $ertek);

   header(string: 'Location: blabla.html', http_response_code: 301);
?>
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:

<?php
$password = "abcdefg";
$username = "root";
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:

<?php
adduser($_POST['username'], $_POST['password']);
?>
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":

<?php
  //  a megadott tömb n-edik eleme legyen a kulcs, az n+1-edik
  // pediglen az érték a visszaadott tömbben; aholis n egy kettővel
  // maradék nélkül osztható szám => a paraméterben megadott tömb
  // elemeinek száma legyen páros
  function párosít($args){
    $r = array();
    reset($args);
    while((list(, $kulcs) = each($args))
       && list(, $ertek) = each($args))
      $r[$kulcs] = $ertek;
    
    return($r);
  }
  
  // teszt PHP
  
  error_reporting(error_reporting() & ~E_NOTICE);
  
  function a(){
    // alapértékek
    $a = 1;
    $b = 'false';
    
    // "varázs"-kód
    extract(párosít(${microtime()}=func_get_args()), EXTR_OVERWRITE);
    
    // nézzük meg a változók
    print('$a = '.$a.chr(10));
    print('$b = '.$b.chr(10));
  }
  
  a();
  a(a, 12);
  a(b, 'true');
  a(b, 'null', a, 112);
?>
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.

<script type="text/javascript">
function ar(STarg) {
  var ARtmp = STarg.split(',');
  var ARreturn = new Array();
  for (i=0;i<ARtmp.length;i++) {
    eval('ARreturn.'+ARtmp[i].substring(0,ARtmp[i].indexOf(':'))+'='+ARtmp[i].substring(ARtmp[i].indexOf(':')+1));
  }
  return ARreturn;
}

function func1(arg) {
  alert(arg.username+','+arg.password+','+arg.superuser);
}

func1(ar("username: 'root', password: 'abcdefg', superuser: true"));
</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.:

<?php
function valami($args) {
  /* alapertekek */
  $elso     = 1;
  $masodik  = 2;
  $harmadik = 3;
  /*feluliras a tombben levovel*/
  extract($args)
}

valami (array('elso' => 2, 'harmadik' => -4));
?>
--
Á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