NAZWA¶
perldata - typy danych Perla
OPIS¶
Uwaga! To tłumaczenie może być nieaktualne!
Nazwy zmiennych
Perl posiada trzy typy struktur danych: skalary, tablice skalarów oraz
asocjacyjne tablice skalarów, zwane też "haszami"
("hashes"). Zwykłe tablice indeksowane są liczbami,
począwszy od 0 (indeksy ujemne są liczone od końca
tablicy). Tablice asocjacyjne indeksowane są łańcuchami.
Wartości są zwykle przypisane do nazwy (lub nazwanego
odwołania). Pierwszy znak nazwy mówi o tym, do jakiego rodzaju
struktury danych się ona odnosi. Reszta nazwy określa
konkretną wartość, do której odnosi się
nazwa. Najczęściej składa się ona z pojedynczego
identyfikatora, to znaczy, łańcucha
rozpoczynającego się literą lub znakiem
podkreślenia i zawierającego litery, podkreślenia i
cyfry. W niektórych przypadkach może być ciągiem
identyfikatorów, rozdzielonych przez :: (lub przez ', ale nie jest to
polecane). Wszystkie oprócz ostatniego interpretowane są jako
nazwy pakietów, wskazując przestrzenie nazw, w których
będzie wyszukiwany ostatni identyfikator (szczegóły
znajdziesz w sekcji Packages podręcznika
perlmod(1)).
Możliwe jest zastąpienie prostego identyfikatora
wyrażeniem, które w czasie wykonania tworzy odwołanie do
wartości; jest to opisane szczegółowo poniżej oraz
na stronie
perlref(1) podręcznika.
Istnieją również zmienne specjalne, których nazwy
nie przestrzegają powyższych reguł, po to by nie
kolidowały przypadkowo z którąś z twych
zwykłych zmiennych. Łańcuchy, które pasują
do objętych nawiasami okrągłymi części
wyrażenia regularnego zachowywane są pod nazwami
zawierającymi tylko cyfry po znaku $ (patrz strony
perlop(1) i
perlre(1) dokumentacji). Dodatkowo, kilka zmiennych specjalnych,
umożliwiających dostęp do wewnętrznych
rozwiązań Perla, posiada nazwy zawierające znaki
przestankowe (zobacz strony
perlvar(1) dokumentacji).
Wartości skalarne zawsze noszą nazwy rozpoczynające
się znakiem '$', nawet, gdy odnoszą się do skalara
będącego częścią tablicy. Działa to
podobnie jak angielski przedimek "the". A zatem mamy:
$dni # zwykła wartość skalarna "dni"
$dni[28] # 29-ty element tablicy
$dni{'luty'} # wartość dla klucza 'luty' z hasza %dni
$#dni # ostatni indeks tablicy @dni
ale całe tablice lub wycinki tablic oznaczane są przez '@', co
działa jak angielskie słowo "these" lub
"those":
@dni # ($dni[0], $dni[1],... $dni[n])
@dni[3,4,5] # to samo, co @dni[3..5]
@dni{'a','c'} # to samo, co ($dni{'a'},$dni{'c'})
zaś całe tablice asocjacyjne (hasze) oznaczane są przez
'%':
%dni # (klucz1, wartość1, klucz2, wartość2 ...)
Dodatkowo, procedury nazywane są z użyciem początkowego
'&', choć jest to opcjonalne, jeśli nie jest dwuznaczne (tak
jak w języku angielskim często zbyteczne jest użycie
słowa"do"). Elementy tablicy symboli mogą być
nazywane z użyciem początkowego '*', ale na razie nie musisz
się tym zajmować.
Każdy typ zmiennych ma swoją własną
przestrzeń nazw. Możesz, bez obawy o konflikt,
używać tej samej nazwy dla zmiennej skalarnej, tablicy czy
tablicy asocjacyjnej (lub uchwytu pliku, nazwy procedury czy etykiety).
Oznacza to, że $foo i @foo są dwoma różnymi
zmiennymi. Znaczy to też, że $foo[1] jest
częścią tablicy @foo, nie zaś
częścią skalara $foo. Może się to
wydawać trochę dziwne, ale tak ma być, gdyż to
jest dziwne.
Ponieważ odniesienia do zmiennych i tablic zawsze rozpoczynają
się od '$', '@' lub '%', to słowa "zarezerwowane" nie
są naprawdę zarezerwowane w odniesieniu do nazw zmiennych.
(Jednak SĄ one zarezerwowane w odniesieniu do etykiet i uchwytów
plików, które nie posiadają specjalnego
początkowego znaku. Nie możesz, na przykład,
użyć uchwytu pliku o nazwie "log". Wskazówka:
możesz napisać open(LOG,'logfile') zamiast open(log,'logfile').
Użycie nazw uchwytów plików złożonych z
dużych liter poprawia również czytelność i
chroni przed konfliktami z przyszłymi słowami
zastrzeżonymi. Wielkość liter JEST
znacząca--"FOO", "Foo" oraz "foo"
są zupełnie innymi nazwami. Nazwy rozpoczynające
się literą lub znakiem podkreślenia mogą
zawierać również cyfry i podkreślenia.
Możliwe jest zastąpienie takiej alfanumerycznej nazwy
wyrażeniem, które zwraca odwołanie do obiektu danego
typu. Opis tego znajdziesz na stronie
perlref(1) podręcznika.
Nazwy rozpoczynające się cyfrą mogą zawierać
tylko cyfry. Nazwy, które nie zaczynają się od litery,
podkreślenia ani cyfry ograniczone są do pojedynczego znaku, np.
$% czy $$. (Większość z tych jednoznakowych nazw ma
predefiniowane znaczenie dla Perla. Na przykład, $$ jest
identyfikatorem bieżącego procesu.)
Kontekst
Interpretacja operacji i wartości w Perlu zależy czasami od
wymagań kontekstu, w jakim użyta jest operacja czy
wartość. Istnieją dwa główne konteksty:
skalarny i listowy. Niektóre z operacji zwracają wartości
listowe w kontekście oczekującym listy, zaś
wartości skalarne w przeciwnym przypadku. (Jeśli tak jest dla
danej operacji, to zostanie to wspomniane w jej opisie.) Innymi słowy,
Perl przeciąża pewne operacje w oparciu o to, czy spodziewana
jest pojedyncza wartość czy mnoga. (W podobny sposób
funkcjonują w języku angielskim niektóre słowa,
jak "fish" czy "sheep".)
Na zasadzie wzajemności, operacja dostarcza albo kontekstu skalarnego
albo listowego każdemu ze swych argumentów. Na przykład,
jeśli napiszesz
int( <STDIN> )
to operacja całkowita (integer) dostarcza kontekst skalarny dla operatora
<STDIN>, który odpowiada czytając jeden wiersz z STDIN i
przesyłając go z powrotem do operacji integer. Ta z kolei
znajduje wartość typu integer tego wiersza i zwraca ją.
Jeżeli, z drugiej strony, napiszesz
sort( <STDIN> )
To operacja sortowania dostarcza kontekstu listowego dla <STDIN>,
który będzie przetwarzać wszystkie dostępne
wiersze aż do końca pliku. Następnie prześle
listę tych wierszy z powrotem do procedury sortowania, która z
kolei posortuje dostarczone wiersze i zwróci je w postaci listy do
kontekstu w jakim wywołano sort.
Przypisanie jest trochę specyficzne, w tym, iż posługuje
się swym lewym argumentem do ustalenia kontekstu dla prawego argumentu.
Przypisanie do skalara oblicza prawą stronę w kontekście
skalarnym, podczas gdy przypisanie do tablicy lub wycinka tablicy rozwija
prawą stronę w kontekście listowym. Przypisanie do listy
również oblicza prawą stronę w kontekście
listowym.
Procedury definiowane przez użytkownika mogą sprawdzać, czy
są wywołane w kontekście skalarnym czy listowym, ale
większość z nich nie dba o to, gdyż skalary
są automatycznie interpolowane w listy. Zobacz opis funkcji wantarray
na stronie
perlfunc(1).
Wartości skalarne
Wszystkie dane w Perlu są skalarami lub tablicami skalarów albo
haszami skalarów. Zmienne skalarne mogą zawierać
różne rodzaje pojedynczych danych, jak liczby,
łańcuchy znakowe czy odwołania. Ogólnie, konwersja
z jednej postaci na drugą jest transparentna. (Skalar nie może
zawierać wielu wartości, ale może zawierać
odwołanie do tablicy czy hasza zawierających wiele
wartości.) Z powodu automatycznej konwersji skalarów, operatory
i funkcje zwracające skalary nie muszą dbać o to (i
faktycznie nie dbają), czy kontekst oczekuje łańcucha czy
też liczby.
Skalary nie są koniecznie tą czy inną rzeczą. Nie ma
możliwości zadeklarowania zmiennej skalarnej o typie
"string", "number", typu "filehandle", czy
jakiegoś innego. Perl jest językiem kontekstowo polimorficznym,
w którym skalary mogą być łańcuchami,
liczbami czy odwołaniami (co obejmuje obiekty). Łańcuchy
i liczby uważane są za mniejwięcej to samo w niemal
każdym zastosowaniu. Odwołania są jednak nierzutowalnymi
wskaźnikami o ściśle określonym typie, z
wbudowanym licznikiem odwołań i wywołaniami destruktora.
Wartość skalarna interpretowana jest jako prawda, TRUE, w sensie
logiki boolowskiej, jeśli nie jest łańcuchem pustym ani
liczbą zero (lub jej łańcuchowym
równoważnikiem, "0"). Kontekst boolowski (logiczny)
jest po prostu specyficznym rodzajem kontekstu skalarnego.
Faktycznie istnieją dwie odmiany skalarów pustych: zdefiniowane i
niezdefiniowane. Niezdefiniowane skalary puste zwracane są gdy brak
jest rzeczywistej wartości czegoś, jak w przypadku
wystąpienia błędu lub na końcu pliku, albo gdy
odwołujesz się do niezdefiniowanej zmiennej czy elementu
tablicy. Niezdefiniowany pusty skalar może stać się
zdefiniowany po tym, jak po raz pierwszy użyjesz go tak, jakby
był zdefiniowany. Ale przed tym możesz
posłużyć się operatorem
defined(), by
stwierdzić, czy wartość jest zdefiniowana czy też
nie.
By stwierdzić, czy dany łańcuch jest poprawną
liczbą niezerową wystarczy zwykle porównać go
zarówno z numerycznym 0 jak i leksykalnym "0" (choć
spowoduje to ostrzeżenia opcji
-w). Sposób ten wynika
stąd, że łańcuchy nie będące
liczbami uważane są za 0, tak jak w
awk:
if ($str == 0 && $str ne "0") {
warn "To nie wygląda na liczbę";
}
Zwykle jest to metoda preferowana, gdyż w przeciwnym razie nie
traktowałbyś poprawnie notacji IEEE, takich jak NaN czy
Infinity. Czasami będziesz wolał posłużyć
się funkcją POSIX::strtod czy wyrażeniem regularnym do
sprawdzenia, czy dana jest numeryczna. Dokładny opis
wyrażeń regularnych znajdziesz w podręczniku
perlre.
warn "has nondigits" if /\D/;
warn "not a natural number" unless /^\d+$/; # odrzuca -3
warn "not an integer" unless /^-?\d+$/; # odrzuca +3
warn "not an integer" unless /^[+-]?\d+$/;
warn "not a decimal number" unless /^-?\d+\.?\d*$/; # odrzuca .2
warn "not a decimal number" unless /^-?(?:\d+(?:\.\d*)?⎪\.\d+)$/;
warn "not a C float"
unless /^([+-]?)(?=\d⎪\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/;
Długość tablicy jest wartością
skalarną. Możesz uzyskać długość
tablicy @dni obliczając $#dni, tak jak w
csh. (Faktycznie, nie
jest to długość tablicy, a indeks ostatniego elementu,
gdyż (zwykle) istnieje element o indeksie zerowym.) Przypisanie do
$#dni zmienia długość tablicy. Skracanie tą
metodą tablicy niszczy wartości pozostałe za nowym
końcem tablicy. Wydłużenie uprzednio skróconej
tablicy JUŻ NIE odtwarza wartości, które były w
utraconych elementach. (Było tak w Perlu 4, ale musieliśmy z tym
skończyć, by zapewnić wywoływanie
destruktorów tam, gdzie jest to oczekiwane.) Możesz też
osiągnąć nieco lepszą efektywność
wstępnie poszerzając tablicę, która ma się
powiększyć. (Można także poszerzać
tablicę wykonując przypisanie do elementu, który jest
poza jej obecnym końcem.) Tablicę można
obciąć do zera przez przypisanie do niej pustej listy ().
Poniższe są równoważne:
@cokolwiek = ();
$#cokolwiek = -1;
Jeżeli przetwarzasz nazwaną tablicę w kontekście
skalarnym, to zwraca on długość tablicy. (Zauważ,
że nie jest to prawdą dla list, które zwracają
ostatnią wartość, tak jak operator przecinka w C. Nie
jest to też prawdą dla funkcji wbudowanych, zwracających
to, na co mają ochotę.) Poniższe jest zawsze prawdziwe:
scalar(@cokolwiek) == $#cokolwiek - $[ + 1;
[Zmienna specjalna $[ określa indeks pierwszego elementu w tablicy i
pierwszego znaku w łańcuchu, domyślnie jest to zero.] W
wersji 5 Perla zmieniono semantykę $[: pliki nie ustawiające
wartości $[ nie muszą już zważać na to, czy
inny plik zmienił jej wartość. Inaczej
mówiąc, nie zaleca się używania $[. Zatem
ogólnie możesz zakładać, że
scalar(@cokolwiek) == $#cokolwiek + 1;
Niektórzy programiści wybierają użycie jawnej
konwersji, by nie było żadnych wątpliwości:
$liczba_elementow = scalar(@cokolwiek);
Jeżeli posługujesz się haszem (tablicą
asocjacyjną) w kontekście skalarnym, to zwraca on
wartość, która jest prawdą wtedy i tylko wtedy,
gdy hasz zawiera jakąkolwiek parę klucz/wartość.
(Jeżeli są takie pary, to wartość zwracana jest
łańcuchem składającym się z liczby
użytych jednostek komórek (buckets) oraz liczby zaalokowanych
jednostek komórek, rozdzielonych ukośnikiem. Najbardziej
przydaje się to do sprawdzania, czy wkompilowany w Perl algorytm
haszowania działa kiepsko na twoim zestawie danych. Na przykład,
wrzucasz 10,000 elementów do hasza, ale przetworzenie %HASH w
kontekście skalarnym zwraca "1/16", co oznacza, że
tylko jedna z szesnastu komórek została użyta, i
przypuszczalnie zawiera wszystkie twoje 10,000 pozycji. To się nie
powinno zdarzyć.)
Możesz wstępnie przydzielić miejsce na hasz przy pomocy
przypisania do funkcji
keys(). Zaokrągli to zaalokowane
jednostki komórek do najbliższej potęgi dwójki.
keys(%users) = 1000; # zaalokuj 1024 buckets
Konstruktory wartości skalarnych
Literały numeryczne podawane są w zwyczajowych formatach
zmiennoprzecinkowych lub całkowitych:
12345
12345.67
.23E-10
0xffff # hex
0377 # ósemkowa
4_294_967_296 # podkreślenie dla lepszej czytelności
Literały łańcuchowe ograniczone są zwykle przez
pojedyncze lub podwójne cudzysłowy. Działają one
bardzo podobnie do znaków cytowania powłoki: w literałach
łańcuchowych w cudzysłowach zachodzi zastępowanie
zmiennych i interpretacja odwrotnego ukośnika. W
łańcuchach w apostrofach nie występuje
zastępowanie i interpretacja (z wyjątkiem "\'" oraz
"\\"). To tworzenia znaków takich jak nowa linia, tabulator
itd., stosowane są zarówno zwykłe reguły
użycia odwrotnego ukośnika w Unixie, jak i bardziej egzotyczne
formy. Listę sposobów cytowania znajdziesz w sekcji
Quote and
Quotelike Operators podręcznika
perlop(1).
Zapisy ósemkowe czy szesnastkowe w literałach
łańcuchowych (np. '0xffff') nie są automatycznie
zamieniane na ich całkowitą reprezentację. Konwersje te
wykonują funkcje
hex() i
oct(). Więcej
szczegółów znajdziesz w opisach tych funkcji w
podręczniku
perlfunc(1).
Możesz też umieszczać znaki nowej linii bezpośrednio
w łańcuchach, tj., mogą one kończyć
się w innym wierszu niż się rozpoczęły.
Jest to przyjemne, ale jeżeli zapomnisz zamykającego
cudzysłowu, to błąd nie będzie zgłaszany
dopóty, dopóki Perl nie znajdzie innego wiersza,
zawierającego znak cudzysłowu, który może
znajdować się o wiele dalej w skrypcie. Zastępowanie
zmiennych w łańcuchach ograniczone jest do zmiennych skalarnych,
tablic oraz wycinków tablic. (Inaczej mówiąc, nazw
rozpoczynających się od $ lub @, po których może
opcjonalnie wystąpić, ujęte w nawiasy kwadratowe,
wyrażenie traktowane jako indeks elementu tablicy.) Poniższy
fragment kodu drukuje "Cena wynosi $100."
$cena = '$100'; # nie interpretowane
print "Cena wynosi $cena.\n"; # interpretowane
Tak jak w niektórych powłokach, możesz
umieścić nazwę w nawiasach klamrowych, by
oddzielić ją od następujących dalej znaków
alfanumerycznych. Identyfikator w takich nawiasach traktowany jest zawsze jako
łańcuch, tak samo jak pojedynczy identyfikator
będący indeksem hasza. Nasz wcześniejszy przykład,
$dni{'luty'}
może być zapisany jako
$dni{luty}
a cudzysłowy będą domniemane automatycznie. Ale cokolwiek
bardziej skomplikowanego w indeksie zostanie zinterpretowane jako
wyrażenie.
Zauważ, że łańcuch w pojedynczych
cudzysłowach musi być oddzielony od poprzedzającego go
słowa odstępem, gdyż pojedynczy cudzysłów
jest poprawnym (choć nie zalecanym) znakiem w nazwie zmiennej (zobacz
Packages w podręczniku
perlmod(1)).
Trzema specjalnymi literałami są __FILE__, __LINE__ oraz
__PACKAGE__, które reprezentują nazwę
bieżącego pliku, numer wiersza oraz nazwę pakietu w danym
punkcie twego programu. Mogą być używane
wyłącznie jako odrębne tokeny. Nie będą one
interpolowane wewnątrz łańcuchów. Jeżeli
nie ma bieżącego pakietu (z powodu pustej dyrektywy package;),
to __PACKAGE__ jest wartością niezdefiniowaną.
Tokenami __END__ i __DATA__ można posługiwać się do
wskazania logicznego końca skryptu przed faktycznym końcem
pliku. Dowolny następujący po nich tekst jest ignorowany, ale
może być odczytany przy pomocy uchwytu DATA. Wykorzystaj
main::DATA dla użytego tokenu __END__, lub też
NAZWAPAKIETU::DATA (gdzie NAZWAPAKIETU jest bieżącym pakietem)
dla __DATA__. Dwa znaki sterujące: ^D i ^Z są synonimami dla
__END__ (lub __DATA__ w module). Szerszy opis __DATA__ i przykład
użycia znajdziesz w podręczniku
SelfLoader.
Zauważ, że nie można czytać z uchwytu pliku DATA w
bloku BEGIN. Blok ten jest wykonywany natychmiast po napotkaniu (w czasie
kompilacji). W tym momencie nie został jeszcze znaleziony odpowiedni
token __DATA__ (lub __END__).
Słowo nie posiadające żadnej innej interpretacji w
gramatyce Perla będzie traktowane tak, jakby znajdowało
się w cudzysłowie. Są one znane pod nazwą
"gołych słów" ("barewords"). Tak
samo, jak w przypadku etykiet i uchwytów plików, gołe
słowa składające się wyłącznie z
małych liter narażają na konlikt z przyszłymi
słowami zastrzeżonymi. Jeżeli użyjesz
przełącznika
-w, to Perl będzie ostrzegał o
wystąpieniu takich słów. Niektórzy chcieliby
całkowicie wyjąć spod prawa gołe słowa.
Jeśli napiszesz
use strict 'subs';
to każde gołe słowo, które nie zostanie
zinterpretowane jako wywołanie procedury spowoduje błąd
kompilacji. Ograniczenie to rozciąga się do końca
zawierającego je bloku. Blok wewnętrzny może je jednak
zanegować przy pomocy no strict 'subs'.
Zmienne tablicowe w łańcuchach objętych cudzysłowami
interpolowane są przez złączenie wszystkich
elementów tablicy. Elementy są wówczas rozdzielone
ogranicznikiem podanym w zmiennej $" ($LIST_SEPARATOR w module English),
domyślnie spacją. Poniższe fragmenty są
równoważne:
$temp = join($",@ARGV);
system "echo $temp";
system "echo @ARGV";
Wewnątrz wzorców wyszukiwania (które również
podlegają zastępowaniu w podwójnym cytowaniu) pojawia
się brzydka niejednoznaczność: czy /$foo[bar]/ ma
być interpretowane jako /${foo}[bar]/ (gdzie [bar] jest klasą
znaków wyrażenia regularnego) czy też jako /${foo[bar]}/
(gdzie [bar] jest indeksem tablicy @foo)? Jeżeli nie istnieje @foo, to
jest to oczywiście klasa znaków. Jeżeli @foo istnieje, to
Perl odgaduje czym ma być [bar], i prawie zawsze ma rację.
Jeśli odgaduje źle, albo po prostu jesteś paranoikiem,
możesz wymusić poprawną interpretację
używając nawiasów klamrowych jak powyżej.
Wierszowa forma cytowania oparta jest na składni
"dokumentów-tutaj" używanej ("here-doc") w
powłokach. Po sekwencji << podajesz napis ograniczający
cytowany materiał, a wszystkie wiersze poniżej
bieżącego aż do napisu kończącego są
wartością elementu. Napisem kończącym może
być identyfikator (słowo) albo jakiś cytowany tekst.
Jeżeli jest to tekst cytowany, to rodzaj zastosowanych znaków
cytowania określa traktowanie tekstu, tak jak przy zwykłym
cytowaniu. Niecytowany identyfikator działa tak, jakby był w
podwójnym cudzysłowie. Pomiędzy << a
identyfikatorem nie może wystąpić spacja. (Jeżeli
wstawisz spację, to będzie ona traktowany jak pusty
identyfikator, co jest poprawne i dopasowuje pierwszy pusty wiersz.) Napis
kończący musi pojawić się w wierszu
kończącym samotnie (niecytowany i bez otaczających
białych znaków).
print <<EOF;
Cena wynosi $cena.
EOF
print <<"EOF"; # to samo, co powyżej
Cena wynosi $cena.
EOF
print <<`EOC`; # wykonaj polecenia
echo hi there
echo lo there
EOC
print <<"foo", <<"bar"; # możesz składować, jeden za drugim
I said foo.
foo
I said bar.
bar
myfunc(<<"TO", 23, <<'TAMTO');
Masz tu linijkę
czy dwie.
TO
a tu jeszcze jedną.
TAMTO
Nie zapomnij tylko, że musisz postawić średnik na
końcu instrukcji. Perl nie wie przecież, czy nie zamierzasz
spróbować zrobić tego:
print <<ABC
179231
ABC
+ 20;
Konstruktory wartości listowych
Wartości listowe oznaczane są przez oddzielenie pojedynczych
wartości przecinkami (i otoczenie listy nawiasami jeśli wymaga
tego kolejność):
(LIST)
W kontekście nie wymagającym wartości listowej
wartość literału listowego jest wartością
ostatniego elementu, tak jak w przypadku występującego w C
operatora przecinkowego. Na przykład,
@foo = ('cc', '-E', $bar);
przypisuje wartość całej listy do tablicy foo, ale
$foo = ('cc', '-E', $bar);
przypisuje zmiennej foo wartość zmiennej bar. Zauważ,
że rzeczywista tablica w kontekście skalarnym zwraca
długość tablicy. Poniższy kod przypisuje $foo
wartość 3:
@foo = ('cc', '-E', $bar);
$foo = @foo; # $foo dostaje 3
Przed nawiasem zamykającym listę literałów
możesz użyć opcjonalnego przecinka, zatem możesz
pisać:
@foo = (
1,
2,
3,
);
LISTY dokonują automatycznej interpolacji podlist. To znaczy, kiedy
przetwarzana jest LISTA, to każdy jej element jest przetwarzany w
kontekście listowym. Wynikowa wartość listy interpolowana
jest do listy LISTA tak, jakby każdy pojedynczy element był
członkiem LISTY Zatem w LIŚCIE tracą swoją
tożsamość tablice i hasze--lista
(@foo,@bar,&SomeSub,%glarch)
zawiera wszystkie elementy @foo, po których następują
wszystkie elementy @bar, wszystkie elementy zwrócone przez
procedurę o nazwie SomeSub wywołaną w kontekście
listowym, i na końcu pary klucz/wartość z %glarch.
Jeżeli chcesz odwołać się do listy, NIE
wykonując interpolacji zajrzyj do podręcznika
perlref(1).
Lista pusta reprezentowana jest przez (). Jej interpolowanie w liście nie
daje żadnego efektu. Zatem ((),(),()) jest równoważne ().
Podobnie, interpolowanie tablicy bez elementów jest tym samym, co nie
interpolowanie w tym miejscu żadnej tablicy.
Wartość listowa może być też indeksowana tak,
jak zwykła tablica. Musisz tylko umieścić listę w
nawiasach, by uniknąć niejasności. Na przykład:
# Stat zwraca wartość listową
$time = (stat($file))[8];
# TUTAJ BŁĄD SKŁADNI
$time = stat($file)[8]; # Oj, zapomniałem nawiasów
# znajdź cyfrę szesnastkową
$hexdigit = ('a','b','c','d','e','f')[$digit-10];
# "reverse comma operator"
return (pop(@foo),pop(@foo))[0];
W liście możesz wykonać przypisanie do undef. Przydaje
się to do pozbywania się niektórych wartości
zwracanych przez funkcję:
($dev, $ino, undef, undef, $uid, $gid) = stat($file);
Do list można wykonać przypisanie wtedy i tylko wtedy, gdy
dozwolone jest przypisanie do każdego z elementów listy:
($a, $b, $c) = (1, 2, 3);
($map{'czerwony'}, $map{'niebieski'}, $map{'zielony'})
= (0x00f, 0x0f0, 0xf00);
Przypisanie tablicy w kontekście skalarnym zwraca liczbę
elementów utworzonych przez wyrażenie po prawej stronie
przypisania:
$x = (($foo,$bar) = (3,2,1)); # ustaw $x na 3, nie 2
$x = (($foo,$bar) = f()); # ustaw $x na ilość zwróconych przez f()
Jest to bardzo wygodne, gdy chcesz wykonać przypisanie listy w
kontekście logicznym (boolowskim), gdyż
większość funkcji listowych zwraca po zakończeniu
przetwarzania listę pustą, co przy przypisaniu daje 0,
interpretowane jako fałsz.
Ostatni element może być tablicą lub haszem:
($a, $b, @rest) = split;
my($a, $b, %rest) = @_;
Faktycznie możesz umieścić tablicę lub hasza w
dowolnym miejscu listy, ale pierwsze z nich na liście wessie wszystkie
wartości i pozostałe dostaną wartość nul.
Może to być pomocne w
local() lub
my().
Literał hasza (tablicy asocjacyjnej) zawiera pary wartości,
które będą interpretowane jako klucz i
wartość:
# takie samo przypisanie jak powyżej
%map = ('czerwony',0x00f,'niebieski',0x0f0,'zielony',0xf00);
Choć listy literałów i nazwane tablice są zwykle
wzajemnie wymienne, to nie zachodzi to w przypadku haszy. To, że
możesz indeksować wartości listy tak jak zwykłej
tablicy nie oznacza, że możesz indeksować listę
tak jak hasz. Podobnie, hasze włączone jako części
innych list (łącznie z listami parametrów i list
zwracanych przez funkcje) zawsze ulegają spłaszczeniu do par
klucz/wartość. Dlatego czasem dobrze jest użyć
wskazania.
Często bardziej czytelne jest użycie pomiędzy parami
klucz/wartość operatora =>. Operator ten jest po prostu
bardziej wyróżniającym się wzrokowo synonimem
przecinka. Ponadto powoduje, że jego lewostronny operand jest
interpretowany jako łańcuch, jeśli jest on gołym
słowem, które mogłoby być poprawnym
identyfikatorem. Uprzyjemnia to inicjowanie haszy:
%map = (
czerwony => 0x00f,
niebieski => 0x0f0,
zielony => 0xf00,
);
lub inicjowanie odwołań do haszy, które będą
używane jako rekordy:
$rec = {
witch => 'Mable the Merciless',
cat => 'Fluffy the Ferocious',
date => '10/31/1776',
};
albo użycie wywoływanych przez nazwę parametrów
skomplikowanej funkcji:
$field = $query->radio_group(
name => 'group_name',
values => ['eenie','meenie','minie'],
default => 'meenie',
linebreak => 'true',
labels => \%labels
);
Zwróć uwagę na to, iż fakt, że tablica
asocjacyjna jest zainicjowana w takim porządku, nie oznacza, że
zostanie zwrócona w tym samym porządku. Przykłady, jak
ułożyć kolejność zwracanych wyników
znajdziesz przy opisie sort w podręczniku
perlfunc(1).
Typeglob i uchwyty plików
Perl posługuje się wewnętrznym typem zwanym
typeglob. Przechowuje w nim wszystkie zapisy tablicy symboli.
Przedrostkiem typu typeglob jest *, gdyż reprezentuje on wszystkie
typy. Był on zalecanym sposobem przekazywania tablic i tablic
asocjacyjnych przez odwołanie do funkcji, ale obecnie istnieją
prawdziwe odwołania, więc jest to rzadko potrzebne.
Podstawowym zastosowaniem typeglob we współczesnym Perlu jest
tworzenie synonimów tablicy symboli. To przypisanie:
*cos = *inne;
robi $cos synonimem (aliasem) dla $inne, @cos jest aliasem dla @inne, %cos
aliasem dla %inne, &cos aliasem dla &inne, itd. Dużo
bezpieczniej jest użyć odwołania (wskazania). To:
local *Tutaj::niebieski = \$Tam::zielony;
tymczasowo czyni $Tutaj::niebieski aliasem dla $Tam::zielony, ale nie robi
@Tutaj::niebieski aliasem dla @Tam::zielony, czy %Tutaj::niebieski aliasem dla
%Tam::zielony, itd. W sekcji
Symbol Tables podręcznika
perlmod(1) znajdziesz więcej takich przykładów.
Mimo, że może to wyglądać dziwnie, jest to
podstawą całego systemu importu/exportu modułów.
Innym zastosowaniem typeglob jest przesyłanie uchwytów
plików do funkcji lub tworzenie nowych uchwytów. Jeżeli
potrzebujesz posłużyć się typeglob, by
zachować uchwyt pliku, zrób to tak:
$fh = *STDOUT;
albo może jako prawdziwe odwołanie, jak to:
$fh = \*STDOUT;
W podręczniku
perlsub(1) znajdziesz przykłady zastosowania
typeglob jako pośrednich uchwytów plików w funkcjach.
Typeglob są również sposobem na tworzenie lokalnych
uchwytów plików przy użyciu operatora
local().
Istnieją wówczas aż do wyjścia z ich bloku, ale
mogą być przesłane powtórnie. Na przykład:
sub newopen {
my $path = shift;
local *FH; # nie my!
open (FH, $path) or return undef;
return *FH;
}
$fh = newopen('/etc/passwd');
Obecnie, gdy dysponujemy notacją *foo{COŚ}, typeglob nie są
tak często używane do manipulowania uchwytami plików,
chociaż wciąż są konieczne do przesłania
całkiem nowego uchwytu pliku czy katalogu do funkcji czy z funkcji.
Wynika to stąd, że *UCHWYT{IO} działa tylko jeśli
UCHWYT był już użyty jako uchwyt. Inaczej
mówiąc, do tworzenia nowych wpisów w tablicy symboli
może posłużyć *FH, ale nie *foo{COŚ}.
Inną metodą tworzenia anonimowych uchwytów plików
jest wykorzystanie modułu IO::Handle. Zaletą tych
modułów jest nieukrywanie różnych typów tej
samej nazwy podczas
local(). Na końcu opisu open() w
podręczniku
perlfunc(1) zamieszczono odpowiedni przykład.
Dalsze rozważania na temat typeglob i składni *foo{THING}
znajdziesz w podręcznikach
perlref(1) i
perlsub(1), a
także w sekcji
Symbol Tables podręcznika
perlmod(1).
Powyższe tłumaczenie pochodzi z nieistniejącego już
Projektu Tłumaczenia Manuali i
może nie być
aktualne. W razie zauważenia różnic między
powyższym opisem a rzeczywistym zachowaniem opisywanego programu lub
funkcji, prosimy o zapoznanie się z oryginalną
(angielską) wersją strony podręcznika za pomocą
polecenia:
- man --locale=C 1 perldata
Prosimy o pomoc w aktualizacji stron man - więcej informacji można
znaleźć pod adresem
http://sourceforge.net/projects/manpages-pl/.