Štěpán Roh

Alive But Sleepy

← Oracle a Java Detaily a příklady použití widgetu GtkTextView →
Sunday, November 30, 2003

Perl 5.6.0

by Štěpán Roh

Tento text byl vyhotoven jakožto příloha k semináři Linux na MFF UK, jehož stránky byly až donedávna na serveru Sunsite (nyní tam již nejsou vůbec žádné stránky :-)

Obsahem tohoto textu jsou některé (obzvláště vypečené) nové věci obsažené v Perlu verze 5.6.0. Vycházím víceméně z dokumentu perldelta(1).

Nové číslování verzí

První a největší :-) změnou v novém Perlu je změna číslování verzí. Místo původního major.minor_patch (kdy patch větší než 50 indikuje vývojovou verzi) přešli autoři Perlu ke stále populárnějšímu major.minor.patch (kdy lichý minor značí vývojovou verzi). Bohužel, takový přechod způsobí problémy se zpětnou kompatibilitou, neboť např. 5.005_62 je v Perlu platné reálné číslo (jelikož podtržítko pouze opticky odděluje číslice), zatímco 5.6.0 nikoliv. Jenže! Nebyli by to autoři Perlu, aby nevyřešili i tento problém. Do Perlu byla přidána nová konstrukce včíslo(.číslo)* (např. v5.6.0), která reprezentuje řetězec jako vektor ordinálů. Úvodní 'v' je možno vynechat, jsou-li zapsány více jak dva ordinály (tedy v5.6.0 je ekvivalentní 5.6.0). Ke zpětné konverzi je možno použít nový formátovací příznak pro *printf() %v, který rozloží řetězec zpětně na ordinály (implicitně oddělené tečkou):

printf "v%vd", $^V;		# vytiskne aktuální verzi Perlu např. v5.6.0
printf "v%*vX", ":", $addr;	# zformátuje adresu IPv6

Unicode

Zřejmě největším zásahem do jádra Perlu je přechod na Unicode, konkrétně na kódování UTF-8 (znaky s Unicode hodnotou větší jak 127 jsou zapsány jako posloupnost znaků s nastaveným osmým bitem). Veškeré řetězce a operace s nimi jsou v Unicode, takže např. tečka se shoduje s celým Unicode znakem apod. Jediná vyjímka jsou funkce pack() a unpack(), u nichž formátovací znak 'C' značí i nadále jeden byte a 'U' jeden znak.

Jak dostat Unicode znaky přímo do perlovského programu? Existuje několik způsobů. Jedním z nich je použití pragma 'use utf8', poté je celý skript očekáván v UTF-8. Dalším je sekvence \x{hexa}, která dovoluje i vícebytové znaky. Dalším způsobem je \N{Unicode jméno znaku}. K aktivaci této funkce je nutné použít modul charnames. Poslední cestou je operátor tr//, který má nové volby /U a /C (ve formě tr /...//UC nebo tr /...//CU), kde U značí UTF-8 a C je ISO-8859-1.

Temnými stránkami je neexistence vstupních a výstupních překódování, jakož i problémy při koexistenci s locales, ale obecně je to dobrá myšlenka. Spolu s Unicode se objevily i POSIX třídy znaků v regulárních výrazech, takže je konečně možno použít i [:alpha:] apod. známé ze sedu a spol. Unicode znaky jsou implementovány včetně svých atributů, které se dají testovat v regulárních výrazech pomocí \p{} (shoduje se) nebo \P{} (neshoduje se) - např. \p{Lu} jsou veliká písmena. Identifikátory mohou nyní být jakékoliv alfanumerické znaky dle Unicode (takže asi i nějaké japonské :-))

64-bitová podpora

64-bitová podpora se vyznačuje podporou dlouhých souborů (>2 GB), 64-bitových integerů a dlouhých reálných čísel. Všechny tyto vlastnosti je nutno zapnout před překladem samotného Perlu při konfiguraci.

Bytecode

Jelikož tato kapitolka se zabývá překladem Perlu, tak nejprve letmo nastíním způsob překladu:

zdrojový text -> parser -> DAG -> interpret
                            |
                            v
                     kompilační backend
                            |
                            v
                    zkompilovaný program

Kompilační backendy se nachází v balíku B. Kompilaci zjednodušuje program perlcc, který sám vybere správný backend. Dostupné backendy jsou C (překlad do jazyka C), CC (optimalizované C) a Bytecode. Postupují tak, že projdou DAG a zakomponují jej do zkompilovaného programu, v případě C backendů je součástí výsledného programu i celý kompilátor Perlu. Jediné urychlení výsledného programu spočívá v přeskočení fáze parsování. Kompilace je pomalá a výsledný kód obrovský. Novinkou verze 5.6.0 je právě backend Bytecode. Dlouho, předlouho mi trvalo než jsem přišel na způsob jak výsledný kód spustit. Jde ve skutečnosti o normální perlovský program, následujícího formátu:

#!/bin/perl

use ByteLoader 0.03;

<binární data>

Výsledný bytecode je nezávislý na platformě.

Podprogramy vracející l-hodnotu

Podprogramy mohou vracet l-hodnotu, tedy je možná konstrukce:

my $a;

sub mod_a () : lvalue {
  $a;
}

mod_a() = 5; 

L-hodnota může být pouze skalární a nelze ji vracet (z mě neznámých důvodů) pomocí příkazu return. Ještě jedna novinka je vidět na výše uvedeném kódu a to jsou atributy podprogramů (lvalue v našem případě). Dříve se atributy museli uvádět za 'use attrs' před funkcí a vypínat pomocí 'no attrs', teď je možno je přes dvojtečku připojit přímo za jméno.

Y2K varování

Při spojení čísla 19 s jiným číslem je vydáno varování. Toto je bohužel :-) třeba zapnout při kompilaci Perlu.

Malá vylepšení a opravy

Funkce glob() (a tedy i operátor globalizace <...>) je konečně implementována vnitřně (tato implementace se dá změnit) a nevolá se externí csh.
Operátor qw// (rozdělení řetězce do slov) je vyhodnocován v čase kompilace (dříve se nahradil voláním split()).
Byl přidán zápis binárních čísel ve tvaru 0b<číslice>.
Byly přidány slabé reference (weak references = odkazy, které nezvedají čítač odkazů pro dané objekty, takže je garbage collector může zrušit), jejichž použití je experimentální a je nutná dodatečná dokumentace a kód z balíku WeakRef na CPAN.

Perl je skvělý jazyk vhodný pro malé i velké úlohy a takovým zůstává i nadále. Podpora pro 64-bitové stroje a operační systémy, jakož i stále větší podíl práce od chlapíků z ActiveState (odnož Microsoftu :-() svědčí o snaze proniknout opravdu všude (i do vašeho kávovaru :-)). Většina vylepšení směřuje správným směrem (Unicode je dobrá věc, když máte podporovat vše od Psionu, přes Unixy až po Windows). Co jiného říci...

25.5.2000 Štěpán Roh

← Oracle a Java ↑Back to top Detaily a příklady použití widgetu GtkTextView →