Kispad

Kispad: közös blog
4230 cikk, 53905 hozzászólás
Szerzők | Tudnivalók | Feedek


map { ... } @valami

stsmork cikke a Torokgeek rovatból, 2006. november 29. szerda, 22:44 | 7 hozzászólás

A címben szereplő {} és @ jelek nem obszcén szavakat hivatottak helyettesíteni, hanem egy felettébb hasznos Perl utasítás szintaxisát jelölik. Évek óta programozom Perlben, a map léte azonban mindaddig rejtve maradt előttem, amíg egyszer eszpee fel nem hívta rá a figyelmem, azzal a megjegyzéssel, hogy ő imádja. Utánanéztem, hogy mit csinál, és azóta én is imádom (mármint nem eszpee-t, hanem a map utasítást).

A hash listát gyakran használják adatstruktúrák tárolására, többek között a mySQL adatbázis API is ilyen formában adja vissza a lekérdezés eredményeit. A hash listáról a -> operátor segítségével tetszetős módon nyerhetők ki az egyes értékek:

my $name = $hit->{'name'};
my $user_id = $hit->{'user_id'};
my $email = $hit->{'email'};
...

Elég gyakori eset, hogy az SQL lekérdezés eredménye több sorból áll, ilyenkor egy tömböt kapunk vissza, amelynek elemei hash listák, a fenti módon összerakva. De mi van, ha mi csak simán a neveket akarjuk, egy tömbben? Ekkor:

my @names;
foreach my $hit (@hits)
{
  push @names, $hit->{'name'};
}

Nos, pontosan ez az, amit frankón be lehet tömöríteni egyetlen sorba, a map utasítás segítségével:

my @names = map { $_->{'name'} } @hits

Ez pontosan ugyanazt csinálja, mint az előző ciklus: végigiterál a paraméterként megadott tömb elemein, behelyettesíti őket a $_ változóba, végrehajtja a { } zárójelek közé zárt kódot, a kiértékelés ereményét bedig bedugja az egyenlőségjel bal oldalán álló tömbbe. Mindezt, nagyon Perl-szerűen, egyetlen sorban.

Akik idáig jutottak az olvasással, azoknak ráadásként következik egy fejtörő. Hogyan lehet hash referenciák segítségével duplikálni egy hash listát? Adva van egy hash listánk:

my $foo = {};
$foo->{'one'} = 1;
$foo->{'two'} = 2;
$foo->{'thee'} = 3;

Erről a listáról szeretnénk egy másolatot, a $bar változóval referálva. A kézenfekvő

my $bar = $foo

megoldás nyilván hibás, mert így mind $foo, mind $bar ugyanarra a hash listára mutatna, tehát a $bar->{'one'} = "egy" utasítás után $foo->{'one'} értéke is "egy" lenne, pedig mi azt szeretnénk, ha "1" maradna. (Elnézést kérek azoktól, akiknek ez olyan bonyolultan hangzik, mint a bridzs rovat a Füles rejtvényújságban.) Egysorosnál hosszabb megoldásokat nyilván nem fogadunk el :-)

» Ugorj a hozzászóló ablakhoz

Megosztások Facebookon

Eddigi hozzászólások (7)

1

Author Profile Page eszpee, 2006. november 29. szerda, 23:18 (#)

Bonyolítsuk, elvégre perlről beszélünk: a map-en belüli kódrészletben a $_ egy _módosítható_ alias a lista adott elemére! Ez óvatlan programozók kezében rejtélyes hibákat, perverzek kezében pedig visszafejthetetlen kódot eredményezhet. :)

2

Ply, 2006. november 30. csütörtök, 00:30 (#)

Részemről:

my $bar = { %$foo };

De ebben nincs map, úgyhogy nyugodtan ki lehet zárni. :-)
Viszont el kellett párszor olvasnom a kiírást, annyira furának találtam a "hash lista" kifejezést a hash-re. A "hash lista" nálam ({}, {}, {}) alakú dolgokat szokott jelenteni. Ja, és hogy tovább gizduljak: a példádat én

my @names = map $_->{name}, @hits;

alakban írnám, ilyen egyszerű esetekben nem kell blokk,és a hash indexét sem kell idézőjelbe rakni.

3

pblue, 2006. november 30. csütörtök, 21:39 (#)

most köcsög leszek, de tenyleg azért jó a perl, mert egy sorban el lehet intézni kb 20-30 műveletet, ezáltal debugolhatatlanná és átláthatatlanná téve a kódot? szoktatok ti perl programozók csapatban dolgozni egy projekten?

4

robi, 2006. december 1. péntek, 10:15 (#)

Valóban, ez a mondat valóban flamebait...

5

Author Profile Page NagyGa1, 2006. december 1. péntek, 12:15 (#)

A baj nem is csak ez, hanem az hogy az egész dolog leragadt egy eléggé avítt kisipari programozási módnál, ami nem is ad túl robosztus eredményt, mindezt akkor amikor a világ már rég automatikus perzisztenciáknál jár.

(;))

6

robi, 2006. december 1. péntek, 13:56 (#)

és a szinergiáról se feledkezzünk meg! (vagy az már old time? pedig annyira oda lehetett mondani mindenhez: szinergikus rendszerek, szinergikus sütő, szinergikus pumpa)

7

Boca, 2006. december 1. péntek, 23:04 (#)

Pblue, nemcsak ezért jó. Csapatmunkában nem szokás egysorosokkal zsonglőrködni. De azokról nem írnak a Kispadon.


Hozzászólsz?

Igen

Hozzászólást csak névvel együtt fogadunk el. Ha linket írsz be, akkor előtte és utána hagyj egy szóközt, főleg akkor, ha zárójelbe teszed.


Az oldal tetejére | Szerzők, tudnivalók, feedek | sesblog és Kispad © 2003-2010 ervin, eszpee, stsmork