Perlininkai visur…

Vat nuėjau į IRC tinklą irc.freenode.org pasižiūrėti kaip
gyvena pasaulio programuotojai. Užsukau į #php ir #perl, pamačiau
klausimą apie tai kaip sužinot ar serveris gyvas ir nepažiūrėjau kuriame
kanale esu. Kadangi pasiūliau Perlinį sprendimą, tai buvau ne kaip
sutiktas pasaulio PHPistų ;)

    <hollo> errr.. i cant figure out the most optimal way to 
deturn wether a server ip running or not
 <doc|work> hollo: check out curl (is the standard answer for that)
<moxliukas> Net::Ping?
 <doc|work> moxliukas: get out. now
 <doc|work> :)
 <doc|work> damn perl people infiltrating #php

O jei rimčiau, tai mane sudomino diskusija apie tai, jog PHP jau
perrašomas n-tąjį kartą, bet vis tiek yra labai neapgalvotas, padrikas
ir panašiai. Štai Python versija tik antra, Ruby – 1.7, tuo tarpu
PHP jau ruošiamas penktas (Perlas ruošiamas šeštas, bet jis žymiai
ilgiau gyveno nei čia paminėtos kalbos). Kartu buvo aišku užvažiuota ir
PHP padrikumui (na, ten visokie is_array,
is_empty() ir isset();
strstr(haystack, needle),
explode(needle, haystack)…) bei PHP
kintamųjų apibrėžimo sričių keistenybių. Šiaip prieita išvados, jog
tokie radikalūs skirtumai tarp PHP ir kitų kalbų stabilumo/išbaigtumo
yra galbūt todėl, kad PHP kūrime nelabai dalyvauja mokslininkai iš
kompiuterijos sričių, kurie nurodytų labiau mokslinį poižūrį į kodą, o
ne šiaip „o čia faina funkcija, tuoj pridedu prie kalbos, nesvarbu
kad gal ji nedera prie sistemos“. Čia aišku galima ginčytis, bet
dar vienas dalykas svarbus tame, kad PHP nėra vieno žmogaus kūrinys. Na,
Perl, Python, Ruby irgi ne vieno žmogaus kūriniai, bet visad yra vienas
pagrindinis, kuris gali spręsti kuria linkme kalba turi būti
programuojama (Perl turi Larry Wall, Python turi Guido van Rossum, Ruby
turi Yukihiro Matsumoto).

Naudinga Perlo pragma

Kažkaip šiandien varčiausi Perlo dokumentaciją ir aptikau labai
naudingą Perlo pragmą, kuri padeda geriau išsiaiškinti kaip veikia
įpraiškos. Tereikia parašyti use re 'debug'; ir
visas įpraiškų paieškos procesas atsiveria prieš jus ;) Štai pavyzdys:

use re 'debug';
my $f = 'foo';
$a =~ /o+/;

Spausdina:

Compiling REx `o+'
size 4 Got 36 bytes for offset annotations.
first at 2
   1: PLUS(4)
   2:   EXACT <o>(0)
   4: END(0)
anchored `o' at 0 (checking anchored) plus minlen 1
Offsets: [4]
        2[1] 1[1] 0[0] 3[0]
Guessing start of match, REx `o+' against `foo'...
Found anchored substr `o' at offset 1...
Starting position does not contradict /^/m...
Guessed: match at offset 1
Matching REx `o+' against `oo'
  Setting an EVAL scope, savestack=3
   1 <f> <oo>             |  1:  PLUS
                           EXACT <o> can match 2 times out of 
2147483647...
  Setting an EVAL scope, savestack=3
   3 <foo> <>             |  4:    END
Match successful!
Freeing REx: `"o+"'

Truputis ASP

Na, galvojau, kad ko jau ko, o VBScript tai nereikės niekad
krapštyt. Klydau. Vat prisireikė staiga su ASP padaryt priėjimą prie
Access duombazės ir būtent reikėjo daryti tai su ASP.

Problemos sprenimą pradėjau pasigooglindamas apie pačią ASP
technologiją. Realiai serveryje turėjau pasirinkimą iš VBScript,
JavaScript ir PerlScript. Spėkit iš trijų kartų kurią
kalbą pasirinkau naudoti. Neatspėjot, ne Perlą. Tiksliau jau buvau
beveik viską parašęs PerlScriptu, bet ten tokia kvaila implementacija,
kad nelikę iš to PerlScript viso Perlo grožio. Jau
VBScript ganėtinai blogai padarytas, o PerlScript dar ir
VBScript blogumu aplenkia ;) Tarkim su PerlScript norint
pasiimt ką nors iš URL GET metodu perduotos informacijos reikia rašyti

my $foo = $Request->QueryString('foo')->Item(), tuo tarpu VBScript tereikia foo = request.querystring("foo")

Kad ir kaip ten bebūtų, teko rašytis viską su VBScript. Aišku pritrūko man ten normalaus įpraiškų palaikymo (arba man tiesiog IsNumeric() kažkaip kvailai
veikė – kintamųjų tikrinimas gali tapti skausmu ne patys žinot kur – nors gal visa tai man tik atrodo, nes neturiu patirties su ASP), ir kas
svarbiausia, supratau jog esu per daug priprates prie kabliataškių sakinių gale ;) Tiesiog keista kai nereikia dėti kabliataškio. Ir dar tie If ... Then ... End If… hrr…

Dar keletas „įvado į Perlą“ formatų

Na, kadangi trūko pdf formato, tai padariau ir jo versiją (bei
keletą kitų). Dabar galima rasti pod, html, pdf, txt, TeX, man, doc, rtf ir chm
versijas. Beje, labai būčiau dėkingas, jei galėtumėte padėti pataisyti
šio įvado stilių ir rasti bei ištaisyti klaidas. Lietuvių kalba nėra
mano stipriausia sfera, ir ypač prie galo sunkokai sekėsi versti. Žodžiu
labai laukiu pastabų ir pasiūlymų.

Aišku šiuo įvadu neapsiribosiu.. Perlo dokumentaciją sudaro 800000
eilučių, dar darbo niekad nepritruks ;)

Įvadas į Perlą įvairiais formatais

Persirašiau savąjį įvadą į Perlą (perlintro vertimą) į POD
formatą. POD formatas yra Perlo dalis, juo rašoma visa Perlo
dokumentacija, tad nenuostabu kad egzistuoja daug visokių konvertavimo
programėlių, kuriomis iš POD galima sukurti HTML, txt, LaTeX, man ir
kitokių formatų dokumentus. tad dabar įvadą į Perlą lietuviškai galima
parsisiųsti šiais formatais: POD, HTML, LaTeX, man ir txt.

Parrot ir Python lenktynės

Jau seniai buvo kalbėta, jog vienas pagrindinių Parrot kūrėjų (Parrot yra Perl6
virtualioji platforma) Dan Sugalski susilažino su Python kūrėju Guido
van Rossum, kad Parrot
baitkodas bus greitesnis už Pitono baitkodą
(Į Parrot baitkodą bus
galima kompiliuoti ne vien Perl, bet ir Python, Ruby, Smalltalk, Basic,
ir ką tik nori). Atrodo, jog Dan nori sukurti tokią platformą,
kuri laisvai galėtų konkuruoti tarp jau dabar egzistuojančių. Tiesą
sakant jau dabar mano 120MHz Pentiume Parrot sugeba vykdyti apie 1-2
milijonus instrukcijų per sekundę (Perl5 kokius 10-20 kartų lėtesnis).

Įvadas į Perl: baigiamoji dalis: įpraiškos ir kita

Įpraiškos

Perlas palaiko sudėtingą ir plačią įpraiškų sintaksę. Pilną jos aprašymą galima rasti perlrequick,

perlretut ir kituose dokumentacijos skyriuose. Tačiau trumpai:

Paprastas tikrinimas

if (/foo/)      { ... } # 'true' jei $_ yra simbolių seka 'foo'
if($a =~ /foo/) { ... } # 'true' jei $a yra simbolių seka 'foo'

Įpraiškų operatorius // aprašytas perlop dokumentacijoje. Jis pagal nutylėjimą įprašką

taiko kintamajam $_, tačiau tai galima pakeisti, pasinaudojus operatoriumi =~ (kurio

aprašymą irgi galima rasti perlop dokumentacijoje).

Paprastas pakeitimas

s/foo/bar/;           # pakeičia 'foo' į 'bar' kintamajame $_
$a =~ s/foo/bar/;     # pakeičia 'foo' į 'bar' kintamajame $a
$a =~ s/foo/bar/g;    # pakeičia VISUS 'foo' į 'bar' kintamajame $a

Pakeitimo operatorius s/// aprašytas perlop dokumentacijoje.

Sudėtingesnės įpraiškos

Įpraiškos nebūtinai sudaromos iš pastovių simbolių eilučių. Tiesą sakant, naudojantis sudėtingesnėmis

įpraiškomis galite aprašyti tokius šablonus, kokius tik sugalvosite. Pilnai tai aprašyta perlre

dokumentacijoje, o čia pateikiama tik trumpa lentelė:

.               vienas bet koks simbolis
\s              tarpai, naujos eilutės ir tabuliacijos simboliai (whitespace)
\S              ne tarpai, ne neujos eilutės ir ne tabuliacija (non-whitespace)
\d              skaitmuo (0-9)
\D              ne skaitmuo
\w              žodžių simbolis (a-z, A-Z, 0-9 ir _)
\W              ne žodžių simbolis
[aeiou]         atitinka vieną simbolį iš duotos aibės
[^aeiou]        atitinka vieną simbolį ne iš duotosios aibės
(foo|bar|baz)   atitinka vieną iš alternatyvų
^               eilutės pradžia
$               eilutės pabaiga

Taip pat galima nurodyti kiek kartų įpraiška turi atitikti prieš tai nurodytą išraišką, kur

„išraiška“ yra paprastas simbolis arba vienas iš metasimbolių nurodytų prieš šią pastraipą

esančioje lentelėje.

*       nulį ar daugiau kartų
+       vieną ar daugiau kartų
?       nulį arba vieną kartą
{3}     lygiai tris kartus
{3,6}   nuo trijų iki šešių kartų
{3,}    tris ar daugiau kartų

Keletas trumpų pavyzdžių:

/^\d+/         eilutė prasidedanti vienu ar daugiau skaitmenų
/^$/            tuščia eilutė (po eilutės pradžios iš karto eina eilutės pabaiga)
/(\d\s){3}/    trys skaitmenys atskirti tarpais ar tabuliacija (tarkim "3 4 5 ")
/(a.)+/         eilutė, kurioje kiekviena neporinė raidė yra 'a' (pvz 'abacadaf')
# Šis ciklas skaito iš STDIN ir spausdina netuščias eilutes:
while (<>) {
    next if /^$/;
    print;
}

Skliausteliai

Skliausteliai naudojami ne vien tik grupavimui – jie turi ir kitą paskirtį. Jie gali būti naudojami

įpraiškos rezultatų išsaugojimui. Rezultatai atsiduria kintamuosiuose $1, $2 ir taip

toliau.

# pigus ir ne visai tikslus būdas išskaidyti el.pašto adresą į dalis:
if ($email =~ /([^@])+@(.+)/) {
    print "Vartotojo vardas: $1\n";
    print "Domenas: $2\n";
}

Kitos įpraiškų galimybės

Perlo įpraiškos dar palaiko daugybę dalykų (backreferences, lookaheads ir t.t.) Apie visą tai

galima pasiskaityti perlrequick, perlretut ir perlre dokumentacijose.

Subrutinų rašymas

Labai lengva rašytis savo subrutinas:

sub log {
    my $pranesimas = shift;
    print LOGBYLA $pranesimas;
}

Ką veikia tas shift? Na, subrutinai perduodami argumentai atsiranda masyve @_ (apie tai

daugiau perlvar dokumentacijoje). Jeigu shift neperduodami jokie argumentai, ši funkcija

naudoja masyvą @_. Tad my $pranesimas = shift; paima pirmą argumentų masyvo narį ir

priskiria jį kintamajam $pranesimas.

Su @_ galima elgtis ir kitaip:

my ($pranesimas, $svarbumas) = @_; # dažnas būdas
my $pranesimas = $_[0];            # retas ir bjaurus būdas

Subrutinos gali ir grąžinti reikšmes:

sub kvadratas {
    my $skaicius = shift;
    my $rezultatas = $skaicius * $skaicius;
    return $rezultatas;
}

Daugiau apie subrutinas perlsub dokumentacijoje

Objektinis Perlas

Objektinis Perlas yra ganėtinai paprastas. Objektai perle yra nuorodos, kurios magiškai žino kokį

objektą jos vaizduoja. Tačiau objektinis perlas neįeina į šį trumpą įvadą. Skaitykite perlboot,

perltoot, perltooc ir perlobj dokumentaciją.

Pradedantieji Perlo programuotojai dažniausiai su objektiniu programavimu susiduria tik naudodamiesi

Perlo moduliais.

Naudojimasis Perlo moduliais

Perlo moduliai leidžia jums neišradinėti dviračio, nes galima naudoti skodu, kuris jau kažkieno

parašytas. Modulius galima parsisiųsti iš http://www.cpan.org. Nemažai

modulių yra įdiegiami kartu su pačiu Perlu.

Moduliai CPAN svetainėje yra kategorizuoti. Yra daug įvairiausių kategorijų: nuo tekso apdorojimo iki

tinklo protokolų, nuo duomenų bazių iki grafikos.

Norint sužinoti kaip naudotis kuriuo nors moduliu, komandinėje eilutėje parašykite perldoc

Modulio::Pavadinimas. Kode dažniausiai jums reikės rašyti use Modulio::Pavadinimas – tai

įkraus moulį ir leis naudotis jo funkcijomis.

perlfaq dokumentacijoje yra dažnai užduodami klausimai ir atsakymai apie dažnai pasitaikančias

užduotis. Dažnai atsakymai siūlo naudotis vienu ar kitu moduliu.

perlmod dokumentacija bendrai aprašo Perlo modulius, perlmodlib dokumentacijoje yra sąrašas

modulių, kurie įdiegti kartu su Perlu.

Jeigu patys norite rašytis Perlo modulius, skaitykite perlnewmod dokumentaciją.

HTML::Mason

Šiandien susidėjau į serverį HTML::Mason modulį, kurio pagalba galima rašytis Perlinius skriptus PHP stiliumi – t.y. tiesiai įterpiant juos į HTML kodą. Tiesa, viskas ne taip paprasta, kaip tik HTML::Mason turi daugiau visokių ypatybių ir gali būti naudojamas tiek šablonams (jei norima tik tokio funkcionalumo), tiek PHP stiliaus programavimui.

Kiek pamenu Nightblade buvo pareiškęs, kad jis stengiasi nebenaudot šablonų, o tik nuosaikiai naudoja PHP kodą pačiame HTML. Tai atrodo jog HTML::Mason filosofija ir yra būtent tokia. Pats kol kas tik susiinstaliavau šį modulį (ir tuo pačiu atnaujinau mod_perl), tad jokių naudojimo įspūdžių dar neturiu. Bet vat Oreilly knyga apie Mason guli internete nemokamai, tad reikės pasiskaityt.

Super pakaitalas phpDevServeriui

Beklaidžiojant po PerlMonksus
užtikau nuorodą į vieną neblogą sprendimą Windows platformai. Tai web serveris su visais
programavimui reikalingais dalykais
. Nors idėja panaši į phpDevServer, bet filosofija
radikaliai skirtinga – kai devserver stengėsi būti kuo mažesnis,
šitas daiktas stengiasi būti kuo didesnis ;) Štai kas į jį įeina:

  • Apache 2.0.46,

  • MySQL 4.0.13,

  • PHP 4.3.2 + PEAR,

  • Perl 5.8.0,

  • mod_php 4.3.2,

  • mod_perl 1.99_10,

  • mod_ssl 2.0.46,

  • openssl 0.9.7b,

  • PHPMyAdmin 2.5.1,

  • Webalizer 2.01-10,

  • Mercury Mail Transport System for Win32 and NetWare Systems
    v3.32.

Tai ir nekeista kad viskas sveria apie 33 MB ;)

Perlo skaitymo iš bylų būdai

Perlas leidžia nuskaityti duomenis iš bylų daugybe būdų, kai kurie
ganėtinai bjaurūs ir nenaudotini. Štai kad ir šis, sutinkamas
dažniausiai:

{
    local $/ = undef;
    open FH, "<$byla";
    $duomenys = <FH>;
    close FH;
}

Teigiamos pusės: visiems įprasta. Iš kart nuskaito duomenis iš bylos
nenaudojant tarpinių masyvų.

Neigiamos pusės: $duomenys negali būti leksinis
kintamasis, aprašytas su my, nes specialiai reikia
sukurti bloką tam kam lokalizuotume $/

Kitas dažnas pavyzdys:

@ARGV = ($byla);
my $duomenys = join '', <>;

Teigiama: Trumpa ir aišku. Neigiama: užteršia
@ARGV masyvą, sunku gaudyti klaidas, neefektyvu
esant didelioms byloms.

my $duomenys = `cat $byla`;

Teigiama: Labai trumpa. Labai aišku shell programuotojams.
Neigiama: Prastas saugumas – bylos pavadinime gali būti paslėptos
shell komandos. Sukuriamas naujas procesas, todėl kodo
efektyvumas mažas. Sunku gaudyti klaidas. Neportabilu.

open my $fh, '<', $byla or die $!;
read $fh, my $duomenys, -s $fh or die $!;

close $fh;

Teigiama: Lengva rast klaidas, gana trumpa, nenaudoja per daug Perlo santrumpų,
visur naudoja tik leksinius vietinius kintamuosius. Neigiama: kaip ir nėra

use Sys::Mmap;
new Mmap my $duomenys, -s $byla, $byla or die $!;

Teigiama: Labai greitas duomenų pasiekimas, nes duomenys nenuskaitomi iš bylos iki paskutinės akimirkos kai jų prisireikia.
Keičiant kintamąjį $duomenys automatiškai keičiasi ir bylos turinys (šis kintamasis „pririštas“ prie bylos). Neigiama: reikia modulio Sys::Mmap, veikia tik UNIC platformoje, sunku suprasti ne UNIX ir C programuotojams.

[Versta iš PerlDesignPatterns – pamečiau dabar nuorodą, gal darbe atknisiu :)]