vps

Ma tot uit de ceva timp dupa un provider de vps-uri pe kvm sau pe xen, care sa fie in .ro si sa fie cat de cat ok. Si n-am gasit decat la niste preturi care mie imi par cam mari pentru ce ofera (min 30EUR la 512RAM, 10-20G disc) :-S

09. February 2012 · 4 comments · Categories: perl, tech · Tags: ,

Interpolarea

Daca n-am spus-o o repet: consider ca Perl este unul din cele mai abuzate limbaje si mai cred ca Perl pierde enorm de pe urma celor care scriu cod cu toate cele 4 picioare. Una din facilitatile importante, interpolarea variabilelor, este si una din cele mai abuzate. Mai ales ca toata lumea ajunge la print “Hello World !” .

Stim ce e aia interpolare: inlocuirea intr-un sir de caractere a unei variabile cu valoarea sa. Simplu. Interpolarea presupune ca la momentul rularii aplicatiei, inainte de a fi folosit, sirul de caractere este “cautat” de variabile si acolo unde acestea sunt gasite sunt inlocuite cu valoarile corespunzatoare. Asta se traduce prin resurse folosite de catre interpretor pentru a rula aplicatia. Exemplu:

#!/usr/bin/perl

  use common::sense;

  my $vremea = "cald si rau";

  sub main {
    print "Afara e $vremea\n";
  }

  main();

Daca rulam exemplul de mai sus, obtinem la output: “Afara e cald si rau”. Totul bine si frumos nu ? Sa stiti ca nu-i nici bine si nici frumos. Sa explicam:

  my $vremea = "cald si rau";

Linia de mai sus este risipitoare, pentru ca se folosesc ghilimele duble, ceea ce inseamna ca in sirul de caractere pot fi interpolate variabile. Chiar daca in exemplul de mai sus nu sunt interpolate variabile, la rulare, interpretorul de Perl va verifica daca in acel sir sunt variabile ce trebuie interpolate. Asta pana la urma se traduce in resurse folosite ineficient care inseamna bani aruncati pe fereastra, care inseamna energie irosita, care … Cum evitam aceasta situatie ? Folosim ghilimele simple, atunci cand nu este nevoie de interpolare:

  my $vremea = 'cald si rau';

Prin urmare, programul nostru arata acum cam asa:

#!/usr/bin/perl

  use common::sense;

  my $vremea = 'cald si rau';

  sub main {
    print "Afara e $vremea\n";
  }

  main();

Este ok ? Nu inca :) Chiar daca putem spune ca in cazul argumentului dat functie print, avem interpolare a unei variabile si mai mult avem si un newline (care apropos, nu ar fi interpretat ca newline in cazul folosirii ghilimelelor simple) putand sa justificam astfel folosirea ghilimelelor duble, o varianta mult mai eleganta (si teoretic mai rapida) a aceleasi linii ar fi:

  print 'Afara e ', $vremea, $/;

De ce spun ca este mai rapida ? Pentru ca nu se mai analizeaza nimic in plus: sirul de caractere ‘Afara e’ este copiat asa cum este, variabila $vremea oricum era procesata in ambele variante, iar in loc de \n avem $/ , care sunt oarecum similare. Prin urmare, castigam timpul pe care procesorul l-ar pierde analizand sirul de caractere din primul exemplu. Unde pierdem totusi ? In loc de un parametru, print primeste 3. Ceea ce inseamna niste iteratii in plus.

Exemplu (deloc rar) de abuz a limbajului Perl:

$a=752;
  $b=13;
  $r=5;
  $profit=($b-$r)*$a*1.24*1.10;

  print "din $b maturi au mai ramas $r si am incasat $profit\nS-au dat " . ($b-$r) . "bucati\n";

Codul de mai sus este suboptim si pe langa faptul ca nu sparge linia in elemente mai mici, mai logice si mai usor de citit, foloseste si concatenare de siruri ce pot contine variabile interpolate ceea ce mareste si mai mult timpul de rulare. Cum ar fi trebuit rescrisa linia cu print pentru a fi lizibila si prietenoasa ?

my $vandute = $b - $r;

  print <<'EOS';
  din $b maturi au mai ramas $r si am incasat $profit
  S-au dat $vandute bucati
  EOS

Pare un pic mai lizibila ? Eu zic ca da.

PS: Numele variabilelor din ultimul exemplu au fost intentionat alese, pentru a nu face nota discordanta cu restul codului.

08. February 2012 · 6 comments · Categories: perl, tech · Tags: , ,

Lizibilitatea

Puteti spune ca lizibilitatea este specifica tuturor limbajelor si ca nu-si are rostul intr-o serie de tips & tricks despre Perl. Eu zic ca isi are rostul, mai ales datorita faptului ca Perl este bland cu persoanele care il folosesc si le permite acestora sa-si manifeste creativitatea in moduri cu totul si cu totul noi.

Lizibilitatea, mai ales in limbaje in care se poate aluneca usor pe o panta “criptica” este deosebit de importanta. Adoptarea unui stil lizibil aduce beneficii mari mai ales in cazul aplicatiilor medii si mari. Principiile dupa care ar trebui sa se ghideze cineva care scrie o aplicatie trebuie sa includa cel putin:

  1. Folosirea de nume adecvate si relevante, pentru variabile, functii, metode, clase, etc.
  2. Indentarea codului conform standardelor;
  3. Gruparea in functii cu scop precis si specific;
  4. Reutilizarea codului;
  5. Folosirea tuturor avantajelor limbajului.
Toate aspectele de mai sus au relevanta doar aplicate corect si la locul potrivit ! Nu trebuie ca scopul unei aplicatii sa fie modul in care aceasta este scrisa !

Seria ‘asa nu’:

my ($v1,$v2);

print "Enter v1: ";
$v1=<>;
$v2 = $v1*1.12*1.24;
print "V2 este: $v2\n";

Seria ‘asa da’:

#!/usr/bin/perl

use common::sense;

my ($adaos, $tva);

sub init {
  #adaosul este de 10% iar TVA de 24%
  $adaos = 1.10;
  $tva = 1.24;
}

sub calculeaza_pret_vanzare {
  my $pret_achizitie = shift;

  return $pret_achizite * $adaos * $tva;
}

sub main {
  my $pret_achizitie;

  init();

  print 'Introduceti pretul de achizitie:',$/;
  $pret_achizitie = <STDIN>;

  print 'Pretul de vanzare este: ', calculeaza_pret_vanzare($pret_achizitie), $/;
}

main();

IMHO, al doilea cod sursa este foarte usor de inteles. Este cat se poate de clar din sursa ca vorbim de o aplicatie care calculeaza un cost, este clar care sunt variabilele, la ce folosesc unde se initializeaza si care e durata lor de viata. Din punct de vedere al utilizatorului, stie ce introduce, stie ce obtine. De asemenea, pornind de la un astfel de cod, este foarte usor de crescut o aplicatie. Trebuie doar sa urmati aceleasi principii.

PS: Sursele prezentate nu sunt exemplu absolut ci doar cu titlu de exemplu didactic.

07. February 2012 · Write a comment · Categories: ganduri, tech · Tags:

Sa stiti ca n-am renuntat la seria de tips pentru Perl, sunt inca articole in lucru. Pana atunci, sa va povestesc ce-am mai descoperit azi. Am nevoie sa scriu o aplicatie mica (care se va face maaare), care sa lucreze cu adrese IP. In principiu aplicatia trebuie sa ia de pe un router clasele de adrese IP exportate de routerul ala catre diversi neighbours, sa le bage intr-o baza de date si sa le zica cand se schimba ceva pe acolo. Ofc, din baza aia de date clasele de adrese IP se vor exporta prin diverse metode (webservices mostly) catre diverse aplicatii. Pare simplu nu ? O aplicatie triviala, care nu necesita cine stie ce chestii complicate. Asta in teorie, pentru ca in practica la jumatatea aplicatiei iti dai seama ca adresele alea IP nu sunt doar IPv4 ci si IPv6 :) Si asta schimba cu totul aplicatia. Pentru ca:

  • daca baza de date utilizata este MySQL, surpriza: MySQL are suport pentru IPv6 doar in MySQL 6.0, care nu e pe nici o distributie.
  • o adresa IPv4 impreuna cu netmask-ul asociat, pot fi stocate lejer in 2 campuri de 32 de bits fiecare. Super optimizare de stocare, indecsi rapizi, etc.
  • o adresa IPv6 poti sa o stochezi momentan doar ca sir de caractere. Si netmask-ul la fel. Nu mai avem nici optimizare la stocare, nici indecsi rapizi, nici macar etc (asta tot pe MySQL)
  • multe din modulele din CPAN (in special cele ce au bucati [sau sunt complet] in C) nu au suport pentru IPv6.
  • regexp-urile folosite pentru IPv4 nu mai merg. Trebuie altele.

Si tot asa. Pana la urma, tot am gasit ceva bun: Net::Subnet stie sa lucreze si cu IPv4 si cu IPv6 ;)

03. February 2012 · Write a comment · Categories: perl, tech · Tags: ,

use common::sense;

Nope. Nu e o gluma. Initial m-am uitat patrat cand am vazut in lista de dependente a unui modul Perl (despre care sper sa am ocazia sa povestesc odata). Dar dupa ce m-am uitat in pagina de manual, mi-a placut foarte mult ideea. Iar numele impreuna cu use sunt excelente :)

Pe scurt, common::sense “trage” dupa sine mai multe setari implicite, de bun simt. Citez din pagina de manual:

   # supposed to be the same, with much lower memory usage, as:
    #
    # use utf8;
    # use strict qw(vars subs);
    # use feature qw(say state switch);
    # no warnings;
    # use warnings qw(FATAL closed threads internal debugging pack
    #                 portable prototype inplace io pipe unpack malloc
    #                 deprecated glob digit printf layer
    #                 reserved taint closure semicolon);
    # no warnings qw(exec newline unopened);

Eu zic ca este super fain.

02. February 2012 · Write a comment · Categories: perl, tech · Tags: ,

Documentarea

Fiecare are motivele lui pentru fuga de documentarea codului sau mai rau, a aplicatiei in sine. Nu cred ca am intalnit inca pe cineva care sa spuna ca ii place sa scrie documentatie in cod. Cu toate acestea, documentarea codului este importanta mai ales pentru cei cu memoria scurta (adica eu). Codul trebuie mentinut, indiferent cat ne place sa sustinem contrariul. Un cod trebuie adus la zi, curatat sau modificat in functie de necesitati.

Eu am crescut cu interfata CLI in fata iar paginile de manual din Linux (man pages) mi-au fost cel mai bun prieten, mai ales ca atunci accesul la Internet era destul de lent (Iasi – Bucuresti, 256Kbps). Prin urmare primul lucru de care m-am bucurat atunci cand a trebuit sa documentez o aplicatie Perl a fost ca documentarea unei surse in Perl inseamna ca acea documentatie poate fi folosita in stilul man pages.

Aici sunt descrise foarte bine si pe larg directivele pe care le puteti utiliza pentru a documenta cat mai facil, util si clar un cod sursa. Pentru ca nu tot timpul este nevoie de documentare completa a codului si pentru ca sunt momente cand este nevoie doar de cateva fraze, o macheta de documentare de bun simt a unei aplicatii ar putea arata asa:

__END__

=head1 NAME

YARFA - Yet Another Rabbit Feeding Application

=head1 VERSION

0.1

=head1 DESCRIPTION

My app is B<the> feeding rabbits B<application>

=head1 SYNOPSIS

Just start the application in the background and it will
detect and feed all your rabbits automatically.

=head1 SUBROUTINES/METHODS

=head2 new()

Class constructor.

=head2 start()

Starts the feeding process

=head1 DEPENDENCIES

L<Rabbits>, L<Food>

=head1 CONFIGURATION AND ENVIRONMENT

You must point your rabbit location on Google Maps

=head1 INCOMPATIBILITIES

Only the blue eye rabbits can be fed by this application due to their
sensibility in daylight.

=head1 BUGS AND LIMITATIONS

If the application is started during the night, the rabbits will be fed
only on the second day.

=head1 SEE ALSO

L<Dogs>.

=head1 AUTHOR

John DOE C<< <john@doe.name> >>.

=head1 LICENSE AND COPYRIGHT

Copyright (c) 2011, John Doe C<< <john@doe.name> >>.
All rights reserved.

This module is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
See L<perlartistic>.

Macheta de mai sus se poate adauga pur si simplu la sfarsitul unui program in Perl si se poate vizualiza folosind: “perldoc sursa.pl”. Si mai fain este ca documentatia respectiva se poate exporta si in alte formate utilizand pod2{man,text,latex,html}. Sa stiti ca tag-urile puse de mine in exemplu nu sunt batute in cuie. Puteti trece orice atata vreme cat sunt relevante. Eu le-am pus pe cele de mai sus pentru ca eu consider ca sunt minimumul care ar trebui sa existe intr-un program OpenSource.

Hint ! Pod, chiar daca a fost gandit ca un markup language pentru Perl, poate fi folosit pentru a scrie orice informatie ;)

01. February 2012 · Write a comment · Categories: perl, tech · Tags: ,

Gruparea codului

Desi nu este dependenta de limbaj, gruparea codului in functii, este un aspect important care nu trebuie niciodata ignorat. In Perl cu atat mai mult cu cat limbajul permite folosirea sa intr-un mod creativ :)

Bad code:

   #!/usr/bin/perl

   use strict;
   use warnings;

   print "Hello world";

Good code:

   #!/usr/bin/perl

   use strict;
   use warnings;

   sub main {
      print "Hello world";
   }

   main();

Gruparea codului in functii ajuta la:

  • claritate: este mult mai usor pentru oricine, inclusiv pentru autor, sa parcurga un fisier sursa in care codul este grupat logic si rational in blocuri. Claritatea este unul din aspectele cheie intr-un cod sursa !
  • refactorizare: in cazul in care la un moment dat este nevoie de schimbat modul in care functioneaza o anumita functie insa nu si modul in care este apelata (parametri, rezultat intors), un cod grupat in functii este mai usor de refactorizat, oferind o privire de ansamblu mai larga;
  • documentare: un cod grupat in functii mici, este usor de documentat nefiind necesara explicarea tuturor pasilor/instructiunilor ci doar a blocului respectiv;
  • intretinere si depanare: in cazul gasirii de bug-uri, un cod modular va fi mai usor de intretinut si de depanat, functiile mici permitand o depanare rapida.
  • scalabilitate: atunci cand o aplicatie creste destul de repede si se impune “spargerea” sursei initiale in mai multe bucati, un cod sursa modular va facilita reorganizarea rapida a functionalitatilor comune intr-o noua forma (librarii, clase, etc).

Stiu ca subiectul este foarte larg si este mult de povestit, dar dupa cum spuneam si la inceput, ideea este sa povestesc tips & tricks care sa ajute, nu sa fac curs de Ingineria Programarii sau mai stiu eu ce altceva.

PS: Din experienta pot sa va spun ca oricand o aplicatie “de test” se poate transforma intr-un proiect la care sa lucrezi 2-3 ani (eu am patit-o de 2 ori ;)

Switch to our mobile site