Switch galimybės Perle

Kaip žinia, Perlo kalboje nėra switch konstrukcijos. Gal
kam ir keista, bet yra keletas (kaip visada Perle yra keletas būdų
atlikti tam pačiam daiktui ;) būdų kaip apsieiti be to.
Pirmas būdas gana man bjaurokas, nes naudoja goto (nors
šiaip tai labai primena įprastą switch:


SWITCH:{ # switch($option)
    $_='CASE_'.$option; eval("goto $_"); $_= 'DEFAULT' if ($@); goto $_;

        CASE_1:    print "Case 1\n";
                last SWITCH;
        CASE_4:    print "Case 4:\n";
                last SWITCH;
        CASE_FOUR:    print "Case FOUR\n";
                last SWITCH;
        CASE_9:    print "Case 9\n";
                return "Because I can";
        CASE_WHAT:    ;
        CASE_STR:    print "Case STRING on $option\n";
                last SWITCH;
        DEFAULT:    print qq|Undefined Case "$option"\n|;
    }    

Dažniausiai naudojama nuorodų lentelė (dispatch table):


my %switch = (
    default             => \&list_ads,
    submit_payment      => \&save_payment,
    set_duration        => \&set_duration,
    go_here             => sub {print 'hi'},
);
$switch{$value} ?
    $switch{$value}->() :
    $switch{'default'})->();

Dar vienas būdas:

for ($val)
{
    /^1$/       && do { do_something };
    /^abc$/     && do { do_something_else };
    /^d{2,4}$/ && do { do_something_further };
}

Arba galima naudotis Switch
moduliu. There is more than one way to do it.

XHTML 1.1

Vakar kaip įprasta skaitinėjausi W3C standartus ir pamaniau, kad gal vertėtų pereiti
prie XHTML 1.1 standarto. Didžiausias šio standarto
skirtumas nuo ankstesnių versijų yra tas, kad reikia nurodyti
Content-type: application/xhtml+xml. Pasirodo jeigu
nurodomas senas text/html tipas tai naršyklės
interpretuoja kodą kaip įprastą HTML košę, net jei tai ir yra standartus atitinkantis
XML. Priversti naršyklę
dirbti XML režimu nelengva – būtent tam ir reikia specialaus
Content-type. Tiesa, XML parseris yra negailestingas – viena
klaidelė ir matysis tik klaidų pranešimai. Bet gana smagu turėtų būti
ant peilio ašmenų ;)

Tiesa, ne viskas taip paprasta kad tik pakeiti
Content-Type ir viskas. XML neturi jokios prasmės naršyklei, tad jį parodo kaip
XML medį. Tad reikia
priskirti stilius naudojantis ne sena gera <link>
žyme o štai tokia konstrukcija:

<?xml-stylesheet alternate="no" href="alt.css" title="alt" 
media="screen" type="text/css"?>

Bet problemos tuo nesibaigia. Jos tik prasideda ;) Mat XML nežino, jog tarkim
<p> yra paragrafas ir jį reikia vaizduoti kaip bloką.
Arba aš kažką ne iki galo padariau su DTD arba pačiam reikia didelį CSS rašytis. tad atidedu vėlesniam laikui ;)

Oh, beje IE visai nesusitvarko su application/xhtml+xml
ir siūlo saugoti jį (arba atidaryti su kita programa… tarkim Mozilla
– truputį ironiška ;)

Graži Perlo programėlė

Kas čia vis sako, kad Perlo programos neįskaitomos dėl to kad pilna
visokių @$%&*; ? Pasirodo, kad galima rašyti ir labai
švarias ir tvarkingas Pelro programas – Perlmonksuose blockhead parašė
vieną geresnių
obfuscated“ programėlių
:

#!/usr/bin/perl

not exp log srand xor s qq qx xor
s x x length uc ord and print chr
ord for qw q join use sub tied qx
xor eval xor print qq q q xor int
eval lc q m cos and print chr ord
for qw y abs ne open tied hex exp
ref y m xor scalar srand print qq
q q xor int eval lc qq y sqrt cos
and print chr ord for qw x printf
each return local x y or print qq
s s and eval q s undef or oct xor
time xor ref print chr int ord lc
foreach qw y hex alarm chdir kill
exec return y s gt sin sort split

Šito kodo pervarymas per O::Deparse irgi neduoda naudos, netgi kaip tik dar viską supainioja:

moxliukas@www:~$ perl -MO=Deparse,q obfu.pl
print ' ' and eval " undef or oct xor\ntime xor ref print chr int ord lc\nforeac
h qw y hex alarm chdir kill\nexec return y " gt sin sort(split(" ", $_, 0)) unle
ss not exp log srand xor s// /x xor s/ / length uc ord and print chr\nord for qw
 q join use sub tied q/ xor eval $_ xor print ' ' xor int eval " cos and print c
hr ord\nfor qw y abs ne open tied hex exp\nref y " xor scalar srand print(' ') x
or int eval " sqrt cos\nand print chr ord for qw x printf\neach return local x "
;
obfu.pl syntax OK

Atrodo visa idėja yra gudrus xor naudojimas ir alternatyvių simbolių eilučių delimiterių nešykštėjimas. Reikės pasiknist dar giliau truputį ;)

CSS tekstų dydžiai

pbg
rašant apie šriftų dydžius
EnC pamanė
jog CSS nurodomi šriftų dydžiai yra blogai
, nes juos naudojant
neveikia šrifto sumažinimo ar padidinimo galimybės naršyklėse. Tai ne
visai tiesa. Štai pavyzdys:

<style>
p.pixeliais  { font-size: 14px; }
p.emais      { font-size: 1em;  }
p.procentais { font-size: 100%; }
p.taskais    { font-size: 14pt; }
</style>
<p class="pixeliais">Čia nurodyta pikseliais</p>
<p class="emais">Čia nurodyta emais</p>
<p class="procentais">Čia nurodyta procentais</p>
<p class="taskais">Čia nurodyta taškais</p>

Mozilla didina šriftus visais šiais atvejais (View->Text
Zoom
), tuo tarpu IE pikseliais ir taškais nurodytus šriftų
dydžius palieka nepakeistus (View->Text Size). Nežinau
kaip tiksliai turėtų būti teisinga (t.y. ar turėtų didinti šriftų
dydžius jei jie nurodyti pikseliais), bet jau senokai būtent dėl šitos
savybės stengiuosi nenaudoti px ir pt, o
stengtis viską nurodyti procentais arba em‘ais.

<FIELDSET>

Bevaikščiodamas kažkurioje svetainėje aptikau įdomų
rėmelį aplink tekstą
. Iš pradžių pagalvojau kad čia su CSS padaryta (na, tekstui uždėt
galima position: relative; top: -20px;, truputį pažaist su
z-index ir nustatyt background-color: white
su padidintomis paraštėmis), bet pasirodo kad naudojamos
<FIELDSET> ir <LEGEND> žymės.
Kažkaip nemaniau kad jos priklauso W3C standartams , bet klydau
– jos yra HTML4.0 standarto dalis
. Kasdien vis ką nors naujo
sužinai :)

Kibiras nuorodų (3)

Aš vis dr gyvas. Nors beveik palaidotas po darbais, universitetais,
mokslais ir šiaip visokia veikla. Čia jau matau sunerimot, kad merginą
būsiu susiradęs ;) Tai va, nė velnio, štai jumi krūva nuorodų:

Mozillos raktiniai žodžiai

Vakar kilo man nenumaldomas noras pasidaryti taip, kad Mozilloje būtų
galima ieškoti ne tik per Google, bet ir
per CPAN, nes labai dažnai tenka
ten eiti ir įvedinėti paieškos žodžius rankomis. Sprendimą radau, ir jis
labai paprastas ir puikus. Einam į Bookmarks->Manage
Bookmarks
, darom New Bookmark, į Name
įrašom CPAN, o į Location
http://search.cpan.org/search?query=%s&mode=all.
Spaudžiam OK, dabar susirandam kur atsirado tas mūsų naujai
sukurtas bookmarkas, spaudžiam ant jo dešiniu pelės klavišu,
išsirenkam Properties ir lauke Keyword įrašom
cpan. Paspaudę OK viską uždarom ir adreso
laukelyje galim dabar parašyt cpan ACME::Pony ir Mozilla
turėtų automagiškai ieškoti ACME::Pony modulio CPAN
svetainėje.

lwpcook vertimas

lwpcook – libwww-perl bibliotekos receptai

Šiame dokumentacijos skyriuje galima rasti tipinius
libwww-perl naudojimo pavyzdžius. Išsamesnės informacijos

ieškokite individualių modulių dokumentacijose.

Visi šie pavyzdžiai yra pilnos programos.

GET

Naudojantis šia biblioteka labai lengva parsiųsti dokumentus iš
tinklo. LWP::Simple modulis turi funkciją

get(), kuri grąžina URL turinį:

use LWP::Simple;
$doc = get 'http://www.linpro.no/lwp/';

Arba tiesiai iš konsolės viena Perlo eilute:

perl -MLWP::Simple -e 'getprint "http://www.linpro.no/lwp/";'

O štai taip galima parsisiųsti naujausią Perl versiją:

perl -MLWP::Simple -e '
   getstore "ftp://ftp.sunet.se/pub/lang/perl/CPAN/src/latest.tar.gz",
            "perl.tar.gz";'

Be to galbūt jums norėsis sužinoti kur yra artimiausiais CPAN
veidrodis:

perl -MLWP::Simple -e 'getprint 
"http://www.perl.com/perl/CPAN/CPAN.html";'

Užteks šitų paprastų pavyzdžių! LWP objektinė sąsaja leidžia
kontroliuoti visą bendravimo su nutolusiu serveriu procesą.

Naudojantis šia sąsaja galite pilnai kontroliuoti headerius bei
nurodyti ką daryti su gautais duomenimis.

use LWP::UserAgent;
$ua = LWP::UserAgent->new;
$ua->agent("$0/0.1 " . $ua->agent);
# $ua->agent("Mozilla/8.0") # arba apsimetam, kad mes labai pažengusi 
naršyklė

$req = HTTP::Request->new(GET => 'http://www.linpro.no/lwp');
$req->header('Accept' => 'text/html');

# siunčiame užklausą
$res = $ua->request($req);

# patikriname ką gavome
if ($res->is_success) {
   print $res->content;
} else {
   print "Klaida: " . $res->status_line . "\n";
}

HEAD

Jei tik norite pažiūrėti ar dokumentas egzistuoja (t.y. ar geras URL)
pabandykite štai tokį kodą:

use LWP::Simple;

if (head($url)) {
   # ok, dokumentas egzistuoja
}

Iš tikrųjų head() funkcija grąžina sąrašą
meta-informacijos apie apie dokumentą. Pirmos trys šio sąrašo

reikšmės yra dokumento tipas, jo dydis ir amžius.

Norint turėti daugiau kontrolės bei pasiekti visus headerius
reikia naudoti objektinę sąsają, kuri buvo jau

aprašyta šiek tiek aukščiau GET metodui. Tiesiog visur
pakeiskite GET į POST.

POST

Procudūrinės sąsajos duomenų siuntimui POST metodu į www serverį
nėra. Tam reikai naudoti objektinę sąsają. Dažniausiai

pasitaikanti POST operacija yra WWW formos užpildymas:

use LWP::UserAgent;
$ua = LWP::UserAgent->new;

my $req = HTTP::Request->new(POST => 
'http://www.perl.com/cgi-bin/BugGlimpse');
$req->content_type('application/x-www-form-urlencoded');
$req->content('match=www&errors=0');

my $res = $ua->request($req);
print $res->as_string;

Tinginiai dažniausiai naudoja HTTP::Request::Common
modulį, kuris teisingai, su visomis išvengties sekomis,

suformuoja POST užklausos duomenis bei nustato reikiamą
content_type:

use HTTP::Request::Common qw(POST);
use LWP::UserAgent;
$ua = LWP::UserAgent->new;
my $req = POST 'http://www.perl.com/cgi-bin/BugGlimpse',
               [ search => 'www', errors => 0 ];
print $ua->request($req)->as_string;

Su libwww-perl biblioteka ateinanti POST programa irgi
gali būti naudojama duomenims siųsti POST

protokolu.

Proksiai

Proksiai kai kur naudojami dėl ugniasienių arba
kešavimo sumetimų. kartu naudojantis proksiais

galima pasiekti duomenis per libwww-perl nepalaikomus (arba prastai
palaikomus ;-) protokolus.

Prieš siunčiant užklausas jums reikia nurodyti proksių
nuostatas:

use LWP::UserAgent;
$ua = LWP::UserAgent->new;
$ua->env_proxy; # proxy nuostatos iš aplinkos kintamųjų
# arba
$ua->proxy(ftp  => 'http://proxy.myorg.com');
$ua->proxy(wais => 'http://proxy.myorg.com');
$ua->no_proxy(qw(no se fi));

my $req = HTTP::Request->new(GET => 'wais://xxx.com/');
print $ua->request($req)->as_string;

LWP::Simple modulis automatiškai išsikviečia ir
env_proxy(). Programos kurios jau naudoja

$ua->env_proxy() metodą dažniausiai nenaudos
$ua->proxy() ir $ua->no_proxy()

metodų.

kai kurie proksiai reikalauja, kad naudotumėte prisijungimo
vardą ir slaptažodį. Nesunku pridėti reikiamą

headerį rašant šitaip:

use LWP::UserAgent;

$ua = LWP::UserAgent->new;
$ua->proxy(['http', 'ftp'] => 
'http://username:password@proxy.myorg.com');

$req = HTTP::Request->new('GET',"http://www.perl.com";);

$res = $ua->request($req);
print $res->content if $res->is_success;

Pakeiskite proxy.myorg.com, username ir
password kuo nors tinkančiu jums.

Apsaugotų dokumentų pasiekimas

Dokumentai apsaugoti paprasta autorizacija gali būti pasiekiami taip:

use LWP::UserAgent;
$ua = LWP::UserAgent->new;
$req = HTTP::Request->new(GET => 'http://www.linpro.no/secret/');
$req->authorization_basic('vardas', 'slaptazodis');
print $ua->request($req)->as_string;

Kita alternatyva yra pasirašyti LWP::UserAgent subklasę,
kuri perrašo get_basic_credentials()

metodą. Kaip pavyzdį pasižiūrėkite lwp-request programą.

Sausainiukai

Kai kurios svetainės mėgsta pasižaisti su sausainiukais
(cookies). Pagal nutylėjimą LWP ignoruoja

visus sausainiukus, kuriuos duoda serveriai. Bet jeigu nurodysite
sausainių dėžutę, tai LWP saugos ir naudos

sausainiukus kaip tikra naršyklė:

use LWP::UserAgent;
use HTTP::Cookies;

$ua = LWP::UserAgent->new;
$ua->cookie_jar(HTTP::Cookies->new(file => "lwpcookies.txt",
                                     autosave => 1));

# o po to siunčiam užklausas kaip ir iki šiol
$res = $ua->request(HTTP::Request->new(GET => 
"http://www.yahoo.no";));
print $res->status_line, "\n";

Byla lwpcookies.txt palaipsniui didės, besilankant
svetainėse, kurios duoda jums sausainiukų.

HTTPS

Dokumentai pasiekiami per SSL lygiai taip pat kaip ir per http, jeigu
tik SSL modulis yra tinkamai įdiegtas (žiūrėkite

README.SSL libwww-perl distribucijoje). Jei SSL sąsaja
neįdiegta, bandydami pasiekti dokumentus per

HTTPS gausite klaidos pranešimus „501 Protocol scheme
‘https’ is not supported“.

Štai SSL naudojimo pavyzdys:

use LWP::UserAgent;

my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new(GET => 'https://www.helsinki.fi/');
my $res = $ua->request($req);
if ($res->is_success) {
    print $res->as_string;
} else {
    print "Failed: ", $res->status_line, "\n";
}

Veidrodžiai

Jeigu norite turėti veidrodines WWW serverio dokumentų kopijas,
bandykite paleisti panašią programėlę reguliariais

intervalais:

use LWP::Simple;

%mirrors = (
   'http://www.sn.no/'             => 'sn.html',
   'http://www.perl.com/'          => 'perl.html',
   'http://www.sn.no/libwww-perl/' => 'lwp.html',
   'gopher://gopher.sn.no/'        => 'gopher.html',
);

while (($url, $localfile) = each(%mirrors)) {
  mirror($url, $localfile);
}

Arba viena perlo eilute konsolėje:

perl -MLWP::Simple -e 'mirror("http://www.perl.com/", 
"perl.html")';

Jeigu dokumentas nebuvo nuo paskutinio karto nebuvo atnaujintas tai
jis ir nebus persiųstas.

Dideli dokumentai

Jei dokumentas kurį bandot gauti yra per didelis kad tilptų
atmintyje, tai turite du problemos sprendimo būdus. Galilte

liepti bibliotekai rašyti dokymento turinį į bylą (antras
$ua->request() argumentas yra byla):

use LWP::UserAgent;
$ua = LWP::UserAgent->new;

my $req = HTTP::Request->new(GET =>
              'http://www.linpro.no/lwp/libwww-perl-5.46.tar.gz');
$res = $ua->request($req, "libwww-perl.tar.gz");
if ($res->is_success) {
   print "ok\n";
}
else {
   print $res->status_line, "\n";
}

Arba galite apdoroti duomenis kai tik jie atvyksta (antras
$ua->request() argumentas yra nuroda į

kodą):

use LWP::UserAgent;
$ua = LWP::UserAgent->new;
$URL = 'ftp://ftp.unit.no/pub/rfc/rfc-index.txt';

my $expected_length;
my $bytes_received = 0;
my $res =
   $ua->request(HTTP::Request->new(GET => $URL),
             sub {
                 my($chunk, $res) = @_;
                 $bytes_received += length($chunk);
                 unless (defined $expected_length) {
                    $expected_length = $res->content_length || 0;
                 }
                 if ($expected_length) {
                      printf STDERR "%d%% - ",
                                100 * $bytes_received / $expected_length;
                 }
                 print STDERR "Gauta $bytes_received baitu\n";
                  # XXX Kažką reiktų daryti su gautu kąsniuku
                 # print $chunk;
             });
print $res->status_line, "\n";

Bangos dienoraščiai

Nagi paskatintas Nightblade komentaro apie lietuvišką blogosferą, nuėjau pasidaryti po
Bangos dienoraščius. Yra ten toks patogiai
padarytas skyrelis „Populiariausi
dienoraščiai
“, kuriame surašyti lankomiausi Bangos dienoraščių
įrašai (hmm… kodėl įrašai, o ne patys dienoraščiai? Kažkaip toje
Bangoje sąvoka „dienoraštis“ ištirpsta, nes ten faktiškai
privatus vieno žmogaus forumas gaunasi). Na, įspūdis tai ganėtinai
prastas – visiems rūpi tik įrašai, kur yra prisegtos nuotraukos,
bet šiaip pliurpalynės apie tai kad kažkas eidamas iš mokyklos namo
apsitaškė kelnes ar kad kažkieno vėžliukas pabėgo ir dabar jis dėl to
ruošiasi arba pirkt naują arba žudytis. Priklausomai nuo nuotaikos.
Rimto žurnalizmo ten nerasi ne vien kad su žiburiu bet ir su metalo
detektorium (aišku neieškojau nei su žiburiu nei su detektorium –
galbūt tiesiog rimti dienoraščiai neįdomūs statistiniam Bangos
skaitytojui ir niekada nepapuola į „populiariausiųjų“
sąrašus). Įdomu, yra kokia nors statistika, kas yra Bangos vartotojai?
Man atrodo kad statistiškai jie kokie 15-16 metų paaugliai ieškantys
romantikos ir ryškiai per dažnai vartojantys šypsenėles (ir dar velnias
žino ką).

Va labai geras vienas
iš dienoraščių įrašų
, maždaug ir apibūdinantis, kas yra sėkmingas
dienoraštis Bangoje (kalba netaisyta, lietuvybės nesudėjau):

Ogi pats rasyk ir rasyk, rasyk bet ka, bet kokiais
kiekiais, bet kada ir bet kur, rasyk nesamones ir samones, savo
isgyvenimus ir praradimus, rasyk… svarbiausiai, kad RASYTUM.

[…]

p.s. dar pavadinime reikia parašyti žodį
„FOTO“

Tad arba aš neklydau apie tai kad Bangoje dar blogiau nei dabar
lietBlogsuose arba jūs tuoj mane užfludinsit nuorodomis į
puikius analitinius kompiuterastinius dienoraščių įrašus Bangoje ;-)

RSS Lietuvos komercinėse svetainėse?

Kiekvieną dieną važiuodamas troleibusu į darbą ir iš jo esu įpratęs
skaityti arba dienoraščius nusiurbtus į mano Palmą arba lakstyti (na
žodis „lakstyti“ čia netinka… tiksliau būtų
„šliaužioti“) po WAP svetaines. Lietuviškajame WAP internete nėra labai kažko išskirtinio
(na, prieinama visa Banga, bet kažkaip tie visiškai
nekontroliuojami ir nuobodūs forumai ten nevilioja, o rimto
kompiuterastizmo ten nerasi), tačiau vis tiek kas kartą apsilankau OMNI Laike. Kai kurie OMNI Laiko
skyriai atrodo kaip normalios naujienų skiltys, bet labiausiai mane
domina weblogų (hmmm… reikia kokį nors lietuvišką žodį
sugalvot, nes „internetiniai dienoraščiai“ yra baisiai ilga
struktūra) stiliaus skiltys. Vat IT pasaulis yra viena iš jų.
Yra ten keletas žurnalistų, kurie kartais parašo taip, lyg rašytų savame
kompiuterastiniame dienoraštyje (turbūt labiausiai man įstrigusi pavardė
yra Darius Mikšys – sekasi gi žmonėms: pildo
weblogus ir dar pinigus už tai gauna ;-). Bet viskas ką norėjau
pasakyti yra ne apie tai. Man kilo idėja paprašyti jų idėti RSS feedus (kas bent
jau man tai būtų naudinga). Juk BBC
tai daro
, New York Times tai daro, visi tai daro. Tiesa,
įdomu kaip OMNI susitaikytų su savo turinio iškeliavimu už savo
svetainės ribų, nes jų autorinių teisių įspėjimas atrodo gana
grėsmingai:

Visa medžiaga pateikta OMNI vartuose yra UAB
„Omnitel“ nuosavybė. Kopijuoti, platinti be bendrovės
sutikimo draudžiama.

Mat jeigu jie pateikinės viską RSS formate, tai turbūt sumažės jų reklamos
žiūrimumas (nors šiaip tai aš sakyčiau jog yra kaip tik atvirkščiai
– žmonės vienu metu gali stebėti daugiau svetainių ir
nepražiopsoti ko nors įdomaus, tad jie pamatę įdomią antraštę kaip tik
skubės į svetainę perskaityti visos naujienos. O be to juk ir taip dabar
viskas pateikiama WML
formate, kur nesimato reklamos)

Įdomu ar verta jiems pasiūlyt šią RSS idėją?