Čekai vs. slovakai

Vakar buvo užvažiavę mūsų partneriai ir kolegos iš Čekijos, su kuriais po pokalbių darbe apie Čekijos akcijas ir makroekonominę situaciją praleidome ir vakarą vienoje Vilniaus užeigoje. Pokalbis dažnai sukosi apie įmones, apie verslą, apie visa tai, kas iš esmės mus ir sieja. Bekalbant su jais prisiminiau, jog esu susidaręs tokią nuomonę, jog Slovakija yra itin agrarinė, neišsivysčiusi, o žmonės ten labiau išlaikę tradicijas, labiau „kaimietiški“ ir „nuo dūšios“ nei Čekijoje. Nežinau, ar tai tik Kunderos knygų sudarytas įspūdis, tačiau kiek teko bendrauti su slovakais, šis mano požiūris lyg ir pasitvirtina (štai Bratislavos birža likvidumu tikrai nepasižymi). Kolegos čekai irgi patvirtino šį slovakų stereotipą: jų nuomone čekai yra vakarietiškesni, labiau kapitalistinio mąstymo, galvojantys apie pinigus. Tuo tarpu slovakai yra ramesni, kaimiškesni, bet žymiai šiltesni ir nuoširdesni. Čekų nuomone, slovakai labai paprasti ir nesididžiuojantys. Taigi, mano slovakų stereotipas tapo dar stipresnis.

Perliška vartotojų sistema

Skaičiausi čia neseniai apie Perlo modulį Class::DBI ir šiandieną sumaniau jį šiek tiek išbandyti. Šis modulis yra duomenų bazės objektinė abstrakcija, ir viską daro tokiame aukštame lygyje (t.y. taip toli nuo pačios duomenų bazės), kad norint ja naudotis net nereikia mokėti SQL (OK, OK, SQL visada pravartu mokėti, bet labai paprastiems dalykams gali to ir neprireikti). Taigi išbandymui sugalvojau pasirašyti vartotojų prisijungimo sistemą.

Class::DBI priverčia viską apgalvoti ir išdėlioti objektiškai, į atskirus modulius, tad atsiranda krūvos mažų failiukų, kuriuos reikia dėti kažkur į atskirą lib direktoriją. Bet pirma pradėkim nuo SQL lentelės:

CREATE TABLE `vartotojai` (
  `vartotojoid` int(11) NOT NULL auto_increment,
  `login` varchar(40) NOT NULL default '',
  `pass` varchar(32) NOT NULL default '',
  `status` int(11) NOT NULL default '0',
  `vartotojaskada` timestamp(14) NOT NULL,
   PRIMARY KEY  (`vartotojoid`),
   UNIQUE KEY `login` (`login`)
) TYPE=MyISAM PACK_KEYS=0 AUTO_INCREMENT=1;

Tiesa, login yra unikalus, tad realiai užtektų tik jį padaryt pirminiu raktu, bet man kažkodėl patinka turėti ir skaitinį vartotojo ID. Nevisai dar sugalvojau kodėl.

Pradedam apsirašinėti duomenų bazę. Byloje lib/Bilekas/DBI.pm saugom duomenų bazės prisijungimo duomenis:

package Bilekas::DBI;
use base 'Class::DBI';
Bilekas::DBI->set_db('Main', 'dbi:mysql:bilekas', "root", "");
1;

Apsirašome klasę Bilekas::Vartotojas ir išsaugom byloje lib/Bilekas/Vartotojas.pm:

package Bilekas::Vartotojas;
use base 'Bilekas::DBI';
Bilekas::Vartotojas->table('vartotojai');
Bilekas::Vartotojas->columns(All => qw/vartotojoid login pass status vartotojaskada/);
1;

Bilekas::Vartotojas modulyje užtenka tik nurodyti kurią SQL lentelę naudoti, bei kokie yra tos lentelės stulpeliai (jeigu būtų ir daugiau lentelių tai reikėtų nurodyti ir ryšius tarp jų)

Galvojant apie ateitį, reikėtų pasirašyti ir vieną pagrindinį modulį Bilekas.pm, kuris būtų atsakingas už bendrą visai svetainei kodą (reikiamų modulių užkrovimą, CGI objekto sukūrimą, sesijas ir pan). Štai ir Bilekas.pm:

package Bilekas;
use strict;
use CGI;
use CGI::Session;

BEGIN {
        use Exporter ();
	our (@ISA, @EXPORT);
        @ISA = qw/Exporter/;
        @EXPORT = qw/$q $s/;
}

our $q = new CGI;
our $s = new CGI::Session("driver:File", $q, {Directory => '/tmp'});

END {
	$s->close;
}
1;

Šiame pakete yra šiek tiek magijos, kurią vertėtų paaiškinti. Pačioje pradžioje yra užkraunami moduliai CGI ir CGI::Session. Toliau eina BEGIN blokas, kuriuo iš paketo Bilekas vardų srities (namespace) eksportuojami kintamieji $q ir $s – tai leidžia vėliau bet kurioje byloje parašius use Bilekas; iš karto naudotis jau sukurtais ir užpildytais kintamaisiais $q ir $s (viename iš jų yra CGI objektas, o kitame – sesijos objektas).

Kitomis dvi eilutėmis yra sukuriami minėtieji eksportuojami kintamieji, o po to seka END blokas, kuri yra vykdomas paskutiniu programos gyvavimo metu. Jo pareiga yra teisingai įrašyti visus sesijos duomenis į bylą, kad jie neliktų laikinojoje atmintinėje (tą daro $s->close;)

Kadangi turime šitus modulius, galima pradėti jais naudotis. Pirma parašome index.pl, kuris nesant užsiregistravusio vartotojo rodys formą, kurios pagalba galima prisijungti prie sistemos:

#!/usr/bin/perl -w
use strict;
use lib './lib';

# Mūsų parašytieji moduliai
use Bilekas;
use Bilekas::Vartotojas;

# Siunčiame HTTP antraštes (su sausainiuku su sesijos informacija)
print $s->header;

# Jeigu yra nustatytas sesijos kintamasis, pranešantis apie klaidą, tai ją išspausdiname
if($s->param("bilekas_error")) {
        print "<h1>!!! " . $s->param("bilekas_error") . " !!!</h1>";
	# Išspausdinę klaidos pranešimą ištriname šį sesijos kintamąjį, kad
	# nespausdintume klaidos keletą kartų
        $s->clear(['bilekas_error']);
}

# Jeigu yra nustatytas sesijos kintamasis 'user', reiškia vartotojas prisijungęs
if($s->param('user')) {
        print "Esi isilogines kaip UID <em>", $s->param('user')->{vartotojoid}, "</em>";
} else {
	# Vartotojas neprisijungęs, rodome prisijungimo formą
        print <<EOHTML;
        <form action="login.pl" method="post">
        <input type="text" name="user"><br>
        <input type="password" name="pass"><br>
        <input type="submit">
        </form>
EOHTML
}

Beliko parašyti patį prisijungimo kodą login.pl:

#!/usr/bin/perl -w
use strict;
use lib './lib';

use Bilekas;
use Bilekas::Vartotojas;
use Digest::MD5 qw/md5_hex/;

my $location = $q->referer || 'index.pl';

if ($q->param('user') && $q->param('pass')) {
        my $user = Bilekas::Vartotojas->retrieve(login => $q->param('user'),
                                                 pass  => md5_hex($q->param('pass')));
	if ($user) {
		$s->param('user', $user);
		$s->expire(user => "+15m");
	} else {
		$s->param('bilekas_error', "Blogas login/pass");
        }
}

print $s->header(-location => $location);

Sitepoint apie PHP::Strings

Harry Fuecks, PHPPatterns kūrėjas ir sitepoint PHP weblogo savininkas, pastebėjo minėtame webloge mano dabar palaikomą Perlo modulį PHP::Strings. Harry klaidingai mano, jog perlininkai priešiškai nusiteikę prieš PHP dėl to, kad pavydi jam sėkmės. Kiek teko bendrauti su viso pasaulio perlininkais, tai požiūris į PHP visada būdavo neigiamas ne dėl pavydo, o dėl to, kad PHP nelaikoma rimta kalba (dėl tokio įsitikinimo teisingumo, aišku, galima ginčytis, bet enterprise lygyje PHP vis dar neturi tokių stiprių pozicijų kaip Perl, Java ir panašiai). Na, tikiuosi neužvirs šventasis karas dėl mano palaikomo modulio. Juolab, kad stengsiuosi jį padaryti naudingesniu PHP programuotojams.

Santrumpų automatizavimas

Atsibodo kiekvieną kartą darant įrašą visoms santrumpoms <abbr> žymas dėlioti rankomis. Tad pasirašiau
Perlinį skriptuką, kuris visą tai atlikea automatiškai. Visą skriptą rašiau troleibuse važiuodamas namo ant Psiono
– vat dėl Perlo jį galima mylėti ;-)

Šitam automatizavimui išrinkau visas santrumpas, kurios buvo naudotos mano dienoraštyje. Visos jos čia – gal kam
pravers.

API	Application Programmer's Interface
ASCII	American Standard Code for Information Interchange
CGI	Common Gateway Interface
CMS	Content Management System
CPAN	Comprehensive Perl Archive Network
CSS	Cascading Style Sheets
CVS	Concurrent Version System
DDOS	Distributed Denial of Service
DOS	Denial of Service
DRM	Digital Rights Management
DTD	Document Type Definition
FOAF	Friend Of A Friend
GPL	GNU Public Licence
GPS	Global Positioning System
HTML	HyperText Markup Language
IP	Internet Protocol
IRC	Internet Relay Chat
JAPH	Just Another Perl Hacker
LCD	Liquid Crystal Display
LWP	Lib-Www Perl
MIT	Massachusetts Institute of Technology
MMS	Multimedia Messaging Service
PEAR	PHP Extension and Application Repository
PECL	PHP Extension Community Library
PHP	PHP: Hypertext Preprocessor
PMC	Perl Magic Cookie
POP3	Post Office Protocol version 3
PPM	Perl Package Manager
RC	Release Candidate
RDF	Resource Description Framework
RSS	Really Simple Syndication
SMTP	Simple Mail Transfer Protocol
SQL	Sequential Query Language
TCO	Total Cost of Ownership
TVS	Turinio Valdymo Sistema
URL	Universal Resource Location
W3C	World Wide Web Consortium
WAP	Wireless Application Protocol
WML	Wireless Markup Language
XFN	XHTML Friends Network
XHTML	eXtensible HyperText Markup Language
XML	eXtensible Markup Language
XSS	Cross Site Scripting
ssh	Secure SHell
yacc	yet another compiler compiler

Sesija baigias, grįžtu internetan

Vakar pagaliau baigėsi kai kurie deadlainai, o šios savaitės pradžioje baigėsi ir sesija, tad galima šiek tiek ramiau grįžti į internetinį pasaulį. Ta proga krūva nuorodų:

  • CSS hacks and filters – daugelio CSS gudrybių rinkinys vienoje vietoje (su labai naudinga lentele, rodančia kokiose naršyklėse jos (ne)veikia)
  • Mezzoblue – wanted: CMSDave ieško geros turinio valdymo sistemos, ir gauna
    daug labai naudingų atsakymų.
  • Web Services Project roles – IBM mano, jog web servisams sukurti reikia viso kaimo darbuotojų. Truputį primena man knygą, kurią dabar skaitau – Scott Adams „Dilbert and The Way of Weasel“
  • OneLook Reverse Dictionary – atvirkštinis žodynas: suvedi aprašymą ir jis bando pateikti žodį.
  • PerlGuts Illustrated – puikus pasiskaitymas tiems kas nebijo giliai sukišti rankas į Perlo vidurius.

Asmens::Kodas

The URL

http://moxliukas.esu.as/download/src/Perl/Asmens-Kodas-0.01.tar.gz

has entered CPAN as

file: $CPAN/authors/id/K/KU/KUDARASP/Asmens-Kodas-0.01.tar.gz

  size: 1859 bytes

   md5: 14269ea9efca41e0559951ac20152858

No action is required on your part

Request entered by: KUDARASP (Petras Kudaras)

Request entered on: Mon, 29 Dec 2003 09:07:23 GMT

Request completed:  Mon, 29 Dec 2003 09:09:13 GMT

Thanks,

-- paused, v460

Reikės dar padaryt normalesnį datų tikrinimą Asmens kodui :/