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¶
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.