Article View: pl.comp.lang.perl
Article #543Re: przekazywanie przez referencje
From: Piotr Auksztulewicz
Date: Thu, 04 Sep 1997 12:12
Date: Thu, 04 Sep 1997 12:12
91 lines
4105 bytes
4105 bytes
Maciek (toczyski@delta.sggw.waw.pl) wrote:
: push(@tab,join('%%',$a,$b,$c,@d,@e));
: .
: .
: jakis kod
: .
: .
: for($i0;$i<=$#tab;$i++) {
: ($a,$b,$c,@d,@e) = split('%%',@tab); # tu chyba miało być $tab[$i] ...
: }
: W takiej postaci to oczywiscie nie dziala i ja wiem, ze nie powinno.
Oczywiście. Przypisanie typu (@a, @b) = ( lista ) nie ma sensu, bo wszystko
wyląduje w @a. Ponadto użycie join/split w tym przypadku nie daje zamierzonego
efektu z prostej przyczyny: po takim join jak powyżej nie można stwierdzić
gdzie się kończą elementy z @d i zaczynają elementy z @e.
: Co jednak zrobic, zeby zaczelo dzialac? Wiem, ze jesli chce sie
: przekazac funkcji dwie lub wiecej tablic, nalezy uzyc referencji.
: Ja jednak nigdy wczesniej tego nie robilem. Prosilbym o pomoc,
Mozna by to zrobić tak:
push @tab, [ $a, $b, $c, \@d, \@e ];
o ile @d i @e nie zmieniają się podczas wykonywania "jakiegoś kodu".
Ale zgaduję, że w "jakimś kodzie" będzie więcej takich push'y.
Lepiej więc będzie tak:
push @tab, [ $a, $b, $c, [ @d ], [ @e ] ];
Wtedy do @tab będzie "wepchnięta" referencja do tablicy zawierającej pięć
elementów: trzy skalary (kopie $a, $b i $c) oraz dwie referencje do tablic,
będących kopiami @d i @e. Tutaj nawiasy kwadratowe pełnią funkcję konstruktora
referencji do tablicy - działanie jest takie, że tworzona jest nowa tablica
zawierająca wyszczególnione elementy i zwracana referencja do niej. Jak
widać, można tę konstrukcję zagnieżdżać.
Wyciąganie wartości wewnątrz for będzie trochę bardziej skomplikowane.
A w ogóle tego for'a zapisałeś całkiem jak w C. To nie jest błąd, ale dużo
bardziej przejrzysty jest taki zapis:
for $element ( @tablica ) # ew. można napisać 'foreach' - działa tak samo
Ale wróćmy do tematu wyciągania tego z powrotem.
for($i0;$i<=$#tab;$i++) {
$ref = $tab[$i]; # $ref jest referencją do tego, cośmy push'nęli
# Dostęp do elementów można mieć tak: $ref->[0] - to będzie $a,
# $ref->[1] - to będzie $b, $ref->[3][0] to będzie $d[0] itd.
# Ogólnie -> to jak * w C (dereferencja). Uważny czytelnik
# zapewne stwierdził, że trzeci przykład powinniśmy zapisać
# $ref->[3]->[0]. Ale perl jest na tyle domyślny, że nam tę drugą
# strzałkę sam wstawi. Jednak zwięźlej będzie tak:
($a, $b, $c, $ref_d, $ref_e) = @$ref; # Dereferencja ref. do tablicy
@d = @$ref_d;
@e = @$ref_e;
}
Niestety nie da się tego zrobić "na jeden strzał", trzeba schować sobie
te referencje do tablic @d i @e i potem odkręcić drugi poziom referencji.
Uwaga: gdybyś chciał pominąć to pomocnicze przypisanie: $ref = $tab[$i] i
napisał tak:
($a, ... itd ) = @$tab[$i];
to będzie błąd, bo perl najpierw będzie chciał zdrereferensować (ale słowo!)
a potem indeksować, co mu oczywiście nie wyjdzie. Trzeba by zrobić tak:
( bla, bla... ) = @{$tab[$i]};
I to już jest strasznie magiczne zaklęcie. Lepiej jednak będzie zamienić
for'a na foreach'a w przebraniu, czyli zrobić:
for $ref ( @tab ) {
( bla, bla ... ) = @$ref;
itd.
}
To jest w miarę przejrzyste i zwięzłe zarazem. A w ogóle to poczytaj sobie
perlref(1) i perldsc(1), tam jest wiele ciekawych rzeczy.
--
Piotr Auksztulewicz piotras@zeus.polsl.gliwice.pl
Centrum Komputerowe Politechniki Śląskiej, Gliwice, Akademicka 16
Technical Details
Message-ID:
<5um8k3$dmm@zeus.polsl.gliwice.pl>Path:
mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!pingwin.icm.edu.pl!agh.edu.pl!news.wnaft.agh.edu.pl!polsl.gliwice.pl!zeus.polsl.gliwice.pl!piotrasReferences:
<340E7FA1.3AD9B4C5@delta.sggw.waw.pl>Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!pingwin.icm.edu.pl!agh.edu.pl!news.wnaft.agh.edu.pl!polsl.gliwice.pl!zeus.polsl.gliwice.pl!piotras From: piotras@zeus.polsl.gliwice.pl (Piotr Auksztulewicz) Newsgroups: pl.comp.lang.perl Subject: Re: przekazywanie przez referencje Date: 4 Sep 1997 12:12:51 GMT Organization: Politechnika Slaska, Gliwice Lines: 91 Message-ID: <5um8k3$dmm@zeus.polsl.gliwice.pl> References: <340E7FA1.3AD9B4C5@delta.sggw.waw.pl> NNTP-Posting-Host: zeus.polsl.gliwice.pl X-Newsreader: TIN [version 1.2 PL2] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit