NAZWA¶
perlop - operatory perla i priorytety
STRESZCZENIE¶
Operatory perla mają następujące związki i
priorytety, wymienione od najwyższych do najniższych.
Zauważ, że wszystkie operatory pożyczone z C
zachowują tamtejsze związki, choć te konwencje są
trochę skopane. (Ułatwia to naukę perla programistom C.)
Poza paroma wyjątkami, wszystkie one operują na
wartościach skalarnych, nie tablicowych.
lewe wyrażenia i lewostronne operatory list
lewe ->
niezwiązane ++ --
prawe **
prawe ! ~ \ and jednoargumentowy + and -
lewe =~ !~
lewe * / % x
lewe + - .
lewe << >>
niezwiązane nazwane operatory jednoargumentowe
niezwiązane < > <= >= lt gt le ge
niezwiązane == != <=> eq ne cmp
lewe &
lewe ⎪ ^
lewe &&
lewe ⎪⎪
niezwiązane .. ...
prawe ?:
prawe = += -= *= etc.
lewe , =>
niezwiązane prawostronne operatory list
prawe not
lewe and
lewe or xor
W następujących sekcjach, operatory te są opisane w
kolejności priorytetowej.
OPIS¶
Uwaga! To tłumaczenie może być nieaktualne!
Wyrażenia i lewostronne operatory list
Wyrażenie ma w perlu najwyższy priorytet. Są to zmienne,
cytaty, operatory w rodzaju cytatów, dowolne wyrażenie w
nawiasach, i dowolna funkcja, której argumenty są umieszczone w
nawiasach. W rzeczywistości, w perlu nie ma tak naprawdę funkcji
w ogólnym sensie, są tylko operatory listowe i operatory
jednoargumentowe, zachowujące się jak funkcje, bo ustawiasz
wokół nich nawiasy. Są one opisane w podręczniku
perlfunc(1).
Jeśli dowolny operator listowy (
print() itp.), lub dowolny
operator jednoargumentowy (
chdir()) ma za sobą lewy nawias, to
operator i argumenty z nawiasów są brane w najwyższym
priorytecie, tak jak przy normalnym wywołaniu funkcji.
Gdy nawiasy nie są podane, priorytet operatorów listowych w
rodzaju print, sort, lub chmod jest albo bardzo wysoki, albo bardzo niski,
zależnie od tego czy patrzysz na lewą stronę, czy na
prawą stronę operatora. Na przykład w
@ary = (1, 3, sort 4, 2);
print @ary; # drukuje 1324
przecinki po prawej stronie sort-a są analizowane przed sortowaniem, lecz
przecinki po lewej są analizowane później. Innymi
słowy, operatory listowe pożerają wszystkie argumenty,
które za nimi następują, a potem zachowują
się jak proste wyrażenie, szanujące wyrażenie
poprzedzające. Zauważ, że musisz być
ostrożny z nawiasami:
# Wykonują exit przed drukowaniem:
print($foo, exit); # raczej nie to, czego chcesz
print $foo, exit; # ani to
# Te drukują przed wykonaniem exit
(print $foo), exit; # To jest to czego chcesz
print($foo), exit; # to też
print ($foo), exit; # nawet to
Zauważ też, że
print ($foo & 255) + 1, "\n";
Prawdopodobnie nie robi tego, co oczekujesz. Zobacz sekcję o nazwanych
operatorach jednoargumentowych.
Ponadto, jako wyrażenia przetwarzane są też konstrukcje do
{} i eval {}, a także wywołania podprocedur i metod, oraz
anonimowe konstruktory [] i {}.
Zobacz też sekcję o operatorach cytowania, a także
sekcję o operatorach I/O.
Operator strzałki
Podobnie jak w C i C++, "->" jest operatorem dereferencji.
Jeśli prawa strona to element [...] lub {...}, to lewa strona musi
być twardą, lub symboliczną referencją do tablicy,
lub tablicy asocjacyjnej (lub miejsca, które jest w stanie
przechowywać twardą referencję, jeśli jest to
lwartość (przypisywalna)). Zobacz stronę
perlref(1).
W przeciwnym wypadku, prawa strona jest nazwą metody, lub prostą
zmienną skalarną, zawierającą nazwę metody,
a lewa strona musi być albo obiektem
(pobłogosławioną przez bless referencją), lub
nazwą klasy (tj. nazwą pakietu). Zobacz stronę
perlobj(1).
Auto-inkrementacja i Auto-dekrementacja
"++" i "--" działają jak w C. To znaczy,
jeśli są umieszczone przed zmienną, to
inkrementują lub dekrementują zmienną przed
zwróceniem wartości, a jeśli są umieszczone za
zmienną, to powodują inkrementację lub
dekrementację po zwróceniu wartości.
Operator auto-inkrementacji ma wbudowanych parę dodatkowych rzeczy.
Jeśli inkrementujesz zmienną, która jest numeryczna, lub
która była kiedykolwiek użyta w kontekście
numerycznym, to uzyskasz normalną inkrementację. Jednak
jeśli zmienna była używana tylko w kontekstach
łańcuchowych, a jej wartość nie jest nullem i
odpowiada wzorcowi /^[a-zA-Z]*[0-9]*$/, to inkrementacja jest dokonywana jak
na łańcuchu, zachowując każdy znak w zakresie, z
przeniesieniem:
print ++($foo = '99'); # drukuje '100'
print ++($foo = 'a0'); # drukuje 'a1'
print ++($foo = 'Az'); # drukuje 'Ba'
print ++($foo = 'zz'); # drukuje 'aaa'
Operator autodekrementacji nie ma tych właściwości.
Potęga
Binarny "**" jest operatorem potęgowania. Zauważ,
że łączy mocniej niż jednoargumentowy minus,
więc -2**4 to -(2**4), a nie (-2)**4. (Jest to zaimplementowane przy
użyciu funkcji
pow(3) z C, która w rzeczywistości
działa na liczbach typu podwójnej precyzji.)
Symboliczne operatory jednoargumentowe
Jednoargumentowy "!" wykonuje negację logiczną, czyli
"not". Zobacz też not dla wersji o niższym
priorytecie.
Jednoargumentowy "-" dokonuje arytmetycznej negacji na numerycznym
operandzie. Jeśli operand jest identyfikatorem, zwracany jest
łańcuch składający się ze znaku minus i z
identyfikatora. W przeciwnym wypadku, jeśli łańcuch
rozpoczyna się znakiem plus lub minus, zwracany jest
łańcuch z przeciwnym znakiem. Jednym z efektów tego
działania jest to, że -bareword jest równoważne
"-bareword".
Jednoargumentowy "~" dokonuje negacji bitowej. (Zobacz też
sekcję o arytmetyce całkowitej.)
Jednoargumentowy "+" nie daje żadnego efektu, nawet na
łańcuchach. Jest przydatny do rozdzielania nazwy funkcji od
otoczonego nawiasami wyrażenia, które w przeciwnym wypadku
byłoby interpretowane jako całkowita lista argumentów
funkcji. (Zobacz przykłady w sekcji o wyrażeniach i
lewostronnych operatorach listowych.)
Jednoargumentowy "\" tworzy referencję do tego, co po nim
następuje. Zobacz podręcznik
perlref(1). Nie myl tego
zachowania z zachowaniem w łańcuchu odwrotnego ukośnika,
choć obie postacie mają tę samą
właściwość chronienia następnej rzeczy od
interpretacji.
Operatory łączenia
Binarny "=~" łączy wyrażenie skalarne z
obsługą wyrażenia regularnego. Pewne operacje
domyślnie szukają lub zmieniają łańcuch $_.
Operator ten powoduje, że taka operacja działa na innym
łańcuchu. Prawy argument jest wzorcem przeszukiwania,
podstawienia lub translacji. Lewy argument jest przeszukiwanym
łańcuchem, zamiast domyślnego $_. Wartość
zwracana określa sukces operacji. (Jeśli prawy argument jest
raczej wyrażeniem niż wzorcem przeszukiwania, podstawiania lub
translacji, to jest interpretowany jako wzorzec przeszukiwania czasu
działania. Może to być mniej efektywne niż jawne
szukanie, gdyż wzorzec musi być za każdym razem
kompilowany.
[Przyp. tłum: Na przykład "$lancuch="bla";
$lancuch=~s/l/q/; print $lancuch" da w wyniku łańcuch
"bqa".]
Binarny "!~" jest podobny do "=~" lecz wartość
zwracana jest logicznie negowana.
Operatory mnożenia
Binarny "*" mnoży dwie liczby.
Binarny "/" dzieli dwie liczby.
Binarny "%" oblicza resztę (modulo) z dwóch liczb. Z
całkowitymi operandami $a i $b: jeśli $b jest dodatnie, to $a %
$b to $a minus największa wielokrotność $b, która
nie jest większa od $a. Jeśli $b jest ujemne, to $a % $b to $a
minus najmniejsza wielokrotność $b, która nie jest
mniejsza niż $a (np. wynik będzie mniejszy lub równy od
zera).
Binarny "x" jest operatorem powtórzenia. W kontekście
skalarnym, zwraca łańcuch składający się z
lewego operanda, powtórzonego tyle razy, ile podano w prawym. W
kontekście listowym, jeśli lewy operand jest listą w
nawiasach, powtarzana jest lista.
print '-' x 80; # wydrukuj wiersz kresek
print "\t" x ($tab/8), ' ' x ($tab%8); # tabuluj poprzez
@ones = (1) x 80; # lista 80 jedynek
@ones = (5) x @ones; # ustaw wszystkie elementy na 5
Operatory dodawania
Binarny "+" zwraca sumę dwóch liczb.
Binarny "-" zwraca różnicę dwóch liczb.
Binarny "." łączy (konkatenuje) łańcuchy.
Operatory przesuwania
Binanry "<<" zwraca wartość swojego lewego
argumentu, przesuniętego w lewo o ilość bitów,
podaną w prawym argumencie. Argumenty powinny być liczbami
całkowitymi. (Zobacz też sekcję o arytmetyce
całkowitej.)
Binarny ">>" zwraca wartość swojego lewego
argumentu, przesuniętego w prawo o ilość bitów,
podaną w prawym argumencie. Argumenty powinny być liczbami
całkowitymi.
Nazwane operatory jednoargumentowe
Różne nazwane operatory jednoargumentowe są traktowane jak
jednoargumentowe funkcje, z opcjonalnymi nawiasami. Są to m.in testy
plikowe, itp. Zobacz podręcznik
perlfunc(1).
Jeśli za dowolnym operatorem listowym (
print() itp.), lub
operatorem jednoargumentowym (
chdir() itp.) następuje lewy
nawias, to operator i argumenty w nawiasach są brane z
najwyższym priorytetem, tak jak przy wywołaniu funkcji.
Przykłady:
chdir $foo ⎪⎪ die; # (chdir $foo) ⎪⎪ die
chdir($foo) ⎪⎪ die; # (chdir $foo) ⎪⎪ die
chdir ($foo) ⎪⎪ die; # (chdir $foo) ⎪⎪ die
chdir +($foo) ⎪⎪ die; # (chdir $foo) ⎪⎪ die
lecz ponieważ * ma wyższy priorytet niż ⎪⎪:
chdir $foo * 20; # chdir ($foo * 20)
chdir($foo) * 20; # (chdir $foo) * 20
chdir ($foo) * 20; # (chdir $foo) * 20
chdir +($foo) * 20; # chdir ($foo * 20)
rand 10 * 20; # rand (10 * 20)
rand(10) * 20; # (rand 10) * 20
rand (10) * 20; # (rand 10) * 20
rand +(10) * 20; # rand (10 * 20)
Zobacz też sekcję o wyrażeniach i lewostronnych operatorach
listowych.
Operatory relacji
Binarny "<" zwraca prawdę, jeśli lewy argument jest
numerycznie mniejszy niż prawy.
Binarny ">" zwraca prawdę, jeśli lewy argument jest
numerycznie większy niż prawy.
Binarny "<=" zwraca prawdę, jeśli lewy argument jest
numerycznie mniejszy lub równy prawemu.
Binarny ">=" zwraca prawdę, jeśli lewy argument jest
numerycznie większy lub równy prawemu.
Binarny "lt" zwraca prawdę, jeśli lewy argument jest
łańcuchowo mniejszy od prawego.
Binarny "gt" zwraca prawdę, jeśli lewy argument jest
łańcuchowo większy od prawego.
Binarny "le" zwraca prawdę, jeśli lewy argument jest
łańcuchowo mniejszy lub równy prawemu.
Binarny "ge" zwraca prawdę, jeśli lewy argument jest
łańcuchowo większy lub równy prawemu.
Operatory równości
Binarny "==" zwraca prawdę, jeśli lewy argument jest
numerycznie równy prawemu.
Binarny "!=" zwraca prawdę, jeśli lewy argument nie jest
numerycznie równy prawemu.
Binarny "<=>" zwraca -1, 0, lub 1, zależnie od tego czy
lewy argument jest numerycznie mniejszy, równy, lub większy od
prawego.
Binarny "eq" zwraca prawdę, jeśli lewy argument jest
łańcuchowo równy prawemu.
Binarny "ne" zwraca prawdę, jeśli lewy argument nie jest
łańcuchowo równy prawemu.
Binarny "cmp" zwraca -1, 0, lub 1, zależnie od tego, czy lewy
argument jest łańcuchowo mniejszy, równy, lub
większy od prawego.
"lt", "le", "ge", "gt" i "cmp"
mogą używać kolejności sortowania,
określonej przez bieżące locale (gdy użyte jest
use locale). Zobacz podręcznik
perllocale(1).
Bitowy And
Binarny "&" zwraca jego operatory, połączone bitowo
operacją logiczną AND. (Zobacz też sekcję o
arytmetyce całkowitej.)
Bitowy Or i Xor (eXclusive Or)
Binarny "⎪" zwraca swoje operatory, połączone
bitowo operacją logiczną OR. (Zobacz też sekcję o
arytmetyce całkowitej).
Binarny "^" zwraca swoje operatory, połączone bitowo
operacją XOR. (Zobacz też sekcję o arytmetyce
całkowitej.)
Logiczny And w stylu C
Binarny "&&" dokonuje logicznej operacji AND. Jeśli
lewy operand jest fałszywy (false), to prawy nie jest nawet
analizowany. Kontekst skalarny, lub listowy propaguje do prawego operatora,
jeśli jest on analizowany.
Logiczny Or w stylu C
Binarny "⎪⎪" dokonuje logicznej operacji OR. To znaczy,
że jeśli lewy operand jest prawdziwy (true), to prawy nie jest
nawet analizowany. Kontekst skalarny, lub listowy propaguje do prawego
operatora, jeśli jest on analizowany.
Operatory ⎪⎪ i && różnią się
od C tym, że zwracają ostatnią analizowaną
wartość zamiast 0 czy 1. Tak więc przenośnym
sposobem znalezienia katalogu domowego (zakładając, że
nie jest "0"), może być:
$home = $ENV{'HOME'} ⎪⎪ $ENV{'LOGDIR'} ⎪⎪
(getpwuid($<))[7] ⎪⎪ die "You're homeless!\n";
Jako czytelniejsze alternatywy && i ⎪⎪, perl
udostępnia operatory "and" i "or" (patrz
niżej). Zachowanie jest identyczne. Jednak ich priorytet jest
niższy, więc możesz ich bezpiecznie używać
po operatorze listowym, bez konieczności używania
nawiasów:
unlink "alpha", "beta", "gamma"
or gripe(), next LINE;
Z użyciem operatorów w stylu C, trzeba by było to
zapisać jako:
unlink("alpha", "beta", "gamma")
⎪⎪ (gripe(), next LINE);
Operator zakresu
Binarny ".." jest operatorem zakresu, który jest w
rzeczywistości dwoma innymi operatorami, zależnymi od kontekstu.
W kontekście listowym, zwraca tablicę wartości,
liczoną (po jednym) od wartości lewej do prawej. Jest to
przydatne do zapisywania pętli for (1..10) i robienia operacji
wycinania (slice) na tablicach. Bądź świadom, że w
bieżącej implementacji tworzona jest tymczasowa tablica,
więc potrzeba na to trochę pamięci, jeśli
zapiszesz coś takiego:
for (1 .. 1_000_000) {
# kod
}
W kontekście skalarnym, ".." zwraca wartość
logiczną. Operator jest dwustanowy, jak flip-flop i emuluje operator
zakresu liniowego (przecinek) z
sed(1),
awk(1) i
różnych edytorów. Każdy operator ".."
obsługuje swój własny stan logiczny. Jest on
fałszywy tak długo, jak długo lewy operand jest
fałszywy. Gdy lewy operand stanie się prawdziwy, operator
zakresu pozostaje prawdziwy dopóki prawy argument jest prawdą,
PO czym, operator zakresu przyjmuje wartość fałszu. (Nie
staje się fałszywym do czasu następnej jego analizy.
Może testować prawy operand i stać się
fałszywym w tej samej analizie, kiedy stał się prawdziwym
(jak w
awk(1)), lecz wciąż będzie raz
zwracał prawdę. Jeśli nie chcesz by testował prawy
operand przed następną analizą (jak w
sed(1)),
użyj trzech kropek ("...") zamiast dwóch.) Prawy
operand nie jest analizowany podczas gdy operator jest w stanie fałszu,
a lewy operand nie jest analizowany gdy operator jest w stanie prawdy.
Priorytet jest trochę niższy niż ⎪⎪ i
&&. Zwracana wartość jest albo łańcuchem
null dla fałszu, lub liczbą sekwencyjną
(zaczynającą się od 1) dla prawdy. Liczba sekwencyjna
jest resetowana dla każdego napotkanego zakresu. Końcowa liczba
sekwencyjna w zakresie ma doklejony łańcuch
"E0®", który nie ma jednak wpływu na
wartość numeryczną, a za to daje coś, czego
możesz oczekiwać na końcu. Możesz
wyłączyć punkt początkowy przez oczekiwanie
aż liczba sekwencyjna stanie się większa niż
jeden. Jeśli któryś z operandów skalarnego
".." jest literałem numerycznym, operand jest niejawnie
porównywany ze zmienną $., bieżącym numerem linii.
Przykłady
Jako operator skalarny:
if (101 .. 200) { print; } # wydrukuj drugą setkę linii
next line if (1 .. /^$/); # pomiń linie nagłówka [pocztowego]
s/^/> / if (/^$/ .. eof()); # Cytuj ciało
Jako operator listowy:
for (101 .. 200) { print; } # drukuj 100 razy $_ 100
@foo = @foo[0 .. $#foo]; # kosztowny no-op
@foo = @foo[$#foo-4 .. $#foo]; # wytnij ostatnich 5 elementów
Operator zakresu (w kontekście listowym) używa w wypadku gdy
operandy są łańcuchami magicznego algorytmu
autoinkrementacji. Możesz powiedzieć
@alphabet = ('A' .. 'Z');
i uzyskać tak wszystkie litery alfabetu, lub
$hexdigit = (0 .. 9, 'a' .. 'f')[$num & 15];
by uzyskać liczby szesnastkowe, lub
@z2 = ('01' .. '31'); print $z2[$mday];
by uzyskać daty z początkowymi zerami. Jeśli ostatnia
podana wartość nie jest w sekwencji, którą daje
magiczna inkrementacja, to sekwencja idzie tak daleko, aż
następna wartość nie będzie dłuższa
niż podana ostatnia wartość.
Operator warunkowy
"?:" jest operatorem warunkowym, zupełnie jak w C.
Działa podobnie do konstrukcji if-then-else. Jeśli argument
przed ? jest prawdziwy, to zwracany jest argument przed :. W przeciwnym
wypadku, zwracany jest argument po :. Na przykład:
printf "Mam %d ps%s.\n", $n,
($n == 1) ? "a" : "y";
Kontekst skalarny, lub listowy propaguje do 2-giego lub 3-ciego argumentu,
zależnie od wyboru.
$a = $ok ? $b : $c; # weź skalar
@a = $ok ? @b : @c; # weź tablicę
$a = $ok ? @b : @c; # oops, to tylko licznik!
Operator może być przypisany jeśli obydwa argumenty -- 2-gi
i 3-ci są legalnymi lwartościami (co znaczy że
można do nich przypisać):
($a_or_b ? $a : $b) = $c;
Niekoniecznie musi to jednak poprawić czytelność twojego
programu.
Operatory przypisania
"=" jest zwykłym operatorem przypisania.
Operator przypisania działa jak w C. Tzn,
$a += 2;
jest równoważne
$a = $a + 2;
choć bez powielania efektów ubocznych, które może
pociągać za sobą dereferencja lwartości, tak jak
dla
tie(). Inne operatory przypisania działają podobnie.
Rozpoznawane są następujące:
**= += *= &= <<= &&=
-= /= ⎪= >>= ⎪⎪=
.= %= ^=
x=
Zauważ, że podczas gdy są one zgrupowane w rodziny,
mają jednakowy priorytet przypisania.
W przeciwieństwie do C, operator przypisania daje
prawidłową lwartość. Modyfikowanie przypisania
jest równoważne do robienia przypisania, a potem zmieniania
przypisanej zmiennej. jest to przydatne do modyfikowania kopii czegoś,
np:
($tmp = $global) =~ tr [A-Z] [a-z];
Podobnie,
($a += 2) *= 3;
jest równoważne
$a += 2;
$a *= 3;
Operator przecinka
Binarny "," jest operatorem przecinka. W kontekście skalarnym
analizuje swój lewy argument, wyrzuca jego wartość i
następnie analizuje prawy argument, zwracając jego
wartość. Jest to takie samo, jak operator przecinka z C.
W kontekście listowym, jest to po prostu separator listy i wstawia obydwa
argumenty do listy.
Znak => jest często synonimem operatora przecinka. Przydatny jest do
dokumentowania argumentów, które są w parach. Od wersji
5.001 wymusza to też interpretację każdego słowa z
lewej jako łańcucha.
Operatory listowe (w prawo)
Po prawej stronie operatora listowego, jest niski priorytet, taki że
kontroluje on wszystkie znalezione tam elementy, oddzielone przecinkami.
Jedyne operatory o niższym priorytecie to operatory logiczne
"and", "or", i "not", które mogą
być używane do analizowania wywołań do
operatorów listowych, bez potrzeby dodatkowych nawiasów:
open HANDLE, "filename"
or die "Can't open: $!\n";
Zobacz też dyskusję operatorów listowych w sekcji o
wyrażeniach i operatorach listowych lewostronnych.
Logiczny Not
Jednoargumentowy "not" zwraca logiczną negację prawego
argumentu. Jest równoważny "!", lecz ma niższy
priorytet.
Logiczny And
Binarny "and" zwraca logiczną koniunkcję
otaczających wyrażeń. Jest równoważny
&&, lecz ma niższy priorytet. Znaczy to, że prawe
wyrażenie jest analizowane tylko jeśli lewe jest prawdziwe.
Logiczny or i xor
Binarny "or" zwraca logiczną dyzjunkcję
otaczających wyrażeń. Jest równoważny
⎪⎪, lecz ma niższy priorytet. Znaczy to, że prawe
wyrażenie jest wykonywane tylko jeśli lewe jest fałszywe.
Binarny "xor" zwraca XOR otaczających wyrażeń.
Nie może być oczywiście używany z
zawężeniem, jak or.
Operatory C, których brakuje w perlu
Oto operatory C, których perl nie posiada:
- jednoargumentowy &
- Operator adresu. (Lecz zobacz opis operatora "\".)
- jednoargumentowy *
- Operator dereferencji (wyłuskania) adresu. (Perlowe przedrostkowe
operatory dereferencji to: $, @, %, &.)
- (TYP)
- Operator konwersji typów.
Operatory cytatów i cytatopodobne
Podczas gdy normalnie myślimy o cytatach jak o literalnych
wartościach, w perlu mają one funkcję operatorów,
dając różne właściwości
interpolowania i porównywania wzorców. Perl daje dla tych
zachowań tradycyjne znaki cytowania, lecz również
sposób na wybieranie znaku cytowania. W następującej
tablicy, {} oznacza parę ograniczników, które wybierzesz.
Ograniczniki nienawiasowe używają tego samego znaku na
początek i koniec, ale 4 rodzaje nawiasów mogą się
zagnieżdżać.
Zwyczajowy Standardowy Znaczenie Interpoluje
'' q{} Literał nie
"" qq{} Literał tak
`` qx{} Komenda tak
qw{} Lista słów nie
// m{} Porównanie ze wzorcem tak
s{}{} Podstawienie tak
tr{}{} Translacja nie
Dla konstrukcji, wykonujących interpolację, zmienne
zaczynające się od "$" lub "@" są
interpolowane jako następujące sekwencje:
\t tab (HT, TAB)
\n nowalinia (LF, NL)
\r return (CR)
\f form feed (FF)
\b backspace (BS)
\a alarm (dzwonek) (BEL)
\e escape (ESC)
\033 znak ósemkowy
\x1b znak szesnastkowy
\c[ znak sterujący
\l zmień następny znak na małą literę
\u zmień następny znak na dużą literę
\L zmień na małą literę aż do \E
\U zmień na dużą literę aż do \E
\E koniec modyfikacji rozmiaru
\Q cytuj metaznaki regexp aż do \E
Jeśli używane jest use locale, mapa rozmiarów liter
odpowiada lokalnej sytuacji. Zobacz podręcznik
perllocale(1).
Wzorce są podstawą do innego poziomu interpretacji -- jako
wyrażenia regularne. Jest to robione jako drugi przebieg, po
interpolacji zmiennych, tak że wyrażenia regularne mogą
być włączane do wzorca ze zmiennych. Jeśli tego
nie chcesz, użyj \Q.
Poza powyższym, nie ma wielokrotnych poziomów interpolacji. W
rzeczywistości, w przeciwieństwie do oczekiwań
programistów powłokowych, odwrotne cudzysłowy nie
interpolują w podwójnych cudzysłowach, a pojedyncze
otoczone w podwójnych cudzysłowach nie utrudniają analizy
zmiennych w nich zawartych.
Operatory cytatopodobne Regexp
Oto cytatopodobne operatory, które dotyczą się
działań związanych z porównywaniem wzorców.
- ?WZORZEC?
- Jest to coś w rodzaju przeszukiwania /wzorzec/, lecz między
wywołaniami operatora reset(), trafienie jest jednokrotne.
Jest to przydatna optymalizacja, jeśli np. chcesz zobaczyć
tylko pierwsze pojawienie się czegoś w pliku, lub zbiorze.
Resetowane są tylko wzorce ??, lokalne dla bieżącego
pakietu.
To użycie jest niezalecane i może być usunięte w
przyszłych wersjach perla.
- m/WZORZEC/gimosx
-
- /WZORZEC/gimosx
- Przeszukuje wzorzec dla trafienia i w kontekście skalarnym wzraca
prawdę (1), lub fałsz (''). Jeśli nie podano
żadnego łańcucha poprzez operator =~, lub !~,
przeszukiwany jest łańcuch $_. (Łańcuch podany
przez =~ nie musi być lwartością -- może
być wynikiem analizy wyrażenia, lecz pamiętaj,
że =~ wiąże dość mocno.) Zobacz
też podręcznik perlre(1). Zobacz podręcznik
perllocale(1) dla dyskusji o dodatkowych sprawach,
związanych z użyciem use locale.
Opcje to:
g Porównuj globalnie, na wszystkich pojawieniach
i Porównuj bez zwracania uwagi na wielkość liter
m Traktuj łańcuch jako wielokrotne linie
o Kompiluj wzorzec tylko raz
s Traktuj łańcuch jako pojedynczą linię
x Użyj rozszerzonych wyrażeń regularnych
Jeśli ogranicznikiem jest "/", to początkowe m jest
opcjonalne. Używając m, możesz wykorzystać
jako ograniczniki dowolną parę nialfanumerycznych,
niebiałospacjowych znaków. Jest to przydatne do
porównywania unixowych nazw ścieżek, które
mogą zawierać "/". Zapobiega to LTS (syndrom
wąskiej wykałaczki). Jeśli "?" jest
ogranicznikiem, to stosowana jest reguła trafienia-tylko-raz
instrukcji ?WZORZEC?.
WZORZEC może zawierać zmienne, które będą
interpolowane (a wzorzec rekompilowany) za każdą
analizą. (Zauważ, że $) i $⎪ mogą nie
być interpolowane, gdyż wyglądają jak testy
końca łańcucha.) Jeśli chcesz, by takie wzorce
były kompilowane tylko raz, dodaj do ostatniego ogranicznika znak
/o. Zapobiega to kosztownej kompilacji czasu działania i jest
przydatne, gdy wartość, z której korzystasz nie
zmienia się w czasie życia skryptu. Jednak pamiętaj,
że opcja /o daje obietnicę, iż nie zmienisz zmiennych
ze wzorca. Jeśli je zmienisz, perl tego nie zauważy.
Jeśli WZORZEC zostanie zanalizowany jako łańcuch null,
to użyte zostanie ostatnie wykonane wyrażenie regularne.
W kontekście, wymagającym wartości listowej,
porównanie wzorca zwraca listę,
składającą się z listy
podwyrażeń, trafionych przez nawiasy z wzorca, np. ($1, $2,
$3...). (Zauważ, że ustawione tu są
również $1 itp. i że różni się
to od zachowania perla 4.) Jeśli porównanie się nie
powiedzie, zwracana jest tablica null. Jeśli porównanie
się powiedzie, lecz nie będzie nawiasów, zwracana
zostanie wartość listowa (1).
Przykłady:
open(TTY, '/dev/tty');
<TTY> =~ /^y/i && foo(); # zrób foo, jeśli trzeba
if (/Version: *([0-9.]*)/) { $version = $1; }
next if m#^/usr/spool/uucp#;
# grep biedaka
$arg = shift;
while (<>) {
print if /$arg/o; # kompiluj tylko raz
}
if (($F1, $F2, $Etc) = ($foo =~ /^(\S+)\s+(\S+)\s*(.*)/))
Ostatni przykład dzieli $foo na pierwsze dwa słowa i
resztę linii. Przypisuje te trzy pola do $F1, $F2 i $Etc. Warunek
jest prawdziwy, jeśli przypisane zostały wartości
którejkolwiek ze zmiennych, czyli jeśli wzorzec
został trafiony.
Modyfikator /g określa globalne porównywanie wzorców --
tj. takie, gdzie trafień jest tyle ile się da w danym
łańcuchu. Zachowanie tego zależy od kontektu -- w
listowym zwracana jest lista wszystkich podłańcuchów,
trafionych przez wszystkie nawaisy wyrażenia regularnego.
Jeśli nie było nawiasów, zwracana jest lista
trafionych łańcuchów, tak jakby były nawiasy
wokół całego wzorca.
W kontekście skalarnym, ,//g iteruje poprzez łańcuch,
zwracając TRUE za każdym trafieniem i FALSE przy braku
trafienia. (Innymi słowy, zapamiętuje ostatnią
pozycję i restartuje od tego miejsca. Możesz
znaleźć bieżącą pozycję
trafienia przy użyciu funkcji pos(); zobacz jej opis w
podręczniku perlfunc(1).) Brak trafienia normalnie resetuje
pozycję przeszukiwania na początek łańcucha,
lecz możesz temu zapobiec, dodając modyfikator "c"
(np. m//gc). Modyfikowanie łańcucha docelowego
również resetuje pozycję przeszukiwania.
Możesz mieszać porównania m//g z m/\G.../g, gdzie \G
jest zapewnieniem zerowej szerokości, które trafia w
dokładnie tę samą pozycję, gdzie
skończył ewentualny poprzedni m//g. Zapewnienie \G nie jest
obsługiwane bez modyfikatora /g; obecnie bez /g, \G, zachowuje
się zupełnie jak \A, lecz jest to przypadkowe i może
się w przyszłości zmienić.
Przykłady:
# kontekst listowy
($one,$five,$fifteen) = (`uptime` =~ /(\d+\.\d+)/g);
# kontekst skalarny
$/ = ""; $* = 1; # $*, niezalecany w nowoczesnych perlach
while (defined($paragraph = <>)) {
while ($paragraph =~ /[a-z]['")]*[.!?]+['")]*\s/g) {
$sentences++;
}
}
print "$sentences\n";
# używanie m//gc z \G
$_ = "ppooqppqq";
while ($i++ < 2) {
print "1: '";
print $1 while /(o)/gc; print "', pos=", pos, "\n";
print "2: '";
print $1 if /\G(q)/gc; print "', pos=", pos, "\n";
print "3: '";
print $1 while /(p)/gc; print "', pos=", pos, "\n";
}
Ostatni przykład powinien dać:
1: 'oo', pos=4
2: 'q', pos=5
3: 'pp', pos=7
1: '', pos=7
2: 'q', pos=8
3: '', pos=8
Przydatnym idiomem dla skanerów w rodzaju lex jest /\G.../gc.
Możesz tak łączyć różne rodzaje
wyrażeń regularnych, mając tak
możliwość przetwarzania łańcucha
kawałek po kawałku, dokonując różnych
akcji, zależnie od tego, które wyrażenie
zostało trafione. Każde wyrażenie próbuje
trafić tam, gdzie poprzednie zakończyło.
$_ = <<'EOL';
$url = new URI::URL "http://www/"; die if $url eq "xXx";
EOL
LOOP:
{
print(" digits"), redo LOOP if /\G\d+\b[,.;]?\s*/gc;
print(" lowercase"), redo LOOP if /\G[a-z]+\b[,.;]?\s*/gc;
print(" UPPERCASE"), redo LOOP if /\G[A-Z]+\b[,.;]?\s*/gc;
print(" Capitalized"), redo LOOP if /\G[A-Z][a-z]+\b[,.;]?\s*/gc;
print(" MiXeD"), redo LOOP if /\G[A-Za-z]+\b[,.;]?\s*/gc;
print(" alphanumeric"), redo LOOP if /\G[A-Za-z0-9]+\b[,.;]?\s*/gc;
print(" line-noise"), redo LOOP if /\G[^A-Za-z0-9]+/gc;
print ". That's all!\n";
}
Oto wyjście (podzielone na kilka linii):
line-noise lowercase line-noise lowercase UPPERCASE line-noise
UPPERCASE line-noise lowercase line-noise lowercase line-noise
lowercase lowercase line-noise lowercase lowercase line-noise
MiXeD line-noise. That's all!
- q/ŁAŃCUCH/
-
- 'ŁAŃCUCH'
- Pojedynczo zacytowany łańcuch literalny. Odwrotny
ukośnik oznacza odwrotny ukośnik, chyba że znajduje
się za nim ogranicznik lub inny odwrotny ukośnik -- w tym
wypadku odwrotny ukośnik, lub ogranicznik jest interpolowany.
$foo = q!I said, "You said, 'She said it.'"!;
$bar = q('This is it.');
$baz = '\n'; # łańcuch dwuznakowy
- qq/ŁAŃCUCH/
-
- ""ŁAŃCUCH""
- Łańcuch w podwójnych cudzysłowach,
interpolowany.
$_ .= qq
(*** The previous line contains the naughty word "$1".\n)
if /(tcl⎪rexx⎪python)/; # :-)
$baz = "\n"; # łańcuch jednoznakowy
- qx/ŁAŃCUCH/
-
- `ŁAŃCUCH`
- Łańcuch, który jest interpolowany, a następnie
uruchamainay jako komenda systemowa. Zebrane standardowe wyjście
komendy jest zwracane. W kontekście skalarnym, pojawia się
jako pojedynczy, wieloliniowy łańcuch. W kontekście
listowym, jest rozdzielony na listę linii (jakkolwiek
zdefiniowałeś linie $/ lub $INPUT_RECORD_SEPARATOR).
$today = qx{ date };
Zobacz sekcję o operatorach I/O.
- qw/ŁAŃCUCH/
- Zwraca listę słów, wyciągniętych z
łańcucha przy użyciu osadzonych białych
spacji, jako ograniczników słów. Jest to
równoważne
split(' ', q/ŁAŃCUCH/);
Pewne często używane przykłady:
use POSIX qw( setlocale localeconv )
@EXPORT = qw( foo bar baz );
Częstym błędem jest próba rozdzielania
słów przecinkiem, lub wstwianie do wieloliniowych
łańcuchów qw komentarzy. W tej sytuacji,
przełącznik -w daje ostrzeżenia jeśli
łańcuch zawiera znaki "#".
- s/WZORZEC/ZAMIANA/egimosx
- Szuka w łańcuchu wzorca, a jeśli go znajdzie, to
zamienia go tekstem zamiany i zwraca liczbę zamian. W przeciwnym
wypadku zwraca fałsz (specyficznie pusty łańcuch).
Jeśli przez operator =~ lub !~ nie podano łańcucha,
używana jest zmienna $_. (Łańcuch podany przez =~
musi być zmienną skalarną, elementem tablicy, tablicy
asocjacyjnej, lub przypisaniem do jednego z nich, czyli
lwartością.)
Jeśli wybrany ogranicznik jest pojedynczym cudzysłowem, nie
dokonywana jest interpolacja ani zmiennych WZORCA, ani ZAMIANY. W
przeciwnym wypadku, jeśli WZORZEC zawiera $, który
wygląda bardziej jak zmienna, niż test końca
łańcucha, zmienna będzie interpolowana w czasie
działania. Jeśli chcesz, by wzorzec był kompilowany
tylko raz, za pierwszą interpolacją zmiennej, użyj
opcji /o. Jeśli wzorzec jest analizowany jako łańcuch
null, uzywane jest zamiast tego ostatnie normalne wyrażenie
regularne. Zobacz jeszcze podręcznik perlre(1). Zobacz
też perllocale(1), aby dowiedzieć się o
wpływie use locale.
Opcje to:
e Analizuj prawą stronę jako wyrażenie
g Zamieniaj globalnie
i Nie zwracaj uwagi na wielkość liter
m Traktuj łańcuch jak wiele linii
o Kompiluj wzorzec tylko raz
s Traktuj łańcuch jako pojedynczą linię
x Użyj rozszerzonych wyrażeń regularnych
Ukośniki mogą być zamienione przez dowolny,
niealfanumeryczny i niebiałospacjowy ogranicznik. Jeśli
użyte są pojedyncze cudzysłowy, nie dokonywana jest
interpretacja łańcucha zamiany (modyfikator /e
przeciąża to zachowanie). W przeciwnieństwie do perla
4, perl 5 traktuje odwrotne cudzysłowy jako normalne ograniczniki;
tekst zamiany nie jest wykonywany jako komenda. Jeśli WZORZEC jest
rozdzielany cytatami nawiasowymi, ZAMIANA ma swoją
własną parę cytatów, która może,
lub nie, być cytatami nawiasowymi, np. s(foo)(bar) lub
s<foo>/bar/. /e spowoduje, że porcja zamiany zostanie
zinterpretowana jako pełne perlowe wyrażenie i z
eval()owana zaraz potem. Jego składnia jest jednak
sprawdzania podczas kompilacji.
Przykłady:
s/\bgreen\b/mauve/g; # nie zmieniaj wintergreen
$path =~ s⎪/usr/bin⎪/usr/local/bin⎪;
s/Login: $foo/Login: $bar/; # wzorzec czasu działania
($foo = $bar) =~ s/this/that/;
$count = ($paragraph =~ s/Mister\b/Mr./g);
$_ = 'abc123xyz';
s/\d+/$&*2/e; # daje 'abc246xyz'
s/\d+/sprintf("%5d",$&)/e; # daje 'abc 246xyz'
s/\w/$& x 2/eg; # daje 'aabbcc 224466xxyyzz'
s/%(.)/$percent{$1}/g; # zmień eskejpy procentowe; bez /e
s/%(.)/$percent{$1} ⎪⎪ $&/ge; # teraz z wyrażenim, z /e
s/^=(\w+)/&pod($1)/ge; # użyj wywołania funkcji
# /e mogą się zagnieżdżać; to rozwinie
# proste zmienne osadzone w $_
s/(\$\w+)/$1/eeg;
# Usuń komentarze C
$program =~ s {
/\* # Traf na rozdzielacz otwierający.
.*? # Traf w minimalną liczbę znaków.
\*/ # Traf w rozdzielacz zamykający.
} []gsx;
s/^\s*(.*?)\s*$/$1/; # odetnij białą spację
s/([^ ]*) *([^ ]*)/$2 $1/; # zamień 1-sze 2 pola
Zauważ, że w ostatnim przykładzie zamiast $
użyto \. W przeciwieństwie do sed(1)a, używamy
postaci \< cyfra> tylko po lewej stronie. Wszędzie
indziej, jest to $< cyfra>.
Czasami nie można użyć po prostu /g, aby zaszły
wszystkie zmiany. Oto dwa popularne przypadki:
# wstaw przecinki we właściwych miejscach integera
1 while s/(.*\d)(\d\d\d)/$1,$2/g; # perl4
1 while s/(\d)(\d\d\d)(?!\d)/$1,$2/g; # perl5
# rozwiń tabulacje na 8-kolumnowe spacje
1 while s/\t+/' ' x (length($&)*8 - length($`)%8)/e;
- tr/LISTASZUKANIA/LISTAZAMIANY/cds
-
- y/LISTASZUKANIA/LISTAZAMIANY/cds
- Tłumaczy wszystkie pojawienia się znaków, znalezione
w liście szukania, na odpowiadające znaki z listy zamiany.
Zwraca liczbę zamienionych, lub skasowanych znaków.
Jeśli nie podano łańcucha w operatorze =~ lub !~,
używane jest $_. (Łańcuch określony przez =~
musi być zmienną skalarną, elementem tablicy,
elementem tablicy asocjacyjnej, lub przypisaniem do jednego z nich, czyli
lwartością). Dla miłośników edytora
sed(1), udostępniono synonim tr pod nazwą y.
Jeśli LISTASZUKANIA jest rozdzielona nawiasami, to LISTAZAMIANY nie
musi ich mieć, np. tr[A-Z][a-z] lub tr(+-*/)/ABCD/.
Opcje:
c Dopełnij LISTĘSZUKANIA
d Kasuj znalezione, lecz niezamienione znaki
s Zmiażdż zduplikowane zamienione znaki
Jeśli podany jest modyfikator /c, zbiór znaków z
LISTYSZUKANIA jest dopełniany. Jeśli podany jest modyfikator
/d, wszelkie znaki, podane w LIŚCIESZUKANIA, a nie znalezione w
LIŚCIEZAMIANY są kasowane. Jeśli podany jest
modyfikator /s, to sekwencje, które zostały
przetłumaczone do tego samego znaku są
miażdżone do pojedynczej instancji tego znaku.
Jeśli użyty jest modyfikator /d, LISTAZAMIANY jest zawsze
interpretowana tak, jak jest podana. W przeciwnym wypadku, gdy
LISTAZAMIANY jest krótsza niż LISTASZUKANIA, ostatni jej
znak jest replikowany tak długo, aż wypełni
brakujące miejsca. Jeśli LISTAZAMIANY jest null, to
replikowana jest LISTASZUKANIA. Jest to przydatne do zliczania
znaków w klasie, lub dla miażdżenia sekwencji
znakowych klasy.
Przykłady:
$ARGV[1] =~ tr/A-Z/a-z/; # zmień na małe litery
$cnt = tr/*/*/; # zlicz gwiazdy w $_
$cnt = $sky =~ tr/*/*/; # zlicz gniazdy w $sky
$cnt = tr/0-9//; # zlicz cyfry w $_
tr/a-zA-Z//s; # bookkeeper -> bokeper
($HOST = $host) =~ tr/a-z/A-Z/;
tr/a-zA-Z/ /cs; # zmień niealfabetyczne na spacje
tr [\200-\377]
[\000-\177]; # skasuj 8-my bit
Jeśli dla znaku podano wiele translacji, używana jest tylko
pierwsza:
tr/AAA/XYZ/
przetłumaczy A na X.
Zauważ, że z uwagi na to, że tablica translacji jest
budowana w czasie kompilacji, ani LISTASZUKANIA, ani LISTAZAMIANY nie
podlegają interpolacji cudzysłowowej. Znaczy to, że
jeśli chcesz używać zmiennych, musisz
użyć eval():
eval "tr/$oldlist/$newlist/";
die $@ if $@;
eval "tr/$oldlist/$newlist/, 1" or die $@;
Operatory I/O
Istnieje wiele operatorów I/O (wejścia/wyjścia), o
których powinieneś wiedzieć. Łańcuch
ujęty w odwrotne cudzysłowy podlega najpierw podstawieniu
zmiennych, podobnie jak łańcuch ujęty w podwójne
cudzysłowy. Następnie jest interpretowany jako komenda, a jej
wyjście jest wartością pseudoliterału, jak w
powłoce. W kontekście skalarnym, zwracany jest pojedynczy
łańcuch, skłądający się z
całego wyjścia. W kontekście listowym, zwracana jest
lista wartości dla każdej linii wyjścia. (Można
ustawić $/, co przeciąży domyślny terminator
linii.) Komenda jest wykonywana przy każdej analizie
pseudoliterału. Status komendy jest zwracany do $? (zobacz
podręcznik
perlvar(1)). W przeciwieństwie do
csh(1), nie jest na danych zwracanych dokonywana translacja -- nowe
linie pozostają nowymi liniami. W przeciwieństwie do wszelkich
innych powłok, pojedyncze cudzysłowyu nie ukrywają nazw
zmiennych w komendzie od interpretacji. Aby przekazać $ dalej,
należy go wycytować odwrotnym ukośnikiem.
Ogólną postacią odwrotnych cudzysłowów jest
qx//. (Ponieważ podlegają one zawsze również
rozwinięciu przez powłokę, zobacz podręcznik
perlsec(1), który opisuje problemy bezpieczeństwa.)
Analiza uchwytu pliku, który jest w nawiasach trójkątnych,
wyciąga z pliku następną linię, lub undef na jego
końcu. Normalnie, musisz zmiennej przypisać
wartość, lecz jest sytuacja, w której następuje
automatyczne przypisanie.
Jeśli i TYLKO jeśli symbol
wejścia jest jedyną rzeczą wewnątrz warunku
pętli while lub for(;;), to wartość jest przypisywana
automatycznie zmiennej $_. Przypisana wartość jest potem
sprawdzana, by zobaczyć czy jest zdefiniowane (Może się
to wydawać trochę dziwne, lecz będziesz
używać tej konstrukcji w prawie każdym swoim skrypcie
perlowym.) Następujące linijki są sobie
równoważne:
while (defined($_ = <STDIN>)) { print; }
while (<STDIN>) { print; }
for (;<STDIN>;) { print; }
print while defined($_ = <STDIN>);
print while <STDIN>;
Uchwyty plików STDIN, STDOUT i STDERR to uchwyty predefiniowane. Uchwyty
stdin, stdout i stderr też będą działać,
lecz nie w pakietach, w których są interpretowane jako lokalne
identyfikatory nie zaś jako globalne.) Dodatkowe uchwyty plików
można tworzyć funkcją
open(). Zobacz jej opis w
podręczniku
perlfunc(1).
Jeśli <UCHWYTPLIKU jest używany w kontekście,
oczekującym listy, zwracana jest lista, składająca
się ze wszystkich linii wejściowych, jedna linia na element
listy. Łatwo jest zająć tak duży obszar danych,
więc używaj tego ostrożnie.
Zerowy uchwyt pliku <> jest specjalny i może być
używany do emulacji zachowania edytora
sed(1), lub
awk(1). Wejście z <> może nadchodzić
zarówno ze standardowego wejścia, lub z każdego pliku,
wymienionego w linii komend. Oto jak to działa: za pierwszą
analizą <>, sprawdzana jest tablica @ARGV i jeśli jest
zerowa, $ARGV[0] jest ustawiane na "-", co oznacza po otwarciu
standardowe wejście. Tablica @ARGV jest następnie przetwarzana
jako lista nazw plików. Pętla
while (<>) {
... # kod dla każdej linii
}
jest równoważna następującemu pseudokodowi:
unshift(@ARGV, '-') unless @ARGV;
while ($ARGV = shift) {
open(ARGV, $ARGV);
while (<ARGV>) {
... # kod dla każdej linii
}
}
poza tym, że jest trochę ładniejsza i działa.
Naprawdę przesuwa tablicę @ARGV i wstawia
bieżącą nazwę pliku do zmiennej $ARGV.
Używa też wewnętrznie uchwytu
ARGV--<> jest
po prostu synonimem <ARGV>, który jest magiczny. (Powyższy
pseudokod nie działa, gdyż traktuje ARGV amagicznie.)
Przed pierwszym <> możesz modyfikować @ARGV, o ile tablica
będzie zawierała listę plików, których
oczekujesz. Numey linii ($.) są liczone tak, jakby wejście
było tylko jednym, szczęśliwym plikiem. (Lecz zobacz
przykład z
eof(), aby zobaczyć jak zresetować
numery linii.)
Jeśli chcesz ustawić @ARGC na swoją własną
listę plików, to nie ma sprawy. Jeśli chcesz
przekazać do swojego skryptu przełączniki, możesz
użyć jednego z modułów Getopts, lub wstawić
na początku podobną pętlę:
while ($_ = $ARGV[0], /^-/) {
shift;
last if /^--$/;
if (/^-D(.*)/) { $debug = $1 }
if (/^-v/) { $verbose++ }
... # inne przełączniki
}
while (<>) {
... # kod dla każdej linii
}
Symbol <> zwraca FALSE tylko raz. Jesli wywołasz go po tym,
założy, że przetwarzasz nową listę @ARGV i
jeśli jej nie ustawiłeś, pobierze wejście ze
STDIN.
Jeśli łańcuch wewnątrz nawiasów
trójkątnych jest wskazaniem do zmiennej skalarnej (np.
<$foo>), to zmienna ta przechowuje nazwę uchwytu, z
którego pobierane jest wejście. Np:
$fh = \*STDIN;
$line = <$fh>;
Łańcuch w nawiasach trójkątnych nie jest uchwytem
pliku, to jest interpretowany jako wzorzec nazwy pliku do glob()owania i
zwracana jest albo lista nazw pliku lub następna nazwa pliku
(zależnie od kontekstu). Najpierw dokonywany jest jeden poziom
interpretacji $, lecz nie można powiedzieć <$foo>,
gdyż jest to niebezpośredni uchwyt pliku, opisany w poprzednim
paragrafie. (W starszych wersjach perla, programiści mogli
wstawiać nawiasy do wymuszania interpretacji jako nazwy pliku do
globowania: <${foo}>. Dziś jednak, za czystsze uważa
się bezpośrednie wołanie funkcji wewnętrznej --
glob($foo). Przykład:
while (<*.c>) {
chmod 0644, $_;
}
jest równoważny
open(FOO, "echo *.c ⎪ tr -s ' \t\r\f' '\\012\\012\\012\\012'⎪");
while (<FOO>) {
chop;
chmod 0644, $_;
}
W rzeczywistości, obecnie jest to właśnie tak
zaimplementowane. (Co znaczy, że nie będzie
działać na nazwach plików ze spacjami, chyba że
masz u siebie
csh(1).) Oczywiście najkrótszym sposobem
dokonania powyższego jest:
chmod 0644, <*.c>;
Ponieważ globowanie używa powłoki, często szybciej
jest wywołać samodzielnie
readdir() i dokonać
grep()a na nazwach plików. Co więcej, z powodu obecnej
implementacji, wywołanie
glob() może napotkać
błędy w rodzaju "Arg list too long" (chyba że
zainstalowałeś
tcsh(1L) jako
/bin/csh).
Glob analizuje swój (osadzony) argument tylko jeśli rozpoczyna
nową listę. Wszystkie wartości muszą być
odczytane zanim znów rozpocznie. W kontekście listowym nie jest
to istotne, gdyż autmatycznie odczytujesz wszystkie. Jednak w
kontekście skalarnym, operator zwraca następną
wartość za każdym wywołaniem, lub FALSE na
końcu. Znowu, FALSE jest zwracane tylko raz. Jeśli więc
oczekujesz od globa pojedynczej wartości, to lepiej powiedzieć
($file) = <blurch*>;
a nie
$file = <blurch*>;
gdyż to drugie będzie rozróżniać
zwrócenie nazwy plików i zwrócenie FALSE.
Jeśli próbujesz dokonać interpolacji zmiennych, to
zdecydowanie lepiej jest użyć funkcji
glob(), gdyż
starsza notacja może spowodować zakłopotanie u
niektórych osób.
@files = glob("$dir/*.[ch]");
@files = glob($files[$i]);
Zawijanie stałych
Podobnie jak C, perl posiada pewien zestaw analiz wyrażeń,
wykonywanych podczas kompilacji -- dzieje się to jeśli
zauważy, że wszystkie argumenty operatora są statyczne i
nie mają efektów ubocznych. W szczególności, np.
konkatenacja literałów bez podstawień zmiennych jest
dokonywana podczas kompilacji. Interpretacja odwrotnych
ukośników następuje również podczas
kompilacji. Możesz powiedzieć
'Now is the time for all' . "\n" .
'good men to come to.'
a wszystko to wewnętrznie zredukuje się do jednego
łańcucha. Podobnie, jeśli powiesz
foreach $file (@filenames) {
if (-s $file > 5 + 100 * 2**16) { ... }
}
to kompilator przeliczy liczby, które reprezentuje wyrażenie.
Arytmetyka całkowita
Domyślnie, perl wykonuje wszystkie obliczenia zmiennoprzecinkowo. Jednak
powiedzenie
use integer;
mówi kompilatorowi, że może używać
odtąd, do końca bloku operacji całkowitych.
Wewnętrzne bloki mogą temu zaprzeczyć,
mówiąc
no integer;
co wystarcza do końca ich bloku.
Operatory bitowe ("&", "⎪", "^",
"~", "<<", i ">>") zawsze
dają wyniki całkowite. Jednak use integer ma wciąż
dla nich znaczenie. Domyślnie ich wyniki są interpretowane jako
liczby całkowite bez znaku. Po włączeniu tej opcji, sa
interpretowane ze znakiem. Np. ~0 normalnie jest analizowane do wielkiej
wartości całkowitej. Po use integer; ~0 staje się -1.
Arytmetyka zmiennoprzecinkowa
Podczas gdy use integer daje arytmetykę całkowitą, nie ma
podobnej instrukcji dla dawania zaokrągleń, lub
odcięć w konkretnych miejscach dziesiętnych. Dla
zaokrągleń do określonej ilości cyfr, najlepiej
użyć
sprintf() lub
printf().
Moduł POSIX (część standardowej dystrybucji perla)
implementuje funkcje
ceil(),
floor() i kilka innych funkcji
matematycznych i trygonometrycznych. Moduł Math::Complex
(również standardowy) definiuje sporo funkcji matematycznych,
które mogą działać również na
liczbach rzeczywistych. Moduł Math::Complex nie jest tak wydajny jak
POSIX, lecz POSIX nie może działać na liczbach
zespolonych.
Zaokrąglanie w aplikacjach finansowych może mieć
poważne konsekwencje i używana metoda powinna być
podawana dokładnie. W tych wypadkach, lepiej nie ufać temu,
który system zaokrąglania jest używany przez perla, lecz
zaimplementować taką funkcję samodzielnie.
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 perlop
Prosimy o pomoc w aktualizacji stron man - więcej informacji można
znaleźć pod adresem
http://sourceforge.net/projects/manpages-pl/.