Internet Info, s.r.o. Lupa Měšec Podnikatel Root Zdroják DigiZone Slunečnice Vitalia TopDrive KupDnes Navrcholu NovýTarif Dobrý web Weblogy Woko Jagg Computer.cz SK: MojeLinky

Hlavní navigace

Názory k článku
Perličky: práce se seznamy

Keson
Keson (neregistrovaný)
8. 2. 2008 1:20 Nový

Pěkný článek

celé vlákno
Jen tak dál:-)
Michal Svoboda
8. 2. 2008 14:32 Nový

Re: Pěkný článek

celé vlákno
Diky.
lzap
lzap (neregistrovaný)
8. 2. 2008 23:14 Nový

Re: Pěkný článek

celé vlákno
Zdravi i puvodni autor serialu. Jen tak dal :-)
Miroslav Suchý aura:93
8. 2. 2008 11:02 Nový

unless defined $max and $max > 0;

celé vlákno
Místo
unless defined $max and $max > 0;
můžu rovnou použít
unless $max > 0;
protože undef se vyhodnotí jako ==0
kvr
kvr (neregistrovaný)
8. 2. 2008 12:02 Nový

Re: unless defined $max and $max > 0;

celé vlákno
Jenze to zarve warning...

use strict;
use warnings;
Michal Svoboda
8. 2. 2008 14:31 Nový

Re: unless defined $max and $max > 0;

celé vlákno
Presne tak, je to tam kvuli -w. Jinak na 0 se vyhodnoti treba taky "ahoj".
Miroslav Suchý aura:93
8. 2. 2008 20:09 Nový

Re: unless defined $max and $max > 0;

celé vlákno
Aha to "-w" jsem prehledl. Jinak samozrejme "use strict" tam muze byt a nebude to na "unless $max>0" kricet.

Ja osobne "use warnings" nepouzivam, protoze to prave v takovychto chvilich zbytecne prodluzuje kod. Je fakt ze pokud je nekdo zacatecnik a spise tape a uplne nevi co pise, tak to asi je dobre zapnout.
BLEK.
BLEK. (neregistrovaný)
12. 2. 2008 20:05 Nový

Re: unless defined $max and $max > 0;

celé vlákno
Jenže když si vypneš warningy, tak pak jeden překlep ve jménu proměnné budeš hledat půl hodiny.
Petr
Petr (neregistrovaný)
13. 2. 2008 18:30 Nový

Re: unless defined $max and $max > 0;

celé vlákno
No a kdyz si je nevypnes, tak misto toho tu pulhodinu stravis vypisovanim nepodstatnych radku jako treba deklaraci promennych. Tak kde je rozdil?
Michal Svoboda
13. 2. 2008 21:43 Nový

Re: unless defined $max and $max > 0;

celé vlákno
Deklarace promennych je vynucena pomoci 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.
valy
valy (neregistrovaný)
8. 2. 2008 12:04 Nový

Re: unless defined $max and $max > 0;

celé vlákno
a nebude to s use strict; use warnings; davat varovne hlasky?
uživatel si přál zůstat v anonymitě
8. 2. 2008 18:59 Nový

hezky

celé vlákno
jestli i dalsi dily budou timhle stylem, tak se ten perl nakonec snad opravdu naucim :)
tukan
tukan (neregistrovaný)
9. 2. 2008 3:48 Nový

Pěkné

celé vlákno

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ř.:

  • Variable scope, dosah proměnných, lexikální proměnné, closure
  • Efektivní práce s řetězci
  • Speciální proměnné (z nejdůležitějších $|, $0, $$, $/, $\, $., $!, $?, $^O)
  • Debugování, Data::Dumper
  • Signály
  • IPC: pipe mód -| a |- funkce open, open PH, '-|', "command"; moduly IPC::Open[23], IPC::Semaphore, bezpečnější list verze funkcí system a exec
  • Všeobecně možnosti skvělého PerlIO prosřednictvím druhého parametru tříparametrové verze open
  • Vlákna, synchronizace, sdílení: moduly threads, threads::shared
  • Objektové programování, v Perlu jedna radost
  • Tied objekty
  • Autoloader
  • Síťové programování, daemonizace
  • Práce s terminálem, pseudoterminály
  • Gtk2 bindings: Gtk2, Gtk2::GladeXML

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. :)

lzap
lzap (neregistrovaný)
10. 2. 2008 10:33 Nový

Re: Pěkné

celé vlákno
Hash řadí prvky dynamicky, z našeho pohledu náhodně...

Ono je to i z vnitřního pohledu náhodně. Je to hashmapa s roustoucí hranicí a nastavitelným prahem expanze. Fyzicky jsou ty záznamy uloženy náhodně. Není ale problém naimplementovat si hash pole, které bude uděláno pomocí setříděného stromu -- tam už je vše seřazeno.
Michal Svoboda
10. 2. 2008 13:31 Nový

Re: Pěkné

celé vlákno
Pokusim se drive nebo pozdeji vsechna temata nejak adresovat. Jinak diskuse nad tematy take probehla v blogpostu:
http://pht.blog.root.cz/0801/serial-o-pokrocilem-pouzivani-jazka-perl

Jsem rad, ze jste doplnil fakta, ktera v clanku chybi. Tyto a dalsi mezery hodlam vyplnit hojnym pouzivanim operatoru/hashu/... v dalsich dilech.

Souhlasim, ze spousta lidi co pisou v Perlu jej pouziva na velmi primitivni urovni. Tento serial je urcen hlavne jim. Je to, jak rikate, jednoduche a neboli to, jen o tom vedet.
tukan
tukan (neregistrovaný)
10. 2. 2008 15:39 Nový

Re: Pěkné

celé vlákno
Fajn, kdybyste chtěl s něčím píchnout, tak se rád zúčastním. Nemyslím, že byste chtěl pomoct přímo s Perlem - samozřejmě! - ale se seriálem... Honorář za články by šel vám, kvůli tomu bych to nedělal. Prostě bych na root.cz rád viděl víc článků v původním duchu, jako dřív.
uživatel si přál zůstat v anonymitě
11. 2. 2008 11:24 Nový

Dalším častým operátorem jsou dvě tečky .., které umí &#8222;počítat po jednom&#8220;.

celé vlákno

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";
}
Michal Svoboda
11. 2. 2008 16:07 Nový

Re: Dalším častým operátorem jsou dvě tečky .., které umí &#8222;počítat po jednom&#8220;.

celé vlákno

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

Bubla
Bubla (neregistrovaný)
14. 2. 2008 14:55 Nový

Naucte

celé vlákno
se radsi nakej poradnej jazyk.
Michal Svoboda
14. 2. 2008 20:52 Nový

Re: Naucte

celé vlákno
Nevim, ktery zrovna myslite, ale muzete si o nem take udelat clanek. :-)
Zasílat nově přidané příspěvky e-mailem