On reducing complexity

02 IX 2010, 00:14

There's one part of my work that really fascinates me on a downright artistic level. It's the sense of excitement I experience each time it occurs to me that my coworker managed to create a system which, at the same time, feels both intuitively correct and as simple as possible. Whenever I'm tasked with modifying such a system, it's always satisfying to remind myself that I do not really have to think much about how to actually perform the necessary changes, since I can instantaneously figure out the couple of places where the edits should occur. And most of the times, I'm right -- the parts of the code I need to change or extend are where I think they should be, and in the shape I expect them to be. If the code lacks some functionality (and it rarely does), that's not a cause for alarm -- when coding, my predecessor had only his particular set of requirements in mind, so he left some parts of the system in a non-flexible state. Now it is my job to add this flexibility, so that the system can encompass the new functionality. I always get a feeling of satisfaction whenever I manage to add new features while increasing the complexity of the whole system by only a minuscule amount.

Granted, both me and Jacek come from more or less the same background -- Linux/FLOSS in general and PLD in particular, and the product we're working on is partially PLD-derived, so a lot of what I've just described actually amounts to figuring out how to integrate new functionality (often in the form of new applications) into a custom-built limited-purpose Linux distribution. And that's something which has very few obvious ways to do it right and a lot of ways to do it very wrong. On top of that, the (brilliant in its intended simplicity) Unix philosophy of separating systems into small discrete applications with clearly defined interfaces is ever present in our job.

However, the true reason for all of the flowery language from the first paragraph is not just that I know how to use RPM proficiently and am such a very happy camper for it. Actually, it's because the very same qualities I try to attain professionally, in particular being able to reduce the complexity of systems to their most simple and beautiful (see, more flowery language) form, managed to heavily skew my general world view. I actually look at the world I live in, or, to be more precise, at the society and its various constructs, in much the same way as I look at my work. In the XXI century, the age of globalisation and interconnectedness, complexity lurks everywhere and each time I encounter it, I have the strong urge to try and reduce it. To attain true simplicity in its most functional form.

I do know of at least one other complex system of written rules designed to govern interactions with the real world, other than computer source code. It's the legal system. I know for a fact that the number of both the national and international laws that govern even my mid-sized country, is increasing by the hour. Without any signs of reversing the trend.

And blindly increasing complexity is not progress, but a certain path to a catastrophe. For example, each time I come across the statement, that ignorance of law does not excuse the offender, I'm reminded of the sheer absurdity of it. In a western society it's physically not possible for a human to navigate reality with the full knowledge of all the rules and regulations that he might or might not be breaking at any given time. For a potentially eye-opening presentation of how many pitfalls await citizens in a legal system, I strongly suggest viewing the first part of this talk (it's based on the U.S. legal system).

I'm of the opinion that each individual, considering how different our experiences might be, has the potential to give a unique and at least partially useful solution to any problem he has given serious thought to. Having said that, I also believe that people rooted in the "IT mindset" might (just might), on average, have more insight to offer than most, solely due to the nature of our profession. The more ambitious of us try to learn new ways of approaching and solving problems on a regular basis. The very core of our job is to create tools that enable people to take control of the enormous complexity found in the world. One can't send probes to Mars with just pen and paper. Or run a nation's electricity grid. Or its banking system. Or any one of the many millions of extremely complex tasks. Computers and their software are a necessity.

As often is the case in life, I unfortunately have no idea what to do with this knowledge. Yes, the legal system is very complex and yes, if performed correctly, its simplification might be beneficial to society. Also, it's true that IT deals with handling complex problems and has, over the years, developed tools and methodologies for that very purpose. However, my actual understanding of even my own country's legislative process is extremely limited, so I have no real idea how to even try to approach the problem. I do, for example, think that it would be extremely cool to have all of Poland's laws be developed using a central SVN-like repository, I do not however know how to (a) solve such a problem on a technical level and (b) make politicians adopt such a system, once it is ready.

I have tried to write a system that would extract the legislative data from the current sources, figure out which is the next version of which and then present a mercurial repository out of it, but failed miserably. Even trying to compile a list of sources proved to be too daunting a task. Extracting meaningful data (projects of new law) out of those sources would require writing unique code for each source and would be very hit or miss. PDFs are meant for printing, not extracting text from.

Unfortunately I apparently do not possess the sheer will power of an RMS (or an Eben Moglen for that matter), in order to perform such a feat on my own. Instead, I'm kind of hoping that a leader will emerge with a clear vision and the skills necessary to make that vision a reality.

In the past year I have "toured" parts of the NGO landscape of Warsaw and I can't say anything bad about it. Motivated people trying to change reality by doing the things they think are important. However, I can't say that I've met anyone with a clear vision of how to achieve far-reaching fundamental changes, accompanied by the skills and motivation required to focus purely on realizing that vision, without getting distracted by "lesser" goals.

I'm still young and optimistic however. Sooner or later someone like that will emerge and I'll find him. I'm really hoping for sooner, though :)

P.S. Thanks to riddle and Jubal for proof reading. Unfortunately my grasp of the English language is not sufficient for me to be able to express my thoughts in a manner as simple, as I would like.

(Photo: Alcoa Composite One, mikeyexists CC)

Moje największe informatyczne wpadki

10 II 2009, 02:43

Zainspirowane tym wpisem.

1. Pisząc wiele lat temu automatykę ftp-ową do pld, wstawiłem tam demona lockującego (o, to). Fakt, oryginalnie miał robić też kilka innych rzeczy, ale w praktyce nigdy tego nie zakodowałem, więc zamiast paru prostych flocków jest osobny proces i gadanie z nim po unix sockecie.

2. Używanie lokalnych mysql-i jako miejsca do logowania danych, by je później zasysać na centralnego mysql-a i tam obrabiać. I to wszystko na kilkudziesięciu maszynach. W praktyce był to bardzo czasochłonny w maintainowaniu i podatny na błędy koszmarek, który na szczęście nie jest już w użyciu. (Przy padach maszyn bazy się psuły, trza je było ręcznie naprawiać, a update schematu bazy na parudziesięciu maszynach był... upierdliwy.) Serio, już lepiej pisać do pliku, jeśli się nie korzysta z jakiś dedykowanych rozwiązań dla systemów rozproszonych (hadoopy, czy coś).

3. linux-libc-headers. Eh. Przez sporo releasy kerneli 2.6.x upgrejdowałem parędziesiąt mega nagłówków (katalog "include" ze źródeł linuksa) ręcznie przy pomocy diffa i patcha. Tak, jestem skończonym idiotą. Obecnie z umiejętnością używania rzeczy typu mercurial (czy też po przeszkoleniu się w gicie) maintainowanie czegoś takiego byłoby pewnie o rząd wielkości łatwiejsze. Chooooociaż. To były czasy 2.6.0, rok 2003, git nie powstał jeszcze przez półtora roku. Ha! Nie jestem idiotą, tylko prawdziwym twardzielem! (Właśnie sobie uświadomiłem, że grzebałem w zdecydowanie fajniejszych rzeczach, jak byłem nastolatkiem :(

4. Backupy. Udało mi się w jednej firmie już kilka razy odtwarzać/odzyskiwać dane, bo ktoś/ja nie dopilnował, ale ewidentnie uczę się bardzo powoli, gdyż w chwili obecnej jestem odpowiedzialny za co najmniej kilka systemów, którym od dawna mam dorobić sensowny backup, a które, jeśli umrą, to spowodują, że będę miał bardzo przekichane. I nie tylko ja. Ale już niedługo wszystko będzie backupowane. Serio serio. (Dzisiaj miałem badblocka na laptopie i tak się przeraziłem, że szybko zapuściłem mój autobackup. Okazało się, że poprzedni był we wrześniu...)

5. Programistyczny mainstream. W javie zdarzało mi się dłubać, bo musiałem coś zmodyfikować, ale nigdy nie potrafiłbym sam napisać całego programu. C++ poznałem za gówniarza w stopniu podstawowym i nigdy tej wiedzy nie pogłębiłem (nigdy się na przykład nie nauczyłem tej debilnej składni ichnich templejtów). Ostatnie IDE, jakiego używałem z własnej woli (studia pomijam), to były jakieś MS Visual C++ za czasów Windowsowych, czyli przed 2002. Miałem wtedy 14-16 lat. C znam dobrze (sporo grzebałem; eskpertem nie jestem), pythona wystarczająco (cały czas używam, ale gigantycznych systemów nie pisałem). Czyli jak patrzę na ogłoszenia o pracę, to właściwie nie mam w nich czego szukać.

6. Windows. Chcielibyście zatrudnić administratora, który musi się chwilę w głowę podrapać, żeby znaleźć panel administracyjny, bo fizycznie Windowsy ogląda raz na pół roku przez pięć minut? No właśnie. Powinienem był się bardziej zdywersyfikować. Że dywersantem zostać.

Więcej grzechów nie pamiętam. Jeśli sobie jeszcze kilka przypomnę, to wrzucę drugą część tego wpisu.

Oczywiście liczę na rozpoczęcie łańcuszka. Jeśli namówisz dwóch innych blogerów na opublikowanie listy takiej, jak powyższa, to spotka cię wielka miłość/fiskus zabierze ci trochę mniej wypłaty (niepotrzebne skreślić). Serio serio.

Zwyciężył mercurial

27 VIII 2008, 02:21

Vide ostatni wpis. Mercurial jest fajny, bo:

1. Nie jest gitem. Jest specjalnie robiony w taki sposób, żeby być jak najbardziej intuicyjny w użyciu i nie straszyć ludzi nadmiarem opcji (większość bardziej zaawansowanych komend jest domyślnie nieaktywna i trzeba je aktywować w konfigu).

2. Jest w pythonie. Lubimy pythona.

3. Posiada równoważnik najważniejszych funkcji darcsa -- poleceń record/pull, w postaci poleceń record/transplant.

4. Ma out of the box (acz domyślnie nieaktywną) bardzo potężną funkcjonalność Mercurial Queues, które są implementacją koncepcji quilta w oparciu o VCS. Jest to naprawdę zajebista i prosta w użyciu zabawka. Na chwilę obecną w pracy zajmuję się dokładnie tym, co opisywałem w poprzednim wpisie -- grupuję sobie poszczególne commity składające się na implementację jednego konkretnego ficzera, po czym folduję je w jeden (a następnie zmieniam im kolejność, żeby rzeczy branch-specific były zawsze commitowane ostatnie). I nawet jak hg już się dorobi rebase'a, to i tak najprawdopodobniej nie będę z niego korzystał, bo MQ też w bardzo prosty sposób umożliwia zsynchronizowanie się z nowszą wersją upstreama.

I nowy 7thguard będzie trzymany właśnie w mercurialu. Najprawdopodobniej w MQ.

Wheeeee, dawno już nie miałem tyle radochy z nowego narzędzia.

Na ringu zostały: mercurial i git

24 VIII 2008, 19:34

Distributed VCS-y są fajne, od paru lat w pracy używałem darcs-a. Problem z darcsem jest taki, że (a) ma w cholerę bugów i (b) praktycznie rzecz biorąc jest martwy. Czas na alternatywy.

Ostatnio bawię się bazaarem m.in. dlatego, że PLD przeszło na launchpad.net z którym bazaar jest domyślnie zintegrowany, więc gdyby kiedyś mi się nudziło i przerzuciłbym PLD-owego CVS-a do bazaara, to od razu mielibyśmy integrację z bugtrackerem. Poza tym bazaar jest dosyć intuicyjny, Shuttleworth przekonująco pisze, a całość jest w Pythonie.

Problem: nie odpowiada on mojemu trybowi pracy.

Darcs ma dwie wielkie zalety:

1. Polecenie do robienia commitów jest domyślnie interaktywne, tzn. pyta się czy zapisać każdą jedną zmianę w każdym pliku. Brzmi wkurzająco, ale, po pierwsze, wystarczy nacisnąć 'a' (all) i z głowy, a po drugie oznacza to, że mogę, mając kompletnie rozgrzebany plik z kodem, zauważyć, że właśnie stworzyłem self-contained zmianę i sobie ją commitnąć niezależnie od całej reszty śmiecia w pliku. Jest to bardzo naturalny sposób pracy, bo, zwłaszcza przy większych zmianach, dopiero w trakcie ich tworzenia zauważam wyodrębniające się niezależne, eee, ciągi funkcjonalne (?). Afaik inne VCS-y zaadoptowały to w postaci trybu "interactive" (bazaar przez plugin, hg chyba domyślnie w kodzie, nie wiem jak git).

2. Darcs nie ma rewizji, dla niego rezpozytorium to tak naprawdę zbiór patchy. Oznacza to, że (a) komenda rebase (w bazaarze jak zwykle w postaci pluginu, w hg nie mam pojęcia, czy w ogóle jest, a git ma domyślnie) jest kompletnie bez sensu, bo mogę sobie pullnąć patche z czegokolwiek na cokolwiek, ważne, żeby się nakładały i (b) mogę utrzymywać kilka wersji dokładnie tego samego drzewa, różniących się tylko i wyłącznie jednym patchem.

Punkt pierwszy to nie problem, punkt drugi i owszem. Wynikają z niego dwa różne workflowy:

1. Surwiwal fitnessu (survival of the fittest). System ma robić X. Nie mam pojęcia jaki jest najlepszy sposób na zrobienie X, więc robię kilka możliwych implementacji, po czym odpalam je na różnych maszynach. I dalej wprowadzam równoległe zmiany sprawdzając, jak różne wersje na nie zareagują. W darcsie jest to proste, wystarczy, żebym w pewnym momencie do jednego drzewka wprowadził patch XX, a do drugiego XY i pullując nowe zmiany z drzewka A do B lub vice versa, pamiętał o niepullowaniu tych konkretnych patchy. I mogę sobie tak rozwijać równoległe wersje tego samego programu praktycznie w nieskończoność, zachowując owe różniące je patche. O ile wiem w bazaarze w ogóle tak się nie da, nie wiem jak w hg i gicie.

2. Odgałęzianie się od ruchomego pnia (dla twardzieli: odbranchowywanie się od movowalnego trunka). Sprowadza się do tego, że mam gotowy kawałek softu, który jest rozwijany niezależnie ode mnie przez upstream i ja mam na ów soft nałożyć własne poprawki, sporadycznie mergując się z upstreamem. W darcsie nie problem, mogę pullować dowolne patche skądkolwiek dokądkolwiek, w pozostałych natomiast potrzebny jest rebase. Jak pisałem: bzr i git to mają, nie wiem jak hg.

Pierwszy tryb rozwoju softu jest dosyć specyficzny dla mojej pracy, drugi natomiast, co uświadomiłem sobie dosyć niedawno, wcale nie (acz też obecny). radioemiter.pl i pld-users.org to dokuwiki, www.pld-linux.org to MoinMoin, forum.pld-linux.org to bodajże phpbb (acz nie stawiane przeze mnie). I gdybym wtedy wiedział to, co wiem teraz, to wszystkie one od razu lądowałyby w jakimś VCS-ie. Bardzo ładnie ten problem wyszedł z pld-users, gdzie jeden z adminów zupgrejdował do nowszej wersji dokuwiki i wszystkie moje site-specific zmiany poszły do /dev/null. I żeby je teraz odzyskać będę się musiał z jakimiś patchami i diffami bawić (zakładając, że gdzieś się zachowała stara wersja). A tak, to jeden rebase i po paru minutach miałbym z głowy.

I właśnie dlatego nowy 7thguard, stawiany na drupalu, będzie od początku czymś wersjonowany.

Przy czym nie samym rebasem człowiek żyje. Można powiedzieć, że na co mi rebase -- ściągam najnowszą wersję upstreama, diffuję względem wersji od której się odbranchowałem, po czym próbuję nałożyć takiego patcha na swój kod z commitlogiem "upgrade to upstream X.Y.Z". Prawda, rzecz w tym, że w wypadku tego typu workflowu bardzo liczy się przejrzystość commitlogów, gdyż po paru latach pogubię się w tym, co tam właściwie jest zrobione względem oryginału, a już tym bardziej będzie z tym miał problem ktoś inny chcący też coś pomóc.

I tutaj wychodzi drugi problem z bazaarem -- nie wspiera on przepisywania historii. Rebase rebasem, ale po jakimś czasie commitlogi wyglądałyby tak: 3. implemented X; 4. fixed bug in X; 7 upgraded to upstream 5.0; 11 X obsolete, same functionality implemented elsewhere", etc, etc. Tego typu historia jest ważna w przypadku publicznego projektu, do którego jest np. bugtracker i w którym spójność całości jest święta (to dlatego Linus nie rebase'uje swojego drzewa, ani nie grzebie w jego historii post-factum). Jest ona natomiast ewidentną przeszkadzajką (bo zamazuje obraz zmian) w przypadku projektów bardziej prywatnych, typu opisanych powyżej/tych, co mam w pracy. Po prostu utrudnia życie.

Jestem praktycznie pewien, że z gitem tutaj nie byłoby problemów, nie wiem natomiast jak hg.

W ogóle dosyć oczywiste jest, że bazaar odpada i że najprawdopodobniej wyląduje na gicie. Łudzę się jeszcze, że hg spełni moje wymagania, acz nie mam jakiś specjalnych nadziei. Ot, po prostu, autorzy gita najprawdopodobniej przewidzieli powyższe przypadki użycia oraz setki innych, o których jeszcze nie pomyślałem i które pewnie nigdy nie będą mi potrzebne. Do tego git ma pewnie zaimplementowane optymalne sposoby integracji z wszystkimi innymi rozwiązaniami na rynku (perforce anyone?), więc gdybym kiedykolwiek trafił do jakiejś firmy, gdzie standardem jest coś niespecjalnie wygodnego, najprawdopodobniej byłbym w stanie uprzyjemnić sobie życie przy pomocy odpowiednio użytego gita.

Główny problem z gitem jest taki, że jest on trudny i nieintuicyjny dla ludzi wychowanych na czymkolwiek innym. Tego problemu nie ma z bazaarem, nie wiem jak z hg, ale git to jest oczywisty kosmos. Jest to trochę sytuacja jak z vimem -- używam, bo jest dla mnie wydajniejszy, niż alternatywy. Ale gdybym musiał kogoś innego zmuszać do jego używania, to już byłby problem. Ale nie muszę, bo edytować tekst można w czymkolwiek. Z VCS-ami już nie ma tak łatwo. Jeśli wrzucę 7thguarda do gita, to znacznie podniosę poprzeczkę dla kogokolwiek, kto chciałby w tym później coś pogrzebać (ditto dla pld-users i reszty). Tak nie jest w przypadku np. bazaara, bo czyś z CVS-a, SVN-a, czy czegoś takiego, będziesz się czuł jak w domu.

(To jest powód dla którego przy jakichkolwiek zmianach PLD prawie na pewno nie wyląduje na gicie. Zaawansowane funkcje gita i tak nie zostałyby wykorzystane, a ludzie by się pewnie w końcu zbuntowali, że nowy soft działa kompletnie na odwrót, niż stary dobry CVS. Tego problemu praktycznie nie byłoby właśnie z bazaarem.)

W ogóle nowy 7thguard to będzie ciekawy przypadek. W teorii w ogóle nie powinienem musieć grzebać bezpośrednio w kodzie drupala, wszystko powinno być do załatwienia themami, konfigami i pluginami. W teorii. Jak to wyjdzie w praniu, to się jeszcze zobaczy.

Hmmm, tak się zastanawiam. Może te systemy to jest nowy sposób na rozwój różnych webowych CMS-ów i takich tam? Może to właśnie powinno być specjalnie robione tak, żeby klienci mogli upgrejdować swoje rozwiązania przy pomocy jakiegoś bzr-a z rebasem? Nowe tarballe powinny od razu zawierać katalog .bzr, a nowe wersje powinny być także dostępne do łatwego pullowania/mergowania takimi narzędziami? Graficzne konfigo-klikadła powinny automatycznie commitować wprowadzone zmiany? Interesting... Ciekawym, czy dałoby się taki sposób tworzenia stron dla klientów wprowadzić w mojej opolskiej firmie. Acz to już temat na osobny wpis.

Poprelekcyjnie (nagranie)

09 XI 2007, 04:40
  1. Nagranie jest mocno przeedytowane pod kątem przydatności do słuchania. Jeśli ktoś pamięta, że coś się wydarzyło inaczej, niż jest nagrane, to wysoce prawdopodobne, że dobrze pamięta.
  2. Wyciąłem co najmniej kilka minut swoich mlasknięć (co mikrofon bardzo ładnie ponagrywał), chrząknięć, eeeeeyyyyeeeeeania, za długich pauz, przerw technicznych oraz najzwyklejszych wpadek. Więc nie, wcale tak płynnie nie mówię.
  3. W środę miałem depresję, że poszło tragicznie. Po przesłuchaniu stwierdzam, że aż tak strasznie tragicznie wcale nie poszło. Nic czego nie może naprawić kreatywna sesja z edytorem dźwięku.
  4. Acz kilka rzeczy jest oczywistych -- po pierwsze, wcale nie mówię tak płynnie i poprawnie technicznie, jak mi się wydawało, że mówię :(
  5. Po drugie -- miałem nadzieję zrobić super zajebistą prezentację. Poświęciłem na nią z dwa-trzy razy więcej czasu, niż zwykle poświęcam na takie rzeczy. Wyszło niewiele lepiej, jeśli w ogóle. Jedno staje się dla mnie jasne -- jedyny sposób na idealnie płynną prezentację, to po prostu usiąść, napisać całość słowo w słowo i później albo czytać, albo wyryć całość na blaszkę. Nie ma siły, żebym z kartką opisującą tylko schemat wystąpienia był w stanie przeprowadzić je płynnie -- bez zacięć, bez pauz, bez niepotrzebnego powtarzania się. Po prostu się nie da. Może są jacyś geniusze, którzy potrafią, ale generalnie wątpię, żeby to było w zasięgu normalnego człowieka. Mowa ludzka tak nie działa. Zapomina się słów, robi pauzy, gubi wątki, różne rzeczy rozpraszają.
  6. Po trzecie -- jeśli chcę zrobić płynną integrację tego co mówię, z tym co jest na rzutniku, to powinienem mieć w zasięgu wzroku swój laptop, żebym nie musiał się odwracać w celu upewnienia się co właściwie w danym momencie jest na rzutniku (mam ten bezprzewodowy dynks do obsługi prezentacji, więc mogę zmieniać slajdy patrząc się na publiczność). Takie odwracanie psuje płynność, a i mnie dekoncentruje.
  7. Po czwarte -- różne techniczne drobiazgi o zwracaniu uwagi na które człowiek się uczy z wykładu na wykład.

Link do ogga. Jutro jeszcze powinien być nius na stronie oplugowej wraz z jakimiś fotkami.

A, disclaimer: mówiąc zrobiłem sporo uproszczeń, a i wykład był dosyć konkretnie stargetowany (na studentów, którzy nie wiedzą jak takie rzeczy ugryźć). Dodatkowo co najmniej kilka razy powtarzałem, że coś jest moim poglądem na sprawę i na pewno są miejsca, gdzie to działa (z powodzeniem) kompletnie inaczej. Także wiem, że nie opisałem wszystkiego, co było do opisania. Był to świadomy wybór.

Głupie błędy w zarządzaniu, część pierwsza

30 X 2007, 01:04

Niedoszacowałem czasochłonności projektu. Ale tym nie jestem zdziwiony, jeszcze wiele wody w rzece upłynie, zanim będę w stanie w miarę dokładnie terminy przewidywać. Popełniłem inny błąd -- nie zadbałem, by możliwie wcześnie skonsultować odpowiednie fragmenty dokumentacji z osobą, która byłaby kompetentna nam wykazać rozjazdy z rzeczywistym modelem biznesowym. Szczyt kretynizmu jak teraz na to patrzę. Grrr.

Skutek? Kilka mniejszych i niestety kilka większych dziur wymagających poprawek w kodzie. Przy czym ja, jako szef, za swoje błędy płacił nie będę. Nadmiarową robotę będzie miał programista.

Niskoopłacany niedoświadczony programista, który chyba dopiero na tym projekcie zaczyna rozumieć, że "naiwna ocena czasochłonności", typowa dla początkujących koderów ("Ten projekt? Tydzień, maks dwa.") nijak się ma do rzeczywistego mozolnego kodowania. Programista, który zaczyna się wypalać na moich oczach. Programista, którego potrzebuję na zaraz do następnego projektu.

Szlag by to. Przydałoby się zrobić coś konkretnego, tylko co. Na początek niech będzie zapewnienie, że terminy są bardzo fajne, gdy wydają pocieszne dźwięki przelatując nad naszymi głowami. I że nie ma się nimi za bardzo po co przejmować.

GIL

10 IX 2007, 19:36

Facet ma point. W pracy zastanawiając się nad wyborem języka, stanęło na stackless pythonie, ale w pracy miałem systemy bardziej zbliżone do google'owych, gdzie wszyscy wiedzieli, że od razu trzeba pisać z myślą o maksymalnej skalowalności, bo drugiego podejścia nie będzie. Więc nikt się specjalnie nie obruszał, że nie będzie można pójść na łatwiznę z normalnymi wątkami.

Ale wątki to jest mainstream, a im dalej w czas, tym więcej systemów wieloprocesorowych na rynku. I jeśli python pozostanie poza mainstreamem, to może się to dla niego źle skończyć, a tego bym nie chciał.

Z drugiej strony, co potrafię dopiero docenić z perspektywy lat, python w dużej ilości sytuacji stara się być mądrzejszy od programisty i podsuwać mu pod nos najlepsze rozwiązanie, utrudniając korzystanie z innych. I może Guido ma rację zniechęcając do korzystania z wątków. A może nie. Na razie wygląda na to drugie.

SCM-y, a windziarze

29 VIII 2007, 03:02

Padaka. Jedyny SCM, który ma windowsowe GUI z prawdziwego zdarzenia (tzn. integrację z Windows Explorerem), to subversion via tortoisesvn. Więc chcąc nie chcąc, będę w firmie używał scentralizowanego SCM-a, bo alternatywy są jeszcze bardzo niedopracowane: bzr-tortoise, tortoisehg i tortoisedarcs są albo stare, albo niedopracowane, albo masakrycznie trudne w instalacji. A zazwyczaj po trochu z każdego. (Patrzcie i płaczcie.)

Za to tortoisesvn jest po prostu miły. I widać, że się autorom chce.

Od czeladnika do mistrza

11 III 2007, 23:59

Przeczytałem "Pragmatycznego Programistę". Większość rzeczy tam zawartych była mi w większym lub mniejszym stopniu znana, więc część podrozdziałów albo tylko przeskanowałem, albo w ogóle zignorowałem [1]. Tak czy siak książka zdecydowanie dobra i polecałbym wszystkim początkującym (i nie tylko) programistom. Zwłaszcza żałuję, że nie przeczytałem jej jakieś dwa-trzy lata temu (co najmniej; preferowalnie znacznie wcześniej), zanim zabrałem się za pisanie pldzianej automatyki ftpowej. Wtedy zacząłem po raz pierwszy bawić się na serio obiektami w pythonie i tak sobie klepiąc przyszło mi do głowy, że ok, samo tworzenie obiektów jest proste, tyle, że nie mam zielonego pojęcia w jaki sposób dzielić różne rzeczy na obiekty. Szkoda, że wtedy nie postanowiłem coś bardziej doczytać na ten temat.

[1] Jak byłem mały, to potrafiłem przeczytać od deski do deski praktycznie dowolną knigę. Teraz niestety już nie potrafię -- znacznie spadła mi tolerancja na książki techniczne -- za dużo tam słów, za mało przydatnej treści. Nawiasem mówiąc będę musiał pomyśleć w jaki sposób dałoby się napisać książkę tak, żeby zaawansowani nie mieli wrażenia, że tracą czas, a jednocześnie ci nie do końca zaawansowani byli w stanie z niej coś wynieść. Bo zdecydowanie powinno się dać.

Jedna rzecz jest w tym wszystkim mocno przerażająca -- ogrom materiału. Wszyscy znają przypowieść o archetypicznym 'informatyku', który kiedyś nauczył się jakiegoś visual basica i do tej pory wszystko robi przy jego pomocy. No i prawdę mówiąc ja się nie dziwię. Takie rozwiązanie jest bardzo kuszące.

Naczelną zasadą tej książki jest, że programista powinien wiedzieć wszystko o swoim fachu, bo tylko dzięki temu może dobierać właściwe narzędzia do zastanych problemów i używać ich w prawidłowy sposób.

Tylko ile tego wszystkiego jest! Ekosystem uniksiany (shelle, skrypty, szybkie przetwarzanie tekstu), ekosystem javowy (eclipse, javadoc, jUnit, jBoss, jAdziękuję), ekosystem .netowy, języki dynamiczne (trza by przynajmniej z dwa teraz znać, tj. pythona i ruby'ego), a to tylko same narzędzia. Do tego dochodzi jeszcze masakryczna ilość wiedzy, żeby z tego sensownie korzystać. Już te lata wymagane na zdobycie doświadczenia w tym wszystkim pominę -- poznęcam się trochę nad samą suchą wiedzą odnośnie programowania (obiektowego). Na niskim poziomie trza znać jakiś język (maluteńki język zwany javą na przykład). Do tego dochodzą te wszystkie narzędzia i frameworki. Do tego na najwyższym poziomie jakieś typowe architektury, MVC, klient-serwer, etc. A żeby nie było zbyt różowo, to taki UML (z którego olewamy 99%, bierzemy tylko podstawy) i jeszcze jakieś wymysły typu design patterns.

Brrr. W przypadku tych ostatnich zdecydowanie zgadzam się z krytykami -- jeśli przy rozwiązywaniu określonych typów problemów koduje się w sposób, który "zasługuje" na stworzenie wzorca, to znaczy, że nie powinno się robić wzorców, tylko (a) rozszerzyć język o nowe abstrakcje i (b) zrobić jakiś framework/zestaw modułów do niego. To co już jest, jest i tak cholernie skomplikowane, więc zupełnie nie podnieca mnie przedzieranie się przez formalne opisy wzorców projektowych, żeby znaleźć ten, przypominający akurat to, co mam zamiar robić. W takich przypadkach zdecydowanie powinienem mieć gotowy framework, który prowadzi mnie za rączkę krok po kroku, minimalizując przy okazji szansę, że sobie odstrzelę nogę.

Ja jestem leniem. Ja się nie lubię uczyć nowych rzeczy zbyt często. Ilość wiedzy jaka w tym wszystkim jest zawarta mnie przeraża.

(A jak ktoś już jest kompletnie pokręcony, to może spróbować się nauczyć htmla, cssa i jsa w stopniu zaawansowanym, tzn. takim, który wystarczy do stworzenia jakiejś bardziej zaawansowanej strony działającej we wszystkich popularniejszych przeglądarkach. Good luck.)

Coding tips

10 II 2007, 01:45

Dobra rada -- refucktoryzując jakiś kawałek kodu, najpierw należy przeprowadzić wszystkie kosmetyczne zmiany, typu zmiana kolejności jakiśtam linii, dodawanie nagłówków, a zwłaszcza zmiana nazw struktur/pól w strukturach, etc. i doprowadzić to do takiej postaci, żeby się kompilowało na starym kodzie. Mimo, że to jest więcej roboty, to znacznie później ułatwia szukanie błędów, bo można sobie bez zbędnej kosmetyki wstawiać wywołania starych funkcji bez martwienia się o to, że nie zadziałają, bo jakaś struktura się inaczej nazywa.

Btw: czy ja już wspominałem jak ja kurwa nienawidzę R&D?

Obiekty, struktury, relacje, lalalalalalala

29 I 2007, 15:36

Dzisiaj miałem egzamin z inżynierii oprogramowania (UML do obiektówki i klasyczna analiza strukturalna jak za papy Yourdona). A ponieważ właściwie nie umiem ani jednego, ani drugiego, to nie zaliczyłem.

Próbując cośtam wymodzić w trakcie, dotarła do mnie jedna rzecz -- ja tak naprawdę nie rozumiem czym się różni model obiektowy, relacyjny i strukturalny (nie, nie chodzi mi o to, że nie wiem co to obiekt, albo jak zrobić kilka tabelek w bazie danych; chodzi mi o dogłębne zrozumienie fundamentalnych różnic w tych modelach i jak to się ma do projektowania przy ich pomocy). Też moja wina, bo mogłem to zauważyć wcześniej, gdybym się był bardziej do projektu przykładał, ale faktem jest, że nie było takiego mądrego dwa semestry wstecz, żeby nam to spróbował jakoś konkretnie wytłumaczyć.

Prawdę mówiąc ja nadal nie wiem jak powinienem się uczyć (w jaki konkretnie sposób, w jakiej kolejności, etc.) i mnie to drażni, ale spróbuję rzucić jak najlepszym przybliżeniem na to, co mi w tym momencie potrzeba.

1. Książka/tekst tłumaczące w jak najlepszy sposób te trzy (no, dwa, ale powiedzmy, że model strukturalny ze względu na tradycję) obecnie najważniejsze modele. Nie wiem jak to najlepiej zrobić, domyślam się, że poprzez krótką charakterystykę obu, która przechodzi w opis najbardziej reprezentacyjnych różnic w nich na konkretnych przykładach. Tzn. chcę zamodelować rzecz A i teraz gdzie są najważniejsze różnice dla tych trzech modeli oraz jak konkretnie moje malunki (uml, dfd, czy co tam) by się przekładały na fizyczny kod/zawartość bazy danych. To wszystko okraszone konkretnym opisaniem co, gdzie i w jaki sposób jest używane (tzn. strukturalny tu, patrzaj sql, modeluje się to tym, sialalalala).

2. Konkretne kursy użycia tych trzech modeli (kurs umla, kurs strukturalnej i zapewne kurs projektowania relacyjnych do kupy od razu z sql reference). Z konkretnymi odniesieniami do użycia i jak największym nastawieniem na hands-on, ale bez omijania co ważniejszych części teoretycznych. Jak byłem mały, to potrafiłem czytać (i czytałem) te knigi ala Knuth, które się zazwyczaj używa jako podręczniki na studiach, natomiast teraz mi wybitnie szkoda czasu, bo 99,9% treści tam zawartej i tak nie zapamiętam, a tylko stracę w cholerę czasu (kilka miesięcy temu próbowałem przeczytać analizę strukturalną Yourdona; bleee). Potrzebuję minimum konkretnie sprezentowanej wiedzy, która pozwoli mi jak najszybciej sobie w głowie stworzyć model... modelu. Żebym mógł modelować. A modelując będę sobie już sam łatał luki w wiedzy i dorabiał własne spostrzeżenia.

Najgorsze u mnie jest to, że ja myślę kodem. Mam problem z myśleniem o reprezentacji danych w formie strukturalnej, bo mam od razu w mózgu sprzeciw, że przecież nie jestem tego w stanie wstawić do mojego mysqla. Albo mam problem z modelowaniem relacji w umlu, bo ja tak naprawdę nie znam języków obiektowych (obiektowość pythona i c++ rozumiem tylko w stopniu podstawowym, czyli wiecie, obiekty, dziedziczenie i takie tam). Dlatego też bardzo ważne w tym wszystkim byłoby, żeby opisawszy jakiś związek w danym modelu, od razu było pokazane jak to wygląda zaimplementowane w jakimś konkretnym języku.

(Co do sqla, znaczy relacyjnych baz, to chyba wiem te najważniejsze rzeczy. Ale nie jestem tego pewien. I mnie to wybitnie drażni, bo o ile nie jest zbrodnią nie umieć czegoś zrobić, o tyle tragiczne jest nie wiedzieć nawet o istnieniu czegoś. Później kończy się takimi potworkami, jakie wyprodukowałem w pracy dwa lata temu, jak jeszcze nie umiałem nic poza prostym selectem. Mam jakąś niewielką książkę o bazach z WNT, będzie trza przejrzeć, mam nadzieję, że znajdę co trzeba przynajmniej z sqla.)

murderfs

16 X 2006, 22:26

Za każdym razem, gdy gdzieś tam pisali o problemach z dodaniem reiserfsa czwórki do jądra, oczywiste dla mnie było, że rację mają jądrowcy. Tak, Hans mógł sobie do woli gadać o tym, że jego filesystem non stop przechodzi miliardy zautomatyzowanych testów, ma super rozszerzalną i super zajebistą architekturę pluginową i wogle wogle cuda wianki, ale prawda jest i była taka, że z punktu widzenia kernelowców najważniejsza jest maintainowalność danego podsystemu. I nie chodzi tu o to, że autor się zaklina, że będzie maintainował, ale że w razie czego sami kernelowcy będą mogli tam jakieś mniejsze i większe poprawki wstawiać. To jest tzw. 'Linus got hit by a bus problem', czyli co robimy, jak maintainera przejedzie autobus.

Szczerze wątpię, żeby to się przyjęło, ale w sumie od teraz powinno się to nazywać "Linus got hit by a bus/Hans got jailed for killing his wife problem".

Poza tym mam nadzieję, że jeśli ktoś do tej pory nie rozumiał dlaczego Linus&friends byli tacy uparci przy mergowaniu reiserfsa4, to ten, fakt faktem mocno ekstremalny przypadek wystarczy za uzasadnienie. Gdyby ten filesystem został mergnięty dłuższy czas temu w stanie, w jakim był, to teraz kernelowcy mieliby na głowie potencjalnie martwy filesystem zawierający sporo różnych interfejsów (własne wbudowane pluginy), o których nikt nic nie wie. Afaik podobny problem jest już teraz z reiserem trójką, bo ilość osób znających się na rzeczy jest bardzo ograniczona, a sam autor stwierdził, że system jest w maintainance mode i żadnych większych zmian robił w nim nie będzie. A jądro się cały czas zmienia i czasami jednak trzeba...

Python, a niedobory shellowe

10 VIII 2006, 19:01

Python pythonem, ale jednak są takie zadania, które zdecydowanie wygodniej załatwić mi szybkim skryptem shellowym. Czasami użycie i jednego i drugiego narzędzia razem jest sensowne, a czasami nie, więc w tym drugim przypadku muszę się męczyć z robieniem niektórych rzeczy w pythonie.

Z samej swej natury shell jest takim wynalazkiem, że nic go nie zastąpi jeśli idzie o łatwość używania narzędzi shellowych (sed, grep, cut, sort, uniq, żeby wymienić te najpopularniejsze), a użycie tychże jest często jednak znacznie sensowniejsze, niż tworzenie danej funkcjonalności w pythonie.

(Ostatnio ktoś mówił, że ruby ma to fajniej rozwiązane, nie wiem, możliwe, ciekawym jak.)

Chętnie bym zobaczył w pythonie jakiś moduł "shell", czy podobnie nazwany, który po zrobieniu "from shell import *" nie zaśmieciłby mi przestrzeni nazw żadnymi zbędnymi rzeczami, ale jednocześnie dałby mi dostęp do zestawu prostych funkcji, dzięki którym mógłbym bezproblemowo odpalać narzędzia shellowe, łączyć je w potoki, przechwytywać potoki, przekierowywać im wejście i wyjście, mieć łatwy dostęp do zmiennych środowiskowych i w ogóle robić wszystkie te rzeczy, dzięki którym shell w pewnych zastosowaniach jest jednak najwygodniejszy.

Wymagałoby to pewnie sporo pomyślunku, żeby jakoś sensownie zrobić, ale imho jednak byłoby do zrobienia.

Python uber alles

07 VIII 2006, 22:01

W mojej robocie generalnie kluczowym jest dobre opanowanie C i różnego rodzaju kombinacje, jak duże ilości bardzo ciężkich serwerów w owym C napisanych, ze sobą w jakiś wydajny sposób zsynchronizować (z jednego konkretnego swojego rozwiązania jestem szczególnie dumny, bo działa bardzo ładnie :).

Międzymordzie usera jest napisane w pehapie z użyciem smarty'ego, oryginalnie przeze mnie (choć w rzeczywistości pehapa praktycznie nie znam; i nie chcę znać ;), a obecnie jest to rozwijane przez mojego znajomego.

Do tego dochodzi kawałek kodu odpowiedzialny za zasysanie 'logów' z poszczególnych serwerów, obrabianie ich lekko i wsadzanie do lokalnej bazy danych. To postanowiłem zrobić w pythonie i od już gdzieś roku działa bez problemów. Znajomy nawiasem mówiąc w przerwach od pehapienia też coś podobnego robi. Też w pythonie :)

Ostatnio natomiast przyszło mi przerobić jeden z serwerów na coś zbierającego i analizującego dane. Więc kod w C przerobiłem na zbierający dane, natomiast kombinacją pythona i shella zarządzam odpalaniem owego serwera, po czym obrabiam wynikowe dane. Działa pięknie i pozwala na wręcz gigantyczną swobodę.

Ostatnio natomiast szef mi kazał doprowadzić do jakiegoś stanu mieszaninę kodu C i C++ w wersji bardzo bardzo alpha (ledwo proof of concept). Powiedziałem mu, że to będzie duuużo roboty i będzie to długo trwało, na co odpowiedział, że mam to tylko na szybko przyciąć, coby było zdatne na demo dla potencjalnych klientów.

Python rządzi! Robienie w nim gluecodu po prostu wymiata. Zamiast martwić się przerabianiem wnętrzności tego kodu C/C++, po prostu podzieliłem go logicznie na coś w rodzaju modułu synchronizującego i programik 'kliencki' robiący jak najprostszą rzecz, a sterowany z linii komend. A synchronizację jednemu i drugiemu zapewniłem przy pomocy dwóch skryptów pythonowych i kawałka shella. Miodzio. Gdyby nie python, to bym się pewnie posiekał, bo musiałbym to robić nie dość, że w C/C++, co samo z siebie byłoby powolne, to jeszcze cały czas by mi w paradę wchodził oryginalny kod.

Luuudzie! Uczcie się (dobrych) języków skryptowych, bo bez nich jak bez fujarki, znaczy, wróć, bez ręki. Nawet sobie nie wyobrażam co by ze mną było, gdybym się te bodajże dwa lata temu owego pythona nie nauczył.

Odnośnie pldzianej wuwy

15 I 2005, 12:56
MoinMoin wygląda całkiem nieźle. A że jest w pythonie i ma standardowo system pluginów, to w razie czego zrobienie rozszerzeń nie powinno być zbyt kłopotliwe. Jest tylko jeden problem, mianowicie coś ma spaprane z wyświetlaniem 'akcji' (porównajcie sobie jak zakładanie strony powinno wyglądać i jak wygląda). Ale to się pewnie jakoś poprawi. Trzeba tylko powywalać przy pomocy cssa wszystkie opcje do edytowania stron (zarejestrowani użytkownicy będą sobie mogli wybrać inną skórkę z tymi rzeczami widocznymi) i zobaczyć jak tam są rozwiązane ACLe. No i tego nowego cssa zunifikować z tym, co będzie na forum.

Hmmm

16 XI 2004, 23:07
Im więcej kilobajtów ma mój kod, tym mam większe wrażenie, że duże klasy w pythonie są nieczytelne. Nie wiem z czego to wynika - chyba z tego, że brakuje mi nawiasów otaczających poszczególne bloki kodu. W pythonie robi się to samym identowaniem kodu, ale takie nagle się kończące kawałki mocno wyidentowanego kodu mi dziwnie wyglądają... takie wiszące w przestrzeni.
Już wiem! Po prostu w C przy odpowiednim kodowaniu wszystko musi się kończyć optycznie 'łagodnie'. Tzn. jeśli kończę jakiegoś ifa w pętelce w pętelce w pętelce, to kod wygląda tak:
                    koniecmojegoifa();
                }
            }
        }
    }
    itutajdalejkod();

W pythonie natomiast to samo by wyglądało tak:
                    koniecmojegoifa()
    itutajdalejkod()

Podświadomie (a teraz już świadomie, bo żem się pokapował o co mi chodzi) gryzie mnie w oczy taki nagły skok o parę poziomów identacji. Wniosek - jak słoń ma trąbę, żeby się tak gwałtowanie nie zaczynał, tak C ma swoje nawiasiki, żeby się bloki kodu tak gwałtownie nie kończyły.

Argh

13 XI 2004, 20:11
Ja rozumiem, że do założeń pythona pasują te struktury danych, które on ma, ale mi się coś robi, jak zamiast zrobić sobie po ludzku strukturę, to ja generuję jakieś wielopoziomowe słowniki. Zaraz tym walnę i zrobię sobie jakiś normalny strukturowaty obiekt do tego.

Ziuuuuuu

11 XI 2004, 01:35
Jednak kodowanie w pythonie jest szybkie. Bardzo szybkie. Jak nie trzeba się użerać z obsługą podstawowych typów danych, a całą potrzebną 'lowlevelową' funkcjonalność zapewniają gotowe moduły, to wszystko idzie jak z płatka.
Moje międzymordzie www do ftpa pldowego potrafi mnie zautoryzować i wyświetlić mi jakie są dostępne w drzewku testowym paczki. Teraz zrobienie tak, żeby to potrafiło cokolwiek sensownego zrobić, to kwestia kilkunastu dodatkowych linijek kodu. Tyle, że teraz się zaczyna problematycznie - primo muszę od razu wymyślić jakiś sposób cachowania metadanych, żeby każde zalogowanie na www nie oznaczało wczytywania 1,5 mega danych z 300 plików, a secundo muszę być w stanie atomowo lockować. Kto wie jak w pythonie sobie atomowo zlockować np. jakiś katalog? (jak się nie da, to się skończy jakimś małym demonem lockującym w C pewnie)
No a jak to skończę, to będzie najciekawsza część zabawy - zintegrowanie tego z poldkiem, żeby automatycznie testował spsute zależności. Znowu będzie przekopywanie się przez tony nieokomentowanego i zawiłego kodu w C :/

Are we there yet?

13 IX 2003, 19:51
No więc ostateczna diagnoza. Jeśli na prawdziwym systemie jest Ra (pld 1.0 dla niewiedzących), a wewnątrz chroota jest Ac (pld 2.0 dla niewiedzących) i architekturą jest ppc, a do chroota wchodzimy odpalając z pythonowego skryptu os.system("sudo chroot chroot-ac"), to środowisko wewnątrz chroota będzie skażone i aplikacje wątkowe będą się wywalały. Co ciekawe skażenie występuje przy jakiejkolwiek aplikacji odpalanej przez pythona i jest dziedziczone w dół. Zrobiłem takiego testa polegającego na odpaleniu os.system("screen") z pythona. Spod tego screena jakiekolwiek wejście do chroota powodowało znany nam błąd i nie udało mi się tego obejść. Python coś psuł, ale owo psucie objawiało się tylko przy wejściu do środowiska różniącego się glibcem. Przekompilowałem pythona na wersję 2.3 i nie pomogło. Wniosek, że albo glibc 2.2.5 jest skopany, albo kompilacja pod gcc2 daje takie rezultaty (albo oba na raz), przy czym imho to raczej ten ryćkany gcc (który na wszystkim != x86 działa po prostu tragicznie).
Koniec końców jeśli na zewnątrz chroota nie będzie Ra, tylko Ac, to problem nie występuje. Przy obecnej lokalizacji buildera ppc upgrejd jest niemożliwy, ale na szczęście spidi ma mocny desktop, który będzie można zupgrejdować. Obiecał, że zrobi to w poniedziałek. No i git.

Yeah

10 IV 2003, 20:37

Dobiłem swojego segfolta w jggtrans i zrobiłem małą poprawkę na cośtam (i przy okazji stwierdziłem, że gdb nie jest takie złe). Za to Jajcuś rzucił się na głęboką wodę i od paru dni koduje jak szalony. Ja chcę nowe PSI, żeby móc potestować to co on zrobił! (poza tym mi trochę głupio, że przy nim to ja żaden developer jggtransa, tylko jakiś asystent pomocnika :)

Afera z Witkiem F. jest chyba bliska wyjaśnieniu, ale nadal nie wiem o co chodzi :). Przy odrobinie szczęścia coś pożytecznego z tego wyniknie... no ale ja się nie mieszam.

Poza tym kloczek coraz częściej i pewniej przebąkuje o zbudowaniu pakietów Acze. Przy okazji owego budowania oczywiście kilka osób zaczęło narzekać na to, że im cośtam popsuł, no ale co to by był za kloczek gdyby czegoś nie rozwalił od czasu do czasu :).

Do zapamiętania

06 IV 2003, 21:37
Jutro jeden segfolt i brak obsługi jednego komunikatu. A teraz spać.

jggtrans c.d.

06 IV 2003, 15:50
Ależ robienie supportu do gettexta jest pasjonujące. Klepanie, klepanie, klepanie.
A Jajcuś zrobił data gathering i wybieranie języka per user. Trzeba będzie przetestować :)

No to zaczynamy

06 IV 2003, 10:49
Miałem ten tekst wysłać wczoraj, ale jogger nie działał :( No więc przedwczoraj Jajcuś dołożył do gg transportu poprawki na kilka segfoltów (c) venglin (tenże venglin poluje na jeszcze jednego babola co mu powinno zająć ca tydzień - trzymamy kciuki) oraz sam znalazł jeden potencjalny segfolt. Co ważne dołożył wstępne wsparcie dla gettexta! Nawet nie podejrzewałem, że dodanie podstawowej infrastruktury będzie na tyle nietrudne; jednak autoconf/automake to całkiem fajna rzecz pomijając, że oba narzędzia są do dupy. Teraz zostało jeszcze popoprawiać wszystkie odwołania do tekstów w kodzie programu. To już ja zrobię przy okazji paru drobnych fixów. A później trza tylko znaleźć kogoś kto całość przetłumaczy. Chyba nie powinno być z tym większych problemów :) Ja z kolei wreszcie zreanimowałem obsługę updejtu katalogu publicznego gg (tzn. przy rejestracji dane są znowu uaktualniane) przy okazji likwidując jedną niedogodność. Kod jest brzydki, ale to się później popoprawia :) btw: Teraz jest tak, że admin danego serwera może wprowadzić funkcję, że przy zmianie informacji o danym użytkowniku (vcard) jest updejtowany wybrany jabber user directory (nie wiem, czy admini z tego korzystają... bluszcz?). Może by tak zrobić opcję, że jeśli ktoś jest zarejestrowany w ggtransporcie to od razu updejtowane są też informacje w katalogu publicznym gg? (w sumie miało by to spory sens)