Moblogas

Vakar naktį pasidariau moblogą. Tai turbūt vienas iš tų projektų kur dariau nes galiu padaryt, o ne todėl kad reikia. Faktiškai Perlo kodo rašymas visada malonus, net jei ir nepildysiu to moblogo ateityje – iš manęs fotografas tai kaip iš mano bobulės perlininkė.

Visam šitam daiktui tiesiog persikopijavau savo svetainės kodą į kitą direktoriją, šiek tiek pataisiau šablonus (bet ne iki galo, nes vakar jau labai norėjosi miego), sukūriau porą SQL lentelių, pataisiau kodą, kad dirbtų su tomis naujomis lentelėmis ir parašiau el. pašto apdorojimo programėlę. Pakeitimų ne tiek daug kaip atrodo ;)

Štai kodas, kuris apdoroja gautą el. paštą, surašo kur reikia attachmentu atėjusias JPG bylas ir įterpia reikiamus duomenų bazės įrašus:

#!/usr/bin/perl -w

use strict;use MIME::Parser;

use FileHandle;

use File::Path;

use DBI;

$|++; # Autoflush on

# Prisijungiam prie MySQL

my $dbh = DBI->connect("DBI:mysql:database=moxliukas;dbhost=localhost",

        'moxliukas', 'passwordas');

# katalogų keliai - laikinas ir output

my $tmp_dir = '/home/moxliukas/tmp';

my $output_dir = '/home/moxliukas/public_html/moblog/images';

my $parser = MIME::Parser->new;

$parser->output_dir($tmp_dir);

# Skaitom viską iš STDIN

my $entry = $parser->parse(*STDIN);

# Kiekvienai MIME daliai...

for my $part ($entry->parts) {

       # Žiūrim koks duomenų tipas

        my $mime = $part->mime_type;

        if($mime =~ /jpeg/) {  # jei tai JPG...

             # sukuriam bylos pavadinimą pagal unix timestamp

                my $url = time() . '.jpg';

                my $fh = FileHandle->new($output_dir . '/' . $url, 'w');

                binmode($fh);

                my $ifh = $part->open('r');

             # perkopijuojam bylas kur reikia

                $fh->print($ifh->getlines);

                $_->close for($fh, $ifh);

             # įterpiam į duombazę

                my $sql = "INSERT INTO moblogs SET kada=NOW(), url='$url'";

                $dbh->do($sql);

        } else {

          # Jei tai ne JPG, praleidžiam šią dalį

                next;

        }

}

$dbh->disconnect;

Įdomūs lingvistiniai pastebėjimai

Pastarosiomis dienomis internete sklando šis tekstas:

Aoccdrnig to a rscheearch at an Elingsh uinervtisy, it deosn’t mttaer in waht oredr the ltteers in a wrod are, the olny iprmoetnt tihng is taht frist and lsat ltteer is at the rghit pclae. The rset can be a toatl mses and you can sitll raed it wouthit a porbelm. Tihs is bcuseae we do not raed ervey lteter by it slef but the wrod as a wlohe.

Komentarų kaip ir nereikia ;-) Tiesa, lietuvių kalboje suprasti sudarkytus žodžius yra žymiai sunkiau (nes turim mes galūnes, be to mūsų žodžiai ilgesni). Štai parašiai perlinį skriptuką kuris išdarko žodžius:

#!/usr/bin/perl -w
use strict;

while (<>) {
        s/([^[:punct:][:space:][:digit:]]+)/keichiam($1)/ge;
        print;
}

sub keichiam {
        my @w = split //, $_[0];
        my $p = shift @w;
        my $l = pop @w;
        my %h;
        $h{$_} = rand for @w;
        @w = sort { $h{$a} <=> $h{$b} } @w;
        $p .= $_ for @w;
        $p.$l;
}

PHP fanams internete yra ir PHP versija (pradinis kodas).

Kas svarbiausia šablonų varikliams

Nuskaičiau šiandien PHP forume įdomią diskusiją apie tai kas svarbiausia PHP šablonų varikliuose (ačiū scooox už nuorodą). Labiausiai prieštaringų minčių man sukėlė citata O jei template nera svarbiausia greitis... tai kas tada svarbu? Navarotai? Jei taip – tada tu grybas. Tiesą sakant „navarotai“ yra labai svarbu. Ir turbūt svarbiausia (na, jei greitis nėra visiškai šliaužiantis). Gyvename tokiais laikais kai kompiuterio laikas yra pigus, o programuotojų laikas kainuoja brangiai, tad aš geriau rinkčiausi lėtesnę šablonų sistemą (na, ne tris kart lėtesnę, bet tarkim iki 50% lėtesnę) jei su ja man būtų žymiai lengviau programuoti. Šablonų kodas vis tiek neužima labai daug laiko, tad geriausiu atveju bus sutaupoma keletas dešimčių tūkstantųjų sekundės kiekvienai užklausai. Sakoma, kad lašas po lašo ir akmenį pratašo, o centą pridėjus prie cento susidaro milijonai, bet abejoju ar šie palyginimai čia tinka. Na, jei svetainė gauna po 10 užklausų per sekundę, gal tada ir bus pastebėtas šioks toks skirtumas kokį šablonų variklį naudosime, bet kiek yra svetainių, kur užklausos ateina po 10 per sekundę? Juk tai beveik milijonas užklausų per dieną (heh, aš esu laimingas kai gaunu kokį tūkstantį ;)

Tad manau, jog šablonų „benchmarkinimas“ yra per daug sureikšminamas. IMHO aišku ;)

Perlo „range“ operatorius

EnC manęs PHP forume paprašė paaiškint, kaip veikia Perlo „range“ operatorius. Nesinori PHP forumą teršti perliniais
dalykais, tad bandysiu tai paaiškinti čia. Beje, visa tai ką čia rašau galima rasti Perlo dokumentacijoje (konsolėje tereikia surinkt perldoc perlop).

Perlo „range“ operatorius žymimas dviem taškais, ir reiškia faktiškai du dalykus. Pirmoji reikšmė yra labai paprasta –
parašius 1..10 gausime reikšmių nuo 1 iki 10 sąrašą (list). Būtent ši operatoriaus reikšmė naudojama masyvų kontekste
(list context – kai reikia jog išraiška grąžintų masyvą, o ne skaliarą). Šitaip labai lengvai galima formuoti masyvus:

my @masyvas = 1..10;
# tas pats kaip @masyvas = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

Tačiau pats populiariausias šio dalyko panaudojimo būdas yra cikluose, nes vietoj sunkiai įskaitomo

for($i = 1; $i <= 10; $i++) {
# ... kažką darom 10 kartų
}

galima parašyti trumpai ir aiškiai:

for(1..10) {
# ... kažką darom 10 kartų
}

Kitas dažnas šio operatoriaus panaudojimas tame pačiame kontekste yra masyvų dalijimas (slice):

my @foo = (1, 2, 3, 4, 5, 6);
my @bar = @foo[3..5];
# @bar dabar yra (4, 5, 6);
my @baz = @foo[3..$#foo];
# @bar dabar irgi yra (4, 5, 6);

„Range“ operatoriui galima perduot ne vien skaitmenis, bet ir simbolių eilutes (pagal tam tikrą algoritmą bus didinami simbolių eilutės ASCII kodai), tad šis Perlo sakinys atspausdins visą anglišką abėcėlę:

print for 'a'..'z';

Arba tiesiog:

print 'a'..'z';

Vienas geriausių šio operatoriaus pliusų yra tas, kad jis neužsigrobia daug atminties yra intervalo „neišplečia“ atmintyje jei to būtinai nereikia, tad for(1..1000000) {...} nesukuria laikinojo masyvo su milijonu įrašų.

Jei intervalų sudarymas iš simbolių eilučių atrodo ganėtinai magiškai, tai patys didžiausi stebuklai prasideda tada, kai
„range“ operatorius naudojamas skaliariniame kontekste (kai išraiška turi grąžinti skaliarą, o ne masyvą). Dažniausiai taip šis operatorius naudojamas if sąlygoje. Šis operatorius grąžina 0 (false) iki tol kol kairė šio operatoriaus pusė pradeda
grąžint true, tada grąžina true iki tol kol dešinė pusė pradeda grąžint true. Lengviausia turbūt suprast pavyzdžiu:

while(<>) {
print if /PRADZIA/../PABAIGA/;
}

Šis kodas skaito iš bylos eilutes, ir spausdina tik tas, kurios yra tarp eilučių, atitinkančių įpraiškas /PRADZIA/ ir
/PABAIGA/. Tarkime jei byla bus:

foo
bar
PRADZIA
kazkas
dar
PABAIGA
nu
gi

bus atspausdinama tik kazkas ir dar (nespausdina kol neatitinka įpraiškos /PRADZIA/, o tada spausdina iki tol kol atitinka įpraišką /PABAIGA/) Magija čia nesibaigia. Jei vietoj įpraiškos įrašysim skaičių, jis bus magiškai lyginamas su $., kuris reiškia eilutės numerį. Tad kodas

print if 101..200;

atspausdins antrąjį šimtą eilučių.

Apache::DBI

Hmm.. aišku bėdos su MySQL nesibaigia. to $dbh ||= triuko nepakako, teko skripto gale nutraukinėt ryšį su MySQL naudojant $dbh->disconnect; — tai veikia gerai, bet niekas nebekešuojama.

Ir čia į pagalbą atėjo Apache::DBI. Pasirodo užtenka jį užkrauti httpd.conf failiuke ir magiškai visos jungtys su MySQL tampa ‘persistant‘. Smagu ;)

Kas bus po objektinio programavimo?

Žmonės kalba, kad objektinis programavimas pradeda atgyventi. Tai jau praeito dešimtmečio technologija (hm… PHP5 tuo tarpu iš naujo atradinėja objektiškumą), ir reikia ieškoti jai pakaitalų. Na bent jau taip mano American Scientist. Jų straipsnyje sakoma, kad ateitis slypi keistuose dalykuose kaip ‘Pattern oriented programming’, ‘qualities without a name’ ir ‘extreme programming’.

Šiaip idėja įdomi. Parašai keletą tų ‘patterns’, ir jie patys susilipdo į programą. Programuotojų rojus? Galbūt. Pažiūrėsim. Tuo tarpu aš einu toliau rašyt makaroniško kodo.

Kodo stiliai

Vat priėjom šiokį tokį ideologinį karą apie teisingą kodo stilių. Aš visad kodą formatavau pagal K&R stilių, nes pats mokiausi programavimo iš jų puikios knygos apie C. Kažkaip kitiem labiau patinka Allman’o stilius, nors man jis per daug vertikaliai išsidėsto. Na ir man reikia 8 tarpų tabo. Čia labai subjektyvu, bet man taip geriausia.

Įprastinių išraiškų straipsnio papildymai

Taip, žinau. Vis neprisiruošiu pabaigti normaliai to straipsnio apie RegExpus. Iki šiol jis buvo labai nepilnas. Šiandien bent jau pabandžiau labai labai (na tikrai jau labai) trumpai sudėti informaciją apie tai, ko dar neminėjau jame. Ten faktiškai gale tik krūva pavyzdžių (netgi ne krūva… tiesiog keletas) dabar. Reikėtų juos aprašyt normaliai. Na o po to reiktų ir antrą dalį parašyt, apie ‘extended’ sintaksę. Ir pritaikyt viską Perlui ;).