Claudiu Persoiu

Blog-ul lui Claudiu Persoiu


Nu PHP 6 nu este aici… dar cum ramane cu 2013?

without comments

Aceasta este o retrospectiva a ultimului an.

In caz ca inca se mai intreba cineva, nu, PHP 6 nu a aparut si nici nu va aparea prea curand, probabil.

De ce este relevant? De cand am inceput acest blog am avut la final de an un post legat de PHP 6 si faptul ca acesta nu a fost lansat. In 2008 era o intrebare populara, dar nimeni nu mai crede asta acum, asa ca voi incheia acest subiect acum. Sa revenim la anul care s-a incheiat.

Aproape de jumatatea anului a fost lansata versiunea PHP 5.5, aceasta aducand in plus functionalitati cum ar fi: finally , generators si multe alte inbunatatiri.

Ca in 5.4, nu sunt functionalitati definitorii pentru limbaj. In aceasta noua versiune chiar sunt lucruri care pot fi inlocuite cu usurinta, dar daca sunt prezente, sunt bine venite.

Chiar daca PHP da dovada de multa dinamica in ultima vreme, cred ca in acest an cuvintele cheie au fost HTML5 si JavaScript.

HTML5 are parte de multe imbunatatiri, iar componente mai vechi incep sa creasca in popularitate. Firmele incep sa investeasca in jocuri care functioneaza in browser folosing WebGL. Chiar si jocuri mai vechi sunt portate catre platforma, folosind tehnologii cum ar fi asm.js.

Si, pentru ca am vorbit de jocuri, mi se pare foarte interesant cum doar acum 5-7 ani jocurile bazate pe JavaScript erau destul de simpliste, iar acum sunt comparabile cu cele de pe PC sau console.

Cred ca revolutia web, pe care multi o asteptau, incepe sa prinda avant. In sfarsit Web-ul este o platforma in adevaratul sens al cuvantului si JavaScript un limbaj cu adevarat apreciat.

Succesul se datoreaza tuturor partilor, nu mai este vorba doar de ECMA sau doar de producatorii de browsere, acum este o adevarat dinamica. Revolutia Web este in plina desfasurare!

Cand vine vorba de backend, lumina reflectoarelor a fost asupra Node.js. Acesta incepe sa devina un jucator important. Au aparut frameworkuri noi si nu mai este o platforma folosita predominant de hackeri dornici sa exploreze tehnologii noi, ci si de companii mari, cum ar fi PayPal, LinkedIn si Yahoo, oferind un vot de incredere pentru acesta. Cred ca Node.js incepe sa-si gaseasca locul si o nisa de piata, iar eu, un fan JavaScript, nu pot sa fiu decat incantat.

Un avantaj al Node.js este ca nu trebuie sa ai grija mai multor versiuni de JavaScript, asa cum este necesar in browser. Asta permite folosirea ultimelor facilitati ECMA in mod liber, un mediu in care poti dezvolta JavaScript fara dureri de cap.

Tehnologic vorbind, a fost un an foarte interesant pentru web development.

In final, va doresc tuturor un 2014 extraordinar de bun!

Written by Claudiu Persoiu

19 January 2014 at 11:10 PM

Posted in Diverse

Tagged with , , ,

Codul epic din filme

without comments

In filmele unde sunt prezenti si hackeri, apare cod sursa care curge in rauri pe ecran. Pare important, pare sa fie un geniu in calculatoare care se pregateste sa revolutioneze ceva.

Te-ai intrebat ce este codul acela epic din filme? John Graham-Cumming a facut o colectie de filme si codul sursa folosit in acestea: http://moviecode.tumblr.com/.

Written by Claudiu Persoiu

5 January 2014 at 12:07 PM

Posted in Diverse

Appcelerator Titanium – cateva impresii

without comments

Nota: Titanium si PhoneGap sunt doua platforme pentru dezvoltarea de aplicatii hibride pentru mobil. Aceste aplicatii nu sunt scrise in limbajul de programare nativ telefonului, dar pot fi distribuite pe mai multe platforme mobile.

Recent, am publicat pe Github cea mai noua si extraordinara platforma de teste, Just-Quizzing pe numele ei. Am facut-o ca sa o folosesc eu personal, dar pentru ca am gasit cativa colegi care au considerat-o utila, am facut-o publica.

In versiunea initiala foloseam SL4A pentru a publica aplicatia pe telefonul meu mobil cu Android. Aveam nevoie de un mod in care sa folosesc aplicatia cand sunt in miscare si nu am acces la Intenet. Din pacate nu exista actualizare automata pentru teste. Am sperat ca SL4A va avea o directie mai clara in timp, dar platforma si-a pierdut din elanul initial, iar eu am decis sa scriu o aplicatie mobila.

Am avut de ales intre PhoneGap si Titanium. In trecut am folosit PhoneGap pentru ca marimea aplicatiei era prea mare in Titanium, dar am zis sa ii mai dau o sansa. In 2011, cand am mai scris despre Titanium, marimea unei aplicatii de baza era aproximativ 4M. In ziua de azi nu mi se mai pare chiar atat de mare, desi este maricica.

Perspectiva va fi in special pentru Android, desi aplicatia a fost facuta sa fie compatibila si cu iPhone.

Am folosit SDK 3.1.3, fara framework-ul Alloy.

Alloy are si el curba lui de invatare si am vrut sa o evit. Scopul aplicatiei era sa fie o versiune portabila a testelor de pe server si nu am vrut sa fac o investitie foarte mare de timp.

Timpul total de dezvoltare a fost putin mai mult de o saptamana.

Prima parere

Lucrurile nu merg chiar asa cum te astepti, nu ai foarte multa flexibilitate. Din timpul total alocat, mai mult de un sfert am incercat sa fac un “flyout menu”, asa cum au aplicatiile ca: Facebook, Google Plus si Youtube. A fost un dezastru total! Singurele variante care chiar pareau sa mearga au fost folosirea unui modul extern sau folosirea widgetul-ui din Alloy.

Se pare ca la conversia dintre coordonatele relative, unde utilizatorul a atins elementul curent, la punctul efectiv, unde esti pe ecran, exista o discrepanta mare si este imposibil sa faci un efect decent de deschidere a meniului. Intr-un final am renuntat total la acest efect.

Viteza nu este chiar atat de buna cand vine vorba de randare de elemente. Sincer, ma asteptam la o viteza mai buna. Exista mici trucuri care se pot face, de exemplu sa preincarci view-urile inainte sa le afisezi, dar pentru asta trebuie sa interpretezi cam ce va face utilizatorul in continuare, lucru care nu este posibil mereu.

Un alt elemente care m-a deranjat este ca la apasarea butonului de meniu pe Android nu poti pune o actiune anume, sa zicem sa deschida meniul lateral de care vorbeam anterior. In PhoneGap de exemplu, nu se va deschide nici un meniu, acesta trebuie construit din HTML de la zero.

Cand au aparut, Titanium se laudau ca poti dezolta o data si distribui pe mai multe platforme. Acum am avut surpriza ca nu mai au aceasta abordare. In Kitchen Sink, aplicatia care demonstreaza facilitatile platformei, fiecare tip de platforma initializeaza aplicatia in fisierul ei. Unul dintre motive este ca design-ul se face dinamic daca nu vrei sa folosesti Alloy, nu prin fisiere de layout.

Printre primele lucruri pe care le-am incercat cu Titanium a fost sa vad cat este marimea unei aplicatii simple de “Hello World”. Impachetata, aplicatia ocupa ~8.5M, instalata pe telefon ~16M. Nu stiu ce parere aveti voi, dar mie mi se pare foarte mult! Ciudat este ca aplicatia mea finala ocupa ~8.4M impachetata si ~16M instalata, aproape identic cu aplicatia originala. Motivul este simplu, imaginile puse de mine ocupa cu cativa kb mai putin, rezultand in final o aplicatie putin mai mica decat aceea de la care am pornit.

Dar de ce ocupa o aplicatie Titanium atat de mult?

Am avut de cautat pana am gasit raspunsul. In 2011, cand am incercat sa ma documentez, nu am gasit decat ca sunt impachetate toate librariile chiar daca sunt necesare sau nu si din acest motiv este atat de mare. Nu asta era cauza! Intre timp, am aflat adevaratul motiv. Aplicatia ruleaza folosind un “bridge” intre Android si JavaScript. Codul JavaScript nu este “compilat”, asa cum reiese din prezentarile initiale, ci pur si simplu interpretat.

Codul JavaScript este interpretat folosind unul din motoarele disponibile in aplicatie (V8 si Rhino) si apeleaza componentele care construiesc elementele grafice native.

Problema este la interpretoare (engine). Acestea sunt destul de mari si sunt practic prezente in fiecare aplicatie. Si, de parca nu erau destul de mari, sunt si 3, fiecare cu scopul lui:

  • V8 – pentru versiuni de Android noi (dupa Gingerbread 2.3);
  • Rhino – pentru versiuni vechi de Android (inainte de Gingerbread 2.3);
  • x86 – pentru procesoare de tip Intel.

Aceste 3 engine-uri ocupa in total, dezarhivate, 19M pe calculatorul meu. Deci, fara sa eliminam o parte din ele nu avem cum sa scadem dimensiunea.

O metoda prin care cei de la Appcelerator vor sa scada dimensiunea apk-ului este sa renunte la Rhino, dar in acest mod se va pierde si compatibilitatea cu versiuni mai vechi de Android.

Comunitate

Exista o comunitate foarte activa. Pe forumuri si platforme Q/A este plin de intrebari si raspunsuri! Trebuie sa recunosc ca am fost impresionat din acest punct de vedere. Unele intrebari sunt relativ vechi, chiar si de 3 ani de zile.

Curba de invatare

Pentru o saptamana si aproape jumatate, din care mai bine de un sfert am cautat cum sa fac un efect de miscare al unui view, care pana la final nu a functionat, eu zic ca a mers destul de repede!

Recunosc, m-am mai jucat acum 3-4 ani cu el pentru cateva zile si chiar mi-am amintit anumite lucruri, cum ar fi ca erau elemente de tip window, view si label.

Faptul ca gasesti usor raspunsuri la intebarile de pe Stackoverflow, adunate in cativa ani, dar si ca exista o documentatie destul de bine organizata a ajutat foarte mult.

De asemenea si pe Youtube exista cateva tutoriale utile.

Mediul de dezoltare

Pentru primele versiuni nu exista un IDE, aplicatiile erau scrise cu un editor la alegere, apoi impachetate si testate folosind platforma.

Acum exista un IDE care are la baza Eclipse. Numele acestuia este Titanium Studio. Acesta are un autocomplete destul de reusit, care ajuta in cele mai multe cazuri. Are si cateva lucruri care nu merg prea bine, cum ar fi faptul ca mie uneori nu mi-a mai mers syntax highlight, fara sa-mi indice unde este problema. De asemenea, administrarea proiectelor mi se pare un pic ciudata si am avut cateva probleme la importul si exportul de proiecte.

Nu exista implicit o unealta vizuala de editare a elementelor din fereastra. Atat Xcode cat si ADT permit editarea de elemente cu drag & drop. Se pare ca exista si unelte de acest tip, dar nu sunt gratuite.

Emulatoarele nu sunt foarte configurabile. Partea buna este ca nu trebuie sa-ti bati capul, selectezi sistemul de operare si tipul de display si Titanium va configura automat un emulator. Partea proasta este ca poate mi-ar placea sa am un management al resurselor mai clar.

Un alt dezavantaj este ca uneori aplicatia pur si simplu moare pana porneste emulatorul, iar daca incerci din nou va incerca sa mai porneasca un emulator fara succes, caz in care trebuie inchis emulatorul, rulat Project clean si apoi incercat din nou, cu grija sa nu ratam momentul cand se poate debloca ecranul, sau scenariul de la inceput se va repeta.

Pentru iPhone nu merg log-urile cand vine vorba de OS X Mavericks.

Parti bune

Se invata relativ usor.

Documentatia este destul de bine realizata, iar acolo unde ceva nu este clar, sigur a mai intebat altcineva aceeasi intrebare.

Exista o comunitate destul de mare.

IDE-ul este usor de folosit.

Este usor de vazut cam ce este posibil in aplicatia Kitchen Sink.

Aplicatia nu arata ca o pagina web intr-un WebView!

Parti rele

Aplicatia ocupa foarte mult spatiu (16M pe telefon).

Elementele grafice sunt doar niste subseturi din platformele suportate.

Nu este foarte rapid, din cauza faptului ca avem codul intepretat si nu compilat, ca sa poata interactiona direct cu OS-ul.

Nu exista un editor vizual.

Exista probleme de integrare cu emulatoarele, atat pentru Android cat si pentru iPhone.

Concluzie

Daca esti un cunoscator al limbajului JavaScript, ai nevoie repede de o aplicatie si vrei sa foloseasca elemente grafice native, atunci probabil Titanium este pentru tine.

Daca vrei performanta, probabil trebuie sa te orientezi spre altceva.

Eu nu am suficienta experienta cu SDK-ul Android cat sa pot construi aceasta aplicatie in timpul care l-am avut, acesta a fost compromisul meu.

Sincer, nu sunt sigur daca PhoneGap era o optiune mai buna sau nu, vorbind de cazul meu paticular. Astazi exista multe librarii de JavaScript facute special sa emuleze elementele grafice native intr-o aplicatie PhoneGap. Diferenta nu este neaparat vizibila si, pana la urma, uneori poate aplicatia chiar nu trebuie sa arate ca o aplicatie standard, poate o interfata complet diferita este mai potrivita.

Written by Claudiu Persoiu

24 December 2013 at 1:13 PM

Posted in JavaScript

Tagged with , ,

Construind o noua generatie de programatori intr-o societate de consum

without comments

Motivat de articolul lui Rober Martin – Hoards Of Novices, am decis sa scriu si eu un articol pe un subiect similar.

Nu vreau sa scriu despre nevoia angajatorilor de a angaja juniori, ci despre de ce acesti juniori nu se ridica la nivelul asteptarilor, iar pentru final, despre ce am putea face pentru o mai buna pregatire.

Piata software este intr-o continua expansiune. Software-ul este modul in care comandam calculatorului ce sa faca. Astazi, dispozitivele din jur au procesoare, software si aplicatii, de la telefoane, ceasuri, televizoare si pana la masini de spalat si frigidere. Toate aceste dispozitive au nevoie de programe si programatori ca sa dezolte aplicatii pentru ele.

Cu aceste premize ajungem la criza software. S-a ajuns la concluzia ca avem nevoie de software mai repede pentru a rezolva aceasta criza. Acesta a fost un subiect important in anii ’60, dar cu timplul lumea nu i-a mai dat importanta.

Pentru a rezolva aceasta problema au aparut limbaje de nivel inalt si framework-uri. Limbajele de nivel inalt fac dezoltarea si intretinerea unei aplicatii mult mai simpla. In acest mod programatorii se indeparteaza foarte mult de “metal”, de hardware-ul efectiv, lucrand cu notiuni mult mai usor de manipulat.

Intr-o lume a limbajelor de nivel inalt (Java, C#, PHP, Python, JavaScript etc.) este mult mai usor si mai rapid sa compui o aplicatie.

Si totusi, desi modul de dezoltare al aplicatilor devine mai simplu, calitatea programatorilor este si ea in scadere.

O societate de consum

Avem nevoie de scoala pentru o slujba mai buna.

Pentru ca nevoia de studii reprezinta astazi o nevoie generala, scoala in sine se dilueaza. Principiile educationale in mare parte nu au suferit schimbari fundamentale de cand educatia a devenit disponibila tuturor. Rezultatul procesului de invatare este examenul, pentru ca asa se determina nivelul cunostintelor. Si mai presus, un rezultat mediocru ne permite sa avansam, fara sa demonstreze ca baza evaluata este prezenta.

Trecerea la nivelul urmator se face print-o examinare partiala, nu trebuie sa stapanesti 100% din notiuni, ci doar 50-60%. Nu este neaparat clar daca in celalate 40-50% se afla notiuni importante.

Aceasta problema a educatiei este mai mult sau mai putin o problema generala si sunt putini cei care chiar incearca abordari diferite.

In general, eu nu consider scoala un sistem definitoriu de stabilire a cunostinelor, mai ales astazi, cand avem acces la un volum atat de mare de alternative.

Cand studentii termina scoala, ei nu au toate notiunile pentru a lucra efectiv in industrie, ceea ce nu este atat de anormal. Scoala trebuie sa ofere doar o baza generala. De exemplu, in invatamantul superior pot sa-mi amintesc cel putin 8-9 limbaje de programare invatate. Efectiv au fost mai multe, dar nu am tinut o evidenta detaliata. Este clar ca nu ai cum sa cunosti atatea limbaje de programare la nivelul la care sa produci. Pe de alta parte, ai o idee de abordare, care te poate ajuta sa stabilesti o directie in care vrei sa aprofundezi.

Aceasta este cheia, sa aprofundezi! Pentru asta fiecare are abordarea lui, aici poti sa-ti alegi singur calea, fie cursuri, carti, proiecte practice sau toate la un loc. Prin aprofundare ajungi la nivelul la care angajatorii nu doar te accepta, dar te vaneaza!

De multe ori, pasiunea inlocuieste total studiile. Am cunoscut mai multe persoane care, desi nu au studiat informatica, sunt acum profesionisti in ea.

Partea buna este ca multa lume aprofundeaza de placere si sfatuiesc pe oricine citeste aceste randuri sa caute placerea in ce fac. Aceasta este cea mai buna motivatie.

Educatie alternativa intr-o societate de consum

Pentru ca metoda traditionala de invatamant nu este tocmai suficienta, sa vorbim de cateva metodele alternative:

  • carti
  • cursuri
  • tutoriale
  • articole/bloguri

Carti
Cartile in mod traditional sunt cea mai buna sursa de informatii (cel putin pana la aparitia Internetului). Dar calitatea nu este garantata!

Acum 8-9 ani am incercat sa cumpar o carte pentru JavaScript. Selectia nu era foarte mare asa ca am incercat sa analizez fiecare carte in parte.

La final am fost dezamagit de alegerea facuta pentru ca in loc sa ma invete JavaScript, cartea ma invata cum sa fac efecte speciale pe pagini (foarte populare in perioada respectiva).

In cazul meu particular, am gasit raspunsul mult mai tarziu intr-o prezentare a lui Douglas Crockford. Acesta spunea ca majoritatea cartilor de JavaScript sunt de acest fel si a recomandat o singura carte in afara de cartea scrisa de el, JavaScript: The Definitive Guide.

Cauza este simpla, lumea este mult mai atrasa de carti care promit sa te invete un limbaj sau tehnologie intr-un numar limitat de lectii sau zile. Vrem totul acum, dar studiul are nevoie de timp, trebuie sa intelegi notiunile, nu doar sa le treci in revista intr-un mod rapid.

In general, ca sa determini calitatea unei carti ar trebui sa cauti review-uri. In ziua de astazi este foarte usor, eu prefer Amazon.com dar nu numai. Asa poti determina daca este ce cauti.

Uneori si o perspectiva rapida este utila, mai ales daca nu ai alt mod de abordare pentru subiect, dar in general orice subiect abordat rapid nu-ti ofera o perspectiva generala, ci doar o introducere usoara.

Cursuri

Sunt multe cursuri, atat in clasa cat si on-line. La fel ca si in cazul cartilor, este greu sa determini calitatea cursului.

Cursurile promit multe, dar de multe ori nu trateaza in detaliu subiectele, iar la final chiar daca ai impresia ca ai invatat multe, cand vine vorba de aplicat realizezi ca orice variatie de la materialele cursului te pune in dificultate.

Ca si in cazul cartilor, referintele sunt foarte importante! Din pacate pentru cursuri nu sunt la fel de multe ca pentru carti.

Incearca sa vezi subiectele abordate si detaliul de abordare. Sau uneori poti gasi mai repede referinte pentru profesor decat pentru curs.

Tutoriale

In special pe Internet sunt foarte multe tutoriale care promit sa te invete un domeniu, dar nu reusesc sa te invete cum sa realizezi exemplul lor. La final nu poti realiza decat mici variatiuni de la exemplul initial. De multe ori, cel care face tutorialul are cele mai bune intentii, dar este greu sa faci un transfer de informatii.

Pentru cele care sunt gratuite este foarte simplu sa determini daca abordarea este potrivita sau nu pentru nevoile privitorului. Incearca sa privesti cateva episoade si vezi daca la final ai inteles cum functioneaza componenta respectiva. Daca poti doar replica, atunci poate mai ai de cautat.

Partea buna este ca sunt foarte multe si ai de unde alege in general. De exemplu, la un limbaj de programare poti vedea in referinta oficiala cam ce ar trebui sa inveti, apoi in tutorial vezi daca ai inteles punctele din referinta si ai o idee ce fac.

La variantele comerciale este mult mai greu, pentru ca de multe ori ai doar un preview introductiv, insuficient pentru a-ti forma o parere. In aceste cazuri ar trebui sa cauti review-uri.

Bloguri si articole

Partea buna aici este ca investitia in timp este relativ mica. E simplu sa-ti formezi o parere la final.

Dezavantajul este ca unele articole nu se actualizeaza o data cu tehnologia. Trebuie sa te asiguri ca exemplele functioneaza pe versiunea folosita de tine. Din experienta proprie pot spune ca acest lucru este greu si necesita mult timp. De exemplu, unele articole care inca mai atrag cititori pe acest blog sunt scrise acum cativa ani si, daca nu mai folosesc tehnologiile respective, nu mai sunt tentat sa le tin la curent.

Cum sa invatam mai bine

Cauta referinte pentru materialele care presupun o investitie de timp si/sau bani: carti, cursuri sau tutoriale.

Atunci cand te hotarasti sa abordezi un subiect, incearca sa vezi ce materiale recomanda altii. Internetul este plin de materiale de diferite grade de dificultate.

Cand te simti stapan pe un subiect, testeaza-ti cunostintele. Construieste o aplicatie, urmareste subiectul pe platforme de Q/A sau, de ce nu, scrie un tutorial pentru altii. Intelegi mult mai bine un subiect cand il descrii altora.

Exerseaza! Este foarte important sa folosesti ce inveti sau vei uita mai repede decat crezi. Contribuie la proiecte open-source, incearca sa-ti faci proiecte personale sau incearca sa adaptezi proiectele altora la nevoile tale. Github este o unealta forte buna pentru a gasi si publica proiecte.

Este putin mai greu la inceput sa intelegi codul altuia, dar in industrie este imperativ ca sa poti colabora cu altii.

Invata lucruri noi tot timpul. Tehnologia se schimba, la fel cum se schimba si perspectiva asupra ei. De exemplu, AJAX a aparut la sfarsitul anilor “90, dar perspectiva asupra cum acesta se poate folosi s-a schimbat dramatic in anii urmatori, chiar daca tehnologia nu s-a schimbat mult timp. La fel a fost si cu JavaScript, desi a apatur la inceputul anilor “90,  abia dupa anii 2000 a inceput sa fie considerata o unealta utila, inainte era folosita in special pentru efecte speciale.

Mult timp, PHP a fost considerat un limbaj util doar pentru proiecte mici. Astazi, este limbajul preferat de giganti ai internetului cum ar fi Facebook si Yahoo!. O data cu popularitatea si abordarea asupra lui a fost schimbata pentru o performanta si scalabilitate mai buna.

Concluzie

Sistemul educational nu ofera performanta de care angajatorii au nevoie. Asta creeaza o discordanta intre asteptarilor angajatorilor si cele ale absolventilor, iar asta nu este doar o problema a informaticii.

Din pacate si materialele alternative uneori promit lucruri nerealiste, unii studiaza tehnologii si limbaje de programare luni de zile, iar altii promit rezultate dupa doar cateva zile sau chiar ore.

Din fericire, traim intr-o lume a informatiei si putem gasi nu doar materiale ci si pareri despre acestea.

Printr-o mai buna pregatire, sansele de angajare cresc considerabil, rezultand intr-o satisfactie mai mare de ambele parti.

Written by Claudiu Persoiu

17 December 2013 at 11:18 PM

Posted in Diverse

Finally finally in PHP 5.5

with one comment

Cea mai noua versiune de PHP este aproape gata. In momentul cand scriu acest blog, PHP 5.5 este in RC 1.

Cum am mai spus si in blogul anterior, lista de noutati este disponibila la: http://www.php.net/manual/en/migration55.new-features.php

Al doilea feature ca popularitate este “finally”: http://www.php.net/manual/en/language.exceptions.php

Care-i treaba cu “finally“?

Pare un pic confuz, pare un bloc care se executa dupa ce se termina blocul de try catch. Dar ce este nou?

Sa zicem ca avem un bloc try/catch:

PHP 5.x < 5.5:

// open resouce
$resource = new Resouce();
try {
    // do stuff with the resouce
    $resouce->doStuff();
} catch (Exception $e) {
    // log exception
    syslog(LOG_ERR, $e->getMessage());
}
// release resouce
unset($resouce);

PHP 5.5

// open resouce
$resource = new Resouce();
try {
    // do stuff with the resouce
    $resouce->doStuff();
} catch (Exception $e) {
    // log exception
    syslog(LOG_ERR, $e->getMessage());
} finally {
    // release resouce
    unset($resouce);
}

Pana aici nu exista nici un motiv pentru care este nevoie de un nou bloc. Am prins exceptia, am facut logging pe ea si am continuat.

Dar sa zicem ca este o resursa si vrem sa o eliberam, iar ulterior sa aruncam exceptia. O varianta ar fi sa eliberam resursa in catch.

Dar mai ramane cazul “fericit”, sa zicem ca trebuie sa o eliberam si atunci.

// open resouce
$resource = new Resouce();
try {
    // do stuff with the resouce
    $resouce->doStuff();
} catch (Exception $e) {
    // release resouce
    unset($resource);
    // perpetuate exception
    throw $e;
}

Sa complicam si mai mult, sa zicem ca avem n tipuri de exceptii. Vor rezulta n conditii de catch, plus 1 pentru cazul fericit, iar in toate trebuie sa eliberam resursa. Nu foarte eficient…

O alta varianta este sa stocam exceptia intr-o variabila si, dupa ce am eliberat resursa, sa aruncam si exceptia, daca este cazul.

// variable to store the exception
$exception = false;

// open resouce
$resource = new Resouce();
try {
    // do stuff with the resouce
    $resouce->doStuff();
} catch (Exception $e) {
    $exception = $e;
}

// release resouce
unset($resource);

if($exception) {
    throw $exception;
}

Acesta este unul din modurile in care se realizeaza in prezent. Functioneaza, dar nu evidentiaza faptul ca poate doar vrem sa eliberam resursa si sa ne continuam viata in liniste.

Varianta PHP 5.5

In manualul php.net:

In PHP 5.5 and later, a finally block may also be specified after the catch blocks. Code within the finally block will always be executed after the tryand catch blocks, regardless of whether an exception has been thrown, and before normal execution resumes.

De fiecare data cand blocul se executa, indiferent daca se executa cu succes sau nu, finally se va executa. Deci, pentru exemplul:

try {
     echo 'Do stuff' . PHP_EOL;
     throw new Exception('testing');
} finally {
     echo 'inside finally' . PHP_EOL;
}

Outputul va fi:

Do stuff
inside finally

Fatal error: Uncaught exception 'Exception' with message 'testing' in...

Daca vrem sa prindem si exceptia:

try {
     echo 'Do stuff' . PHP_EOL;
     throw new Exception('testing');
} catch (Exception $e) {
     echo 'do something with the exception' . PHP_EOL;
} finally {
     echo 'inside finally' . PHP_EOL;
}

Outputul va fi:

Do stuff
do something with the exception
inside finally

Si chiar daca luam cazul si mai particular, cand prindem exceptia, apoi o aruncam:

try {
     echo 'Do stuff' . PHP_EOL;
     throw new Exception('testing');
} catch (Exception $e) {
     echo 'do something with the exception' . PHP_EOL;
     throw $e;
} finally {
     echo 'inside finally' . PHP_EOL;
}

Pare ca acum am reusit sa prevenim executia blocului finally? Nu este tocmai asa…

Do stuff
do something with the exception
inside finally

Fatal error: Uncaught exception 'Exception' with message 'testing' in...

Cu alte cuvinte, blocul finally se executa de fiecare data, indiferent de rezultat.

Written by Claudiu Persoiu

19 May 2013 at 7:34 PM

Posted in PHP

Tagged with , ,

Generating generators in PHP 5.5

without comments

O noua versiune de PHP este pe cale sa se lanseze. In momentul cand scriu acest blog, PHP 5.5 este in beta4.

Dornic de a vedea noutatile, am compilat noua versiune beta. Lista de noutati este disponibila la: http://www.php.net/manual/en/migration55.new-features.php

Cel mai important feature il reprezinta generatoarele (generators).

Generare de generators in PHP 5.5

Un generator este practic o functie care contine un apel catre “yield”.

Sa luam exemplul de pe php.net:

<?php
function xrange($start, $limit, $step = 1) {
    for ($i = $start; $i <= $limit; $i += $step) {
        yield $i;
    }
}

echo 'Single digit odd numbers: ';

/* Note that an array is never created or returned,
 * which saves memory. */ 
foreach (xrange(1, 9, 2) as $number) {
    echo "$number ";
}
?>

Practic, generatorul (xrange in acest caz), in loc sa intoarca un array, o sa genereze cate o valoare pentru a fi prelucrata.

Dar stai… oare asta nu era deja posibil pana la aceasta versiune?

Generatori inainte de PHP 5.5

Pana la versiunea de PHP 5.5 aveam deja iteratori:

<?php

class xrange implements Iterator
{
    private $position = 0;
    private $start;
    private $limit;
    private $step;

    public function __construct($start, $limit, $step = 1)
    {
        $this->start = $start;
        $this->limit = $limit;
        $this->step = $step;
        $this->position = 0;
    }

    function rewind()
    {
        $this->position = 0;
    }

    function current()
    {
        return $this->start + ($this->position * $this->step);
    }

    function key()
    {
        return $this->position;
    }

    function next()
    {
        ++$this->position;
    }

    function valid()
    {
        return $this->current() <= $this->limit;
    }
}

echo 'Single digit odd numbers: ';

/* Note that an array is never created or returned,
 * which saves memory. */
foreach (new xrange(2, 9, 2) as $number) {
    echo "$number ";
}
?>

In afara de faptul ca Iteratorul este un obiect cu mai multe proprietati, practic putem atinge acelasi rezultat.

Dar de ce era nevoie de generatori atunci? Simplu! In loc sa folosim ~40 linii de cod, putem folosi pur si simplu 5 ca sa atingem acelasi scop.

Un alt lucru interesant este ca:

get_class(printer());

va intoarce Generator.

Deci, practic, un generator va intoarce inapoi un obiect de tip Generator, iar acest obiect extinde Iterator.

Diferenta majora, asa cum este si pe site-ul php.net, este ca generatorul nu poate fi resetat, merge intr-o singura directie.

Trimiterea de informatii catre generator

Da, generatorii functioneaza in doua sensuri, doar ca un anume generator este bun doar pentru un singur sens. Daca sintaxa de mai sus este pentru “producerea” de rezultate, sintaxa de mai jos este pentru “consumare” de date.

Sintaxa pentru un generator “consumator” este simpla:

<?php
function printer() {
    $counter = 0;
    while(true) {
        $counter++;
        $value = yield;
        echo $value . $counter . PHP_EOL;
    }
    echo ‘Never executed...' . PHP_EOL;
}

$printer = printer();
$printer->send('Hello!');
echo 'Something is happening over here...' . PHP_EOL;
$printer->send('Hello!');
?>

Outputul va fi:

Hello!1
Something is happening over here...
Hello!2

Practic, valoarea din yield poate fi folosita ca orice alta valoare. Ce este interesant este while-ul. Pe php.net este urmatorul comentariu:

// Sends the given value to the
// generator as the result of
// the yield expression and
// resumes execution of the
// generator.

Este nevoie de un loop, pentru ca generatorul se va opri dupa ce proceseaza valoarea si va continua doar atunci cand primeste o noua valoare. Daca scoatem while-ul, doar prima valoare va fi procesata, indiferent de cate ori vom apela send().

Un lucru interesant este ca ceea ce este dupa loop nu se va executa, in cazul meu linia:

echo ‘Never executed...' . PHP_EOL;

Desi pare un loc potrivit sa eliberezi o resursa (ex. BD sau fisier), de fapt nu este, pentru ca acel cod nu se va executa.

Mi se pare util la logging. Din nou, nimic ce nu putea fi facut si pana acum, dar totusi permite o abordare mult mai usoara.

Am descoperit totusi un lucru care nu functioneaza:

<?php
function printer() {
    while(true) {
        echo yield . PHP_EOL;
    }
}

$printer = printer();
$printer->send('Hello world!');

foreach($printer as $line) {
    echo $line . PHP_EOF;
}

Un pic haotic, nu? Eram curios ce se intampla:
Fatal error: Uncaught exception ‘Exception’ with message ‘Cannot rewind a generator that was already run’ in…

Odata ce a fost folosit send() pe un iterator, nu mai poti sa iterezi prin el. Evident se poate genera unul nou, cu:

printer();

Ce este si mai confuz este ca Generator este o clasa final, deci nu poate fi extinsa, iar daca incerci sa o instantiezi direct (desi chiar daca ar functiona ar fi inutil):
Catchable fatal error: The “Generator” class is reserved for internal use and cannot be manually instantiated in…

Concluzia

Este un feature interesant, pentru ca simplifica mult lucrurile atunci cand vrei sa construiesti un iterator.

De asemenea, functionalitatea de send() mi se pare foarte interesanta, nu pentru ca face ceva nou, ci pentru ca il face mai usor.

Nu-mi place in schimb ca este aceeasi sintaxa pentru ambele variante de generatori si mai mult, ce este dupa while nu se mai executa.

Mi se pare usor confuza sintaxa, pentru ca nu este o diferentiere clara. Pe de alta parte, se pare ca asta exista deja in Python, deci pentru inspiratie se pot folosi exemplele din acest limbaj.

Written by Claudiu Persoiu

10 May 2013 at 9:11 AM

Posted in PHP

Tagged with , , ,

Closures, de la Scheme la Javascript la PHP

without comments

Notiunea de closure in PHP, desi a aparut in PHP 5.3, a fost realizata intr-un mod adecvat abia in 5.4, asa cum am mai spus-o si pe blogul meu.

Wikipedia ne spune:

In computer science, a closure (also lexical closure or function closure) is a function or reference to a function together with a referencing environment—a table storing a reference to each of the non-local variables (also called free variables) of that function.

In PHP nu este un concept foarte popular sau foarte cunoscut. De multe ori acesta este confundat cu Anonymous Functions. In limbajele functionale totusi, acest concept este foarte popular, pentru ca acolo este cu adevarat nevoie de el!

Scheme

Cand Brendan Eich a conceput JavaScript, s-a bazat pe limbajul Scheme si a ajuns sa faca o implementare a acestuia cu o sintaxa de C. Sintaxa C era si este in continuare mult mai populara, iar atunci (1995) limbajul Java era foarte “la moda”.

Sintaxa Scheme este similara cu sintaxa Lisp, in sensul ca se folosesc paranteze in jurul expresiilor pentru a le rula. Operatorii sunt definiti ca si functii si la fel ca o si in cazul functiilor, se pun in partea stanga a parantezei.

Sa luam un exemplu de closure in Scheme:

(define (make-counter)
  (let ((count (begin 
                 (display "run parent function and return 0") 
                 0)))
    (lambda ()
      (set! count (+ count 1))
      (begin 
        (display "inside child function ") 
        count))))

Functia principala seteaza o variabila “count”, cu valoarea 0 si afisaza “run parent function and return 0”, apoi intoarce o alta functie lambda, care incrementeaza variabila definita in functia principala si apoi afisaza “inside child function”.

Functia rezultata din executia functiei principale o stochez intr-o variabila pentru a o putea rula ulterior de mai multe ori:

> (define counter (make-counter))
run parent function and return 0
> (counter)
inside child function 1
> (counter)
inside child function 2

Cu alte cuvinte, de fiecare data cand apelez (make-couter), acesta va intoarce o functie noua care are acces la mediul in care a fost creata. Daca pare ciudat din pricina sintaxei, promit ca in JavaScript va parea mult mai natural.

Acest concept este foarte interesant pentru incapsulare. Mediul la tipul cand functia parinte este executata se poate incapsula, iar ulterior se va folosi de accest mediu fara grija ca acesta se poate schimba din cauze exterioare.

Pentru limbajele functionale acesta este un concept foarte interesant. Cand vine vorba de limbaje obiectuale totusi, conceptul aproape inutil, pentru ca obiectele au si ele rolul de incapsulare.

JavaScript

JavaScript a fost de la inceput un hibrid, un limbaj functional, orientat obiect, cu mostenire bazata pe prototype. Iar daca acestea nu erau suficiente, sintaxa a fost preluata din Java (C).

JavaScript nu a mostenit multe de la Scheme, dar a mostenit conceptul de closure.

Un motiv pentru care era nevoie de closure in Scheme este acela ca daca o functie nu gaseste o variabila in mediul in care se afla, o va cauta in mediul superior. Sa luam un exemplu:

(define x 1)
(define (add-in-env y) (+ x y))

Daca apelam add-in-env cu 2:

(add-in-env 2) -> 3

Pare la fel de ambiguu ca si in JavaScript, dar nu este tocmai asa. In Scheme sa faci mutatie nu e la fel de usor, simplu si transparent, deci o operatie ulterioara de:

(define x 2)

va rezulta intr-o eroare.

In JavaScript a rezultat un hibrid. Mutatia este permisa, dar notiunea de a cauta o variabila in mediul in care te afli a ramas:

var x = 1;
var add_in_env = function (y) {
   return x + y;
}

add_in_env(2); // rezulta 3

Pana aici e ok, dar pentru:

x = 2;
add_in_env(2); // rezulta 4

In acest caz, lucrurile scapa foarte usor de sub control.

Dar, ca sa rezolvam problema, putem pur si simplu sa definim variabila in mediul care isi va termina executia (se va inchide = will close):

var make_counter = function () {
   console.log("run parent function and set counter to 0")
   var count = 0;

   return function () {
       count = count + 1;
       console.log("inside child function");
       return count;
   }
}

var counter = make_counter();
console.log(counter());
console.log(counter());

var counter2 = make_counter();
console.log(counter2());
console.log(counter());
console.log(counter2());

Outputul va fi:

run parent function and set counter to 0
inside child function
1
inside child function
2
run parent function and set counter to 0
inside child function
1
inside child function
3
inside child function
2

Chiar daca functia principala si-a terminat executia, mediul din interiorul ei este pastrat ca un closure pentru functia care a fost intoarsa. Doar in momentul in care si subfunctia nu mai are referinte catre ea memoria alocata pentru closure va fi dezalocata.

Chiar daca JavaScript are obiecte, acestea nu au metode private. O abordare este sa pui un “_” (underscore) in fata numelui functiei si sa o consideri privata. Din punctul meu de vedere asta este ca si cum ii rogi pe cei care vin dupa tine sa o considere o functie privata. Evident acest lucru nu este tocmai consistent.

Sa luam un exemplu:

var obj = {
   _secretFunction : function (key) { console.log(‘do secret ’ + key) },
   doStuff : function (key) { this._secretFunction(key) }
}

obj.doStuff(‘stuff’); // do secret stuff

Aparent avem o metoda publica “doStuff” si una privata “_secretFunction”. Totusi nu poti preveni un utilizator sa apeleze “_secretFunction”, sau mai rau, sa o modifice:

obj._secretFunction = function (key) { console.log('new secret ' + key); }

obj.doStuff('stuff'); // new secret stuff

Daca vrem ca functia sa fie ascunsa, iar acest lucru sa fie evident pentru toata lumea, din nou putem folosi un closure:

var obj = (function () {
   var secretFunction =  function (key) { console.log(‘do secret ’ + key) }

   return {
      doStuff : function (key) { 
         secretFunction(key) 
      }
   }
})();

obj.doStuff(‘stuff’); // do secret stuff

Pentru ca functia parinte se va executa la inceput, practic spatiul in care a fost definit secretFunction si-a terminat deja executia, incapsuland logica. Obiectul intors poate sa apeleze functia pentru ca este definit in acelasi mediu ca si obiectul.

Pare complicat prima data, dar de fapt este foarte simplu cand intelegi conceptul.

Si apoi a fost… PHP

PHP inglobeaza multe optiuni diferite. PHP s-a dezvoltat initial ca un framework Perl, ulterior engine-ul fiind scris in C.

PHP este un limbaj dinamic care inglobeaza foarte multe concepte, de la obiecte, interfete si functii anonime, pana la goto labels. Nu este foarte clara directia in care ar trebui sa se dezolte limbajul, mai degraba ofera posibilitatea pentru abordari diferite.

In istoria ciudata a PHP, undeva in versiunea 4 a fost introdusa o sintaxa pentru Anonymous Functions, dar abia in PHP 5.3 a aparut o versiune mai “normala“.

Tot in versiunea 5.3 a fost introdusa si prima varianta de closures:

$scalar = 5;

$closure = function () use ($scalar) {
     return 'Scalar: ' . $scalar . PHP_EOL;
};

echo $closure(); // Scalar: 5

$scalar = 7;

echo $closure(); // Scalar: 5

Versiunea functioneaza in mare parte, dar trebuie sa specifici ce vei trimite catre closure.

Si mai exista cateva inconveniente:

<?php 
class Foo {         
   private function privateMethod() {                 
      return 'Inside private method';         
   }

   public function bar() {                 
      $obj = $this;                 
      return function () use ($obj) {                         
         return $obj->privateMethod();
      };
   }
}

$obj = new Foo();
$closure = $obj->bar();
echo $closure();

Fatal error:  Call to private method Foo::privateMethod() from context '' in [...][...] on line 10

Nu functioneaza pentru ca nu poti trimite $this ca parametru la closure, iar daca faci artificiul de mai sus tot nu vei putea accesa metodele private. Nu uitati, asta se intampla in PHP 5.3.

Ideea de a introduce acest tip de closure mi se pare bizara. Nu este prima daca cand in PHP se introduce un feature “bizar”, dupa cum vorbeam mai sus si de Anonymous Function. Pare work in progress.

Cred ca toata lumea se astepta ca acest feature sa functioneze la fel ca in JavaScript. Cred ca doar datorita JavaScript conceptul de closure a devenit atat de popular.

In versiunea PHP 5.4 lucrurile s-au mai schimbat, avem in sfarsit closures asa cum ne asteptam:

class Foo {
   private function privateMethod() {
      return 'Inside private method';
   }

   public function bar() {
      return function () {
         return $this->privateMethod();
      };
   }
}

$obj = new Foo();
$closure = $obj->bar();
echo $closure(); // Inside private method

Functioneaza!

Poti chiar sa spui:

unset($obj);
echo $closure();

si va functiona, pentru ca obiectul in interiorul caruia a fost definit closure-ul a ramas in memorie pana cand se va termina executia scriptului, sau se va apela:

unset($closure);

Pentru mai multe detalii despre cum functioneaza closure in PHP 5.4, puteti citi acest blog.

Written by Claudiu Persoiu

10 April 2013 at 10:02 AM

Passing Magento Developer Plus certification

with 3 comments

De ceva mai bine de un an de zile am inceput sa lucrez pe platforma Magento. In primavara anului trecut, un coleg de la Optaros si-a dat examenul de certificare pentru Magento Developer Plus. De atunci a inceput sa-mi placa ideea de a da certificarea, mai mult ca sa ma motiveze sa invat dedesubturile Magento.

Acum cateva luni am fost inscris intr-un grup de studiu pentru certificare in cardul companiei. Aceasta a fost prima data cand am fost sponsorizat pentru o certificare (da, pana acum totul a fost pe banii mei). Sa te pregatesti in cadrul unui grup a fost o cu totul alta experienta.

Cei care au mai multa experienta intr-un anumit domeniu echilibreaza situatia pentru ceilalti si pot oferi explicatii mai bune din propria lor experienta. E mai usor sa intelegi cand ai exemple concrete, decat sa incerci sa-ti imaginezi scenarii.

Certificarea este disponibila prin Prometric. Deci, cand te-ai hotarat, poti intra pe site sa cumperi un voucher si sa iti programezi examenul.

Pretul unui voucher este de 260$, nu foarte mic, dar daca reusesti sa-ti convingi seful sa il plateasca, probabil nu va fi asa grav. 🙂

Dar sa trecem la subiectul mai interesant, pregatirea.

Materiale
Magento nu sta prea bine la subiectul asta, materialele sunt putine si nu sunt centralizate.

Sursele mele au fost:
Magento® Certified Developer Plus Exam Study Guide – e imperativ sa citesti ghidul si sa incerci sa gasesti raspunsurile la toate intrebarile.
Magento training – in special Fundamentals of Magento Development
– bloguri – nu vreau sa dau nume, sunt multe si multi care scriu despre problemele pe care le intalnesc si care povestesc despre ce este examenul.

Din pacate nu ai modalitatea, cum este la PHP, ZF sau Symfony, sa gasesti cam tot ce ai nevoie intr-un singur loc. Practic, depinde de noroc si skilluri de cautare, nu exista mereu o “varianta oficiala”. Lucrurile devin mai ciudate cand gasesti mai multe abordari in functie de versiune.

Cum m-am pregatit eu
Am inceput cu trainingul video. Nu este perfect, dar ajuta mult. Cred ca problema pentru majoritatea certificarilor este ca nu lucrezi cu toate modulele disponibile, la fel cum in PHP nu ai posibilitatea sa lucrezi prea mult cu socketuri si streamuri.

Chiar daca nu primesti codul si uneori sunt greu de urmarit si transcris exemplele, cred ca tutorialele video sunt una dintre cele mai importante surse in momentul actual.

In al doilea rand, cu Study Guide-ul in mana, am inceput sa incerc sa raspund la intrebarile din el. Cand am intrat in study group, munca s-a impartit la toti cei din grup. Avantajul meu a fost ca era a doua generatie de grup si am putut profita de documentatia deja construita de primul grup.

Daca te pregatesti singur, cred ca cel mai important este sa incepi, este cel mai greu pas. Iar daca nu stii de unde sa incepi, cauta pe Google intrebarile din Magento, sunt multi care au scris deja explicatiile.

Cel mai usor se gasesc raspunsuri pentru intrebarile de la primele capitole. Pe masura ce numarul capitolului creste si rezultatele pe Google scad.

Dar dupa primele intrebari ar trebui sa intelegi despre ce este vorba si teoretic nu vei mai avea nevoie de documentatie.

Foloseste Mage::log(Varien_Debug::backtrace(true, false)); pentru stack trace si xdebug (http://xdebug.org/) pentru a urmari ce se intampla in spate.
Cu rabdare, toate intrebarile isi gasesc raspunsul.

Pentru ca a fost un grup, studiul a fost mult mai usor pentru mine, dar chiar si asa, pentru a fi sigur de raspuns am studiat adanc in cod.

Examenul
Unele intrebari sunt dificile, dar sunt si intrebari accesibile. Cam toate gradele de dificultate se intalnesc in examen.

Pentru Plus, examenul dureaza 2h, nu 2.5h, cum scrie in guide.

Daca optezi pentru Plus, exista 11 intrebari de Enterprise si de dificulatate mai ridicata, din care trebuie sa rezolvi 7 corect, practic in asta consta diferenta de dificultate. Aici conteaza cata experienta ai pe Enterprise.

In fiecare ghid subiectele sunt defalcate procentual pe capitole.

Pentru ca la certificarea fara Plus nu exista intrebari de Enterprise inseamna ca trebuie raspunzi doar la procentul necesar ca sa iei examenul, nu sa faci un minim pentru un anumit capitol.

Lucrurile care se fac in mod uzual sunt studiate in amanunt, e important sa intelegi cum functioneaza fiecare functie pe care se pune accentul din fiecare modul si ce fac toate tag-urile din fisierele xml.

In general sunt lucruri cu care lucrezi, sau mai bine zis cu care este o probabilitate buna sa lucrezi din modulele listate in ghid.

Dupa examen
Inainte sa iesi din sala vei afla daca ai trecut sau nu. Cand iesi din sala vei primi o hartie cu numarul de intrebari corecte din totalul de intrebari pe fiecare sectiune.

In cazul in care nu ai avut succes, vei primi de la Magento un mail cu un voucher cu o reducere pentru o ulterioara incercare. Ei spun ca ar trebui sa mai studiezi cam 3 saptamani inainte de a incerca din nou. Oricum, dupa ce ai dat examenul o sa ai o viziune mai buna daca esti pregatit sau nu pentru o noua incercare.

Dupa cateva zile (cred ca 3 in cazul meu) vei putea sa-ti vezi si profilul pe site-ul Magento, pentru referinta.

Diploma ajunge cam intr-o luna in Romania, la adresa care este trecuta pe site-ul Magento.

Multa bafta!

Written by Claudiu Persoiu

16 February 2013 at 8:23 PM

Posted in Magento,PHP

Tagged with , , ,

Exista viata si fara PHP6 – Retrospectiva 2012

with 3 comments

A mai trecut un an fara suport nativ de unicod in PHP. Da, nu a aparut inca PHP6, in caz ca cineva chiar se mai intreba asta…

In schimb, versiunea care a aparut este PHP 5.4. Cu aceasta versiune cred ca nu au fost adaugate decat lucruri de finete, nu mai e o schimbare asa de mare cum a fost in cazul PHP 5.3. In PHP 5.4, schimbarea majora o reprezinta traits si, favorita mea, noua varianta de closure.

Dupa cum anul trecut cuvintele cheie au fost Drupal si Magento, anul acesta cuvantul cheie a fost doar Magento.

Acum doua luni, mai mult fortat de imprejurari, am sustiunut examenul de certificare pentru Magento Plus. Pentru aceasta certificare, angajatorul meu, Optaros, a avut o influenta majora. Am fost mai mult sau mai putin obligat sa-l sustin si alaturi de asta a trebuit si sa facem parte dintr-un study group organizat de companie.

Nu am mai facut parte dintr-un study group din facultate si trebuie sa recunosc ca uitasem utilitatea lui. Cei care aveau mai multa experienta cu Magento (fata de mine care am putin mai mult de un an), au ajutat foarte mult la clarificarea unor probleme si la documentarea lor.

Dar mai multe despre asta intr-un alt blog, care va urma curand (sper)…

Oricum, dupa ce a trebuit sa studiez atat de in detaliu Magento, trebuie sa recunosc ca am mult mai mult respect pentru platforma. Dupa ce analizezi arhitectura din spate, incepi sa percepi altfel lucrurile. Arhitectura este foarte interesanta si destul de flexibila, lucru care te face sa treci cu vederea unele neajunsuri.

Acum ca a inceput un nou an, imi doresc sa public mai mult, cred ca in ultima perioada nu am fost foarte “productiv” cand vine vorba de publicat, fie ca este text sau cod.

Si anul acesta mi-am propus sa sustin cel putin un examen de certificare. Cum certificarea de Magento era in plan de abia pentru anul acesta, inca mai am optiuni pe lista.

Cam atat despre 2012 si planurile pentru 2013.

Va doresc un 2013 extraordinar!

Written by Claudiu Persoiu

14 January 2013 at 9:54 AM

Posted in Diverse,PHP

Tagged with , ,

Auto Text To Speech

without comments

Acesta este un mic proiect destinat utilizatorilor de Microsoft Windows!

Este un utilitar pentru Text To Speech scris in HTML si JavaScript. Aplicatia ruleaza ca HTML Application.

Am scris aceasta aplicatie de 3 ori pana acum, pentru ca am pierdut primele variante. Intr-un final m-am gandit ca poate si altii pot profita de pe urma lui.

Pentru utlizatorii Linux o alternativa este: eSpeak.

Mai multe detalii pe pagina proiectului.

Written by Claudiu Persoiu

31 July 2012 at 7:17 PM

Posted in Diverse,JavaScript

Tagged with , , ,