Přednáška #5: Co se jinam nevešlo ################################# UniCode (perluniintro, perlunicode, perlunifaq) ======= - tradiční Perl považoval stringy za posloupnosti bajtů - dnes jsou stringy posloupnosti 32-bitových codepointů ("znaků"): -> normální znaky -> kombinující akcenty -> kombinace znak + akcent(y) [nutno normalizovat!] -> ligatury -> značky (right-to-left, zero-width non-breaking space apod.) - zápis v literálech: \x{263a} <-- znak zadaný číslem \N{FIRST QUARTER MOON} <-- pojmenovaný znak use utf8; <-- zdroják je v UTF-8 (i identifikátory) - (de)kódování: use Encode; Encode::encode('iso-8859-2', $string) Encode::decode('utf-8', $string) "utf-8" vs. "utf8" [interní reprezentace: "utf8" + speciální flag] - I/O: open my $fh, '>:utf8', $name open my $fh, '>:encoding(iso-8859-2)', $name binmode STDOUT, ':utf8' :crlf :locale (vyžaduje use PerlIO::locale) - Unicode::Normalize - Regexy: \p{Greek} <-- Unicodové vlastnosti (viz perluniprops) \X <-- "extended grapheme cluster" m{REGEX}a <-- "ASCII-like" mód: \d m{REGEX}aa <-- navíc nemíchá ASCII s non-ASCII (např. "k" a "Kelvin sign" při case-insensitive matchování) Funkcionální konstrukce (perlfunc) ======================= map { 2*$_ } @list <-- anonymní blok, $_ je alias pro prvek map { ($_ < 10) ? $_ : () } @list %hash = map { $_ => 1 } @list map chr, @list <-- místo funkce lze uvést výraz grep { $_ < 10 } @list sort { $a <=> $b } @list Prototypy funkcí (perlsub) ================ sub brum($$@) ... signatura ovlivňuje, jak se parsuje volání funkce $ <-- skalár @ <-- zbytek je seznam $;$ <-- 1. argument povinný, 2. nepovinný &@ <-- jako map *$ <-- jako open (typeglob předává referencí) \$ <-- skalár předaný referencí \[$@] <-- skalár nebo pole předané referencí _ <-- skalár nebo implicitní $_ Signatury funkcí (v5.20, perlsub, experimental!) ================ use feature 'signatures' <-- současně zakáže prototypy sub brum($left, $right) $left <-- interně: my $left = $_[0] $ <-- nepojmenovaný argument $left = 0 <-- defaultní hodnota $right = <-- nepovinný s defaultem undef @rest <-- zbylé argumenty posbírat do pole %rest <-- ... do hashe Atributy funkcí (perlsub, Attribute::Handlers) =============== sub func : attr(val) :prototype($$) <-- prototyp (lze použít se signaturou) :lvalue <-- do výsledku lze přiřazovat Switch (perlsyn) ====== use feature 'switch'; given (EXPR) { when ('abc') { say 'Alphabet'; } when ([1,2,3]) { say '1-2-3'; continue; } when (/^\d+$/) { say 'Number'; } when ($_ == 1) { say 'Strange 1'; } default { die 'Uh?'; } } for (@list) { when ("") { die 'Empty string not allowed'; } } Smart match (perlsyn) =========== $a ~~ $b <-- when (EXPR) je zkratka za if ($_ ~~ EXPR) [část pravidel; předpokládáme automatickou dereferenci $b] Any undef <-- !defined($a) Hash CodeRef <-- funkce schválí aspoň jeden klíč Array CodeRef <-- funkce schválí aspoň jeden prvek Any CodeRef <-- funkce schválí skalár Array Hash <-- alespoň jeden klíč leží v $a Any Hash <-- existuje daný klíč Hash Array <-- alespoň jeden prvek pole je klíčem hashe Any Array <-- alespoň jeden prvek smart-matchuje $a Hash Regex <-- alespoň jeden klíč vyhovuje regexu Array Regex <-- alespoň jeden prvek vyhovuje regexu Any Regex <-- skalár vyhovuje regexu Any Num <-- numerická rovnost Any Any <-- stringová rovnost Eval (perlfunc, perlvar) ==== eval $string eval { BLOCK } <-- vrátí hodnotu posledního vyhodnoceného výrazu (undef, pokud došlo k kompilační/běhové chybě) $@ <-- chybová hláška poslední k./b. chyby či argument die Zaručeno "", pokud eval doběhl úspěšně $! <-- "errno" -- poslední chyba vrácená OS, třeba u open() $? <-- status-kód posledního ukončeného procesu ($? >> 8) je návratový kód procesu ($? & 127) je číslo signálu, kterým byl ukončen Interpolace (perlop) =========== Není definována exaktně. Přibližně: nejdelší konstrukce bez mezer mající smysl. $a, $a[1], $a[1][1] ${skalar} <-- občas se hodí explicitně vymezit konec @pole <-- prvky proložené mezerami (přesněji: $") \r\n\t ... <-- jako v Céčku \033 <-- oktalový kód znaku \x41 \x{263a} <-- "A", smajlík \N{FIRST QUARTER MOON} <-- pojmenovaný unicodový znak \U ... \E <-- konverze na uppercase \L ... \E <-- konverze na lowercase \Q ... \E <-- quote non-word characters Obskurní operátory (perlop) ================== ~ & | <-- fungují i na řetězce (byte po bytu) X .. Y <-- v seznamovém kontextu: generátor posloupností (lze i "A".."Z") COND1 .. COND2 <-- ve skalárním kontextu: flip-flop, poprvé vrátí true při COND1, naposledy při COND2, pak se zresetuje. Doopravdy vrací pořadové číslo v rámci aktuálního běhu (od 1). Trikové, viz perlop. NUM .. NUM <-- strašlivý hack testující čísla řádků (awk/sed) ... <-- "dosud neimplementováno" <*.c> <-- file-glob (vrací seznam), raději používat funkci glob