🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.lang.perl
Article #543

Re: przekazywanie przez referencje

#543
From: Piotr Auksztulewicz
Date: Thu, 04 Sep 1997 12:12
91 lines
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!piotras
References: <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