use strict
, nikoliv use warnings
. Nicmene ano, oboje ma svoje pro a proti - bez strict a warnings si dovolim napsat malej program nebo one-liner, kde presne vim co se deje a co delam. Pokud se poustim do neceho vetsiho, tak tech par deklaraci a kontrol navic me uz nezabije a spolu se strict a warnings to slouzi jako pojistka, abych nemusel travit cas odhalovanim trivialnich chyb.
Super článek!!
V dalších dílech bych se ale možná soustředil na věci, které nejsou dostupné všude - např. idiomy a jejich vysvětlení, prostě něco s "přidanou hodnotou". Konkrétně o idiomech není moc informací, žádná rozsáhlá kompilace, přitom jsou skvělým úvodem do kódování v Perlu. Naučí totiž člověka myslet jinak, myslet po perlovsku. Další zajímavé oblasti, které by rozhodně prospěly nejen začátečníkům jsou např.:
To všechno jsou věci, o nichž moc/nic neví ani lidi, co v Perlu píší denně! Často si vystačí s Perlem jako "lepším shellem" a dál nejdou, přitom jsou to tak užitečné a snadné věci - jen se s tím seznámit. Berte to jen jako doporučení, tenhle článek je po dlouhé době něco opravdu k tématu!!
Jen pár poznámek/doplnění. Například map a grep by si zasloužily více informací. Hlavně grep, který popisujete:
"Pokud vyhodnocovací blok vrátí pravdivou hodnotu, prvek je v seznamu ponechán, jinak je vymazán."To není, přesně řečeno, pravda; vstupní seznam (list, array) zůstává netknutý. To co popisujete se vztahuje na výstupní seznam - návratovou hodnotu. Jde o iteraci a VÝBĚR nad vstupními prvky, ne přidávání nebo mazání čehokoli. To nepíšu vám, ale jen pro upřesnění - vím, že jste to myslel správně.
Když představujete nové operátory, měl byste s kompletní syntaxí. Jak grep, tak map mají ještě jednu, bezvýznamně výkonově rychlejší, možnost zápisu (upravím-li váš příklad):
@skryte_soubory = grep /^\./, @soubory; @mala_pismenka = map lc($_), @slova;
Liší se tím, že neberou block, ale výraz. V tomto případě je potřeba použít čárku.
Také mi tam chybí ukázka možnosti indexace hashe pomocí seznamu, tedy:
my %hash = ('jedna' => 'jedna', 'dve' => 'ctyri', 'tri' => 'devet'); my @a = @hash{'dve', 'tri'}; # qw/ ctyri devet /
nebo
my %platy; my @lidi = qw/ tom jim bob al joe steve /; my $zaklad = 1000; @platy{@lidi} = ($zaklad)x@lidi; print "$_ ma $platy{$_}\n" foreach keys %platy; --- steve ma 1000 tom ma 1000 joe ma 1000 jim ma 1000 bob ma 1000 al ma 1000
Další důležitá věc je informace o tom, že konverze hash <=> list nezachovává pořadí jednotlivých prvků, ale pouze párů prvků, což je způsobeno tím, že hash řadí páry dynamicky a podle interní implementace (z našeho pohledu "náhodně") - tedy ne abecedně nebo podle toho, jak byly přidány:
my %hash = ('jedna' => 'jedna', 'dve' => 'ctyri', 'tri' => 'devet'); my @a = %hash; # qw/ tri devet jedna jedna dve ctyri /
Další věc, kterou bych chtěl zmínit, je rozdíl chování pole ve skalárním a listovém kontextu, hlavně s odhledem na zjišťování počtu prvků v poli:
my @a = qw/ jedna dve tri ctyri pet sest sedm osm devet deset /; my $pocet1 = scalar @a; # 10 my $pocet2 = $#a + 1; # 9 + 1
Jde o to, že $#a vrací index posledního prvku (-1 pro prázdné pole), kdežto pole ve skalárním kontextu vrací počet. Čistě s ohledem na budoucí čtenáře vašeho kódu :) doporučuji vždy, když používáte pole jako skalár, uvádět scalar explicitně. Třeba ne v takto jednoduchém přiřazení, ale pokud by šlo např. o výraz nebo místo kde není kontext zřejmý na první pohled, tak určitě. Všeobecně je scalar (vynucení skalárního kontextu) v souvislosti s úvodem do polí a hashů důležitá věc. Viz např.:
my @delky_poli = (scalar @pole1, scalar @pole2);
Jinak by člověk skončil se spojením dvou polí:
my @a = qw/ 1 2 3 4 5 6 /; my @b = qw/ 7 8 9 10 11 12 /; my @spojeni = (@a, @b); # qw/ 1 2 3 4 5 6 7 8 9 10 11 12 / my @delky = (scalar @a, scalar @b); # qw/ 6 6 /
Poslední věc, co by neměla u hashů chybět je operátor keys, který vrací pole s hodnotami klíčů z hashe.
my %hash = qw/ 1 2 3 4 5 6 /; # 1 => 2, 3 => 4, 5 => 6 my @liche = keys %hash; # qw/ 1 3 5 / my @sude = map $hash{$_}, @liche; # qw/ 2 4 6 /
Operátor keys se nejčastěji používá k procházení celého hashe:
my %hash = qw/ 1 2 3 4 5 6 /; printf "\$hash{'$_'} = '$hash{$_}'\n" foreach keys %hash; --- $hash{'1'} = '2' $hash{'3'} = '4' $hash{'5'} = '6'
Protože sort umí třídit cokoli, klidně v tom příkladu můžete mezi foreach a keys vložit sort, aby nebylo pořadí vypsaných hodnot náhodné.
To je vše co jsem k tomu chtěl dodat. Ještě jednou díky za pěkný článek, který má jako první za hodně dlouhou dobu potenciál přiblížit lidem ten "svět nejen Linuxu" o němž root.cz prý stále ještě je. :)
tenhle operator muze byt velice zradny, obzvlast u vetsich cisel. napriklad (pokus o generovani rady telefonnich cisel):
print "$_\n" for 420464647470..420464647479;
zpusobi chybu "Range iterator outside integer range", pritom s "rucni" iteraci vsechno funguje bez problemu:
for ($_=420464647470; $_ <= 420464647479; $_++) { print "$_\n"; }
Mne to funguje (protoze mam 64 bitu :-)
Nicmene vtip je v tom, ze pri "rucni" iteraci iterujete pres floaty, ackoliv to neni videt. Range operator "umi" jen integery. Pro overeni muzete zkusit nasledujici kod.
for ($_ = 48446744073709551616; $_ <= 48446744073709551620; $_++) { print "$_\n"; }
V tomto pripade uz neni ani float schopen reprezentovat uvedena cisla s presnosti na jednicku. Program se zacykli. (Pokud ne, muzete ta cisla jeste o par radu natahnout.) Nejjednodussi naprava je pouzit use bignum;
na zacatku kodu.
(Podobny problem/reseni bude i v ukazkovem programu na pocitani Pascalova trojuhelniku.)
Internet Info Root.cz (www.root.cz)
Informace nejen ze světa Linuxu. ISSN 1212-8309
Copyright © 1998 – 2021 Internet Info, s.r.o. Všechna práva vyhrazena.