$x = $y = 1; # v proměnných $x i $y je hodnota 1 1 == 1 == 1; # chyba ++$x++; # chyba 1..3..5; # chyba
Asociativita | Arita | Operátory se stejnou prioritou |
není | 0 | termy a seznamové operátory (zleva) |
zleva | 2 | -< |
není | 1 | ++ -- |
zprava | 2 | ** |
zprava | 1 | ! ~ \ unární + unární - |
zleva | 2 | =~ !~ |
zleva | 2 | * / % x |
zleva | 2 | + - . |
zleva | 2 | << >> |
zprava | 0, 1 | pojmenované unární operátory |
není | 2 | > < <= >= lt gt le ge |
není | 2 | == != <=> eq ne cmp |
zleva | 2 | & |
zleva | 2 | | ^ |
zleva | 2 | && |
zleva | 2 | || |
není | 2 | .. ... |
zprava | 3 | ?: |
zprava | 2 | = += -= *= atd. |
zleva | 2 | , => |
zprava | 0+ | seznamové operátory (pravé) |
zprava | 1 | not |
zleva | 2 | and |
zleva | 2 | or xor |
$arrayref->[2]; # dereference prvku pole $hashref->{'klic'}; # dereference hodnoty hashe $subref->(1, 2, 3); # volání odkazovaného podprogramu $objekt->metoda(1, 2, 3); # volání metody objektu
$x = 1; print ++$x; # nejprve zvýší hodnotu $x na 2, vytiskne 2 print $x++; # vytiskne 2 a pak zvýší hodnotu $x na 3 $x='a'; for (1..1000) {print $x++;} # vytiskne a, b, c ... x, y, z, aa, ab, ac ... az, # ba, bb ... zx, zy, zz, aaa, aab, aac ... $x='XY'; for (1..100) {print $x++;} # vytiskne XY, XZ, YA, YB ... ZX, ZY, ZZ, AAA ... $x='K2'; for (1..1000) {print $x++;} # vytiskne K2, K3 ... K8, K9, L0, L1 ... Z8, Z9, # AA0, AA1 ... $x='A123'; for (1..1000) {print $x++;} # vytiskne A123, A124, A125 ... A999, B000, B001 ... $x = 'A+4'; for (1..100) {print $x++;} # vytiskne A+4, 1, 2, 3 ... # 'A+4' je vyhodnoceno jako 0
2**4; # dvě na čtvrtou (výsledek 16) -2**4; # to samé jako -(2**4), výsledek -16 (-2)**4; # minus dvě na čtvrtou, výsledek 16
Unární ! provádí logickou negaci výrazu.
Unární - provádí aritmetickou negaci v případě, že operand je číslo. Je-li operand řetězec nezačínající znaménkem, vrátí se stejný řetězec začínající znaménkem -. Začíná-li řetězec znaménkem, vrátí se řetězec na začátku se znaménkem opačným. Použijeme-li v programu hoplé slovo, které začíná znakem -, přestává být považováno za holé slovo a nebude na něj upozorněno varováním.
Unární ~ provádí bitovou negaci, tzn. doplněk do 1. Na různých počítačich pracujícími s různým počtem bytů vyhrazených pro uložení číselné hodnoty můžeme dostaneme různé výsledky, protože doplněk se provádí pro různý počet bitů. Je-li tento operátor použit na řetězec, vrátí se řetězec se všemi bity komplementovanými. Toto použití je vhodné k negaci většího počtu bitů a neobjevuje se zde problém s rozdílnou velikostí pro uložení jedné hodnoty.
Unární + nemá žádný semantický význam.
print 1, 2, 3; # vytiskne 123 print (1, 2), 3; # vytiskne 12, 3 je nevyužitá konstanta, (1, 2) # je chápáno jako seznam všech argumentů funkce print print +(1, 2), 3; # vytiskne 123, (1, 2) není chápáno jako seznam # všech argumentů funkce printUnární \ vytváří odkaz na cokoliv, co následuje.
print 10/3; # vytiskne 3.33333333333333 use integer; print 10/3; # vytiskne 3 10 % 3; # zbytek 1 (nejbližší násobek 3 menší nebo roven 10 je 9, # zbytek je tedy 10-(3*3) 11 % -5; # zbytek -4 (nejbližší násobek čísla -5 větší nebo roven 11 # je 15, zbytek je tedy 11-(-5*-3) -9 % 4; # zbytek je 3 -9 % -4; # zbytek je -1 $x = '1' x 5; # $x obsahuje '11111' @pole = (1) x 5; # @pole obsahuje (1, 1, 1, 1, 1) @pole = (1, 2) x 3; # @pole obsahuje (1, 2, 1, 2, 1, 2)
2 + 5; # výsledek je 7 'abc' + '123'; # výsledek je 123 'abc' . '123'; # výsledek je 'abc123'
1 << 4; # hodnota je 16 32 >> 4; # hodnota je 2
alarm | caller | chdir |
chroot | cos | defined |
delete | do | eval |
exists | exit | exp |
gethostbyname | getnetbyname | getprgp |
getprotobyname | glob | gmtime |
goto | hex | int |
lc | lcfirst | length |
local | localtime | log |
lstat | my | oct |
ord | quotemeta | rand |
readlink | ref | require |
reset | return | rmdir |
scalar | sin | sleep |
sqrt | srand | stat |
uc | ucfirst | umask |
undef |
cos $x == 1; # chápáno jako cos($x) == 1, operátor == # má nižší prioritu než unární operátor cos; # výsledek výrazu bude logiská hodnota závislá na # porovnání hodnoty 1 a cos $x print $x == 1; # chápáno jako print($x == 1), operátor == má # vyšší prioritu než seznamový operátor print; # vytiske se logická hodnota vzniklá porovnáním # hodnoty 1 a hodnoty $x
Řada z nich pracuje s $_. Vynecháme-li argument a následuje=li něco, co vypadá jako argment, je to za argument považováno.
cos*$x; # má být násobení, chápáno jako cos typeglobu cos .111; # má být zřetězení, chápáno jako cos(0.111) length < $x; # má být porovnání, chápáno jako length(<$x>), chyba, protože # je očekáván uzavírací znak >
Vyřešení tohoto problému:
cos $_ * $x; cos() * $x; (cos) * $x; $x * cos;
Dále dělají problémy znaky + - * / < << . ? % & &&.
Operátory pro testování souborů (znak- + jedno písmeno). Jako argument požadují jméno ovladač nebo souboru, u kterého mají zjišťovat různé vlastnosti. Vracejí pravdivou nebo nepravdivou hodnotu podle toho, zda daná vlastnost existuje nebo se ji podařilo zjistit. V případě, že argument chybí, pracují s hodnotou proměnné $_ (výjimku tvoří operátor -t, který pracuje s ovladačem STDIN).
Operátor | Význam |
-r | soubor je možné číst |
-w | do souboru je možné zapisovat |
-x | soubor je možné spustit |
-o | soubor je vlastněn |
-R | soubor je možné číst pod skutečným UID/GID |
-W | do souboru je možné zapisovat pod skutečným UID/GID |
-X | soubor je spustitelný pod skutečným UID/GID |
-O | soubor je vlastněn skutečným UID |
-e | soubor existuje |
-z | soubor má nulovou délku |
-s | soubor má nenulovou délku (vrací velikost souboru) |
-f | soubor je plain file |
-d | soubor je adresář |
-l | soubor je symbolický odkaz |
-p | soubor je pojmenovaná roura |
-S | soubor je socket |
-b | soubor je speciální blokový soubor |
-c | soubor je speciální znakový soubor |
-t | soubor je otevřen na tty |
-u | soubor má nestaven setuid bit |
-g | soubor má nastaven setgid bit |
-k | soubor má nastaven sticky bit |
-T | soubor je textový |
-B | soubor je binární |
-M | stáří souboru ve dnech od poslední modifikace |
-A | stáří souboru ve dnech od posledního přístupu |
-C | stáří souboru ve dnech od změny inode |
print "do souboru data.txt je možné zapisovat" if -w 'data.txt';
Sekvence -[písmeno] je vždy chápána jako operátor testu souboru.
sub e {return 2.718282}; # funkce vrací Eulerovo číslo $x = 10*e; # $x obsahuje 27.18282 $x = 10*-e; # -e chápáno jako operátor testu souboru
pro čísla | pro řetězce | význam |
< | lt | menší než |
<= | le | menší rovno |
> | gt | větší než |
>= | ge | větší rovno |
pro čísla | pro řetězce | význam |
== | eq | rovno |
!= | ne | nerovno |
<=> | cmp | porovnání |
& - bitový logický součin
| - bitový logický součet
^ - exkluzivní bitový logický součet
Typy operandů
Různé výsledky na počítačích s různou délkou pro uložení čísla.
Operátor | Význam |
&& | logický součin |
|| | logický součet |
open (FILE, "soubor.txt") || die "Nelze otevřít soubor\n");
V seznamovém kontextu vracejí seznam, pracuje pro čísla i řetězce.
foreach (1 .. 10) { # nějaké příkazy } @mala_abeceda = ('a' .. 'z'); @alfanumericke_znaky = ('a' .. 'z', 'A' .. 'Z', 0 .. 9);
Ve skalárním kontextu se tento operátor chová jako operátor rozsahu řádků.
Hodnota je nepravdivá, dokud je levý operand nepravdivý. Jakmile je levý operand pravdivý, zůstane hodnota celého výrazu pravdivá tak dlouho, než bude pravdivý pravý operand. Potom je hodnota celého výrazu opět nepravdivá. Může nastat situace, že výraz s tímto operátorem získá pravdivou hodnotu, ale ihned se stane nepravdivým (vyhodnocením pravého operandu). Je ale vrácena pouze jedna hodnota, a to pravdivá. Jestliže chceme zabránit testování pravého operandu před dalším vyhodnocováním celého výrazu, místo .. se uvede ....
Je-li operend číslo, porovnává se s proměnnou $..
while (<FILE>) { print if 1 .. 10; # vypíše prvních 10 řádek }
$max = $a > $b ? $a : $b; # do proměnné $max se uloží větší z čísel $a a $b
Pokud jsou oba výrazy za ? l-hodnotami, je možné do nich provést přiřazení.
($a < $b ? $a : $b) += 1; # menší z čísel $a a $b se zvýší o 1
První výraz je vyhodnocován ve skalárním kontextu, zbytek v libovolném.
Na levé straně l-hodnota.
Přiřazovací operátor se někdy nachází ve tvaru
l-hodnota OPERÁTOR= hodnota;
Varianty:
**= += *= &= <<= &&= -= /= |= >>= ||= .= %= ^= x=
Toto má stejný význam jako
l-hodnota = l-hodnota OPERÁTOR hodnota;
Funguje jenom pro skalární kontext.
L-hodnota je při tomto zápise vyhodnocována pouze jednou, takže
$pole[$i++] *= 2;je něco jiného než
$pole[$i++] *= $pole[$i++] * 2;kdy se inkrementace provede dvakrát. Výsledkem výrazu s přiřazením je hodnota na levé straně.
$a = $b = $c = 10; # nastaví všechny tři proměnné na hodnotu 10V seznamovém kontextu je možné přiřazení pouze pomocí samotného = a je vrácen seznam l-hodnot, do kterých bylo přiřazení provedeno. Ve skalárním kontextu je vrácen počet prvků na pravé straně přiřazení. Toho je vhodné použít např. na testování toho, že nějaká funkce vrací prázdný seznam:
while (($klic, $hodnota) = each %hash) { # nějaké operace }
Chování operátoru čárky závisí na kontextu, v jakém je použit. Ve skalárním kontextu vyhodnotí levý výraz, jeho hodnotu zapomene, vyhodnotí výraz na pravé straně a jeho hodnotu vrátí. V seznamovém kontextu funguje čárka jako oddělovač prvků seznamu.
$a = (10, 20, 30);\ # v $a je hodnota 30 @pole = ( 10, 20, 30); # v @pole je tříprvkový seznam
Synonymem pro čárku je symbol =>.
Na pravé straně seznamového operátoru je seznam argumentů oddělených operátorem čárky. Tento seznam končí symbolem konce příkazu (např. středník) nebo pravou závorkou nebo některým z operátorů s ještě nižší precedencí (logické and, or, not a xor).
print 1, 2, 3; # operandy funkce print jsou 1, 2, 3 open F, "data" or die "Nelze otevřít soubor"; # operandy funkce open jsou F a "data", # funkce die pouze jeden řetězec open F, "data" || die "Nelze otevřít soubor"; # to samé jako open F, ("data" || die "..."), # operátor || má totiž vyšší preferenci (localtime(time))[5]+1900; # hodnotou výrazu je aktuální rok print (localtime(time))[5]+1900; # výraz print (localtime(time)) je # považován za term, [5] je potom # syntaktická chyba print +(localtime(time))[5]+1900; # v pořádku print 1900+(localtime(time))[5]; # v pořádku print 0+(localtime(time))[5]+1900; # v pořádku print ''.(localtime(time))[5]+1900; # v pořádku
Všechny tyto operátory mají kromě xor svá synonyma, ovšem s vyšší precedencí.
xor provádí logické xor, ^ bitové.
Díky nízké prioritě těchto operátorů je lze uvést např. za seznamovým operátorem bez nutnosti psaní závorek uzavírajících argumenty operátoru.
open FILE, "$soubor" or die "Nelze otevřít soubor.";
Je třeba si uvědomit, že tyto operátory mají nejnižší precedenci a použití místo jejich ekvivalentů s vyšší precedencí v nějakém výrazu, může zcela změnit význam tohoto výrazu.
$vyraz = $a && $b && $c;
je něco jiného než
$vyraz = $a and $b and $c; # špatně $vyraz = ($a and $b and $c); # správně
© 2004, František Dařena |