Operátory

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

Termy a seznamové operátory (zleva)

Termy jsou proměnné, uvozovkové (a podobné) operátory, operátor <>, výrazy v kulatých závorkách a funkce s parametry v závorkách (seznamové i unární operátory). Stejně jako termy je pohlíženo na bloky do {} a eval {}, na volání funkcí a metod objektů a na konstruktory anonymních polí ([ ]), hashů ({ }) a podprogramů (sub {}).

Operátor šipka

$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

Operátor autoinkrementu a autodekrementu

$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

Umocňování

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

Ideografické unární operátory

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 print
Unární \ vytváří odkaz na cokoliv, co následuje.

Vazebné operátory

Pro práci se vzory a jinou proměnnou, než $_. Návratová hodnota závisí na typu operátoru, se kterým jsou spojeny.

Multiplikativní operátory

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)

Aditivní operátory

2 + 5;         # výsledek je 7
'abc' + '123'; # výsledek je 123
'abc' . '123'; # výsledek je 'abc123'

Operátory posuvu

1 << 4;     # hodnota je 16
32 >> 4;    # hodnota je 2

Pojmenované unární operátory a operátory testování souborů

alarmcallerchdir
chrootcosdefined
deletedoeval
existsexitexp
gethostbynamegetnetbyname getprgp
getprotobyname globgmtime
gotohexint
lclcfirstlength
locallocaltimelog
lstatmyoct
ordquotemetarand
readlinkrefrequire
resetreturnrmdir
scalarsinsleep
sqrtsrandstat
ucucfirstumask
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
-rsoubor je možné číst
-wdo souboru je možné zapisovat
-xsoubor je možné spustit
-osoubor je vlastněn
-Rsoubor je možné číst pod skutečným UID/GID
-Wdo souboru je možné zapisovat pod skutečným UID/GID
-Xsoubor je spustitelný pod skutečným UID/GID
-Osoubor je vlastněn skutečným UID
-esoubor existuje
-zsoubor má nulovou délku
-ssoubor má nenulovou délku (vrací velikost souboru)
-fsoubor je plain file
-dsoubor je adresář
-lsoubor je symbolický odkaz
-psoubor je pojmenovaná roura
-Ssoubor je socket
-bsoubor je speciální blokový soubor
-csoubor je speciální znakový soubor
-tsoubor je otevřen na tty
-usoubor má nestaven setuid bit
-gsoubor má nastaven setgid bit
-ksoubor má nastaven sticky bit
-Tsoubor je textový
-Bsoubor je binární
-Mstáří souboru ve dnech od poslední modifikace
-Astáří souboru ve dnech od posledního přístupu
-Cstáří 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

Relační operátory

pro čísla   pro řetězce    význam
< lt menší než
<= le menší rovno
> gt větší než
>= ge větší rovno

Operátory rovnosti

pro čísla pro řetězce význam
==eqrovno
!=nenerovno
<=>cmpporovnání

Bitové operátory

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

Logické operátory se zkráceným vyhodnocováním

Operátor Význam
&&logický součin
||logický součet
open (FILE, "soubor.txt") || die "Nelze otevřít soubor\n");

Operátor rozsahu

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
}

Podmínkový operátor

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

Operátor přiřazení

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 10
V 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
}

Operátor čárka

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

Seznamové operátory (zprava)

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

Logické and, or, not a xor

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

Valid XHTML 1.0! Valid CSS!