Thread View: pl.comp.lang.perl
2 messages
2 total messages
Started by Maciek
Thu, 04 Sep 1997 22:30
przekazywanie przez referencje
Author: Maciek
Date: Thu, 04 Sep 1997 22:30
Date: Thu, 04 Sep 1997 22:30
25 lines
1025 bytes
1025 bytes
Witam,
probuje uzyskac cos takiego :
push(@tab,join('%%',$a,$b,$c,@d,@e));
.
.
jakis kod
.
.
for($i0;$i<=$#tab;$i++) {
($a,$b,$c,@d,@e) = split('%%',@tab);
}
W takiej postaci to oczywiscie nie dziala i ja wiem, ze nie powinno.
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,
pozdrawiam, Maciek
Re: przekazywanie przez referencje
Author: 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
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads