Teorema stergerii cu rest

Am stabilit deja ca lista inlantuita e un subiect delicat. Este timpul sa aratam ca nu doar Ovidiu “MVP” Cucu are probleme cu dinsa, ci si aia carora el le pupa bombeurile au mici dificultati in intelegerea acestei structuri de date fenomenal de complicate. Sa urmarim pentru inceput un scurt material motivational in care se incearca stergerea unei configuratii dintr-un proiect in Visual Studio 2008 (nu stiu de ce se misca in reluare, muie youtube sau muie ffdshow):

Asta e, nu s-a sters. Lucrurile devin insa cu 57% mai interesante daca incercam sa stergem mai multe configuratii deodata:

Acum s-a reusit stergerea, dar ar fi fost un pic mai bine daca ar fi sters ce i-am zis sa stearga, nu ce doream sa pastram (de asemenea gasesc interesant cum in dropdown a ramas selectat “Debug2011”, desi cind il deschizi nu e acolo). Care sa fie explicatia?

Pai e destul de simplu, de fapt. Proiectul are doua configuratii care se cheama Debug5, doua Debug6 si asa mai departe, cite una pentru fiecare platforma (Win32 si x64). Acest lucru se poate observa cu ochiul liber in vcproj, unde nu exista Debug5, ci Debug5|Win32 si Debug5|x64. Mai departe in arhitectura lui VS, o configuratie trebuie sa existe in toate platformele – nu poti, de exemplu, sa ai Debug5 doar in Win32. Orice programator care a folosit vreodata platforme multiple in VC stie asta. Indianul care a implementat stergerea nu stie. Cind apesi pe “Remove”, el cauta prima configuratie care se cheama “Debug5” si o rade. In felul asta se sterge doar aia de Win32, dar cind deschide din nou dropdown-ul, o gaseste p-aia de x64 si o afiseaza acolo, iar acum proiectul e intr-o stare invalida, cu o configuratie care nu exista in toate platformele. Workaround-ul este sa stergi o configuratie, sa inchizi dialogul de edit, sa-l deschizi din nou si s-o stergi inca o data. In felul asta se sterge si Debug5|x64, si proiectul e utilizabil din nou.

Daca te aventurezi sa stergi mai multe configuratii de-odata, ca in al doilea filmulet, se evidentiaza o noua latura a retardarii indiene, aceasta ruda karmica a retardarii ardelene. Boul sterge configuratiile dupa index, nu dupa nume. Daca stersul propriu-zis i-ar fi mers, asta n-ar fi fost o problema. Din pacate insa, deoarece configuratia ramine acolo cind se manifesta prima parte a incompetentei, se fut maparile intre indecsi si nume, asa ca atunci cind dai sa stergi Debug6, se sterge de fapt altceva (jumate de altceva, mai exact). Mai departe retardarea 1 se compune cu retardarea 2 intr-un fel sublim, astfel incit tu dai sa stergi 6 din cele 8 configuratii, dar de fapt se sterg doar 3, printre care si singurele doua pe care vroiai de fapt sa le pastrezi.

VC are acest bug de la 2005, de cind a fost introdus noul configuration manager, cu platforme si cacat. De atunci au iesit 2005 SP1, 2008, 2008 SP1 plus o intreaga pleiada de hotfix-uri, dar nimeni nu s-a ostenit sa invete cum functioneaza de fapt configuratiile si cum se cauta intr-o lista. Bug-ul s-a rezolvat in sfirsit in 2010, pacat ca ala e inutilizabil gratie rescrierii editorului in dotniet (plus alte “goodies”, gen gunoiul ala de MSBuild).

Sa trecem acum in tabara adversa. Aparent exista o corelatie intre retardare si softurile de instalat alte softuri. Cel mai idiot lucru scos vreodata de Microsoft este MSI (chiar luind in considerare Songsmith si reclama pentru el). Cel mai idiot lucru scos de Apple este PackageMaker, echivalentul hipsteristic al lui MSI. Iata ce face PackageMaker cind vrei sa stergi un target din installer:

Pentru asta n-am o explicatie, caci nu inteleg cum functioneaza mintea oamenilor care programeaza pentru Apple. Cert e ca atunci cind stergi ceva, reuseste sa amestece restul target-urilor si chiar sa lase un fisier orfan, atasindu-l de root-ul proiectului. As dori sa mentionez ca in mod normal n-ai cum sa atasezi fisiere direct acolo, folosind UI-ul lui.

Workaround-ul este sa editezi proiectul de mina, caci este tinut in XML. In XML-uri, mai exact. Cite 2 XML-uri pentru fiecare target, plus un XML mare, to rule them all (in speta, 71 de fisiere in proiectul din film). Si aceste XML-uri sint scrise pe o singura linie, cum mentionam in post-ul despre XCode. Si numele lor conteaza, fiind prefixate cu un numar. Si alea in care zici ca vrei sa instaleze tot ce-i intr-un director contin si numele fisierelor din directorul ala, la momentul la care ai facut proiectul. Care nu folosesc la nimic, pentru ca daca adaugi un nou fisier intre timp, se va copia, asa cum iti doresti, dar nu va fi trecut in XML. Si asa mai departe, in pula mea.

Ca sa fiu perfect obiectiv ar trebui sa expun si o muie dintr-un IDE de Linux. Gluma asta se scrie singura, va las pe voi sa va imaginati ce vreti.

Oricum, ce vroiam sa spun e ca le doresc epidermoliza buloasa alora care-s responsabili de chestiile astea. Sau munca silnica pe viata in mina cu Silviu Ardelean ca team leader.

Update: am elucidat si misterul PackageMaker. Si aici retardarea este usor de inteles: gunoiul are un index.xml in care, odata ce-l formatam sa nu mai fie tot pe o singura linie, putem vedea chestii de genul:

<choice title="8.5 plug-in" id="choice210">
	<pkgref id="com.nextlimit.realflowPluginForMaya.realflow.pkg"/>
</choice>
<choice title="2008 plug-in" id="choice211">
	<pkgref id="com.nextlimit.realflowPluginForMaya.realflow-1.pkg"/>
</choice>
<choice title="2009 plug-in" id="choice212">
	<pkgref id="com.nextlimit.realflowPluginForMaya.realflow-2.pkg"/>
</choice>

Mai jos in fisier scrie si:

<item type="file">01realflow.xml</item>
<item type="file">02realflow.xml</item>
<item type="file">03realflow.xml</item>

Observam deja un design fabulos, caci corespondenta dintre “choice-urile” alea si fisierele in care se spune ce contin se face pe baza ordinii. Nu s-a putut pune nodul ala de item sub nodul de choice, sau ceva. Mai departe, daca privim in 01realflow.xml, vedem ca e scris package name ala, ba chiar are si un UUID dupa care ar putea fi identificat:

<pkgref spec="1.12" uuid="A23E47A9-3AB3-4619-847F-2104601981F9">
	<config>
		<identifier>com.nextlimit.realflowPluginForMaya.realflow.pkg</identifier>

Atingerea de geniu este ca muistul tine package name-urile alea acolo doar de decor. De fapt el se asteapta ca in primul fisier sa fie definit intotdeauna pachetul “com.nextlimit.realflowPluginForMaya.realflow.pkg”, in al doilea sa fie ala cu -1 in coada, in al treilea ala cu -2 etc. Nu conteaza ce scrie de fapt in fisier, iar UUID-ul ala nu e folosit la nimic.

Deci ce se intimpla cind dai click dreapta remove? Pai simplu, indianul care a implementat functia de sters nu stie ca numele sint hardcodate. El sterge nodul din XML, sperind ca potriveala se va face dupa nume. Din cauza ca se face dupa ordine, totul aluneca cu o pozitie in jos, deci pachetul de 2009 ajunge in choice-ul de 2008, ala de 2010 in choice-ul de 2009 etc. Primul pachet ramine orfan, iar ultimul choice ramine gol.

Solutia e sa stergi de mina XML-urile corespunzatoare target-urilor de care vrei sa scapi, dupa care sa iei la rind toate XML-urile ramase si sa cirpesti package name-urile alea, ca sa fie consecutive. Apropo, nu eu am dat numele alea care-s toate la fel, sint generate de el pe baza numelor fisierelor din target-uri, iar daca le schimbi se fute.

Uimitor. Fabulos. Nici la scoala ajutatoare nu vezi asemenea “design”. Ala care a facut cacatul asta n-a inteles nimic din programare.

Cum ziceam, epidermoliza buloasa.

Tags: , , , , , , , , , , , , , ,

8 Responses to “Teorema stergerii cu rest”

  1. Luceafaru' huilei Says:

    Shiiieeeet! Ce bine, am ris, :)))

  2. Mihnea Says:

    Am editat cu detalii asupra retardarii lui PackageMaker, caci am descoperit de la ce i se trage, si e prea tare ca sa nu impartasesc.

  3. Aram Hăvărneanu Says:

    De obicei programatorii care preferă XML sunt retardați, așa că nu mă miră nimic la calitatea softurilor antemenționate.

  4. DarkByte Says:

    Cum puii mei sa scrii continutul XML-urilor pe o singura linie, asta inca n-am inteles-o… nu mai vreau sa zic nimic de cele nshpe mii de XML-uri pentru UN SINGUR proiect…

    @Aram: Eu folosesc XML-uri => am sanse mari sa fiu retardat. Tu ce folosesti ?

    Nu sunt de parere ca folosirea XML-urilor e retardata … doar folosirea lor incorecta. Daca nu vezi nuanta, imi pare rau pentru tine. XML-ul a fost chiar inocent in expunerea de mai sus – faptul ca indianu’ mentionat de Mihnea l-a violat in dos nu implica faptul XML-ul e vinovat … sunt convins ca s-a zbatut si a strigat, amaratul, dar in zadar…

  5. thefatredguy Says:

    Formatul xml e retardat si nu are nici un rost.\

  6. bullshit Says:

    @thefatredguy: eu zic ca afirmatia ta e retardat si nu are nici un rost.

  7. Mihnea Says:

    Singurul avantaj al formatului XML este ca exista biblioteci care il pot citi (*) si-ti pot da inapoi datele intr-un format cit de cit structurat. E demn de mentionat ca majoritatea bibliotecilor care fac asta sint atroce, dar de asemenea in multe aplicatii nu conteaza.

    In rest, XML e la fel de bun sau de prost ca orice conventie de structurat date intr-un fisier. Am putea filozofa pe marginea complexitatii inutile introduse de faptul ca nodurile pot avea valori, dar astea-s detalii. Cind ai nevoie sa scrii date intr-un format care sa se poata modifica cu un editor de text, nu conteaza foarte tare ca e XML, JSON sau ceva inventat de tine.

    Asocierea dintre XML si retardare survine deoarece exista programatori care cred ca XML asta e o chestie care merita studiata, standardizata si promovata. Nu e si nu merita. E o banalitate cu nimic mai interesanta decit fisierele text in general.

    Daca eu as fi facut PackageMaker ala, probabil tot in XML as fi tinut proiectul (dar evident, nu scris tot pe o linie). Sigur l-as fi tinut intr-un format text ca sa se poata face diff-uri si merge-uri in source control. Probabil as fi ales XML (sau JSON) ca sa le usurez viata alora care vor sa manipuleze fisierele mele din softu’ propriu, adica sa nu-i pun sa-si scrie si un parser pentru formatul meu inventat ad-hoc. Retardarea indianului n-are legatura cu formatul ales (in cazul asta) ci cu modul idiot in care a decis el sa-si organizeze datele.

    Pe de alta parte, exista multe exemple de XML indesat unde n-are ce cauta, doar de dragul XML-ului. De la alea se trage asocierea XML-programator retardat. Am vazut suficiente cazuri de chestii care nu trebuie sa se poata deschide in notepad, dar sint XML, pentru ca “XML e viitorul”. De asemenea, retardatilor din aceasta categorie le scapa deseori faptul ca human-readable si human-understandable nu-s acelasi lucru.

    ——

    (*) Mai sus am vorbit de XML asa cum e el perceput si folosit de majoritatea programatorilor, adica text d-ala cu mai mic mai mare si structura arborescenta. Daca vorbim insa de XML asa cum e definit de fapt de catre W3C, atunci intram puternic pe teritoriul retardarii. Standardul XML are 37 de pagini si e o telenovela medievala despre gramatici, DTD-uri, character entities, default-uri pentru atribute si alte mui. O groaza din bibliotecile populare de parsat XML parseaza de fapt text cu mai mic mai mare, nu XML asa cum e definit in mizeria aia de document, pentru ca nu inteleg cacaturile cu DTD. Daca il vedeti pe unul ca foloseste XML-ul asta “adevarat” pentru stocat date, ala e incontestabil un retardat.

    Gata, ca am impresia ca am dat-o in tehnicalitati serioase, iar scopul acestui site este bascalia, nu dezbaterea civilizata.

  8. Mihnea Says:

    LE: despre XML ala full-option, cu validare si cacat, si despre XML folosit in moduri penibile, unde tag-urile ocupa mai mult loc decit datele propriu-zise: http://www.schnada.de/grapt/eriknaggum-xmlrant.html.

    Mie mi-a placut asta:

    “If GML was an infant, SGML is the bright youngster far exceeds expectations and made its parents too proud, but XML is the drug-addicted gang member who had committed his first murder before he had sex, which was rape.”

Leave a Reply

Optionally add an image (JPEG only)