22 grudnia 2009

Aktualizacja MediaWiki do wersji 1.15.1, PHPShell i SyntaxHighlight GeSHi

10 komentarzy
Najpierw certyfikaty produktowe IBM WebSphere, a teraz aktualizacja MediaWiki do najnowszej wersji 1.15.1. W końcu i to zdjąłem z mojej listy do zrobienia na ten rok. Na prawdę mi ulżyło, kiedy zobaczyłem 1.15.1 na stronie Wersja oprogramowania mojego Notatnika-Wiki.

Pamiętam, że wielokrotnie podchodziłem do aktualizacji MediaWiki z 1.11 do aktualnej wersji (na daną chwilę) i kończyło się...zniechęceniem. Niejavowe, więc co się dziwić :)

Lektura Manual:Upgrading nie pozostawiała złudzeń - nie będzie lekko, bo konieczne jest uaktualnienie struktur bazodanowych, a to wymaga dostępu do powłoki, albo skorzystania z PHPShell. To było niezwykłe wrażenie, kiedy polecenia powłoki wykonywałem z poziomu przeglądarki.

Pamiętam podobne rozwiązanie jako applet javowy, ale tutaj miałem jedynie PHP. I historia poleceń działa! Nie sądziłem, że ludki od PHP potrafią takie cuda :) Nie żebym ich nie doceniał, bo softu naprodukowali niemało i z wielu korzystam (chociażby samo MediaWiki), ale jakoś tak to podejście było niezwykle odświeżające i nie pasowało do świata PHP.

W końcu udało mi się przebrnąć przez tę aktualizację i, jak się okazało, nie było wcale tak trudno. Kolejny raz sprawdziło się powiedzenie, że "Strachy na Lachy" (albo Lachę, jeśli ktoś wie do czego piję :)). Udało mi się niedawno rozwiązać problem ładniejszych URLi, a teraz aktualizacji, więc choćby z tego powodu możnaby okrzyknąć ten rok jako udany (w obszarze mojego wiki). Super!

Na koniec jeszcze zdopingowany do kolejnych aktualizacji zabrałem się za instalację SyntaxHighlight GeSHi, którego namierzyłem w jedynym artykule dostępnym na Tomek Bujok's IT Notepad. Sam artykuł nie wzbudził u mnie wielkiego zainteresowania (tematyka bez specjalnego znaczenia dla mnie), ale już prezentacja kodu źródłowego jak najbardziej. Zacząłem przeglądać z jakich narzędzi korzysta i tak trafiłem na SyntaxHighlight GeSHi. Ten do swojej pracy wymagał aktualniejszego MediaWiki i tak się zaczęło - najpierw aktualizacja, później instalacja rozszerzenia. Jeszcze się zastanawiam, czy mi się to faktycznie podoba, więc wdrożyłem podświetlanie składni jedynie w artykule Użycie javax.transaction.TransactionManager w OSGi z Apache Felix. Sami oceńcie, czy jest warto z tego korzystać do poprawienia czytelności kodu źródłowego. Dla samego autora to jedynie zmiana przyzwyczajenia z <pre> na <syntaxhighlight>. Niewiele, więc jeśli miałoby to cokolwiek zmienić, to warto. Poza samym kolorowaniem można włączyć numerowanie linii i podświetlenie wskazanej.

Udało się i tym samym mam więcej możliwości w swoich artykułach. A i kolejne zadanie mam z głowy. Możnaby powiedzieć, że to zasługa Tomka Bujoka, bo bez jego artykułu nie zająłbym się pewnie tymi zadaniami w tym roku (mając inne ciekawe rzeczy do zrobienia). Dzięki Tomek! Jak to się mówi "Się czyta, się wie", a "jeśli się jeszcze wdraża, to i się więcej potrafi" :) Każdemu życzę tego w nadchodzącym roku 2010.

20 grudnia 2009

I mnie zwą "IBM Certified Deployment Professional - WebSphere Process Server V6.2"

7 komentarzy
Czy ja kiedykolwiek dobrnę z wynikiem przynajmniej 75%?! 18tego grudnia podszedłem do egzaminu Test 000-375 - IBM WebSphere Process Server V6.2, System Administration i tym samym zakończyłem rok z 2 certyfikatami produktowymi IBM. W końcu! Teraz i mnie zwą IBM Certified Deployment Professional - WebSphere Process Server V6.2.

Jednak patrząc na wynik, to tylko zapłakać - 59% :( Jak tak dalej pójdzie, to za 3-4 egzaminy zejdę na poziom minimum i zacznie się egzaminacyjna bessa. Kolejny egzamin
Test 000-372: IBM WebSphere Business Modeler Advanced V6.2, Business Analysis and Design już 8. stycznia 2010 i już pozwoliłem sobie na podejście testowe za 30 USD. Tym razem postaram się bardziej, bo normalnie mi wstyd z takimi wynikami.

Dobrze chociaż, że klient tylko pyta, czy się ma, a nie pyta, jaki wynik, bo strach takiego specjalistę zapraszać na produkcję :)

Pytania nie były lekkie i nie tylko wynik to potwierdza, ale 1,5h wydało mi się zdecydowanie za mało. Mimo, że na koniec zostało mi 15 minut, to i tak uważam, że gdybym się bardziej zastanawiał nad niektórymi pytaniami, nie wyrobiłbym się (może dlatego taki słaby wynik, ale czyż nie to nazywamy doświadczeniem). Były pytania tak trywialne, jak składowe WPSa, które są równocześnie produktami IBM (odpowiedź oczywista - WESB), ale zaskoczyły mnie pytania typu - mamy środowisko testowe w postaci konfiguracji srebrnej (Remote Messaging) i teraz chcielibyśmy podejść do testów wydajnościowych - jakie rekomendacje. Ta sfera zdecydowanie u mnie kuleje (tylko 20%), ale może niekoniecznie, bo właśnie to, o co proszą najczęściej klienci, to strojenie środowiska, które skończyłem na poziomie 100% (!) Jest nad czym popracować, a tak całkiem serio, to już jest dostępny IBM WebSphere Process Server V7.0, więc można powiedzieć, że jestem w tyle, produktowo.

16 grudnia 2009

Łukasz prosi, Jacek przynosi - kolejne doświadczenia ze screenkastami

4 komentarzy
Po mojej relacji na blogu z wizyty Kirka Pepperdine w Polsce, podczas której zaszczycił Warszawa JUG swoją prezentacją nt. strojenia aplikacji javowych z użyciem narzędzi typu jps czy visualvm - Kirk jeszcze w Polsce, ale spotkanie Warszawa JUG z nim już za nami - rozwinęła się dyskusja nt. wad i zalet dynamicznego typowania w Groovy. W pewnym momencie Łukasz zasugerował "spróbuj zdekompilować klasę napisaną w Groovym". W tym samym czasie dostałem odpowiedź od Ryana Batesa, który stoi za railscasts.com, na którego z kolei wskazał seban w komentarzu do jeszcze innego wpisu, którym zainicjowałem swoje próby ze screenkastami - Grails i ja - pierwsze próby ze screenkastami (testy). Nie było, na co czekać tylko spróbować się z jeszcze jednym narzędziem do nagrywania pulpitu pod MacOS - iShowU. W ten sposób udało mi się odpowiedzieć (a w zasadzie sprowokować) Łukasza do rozwinięcia swojej sugestii w postaci filmiku. To daje już moją, drugą oficjalną próbę nagrywania screenkastów (!)

Zainteresowanych moją twórczością filmową zapraszam na YouTube - W odpowiedzi na sugestię Łukasza - dekompilacja klasy w Groovy, a osoby zainteresowane poznaniem sugestii Ryana do lektury poniżej. A jeśli są jeszcze tacy, którzy zdecydują się na obie czynności, tylko powinszować ilości wolnego czasu :)

Hi Jacek,

I'm sorry for not responding sooner, it's been a busy week.

On Fri, Dec 11, 2009 at 2:41 AM, Jacek Laskowski wrote:
> Hi,
>
> I wonder if you could share some tips and tricks about how you record screencasts.
> I've started doing them with ScreenFlow and Camtasia, but you turned
> my attention to iShowU which is horribly expensive which in fact makes itself
> unbearable for me. It's been 3-4 weeks of my work on MacOS so
> everything's new and so was your list of useful applications for
> screencasting.

Welcome to the Mac. I'm using iShowU classic (not HD) which is only
$20. However this doesn't come with any editing capabilities, for that
I use Final Cut Pro. That's the very expensive one and I probably only
use 5% of what it's capable of. You can likely get by with just
editing in ScreenFlow or Camtasia. I really want to like ScreenFlow
but haven't been able to get it to work with my workflow.

> Do you record your voice separately to a presentation and terminal input?
> Do you do it all at once?

I do both the voice and the screen at the same time, but some others
(such as PeepCode) record the screen first, edit it, and then overlay
the voice on top. I personally like the more live/interactive feel of
doing both at once.

What really helps is to record very short sections (usually around 30
seconds) and edit them all together in the end. This way if you make a
mistake you only need to do the last 30 seconds and not the entire
thing over again. A given Railscasts episode is made up of 20 or so
cuts.

> How much time do you need to publish a new screencast?

It depends a lot on the topic and how many roadblocks I run into. It
can take anywhere between 3 to 8 hours per episode to do everything
(research, recording, editing, and uploading).

Finally, what goes a long way towards screencast quality is getting a
decent microphone. I use the Samson C01U usb mic which is pretty
affordable and sounds decent.

Good luck, and feel free to ask if you have more questions.

Regards,

Ryan

15 grudnia 2009

Kirk jeszcze w Polsce, ale spotkanie Warszawa JUG z nim już za nami

30 komentarzy
Właśnie wróciłem z 58. spotkania Warszawa JUG, którego gościem był Kirk Pepperdine i co by tu nie mówić było...pouczająco. Gość znany w światku javowym, więc nie ma co przedstawiać. Od wielu lat boryka się z klientami, którzy z kolei borykają się z wydajnością aplikacji javowych i zebrał już spore doświadczenie, aby przedstawiać tematy wydajnościowe w świecie. Zawitał i do nas dzięki uprzejmości SUN Microsystems Poland (w osobie Oliwi Łączyńskiej) i Grzegorza Dudy. Skoro na spotkaniu pojawił się duży gracz - Sun - nie zabrakło i dodatków w stylu pizza i napoje, co o tyle mnie zaskoczyło, że nie minął kwadrans a po 20 pizzach XXL zostały tylko opakowania. Zanim skończyłem robić kilka filmików, jak to się ludziska delektują, po pizzy ni widu ni słychu (może to i dobrze, bo wyglądała na smaczną, a pewnie zjadłbym jej więcej niż powinienem). Później dojechała kolejna partia pizz, która też zniknęła w mgnieniu oka. Na koniec Oliwia rozdała zarejestrowanym koszulki, a wcześniej rozesłała wiadomość o certyfikacji Java z odpowiednim rabatem. Mała rzecz, a cieszy.

Zaczęliśmy prezentację kwadrans po 18tej. Zebrało się dobrze ponad 100 osób (!), co z zarejestrowanych 154 daje "obecność ratio" na poziomie 75% (przypominam, że było ponad 100 osób i z moim optymizmem 75% wydaje się być właściwe).

Bardzo podobał mi się styl prezentacji Kirka, w której doświadczyłem pragmatycznego podejścia do rozwiązywania problemów wydajnościowych w Javie. Zdaniem Kirka, analiza kodu źródłowego ma być ostatnim krokiem w tym procesie, jeśli w ogóle kiedykolwiek do niej dojdzie. Był przykład użycia jps, visualvm i hpjmeter, więc koniecznie należy się w te narzędzia zaopatrzyć przed kolejnym wdrożeniem produkcyjnym :) Oporni z pewnością odczują swoje nieprzygotowanie.

Jakkolwiek Kirk nalegał na większą interaktywność spotkania, czy to przez zadawanie pytań, czy prowokowanie do nich, to jednak widać było opór publiczności przed angażowaniem się w dyskusje po angielsku. Mimo ciągłego narzekania na spolszczanie terminów angielskojęzycznych i przywoływanie znajomości angielskiego w naszej branży, zauważyłem brak dyskusji i mam wrażenie, że właśnie z powodu języka, aczkolwiek nie oznacza to, że nie próbowano. Po prostu było jej zbyt mało, jak na liczność uczestników i tematykę, która aż prowokowała do niej. Miałem wrażenie, że wielu bardzo chciało, ale niestety obawa przed przygotowaniem angielskiego była mocniejsza. A szkoda, bo nawet "wystawienie się na strzał" ze znajomości angielskiego mogłaby być ciekawym doświadczeniem, po którym otwarlibyśmy się na tego rodzaju dyskusje. Zdaje się, że wiedzy nam nie brakuje i na prelegentów zagranicznych nie mamy co narzekać - pojawiają się stosunkowo regularnie - więc jedyne, co pozostaje zrobić, to przełamać lody z angielskiego. Odnotowane jako zadanie na 2010.

Skończyliśmy spotkanie około 20tej i przenieśliśmy się do Jeff's na Polach Mokotowskich. Ludziki po piwku, ja soczek i tak po gorliwych dyskusjach nt. technologii javowych typu Grails i rozwiązań IBM o 22ej rozeszliśmy się do domów. Kirk zgromadził wokół siebie kilka osób, ja zasiadłem po drugiej stronie stołu, gdzie była inna grupka, więc u nas było o Grails i WPSie czy WMB, a u nich pewnie wiało nudą wydajnościową :) Dobrze, od czasu do czasu słuchać zamiast mówić. Widać, że Łukasze (nazwiska znane redakcji) nie czują do końca języków dynamicznych i bałagan i brak doświadczenia zespołu chcą ratować statycznietypowaną Javą. Trzeba będzie dokończyć dyskusje kolejnym razem.

Uważam, że tego typu spotkań powinno być znacznie więcej (tych z zagranicznymi osobami, jak i tych w Jeff's czy innych pubach). Pozwalają zorientować się w naszych mocnych/słabych stronach, i jak w moim przypadku poznać narzędzia, które dostępne są pod ręką (jps, visualvm), ale chyba dlatego, że są tak blisko nie są tak atrakcyjne. Podobnie odświeżające dla mnie było użycie klas z java.util.concurrent, których nie dane mi było użyć. Przekonałem się, że wiele traciłem, skoro podczas prezentacji Kirka, profilowana aplikacja zeszła z 20 sekund do kilku, m.in. poprzez ich użycie.

Nagranie ze spotkania niedługo pojawi się w Sieci, a wszystkim spragnionym relacji fotograficznej polecam zdjęcia w albumie "Kirk Pepperdine na spotkaniu Warszawa JUG".

10 grudnia 2009

Grails i ja - pierwsze próby ze screenkastami (testy)

9 komentarzy
Ale wtopiłem z tymi screenkastami. Myślałem, że temat będzie równie łatwy jak niektóre z moich projektów javowych, ale okazuje się, że to zajęcie - tworzenie screenkastów - przeszło moje oczekiwania i może zająć człowieka na długie godziny.

Po tym, kiedy dostałem w swoje ręce Maca (pisałem o tym w Pierwszy wpis z Maca - Ty go masz i ja go mam!) postanowiłem, że zrealizuję swoje marzenie nagrywania screenkastów (w pierwszej kolejności, bo później mają być podcasty, kiedy uwierzę w swój anielski głos :)). Pomyślałem sobie, że nie tylko ja będę miał frajdę z nowego nabytku i podzielę się z innymi (Agata twierdzi, że tu nie ma nic do dzielenia, tylko zabierania...mowa o czasie spędzonym na dzieleniu :]). Najpierw była walka ze skrótami klawiszowymi - kliknięcie na gładzik dwoma palcami, Cmd (aka jabłko) i ten pasek u góry, gdzie znajduje się menu aplikacji. Nie minął tydzień, a miałem to opanowane, do tego stopnia, że PCty się kurzą wyłączone i są włączane, aby z nich kopiować dane na Maca. Oprogramowanie firmowe (Lotus Notes, VMware Fusion z Linuksami) już jest, więc mam wszystko. Przyszła pora na screenkasty. Do wyboru mam ScreenFlow i Camtasia for Mac. Na drugiego sądziłem, że posiadam licencję korporacyjną, ale okazuje się, że niestety nie na wersję na Maca, więc popróbowałem się z jednym i drugim, i padło na ScreenFlow. Obie wersje testowe, ale w pełni funkcjonalne. Przygotowałem sobie temat do sfilmowania i voila do dzieła.

Minęło kilka dni, a wygląda, jakbym wcale nie posuwał się naprzód. Wciąż to nagrywanie, cięcie, nagrywanie, cięcie. I tak w kółko, tak, że mnie zakręciło od tego kręcenia. A filmik ma być niezwykle prosty. Jedna ścieżka ze slajdami, druga z terminalem, trzecia z przeglądarką, a ostatnia, sądzę, że najważniejsza, podkład głosowy. Niby proste, ale tyle z tym jazdy, że zaczynam wierzyć w kolejną dys-coś tam. Przy takiej męczarni stwierdzam wszem i wobec, że mam dysfilmulię, czyli chorobliwy brak umiejętności w nagranie krótkiego filmiku. Się niezwykle zmęczyłem tym poznawaniem trudnej sztuki filmowej.

I w tym duchu postanowiłem wypuścić w sieć moje pierwsze nagranie - z jedną ścieżką ze slajdami i z wszechobecnym napisem ScreenFlow Demo (poza czasowym ograniczeniem na 30 dni mamy piękny znak wodny). Niewiele, ale potrzeba mi było podreperować moje ego i zobaczyć efekt mojego tygodniowego zmagania z nagraniami. Tym samym odhaczyłem dwie rzeczy - zrobiłem pierwszy filmik (o znikomej wartości dla społeczności javowej, ale dla mnie bezcenny, bo pierwszy na Macu) i opublikowałem go na YouTube (!) Momento. Zanim napiszę gdzie, najpierw opis, co autor miał na myśli. Celem filmiku jest przedstawienie mojego doświadczenia ze znacznikiem g:submitToRemote w Grails. Niewiele znajdziecie w samym filmiku, ale to są skromne początki przecie...

Zainteresowanych odsyłam do obejrzenia mojej pierwszej, bezgłośnej 45-sekundówki na YouTube - Grails i ja - pierwsze próby ze screenkastami (testy). Wiele do poprawienia, ale nie od razu...Grudziądz zbudowano. Komentarze, uwagi, oceny mile widziane. Jakbym tak mógł porozmawiać z kimś, kto się screenkastami para, albo parał, byłoby superaśnie. Czego teraz mi najbardziej potrzeba to takiego słownego przewodnika.

p.s. Ach, i nie piszcie, że piszę screenkast zamiast screencast, bo to taki mój językowy dziwoląg :) Chciałbym tak trafić na jakiś chwytliwy dla tego odpowiednik jak skrinek albo podobnie.

09 grudnia 2009

58. spotkanie Warszawa JUG - Kirk Pepperdine's "Performance Tuning with Cheap Drink and Poor Tools"

0 komentarzy
With the cooperation of SUN Microsystems Poland and Grzegorz Duda (dWorld.pl), Warszawa Java User Group (Warszawa JUG) is proud to invite you to a talk with Kirk Pepperdine, a Java Champion focusing on all aspects of Java performance and tuning in each phase of a project life cycle, who will present "Performance Tuning with Cheap Drink and Poor Tools".

The talk takes place on Tuesday, December 15th at 6:00PM in the room 5440 of MIMUW on Banacha 2 street in Warsaw, Poland.

Here is how Kirk announces his presentation:

After a brief introduction to a methodology to performance tune Java applications, the audience will guide me through the steps needed to tune an application. The application models a number of performance problems that are common in real world applications. During the session, I will introduce a number of tools designed to expose causal code paths to each specific problem.

Kirk Pepperdine has been working in high performance and distributed computing for nearly 20 years. His focus has been on performance, working on architecting, developing, and tuning applications running on Cray and other high performance computing platforms. Kirk now specializes in Java, where he works in all aspects of performance and tuning in each phase of a project life cycle. Kirk was recognized by Sun Microsystems as a 2006 Java Champion recipient for his contributions to the Java community. He is a primary contributor and consultant to javaperformancetuning.com and is also the co-author of Ant Developer's Handbook.

The talk is scheduled for about 90 minutes with a free pizza included.

The seats are free of charge, however registration is highly appreciated.

07 grudnia 2009

Kolejny komentarz z Opola i tajemnicze "Your branch is ahead of 'origin/master' by..." przy git status

3 komentarzy
Dostałem dzisiaj kolejną wiadomość z opinią nt. warsztatów "Groovy & Grails" w Opolu.

Warsztaty Groovy/Grails generalnie mi się podobały, jednak oczywiście wszystko da się poprawić. Przede wszystkim były momenty, w których odnosiło się wrażenie (a przynajmniej ja je odnosiłem), że pomimo dużej wiedzy teoretycznej brakowało Ci nieco praktyki.

Poza tym myślę, że warto by było na samym początku przedstawić obraz z lotu ptaka na Groovy/Grails i możliwości, jakie oferuje. Obejrzałem prezentację (http://www.infoq.com/presentations/Web-Development-Grails-Graeme-Rocher), która w godzinę prezentuje kilka najważniejszych (tak mi się wydaje) cech Grailsów. Mając do dyspozycji dwa dni warsztatów, mógłbyś taki wstęp rozwinąć do dwóch godzin, a jednocześnie nieco szerzej przedstawić sam język Groovy (tak jak na warsztatach).

Skoro już mowa o prezentacji samego języka, to przedstawiając slajdy na temat jego cech (obiektowość, skryptowość) warto, moim zdaniem, rozważyć pokazywanie slajdu z definicją jakiejś cechy języka, po którym następuje fragment kodu Groovy, który tą cechę demonstruje (przy czym nie zagłębiać się za bardzo w szczegóły techniczne prezentowanego kodu).

Poza tym po dość pobieżnym przeglądnięciu dokumentacji Grailsów wydaje mi się, że trzeba by w czasie warsztatów przynajmniej wspomnieć o paru rzeczach, a mianowicie:

- wygenerowanych przez Grailsy metodach wyszukujących encje w bazie typu findByName() (na warsztatach było tylko widać w wygenerowanym z rusztowania kontrolerze metodę get()), tym bardziej, że jest to prawdopodobnie jeden ze sztandarowych przykładów na zastosowanie dynamicznej modyfikacji klas i mechanizmu MOP,

- krótka wzmianka o możliwości wykorzystania do wyszukiwania języka HQL (i kryteriów, jeśli byłby czas),

- testowanie (na warsztatach nawet nie otworzyliśmy pliku z prostym testem), gdyż na duży plus Grailsów należy zaliczyć udostępnienie gotowej infrastruktury do przeprowadzania testów,

- wtyczki, czego najbardziej brakuje, gdyż wydaje mi się, że jest to cecha, która ma szansę odróżnić Grails od innych rozwiązań (a wg Roadmap, wtyczki w wersji 2.0 mają być pakunkami OSGI, więc bardziej je zgłębiając będziesz mógł połączyć różne tematy, które cię interesują). W wspomnianej prezentacji jest pokazane jak szybko za pomocą wtyczek (a konkretnie wtyczki Searchable) szybko dodać obsługę wyszukiwania do aplikacji i ta cecha naprawdę może robić wrażenie.


Najbardziej trafne jest owe wskazanie na brak praktyki w pracy z Groovy/Grails. Zbyt często wchodziłem w pułapki technologiczne, których nie potrafiłem do końca wyjaśnić, a to pewnie właśnie z powodu niewielkiego doświadczenia praktycznego. Bardzo cenna wiedza przy "wzmocnieniu" kolejnych warsztatów. Zresztą sądzę, że uwagi są cenne nie tylko dla mnie, ale dla wszystkich przygotowujących warsztaty. Stąd pomysł na upublicznianie komentarzy i pomysł na powrót do nauczyciela. Jak to bywa w życiu, po kilku zmianach przyszło mi zmagać się z Git'em. Nie potrafiłem (a w zasadzie wciąż nie do końca potrafię) wyjaśnić, dlaczego wciąż pojawiał się komunikat "Your branch is ahead of 'origin/master' by 5 commits." przy wydawaniu polecenia git status.
 devmac:nauczyciel jacek$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 5 commits.
#
nothing to commit (working directory clean)
Zacząłem poszukiwania w Sieci i na stackoverflow w pytaniu Why is Git telling me “Your branch is ahead of ‘origin/master’ by 11 commits.” and how do I get it to stop? znalazłem rozwiązanie. Wystarczy przemianować origin na repo nauczyciela. Może przy kolejnym projekcie uda mi się zrozumieć, o co w tej zmianie chodzi. Może ktoś wyjaśniłby Jackowi?
 devmac:nauczyciel jacek$ git remote show origin
* remote origin
Fetch URL: git://github.com/jaceklaskowski/nauczyciel.git
Push URL: git://github.com/jaceklaskowski/nauczyciel.git
HEAD branch: master
Remote branch:
master tracked
Local branch configured for 'git pull':
master merges with remote master
Local ref configured for 'git push':
master pushes to master (up to date)

devmac:nauczyciel jacek$ git remote -v
origin git://github.com/jaceklaskowski/nauczyciel.git (fetch)
origin git://github.com/jaceklaskowski/nauczyciel.git (push)

devmac:nauczyciel jacek$ git remote rm origin

devmac:nauczyciel jacek$ git remote add origin git@github.com:jaceklaskowski/nauczyciel.git

devmac:nauczyciel jacek$ git status
# On branch master
nothing to commit (working directory clean)
Teraz jest czysto, ale dlaczego wcześniej nie było...hmmm...chyba nie rozumiem jeszcze tego Gita. Pomocy!

p.s. Jest robótka od zaraz przy projekcie z IBM WebSphere Message Broker w Warszawie (może i dałoby się zdalnie?). Nie wiem nic nt szczegółów cenowych, ale zlecający wydali mi się na tyle sensowni, że postanowiłem im pomóc w odnalezieniu właściwej osoby. Zainteresowany? Proszę o kontakt na priv.

06 grudnia 2009

Podsumowanie warsztatów "Groovy & Grails" w Opolu

8 komentarzy
Byłem, przeszkoliłem i...czekam na odzew uczestników. Na zachętę przedstawię opinię jednego z uczestników warsztatów "Groovy & Grails", które poprowadziłem na Wydziale Matematyki, Fizyki i Informatyki w Opolu w dniach 3-4.12.2009 (naliczyłem około 30 osób, więc wrażenia nie mogą skończyć się na tej jednej wiadomości, abym mógł poprawić swój warsztat prowadzenia warsztatów):

"Moim zdaniem warsztaty były bardzo udanym pomysłem. Przez 2 dni udało Ci się przyciągnąć moją uwagę na parę ładnych godzin, co nie jest takim łatwym zadaniem bo na ogół nie lubię tracić czasu na rzeczy, które mnie nie interesują i nie widzę w nich sensu (ba! mało tego, muszę powiedzieć, że te godziny bardzo szybko, a nawet za szybko minęły i szkoda, że nie ma trzeciego dnia). Przed spotkaniem do Grailsow podchodziłem ze średnim nastawieniem. Po spotkaniu jestem pod dobrym ich wrażeniem i wiąże z nimi kilka przyszłych projektów. Widzę w nich potencjał, a same warsztaty dały mi dobrą bazę startową i pozytywnego kopa.
Jeśli chodzi o moje zastrzeżenia, to uważam, że niepotrzebnie zagłębialiśmy się parę razy w niuanse Groovy'ego - co stawało się w pewnym momencie trochę nużące. Ogólnie rzecz ujmując uważam, że każdy język ma takie miejsca, a nawet same kolejne wersje Groovy'ego mogą się w tych kwestiach/rozwiązaniach różnić więc nie widzę sensu, żeby tak głęboko w to wchodzić. Kolejnym argumentem jest to, że jeśli ktoś korzysta jeszcze z innych narzędzi to o takich szczegółach języka prędzej czy później pewnie zapomni i będzie próbować/badać te kwestie przy bieżącym projekcie (tutaj bardzo dobrą drogą było pokazanie rozwiązywania takich zagadek poprzez konsolę).

Co do samego stylu przemowy to bardzo mi się podobał - mieszanka wiedzy + porcja dobrego poczucia humoru dobrze działa i potrafi utrzymać umysły w świeżości. No i dobrze, że nie było za dużo slajdów! ;)"


Jak można przeczytać, było znośnie. Widzę potrzebę kolejnych tego typu inicjatyw, bo nie tylko, że inni, ale ja sam wiele się nauczyłem. Trzeba przyznać, że okres przygotowań był dla mnie niezwykle intensywny w poznawanie tajników Groovy i Grails. W trakcie warsztatów spisałem sobie tyle ciekawostek do dalszego zbadania, że pewnie jeszcze przez kilka tygodni para Groovy i Grails stanowić będzie źródło wpisów na moim blogu (może choć w ten sposób przybliżę czytelnikom bloga atmosferę warsztatów). Miałem takiego pietra, że 2 dni warsztatów jest zdecydowanie zbyt długo, że zaplanowałem pokazać całego Groovy i Grails, a i tak wychodziło mi, że jeszcze zostanie trochę czasu. Do samego rozpoczęcia byłem pewien, że zamiast 2 dni wystarczą 2 godziny (!) Nie długo trwało zanim przekonałem się jak bardzo się myliłem.

Przyjechałem do Opola wieczorem w środę (4,5h jazdy pociągiem IC). Jacek Hromiński (Opole JUG) odebrał mnie z dworca i poszliśmy do najbardziej obskurnego hotelu jaki miałem okazję odwiedzić - Hotel Zacisze. Miałem wrażenie, że znalazłem się w hostelu. Pani na recepcji od razu zażądała zapłaty z góry za 1 nocleg i to gotówką, bez możliwości płacenia kartą. Później sam pokój w standardzie do zaakceptowania z dostępem do sieci, ale już na korytarzu przed moimi drzwiami była...palarnia (!) Na moje pytanie "Dlaczego?" dowiedziałem się, że gościom nie chce się schodzić na dwór palić, więc mimo, że mam pokój dla niepalących to "okolica" nie dała tego poznać. Przeniosłem się do hotelu "Hotel Piast". Tutaj warunki znacznie odbiegały od standardu Zacisza (w pozytywnym tego słowa znaczeniu).

Czy ja pisałem, że w Opolu temperatura przywitała mnie minusowa?! Chyba nie, a w porównaniu z temperaturami w Warszawie (przed i już po wizycie w Opolu) to czułem się jak na Syberii. Ziąb, że na samochodach pojawił się szron. A rano...zresztą sami zobaczcie.

I tak przez całe 2 dni. Trząsłem się jak galareta i marzłem, kiedy chodziliśmy po Opolu, szczególnie wieczorami. Pod tym względem cieszę się, że już jestem w domu.

A w kontekście samej wiedzy o Groovy i Grails, to skoncentrowałem się na tych cechach Groovy, które upraszczają tworzenie aplikacji bez porównywania z Javą (której można powiedzieć, że jest..."nakładką", bo ostatecznie i tak kończymy na bajtkodzie w ramach możliwości JVM). Było kilka slajdów, ale nie za wiele. Bazowałem na materiale z książki Groovy in Action Dierk'a Koenig'a (na jej pierwszym wydaniu, bo ją miałem w wersji elektronicznej). Zabrałem jeszcze kilka innych książek, aby ostatecznie skoncentrować się na uproszczeniach składniowych Groovy z domknięciami na pierwszym planie oraz później ich znaczeniu w Grails. W końcu udało mi się zrozumieć akcje Grails, które są niczym innym jak zmiennymi z przypisanymi domknięciami. Niby proste i człowiek używał, ale już wyjaśnić dlaczego tak, to już nie było łatwe. A teraz już jest. Z Grails omówiłem podstawy - pracę bez wsparcia IDE przy tworzeniu aplikacji webowej z klasami dziedzinowymi z relacjami 1-1 i *-* (w międzyczasie wyszedł błąd w wersji 1.1.2, który muszę jeszcze zgłosić), kontrolery z dynamicznym i statycznym rusztowaniem, widoki ze znacznikami GSP oraz na koniec usługi i IoC. Zabrakło choćby wzmianki o Ajax, wtyczkach i więcej o testowaniu.

Dla mnie było super! Chciałbym, aby podobne inicjatywy były dostępne na innych uczelniach i okazuje się, że we współpracy z Unią Europejską jest to możliwe. Piszcie na priv, jeśli jest zainteresowani tego typu przedsięwzięciami, a szczególnie poprowadzeniem takich warsztatów w innych miastach. Ja jestem zainteresowany. Dzięki temu ponownie wróciłem do rozwijania aplikacji Nauczyciel. Zainteresowanych zapraszam do udziału. Trzeba było roku, abym poczuł klimaty wokół Grails :)

Ach, i bym zapomniał. Już wspominałem o tym, ale jeszcze mi się nie znudziło i powtórzę ponownie :) Pracuję na Macu, więc zabawy mam co nie miara, chociażby wyłącznie tylko z tego powodu. Nauczyłem się tych wszystkich palcówek i, pomijając wpadki z klawiszem Cmd (mac'owe jabłko) zamiast Alt przy wprowadzaniu polskich znaków, jest cacy. Ba, jest bardziej niż cacy, bo w końcu zrealizowałem swój pomysł pracy na Uniksie z poziomu linii poleceń z wyrafinowanym systemem okienkowym. Każdemu polecam przesiadkę na Maca, aby zasmakował tego przyjemnego uczucia zwiększonej produktywności z wykorzystaniem możliwości oferowanych przez Mac OS. I ta bateria na 8h. W porównaniu z tymi cegłami z Lenovo...co ja piszę...to jest bez porównania. I jeśli zastanawiasz się, jaki to ma związek z Opolem i moimi warsztatami tam, to niestety, ale nie mogłem wykazać się z prezentacjami na Macu, bo zabrakło przejściówki między nim a projektorem :( Niestety już teraz nie ma adaptera mini-VGA w komplecie z samym laptopem i skończyło się na eksporcie prezentacji do PDFa z Keynote i przesiadka na PeCeta. Cóż, człowiek uczy się na błędach, co w moim przypadku zawsze kończy się na moich :) Pewnie poza zakupem tej przejściówki (100PLN) będę jeszcze musiał kupić licencje na Parallels lub VMware Fusion (do uruchamiania obrazów linuksowych z oprogramowaniem IBM WebSphere), ScreenFlow lub Camtasia (do nagrywania screencastów) i pewnie iWork (prezentacje). Wydatek rzędu 300USD. Cóż, jazda rollsem odciska swoje piętno na moim budżecie. Z niecierpliwością czekam na licencje korporacyjne...

02 grudnia 2009

57. spotkanie Warszawa JUG - Własny mały guglik, czyli jak wbudować silnik wyszukiwania Compass

0 komentarzy
Warszawska Grupa Użytkowników Technologii Java (Warszawa JUG) zaprasza na 57. spotkanie, które odbędzie się we wtorek, 8. grudnia o godzinie 18:00 w sali 5440 Wydziału MIMUW przy ul. Banacha 2 w Warszawie.

Temat: Własny mały guglik, czyli jak szybko i prosto wbudować silnik wyszukiwania w swoją aplikację z pomocą projektu Compass
Prelegent: Marcin Zajączkowski

W czasie prezentacji przedstawione będzie zagadnienie pełnotekstowego wyszukiwania informacji w zbiorze danych oraz jego przydatność w tworzonych na co dzień projektach. Marcin przedstawi bibliotekę Compass, która jest nakładką na silnik wyszukiwania Apache Lucene, wraz z jej mechanizmami znacznie upraszczającymi i przyśpieszającymi pracę z indeksowaniem danych, wychwytywaniem wprowadzanych w nich zmian oraz samym wyszukiwaniem. Zobaczymy jak (przy odrobinie szczęścia) typowa aplikacja webowa wzbogaci się w "niezwykłą" aplikację posiadającą wbudowany silnik wyszukiwania.

Marcin Zajączkowski zajmuje się programowaniem od lat. Obecnie piastuje stanowisko architekta w dużej polskiej firmie tworzącej oprogramowanie. Interesuje się szczególnie architekturą systemów, wzorcami projektowymi oraz zagadnieniami integracyjnymi. Jest zwolennikiem zwinnego podejścia do tworzenia oprogramowania. Poza światem Java miłośnik wolnego oprogramowania, w szczególności powiązanego z systemem Linux.

Planowany czas prezentacji to 1,5 godziny, po której planuje się 15-30-minutową dyskusję.

Wstęp wolny

Zapraszam w imieniu prelegenta i grupy Warszawa JUG!

01 grudnia 2009

Book review: Grails A Quick-Start Guide

0 komentarzy
W czwartek informacja o nowej książce o Grails w ofercie O'Reilly, w piątek przychodzi przesyłka (nie PDF, ale książka w okładce!), a dzisiaj mam przyjemność opublikować moje spojrzenie na zawartą w niej treść. Co będę się rozpisywał - książka jest idealna dla każdego, kto choćby przez chwilę rozważał Grails jako kolejny szkielet webowy, który chciałby poznać, ale niestety ograniczenia czasowe wciąż krępują ręce. 200 stron przechodzi się w mgnieniu oka i zanim się obejrzysz będzie po książce. Jest dostępna w Biblioteka Warszawskiego JUGa, więc już nie wykręcisz się, aby jej nie przeczytać. Po prostu warto poświęcić 1-2 dni i zmierzyć się z prostotą Grails przez pryzmat tej książki. A i bardziej zaawansowani użytkownicy Grails znajdą coś dla siebie. Niewiele, ale i tak warto dla samego stylu literackiego Dave'a. Zainteresowanych proszę o kontakt na priv.

Recenzja w języku angielskim (zgodnie z zasadami wydawnictw książka za recenzję) właśnie ujrzała światło dzienne na moim Wiki - Book review: Grails A Quick-Start Guide. Uwagi mile widziane, bo w końcu nikt nie powiedział, że recenzja nie może mieć swojej recenzji. Jak się pisze po polsku, to można zapomnieć o właściwej składni w angielskim :)

Tym samym rozwiązałem moją główną bolączkę przed nadchodzącym warsztatem na Uniwersytecie Opolskim w ten czwartek i piątek (informacje o nim na forum Opole JUG). Zaplanowałem sobie, że przeczytanie tej książki będzie doskonałym odświeżeniem wiadomości o Grails, ale stanie się czymś więcej - będzie moim przewodnikiem. Właśnie tak! Poprowadzę warsztat, jakbym referował tę książkę, a uzupełnienia (rozszerzenia) poszukam w tych pozostałych, bardziej zaawansowanych. Podeprę się jeszcze agendą z Groovy & Grails Training Syllabus oraz Groovy and Grails Application Development (with Passion!) i powinno być cacy. Zobaczymy jak ocenią to sami zainteresowani. Nie pisałem już, że odczuwam presję?!

27 listopada 2009

Pierwszy wpis z Maca - Ty go masz i ja go mam!

7 komentarzy
I się doczekałem. Ty go masz i ja go mam - swojego nowiutkiego, laptopowego Rolls-Royce'a - 15'' MacBook Pro z 8 GB RAMu!

Dzięki uprzejmości mojej korporacji, zamiast zajmować się przygotowaniami do warsztatów grailsowych na Uniwersytecie Opolskim, zabawiam się Makiem (!) I tak długo wytrzymałem, bo mam go od 3 dni, a jedynie co, to włączyłem go raz, może dwa razy i tyle. Dzisiaj jednak nie wytrzymałem - wymieniłem tego 3-dniowca na nowiutkiego z pudełka. I tak się zaczęło. Ten wpis idzie wprost z niego. Tutaj nawet pisanie stanowi wyzwanie. Nie wspomnę o menu u góry, czy te gesty na gładziku! Zresztą zobaczcie sami na filmiku - na tej stronie (szukajcie "Multi-Touch Trackpad"). A żebym wiedział, jak przejść na koniec linii?! A zrobienie zrzutu ekranu "kosztowało" mnie wizytę na Taking Screenshots in Mac OS X ;-)

Jakby tego było mało, wczoraj O'Reilly wysyłał wiadomość z informacją o książce Grails -
A Quick-Start Guide
. Co miałem robić? Zaraz napisałem do Josette, że potrzebuję tej książki i najlepiej, aby była przed poniedziałkiem i...dostałem ją w niecałe 30h (!) To się nazywa szybka przesyłka. Zacząłem czytanie...

p.s. Praca na Macu przypomina mi podobne odczucia jak przy spotkaniu z programowaniem funkcyjnym z Clojure. Całkiem odświeżające doznania. To lubię.

26 listopada 2009

Skróty stron w Google Chrome - aplikacje webowe jak desktopowe

6 komentarzy
Jedną z wielu rzeczy jakie dane jest nam zaznać podczas konferencji czy spotkań JUGowych jest możliwość podejrzenia warsztatu i narzędzi, których używają inni. Zawsze przyglądam się wokół przypatrując się, jak ludziska posługują się kompem i jakich sztuczek używają. Często sama prezentacja nie wnosi wiele, ale cała otoczka może dostarczyć ciekawych podpowiedzi lub gotowych rozwiązań.

Tak było podczas Eclipse DemoCamp we Wrocławiu, kiedy u Grześka Białka podejrzałem na pulpicie skróty do...aplikacji webowych. Niby nic odkrywczego, ale dla mnie to była "rewolucja umysłowa" (ostatnio przechodzę całe pasmo takich odkrywczych sytuacji, więc tylko czekać, kiedy zejdę na serce od tych achów i echów :)). Nie mogłem się powstrzymać i zamiast przygotowywać się do EDC zacząłem wypytywać Grześka o te skróty. I okazało się, że nieużywany przeze mnie Google Chrome ma coś, co wydało mi się niezwykle interesujące - tworzenie skrótów aplikacji webowych traktując je jako aplikacje desktopowe uruchomione w Internecie (!)

Wystarczy wejść na wybraną stronę i skorzystać z menu "Create application shortcuts...", aby pojawiło się okienko dialogowe, w którym wybieramy miejsce zapisania skrótu.

Po tym tworzony jest skrót, a sama aplikacja webowa otwierana jest bez wszystkich bajerów przeglądarki - pasek przycisków, menu, itp. - a w dodatku na pasku zadań pojawia się ikona strony zamiast przeglądarki.

Po jakimś czasie można skończyć z wieloma skrótami i można przypuszczać, że niedługo trudno będzie zorientować się, czy dany skrót prowadzi do aplikacji zainstalowanej lokalnie, czy dostępnej w Sieci.

Mała rzecz, a cieszy. Teraz wiele z aplikacji webowych doczekało się u mnie swoich skrótów. Fajnie to wygląda w aplikacjach typu Facebook, gdzie w przypadku Chrome ów pasek na dole w FB nabiera sensu - wpasowuje się ciekawie w jego obudowę. Może mi ktoś podpowiedzieć, jak to jest zrobione? jQuery, Prototype, script.aculo.us, ExtJS, czy może coś większego jak YUI albo Dojo Toolkit? Mam na (wirtualnej) półce książki o jQuery i Prototype, i nie ukrywam, że zamierzam po nie sięgnąć. Wolałbym jednak znać odpowiedź wcześniej, jeśli można.

Jeśli tak się zastanowić nad trendem migracji z aplikacjami do Sieci, to faktycznie wracamy do czasów, gdzie komputer będzie ponownie prostym terminalem, którego zadaniem będzie uruchomienie przeglądarki. W końcu zamiast instalować aplikacje lokalnie możemy z nich skorzystać w modelu SaaS już dzisiaj. Jeśli Sieć będzie wszechobecna, to pewnie wcześniej czy później wszystko wypchniemy do niej.

I w ten sposób nie tylko IDE (zintegrowane środowisko programistyczne) mam w kilku wydaniach, ale i przeglądarki. Sądzę, że tym samym potwierdziła się zasada, że różnorodność daje więcej niż próba nagięcia rozwiązania do wykonywania rzeczy, do których nie była przeznaczona. W kontekście IDE, korzystam z Eclipse IDE, NetBeans IDE i IntelliJ IDEA, a w przeglądarkach, obok Firefoksa pojawił się Chrome. Czasami zdarza mi się zajrzeć do IE (wymagania aplikacji) lub Apple Safari, ale to niezwykle rzadko. W przypadku Safari pewnie się trochę odmieni, kiedy wejdę na Mac'a. A to już jutro!

25 listopada 2009

Book review: Pro IBM WebSphere Application Server 7 Internals

6 komentarzy
W końcu i ją mam za sobą. Po kilkunastu dniach, a w zasadzie możnaby powiedzieć tygodniach, ukończyłem lekturę książki "Pro IBM WebSphere Application Server 7 Internals". Tak nudnej książki nie miałem od czasu lektur szkolnych, a i tak większość z nich podobała mi się bardziej. Jeśli ktokolwiek rozważa zmierzenie się z IBM WebSphere Application Server 7, niech zastanowi się dwa razy, czy warto inwestować swój czas w tę książkę. Zdecydowanie odradzam.

Recenzja w języku angielskim (zgodnie z zasadami wydawnictw książka za recenzję) właśnie pojawiła się na moim Wiki - Book review: Pro IBM WebSphere Application Server 7 Internals.

Tym samym kończę czytanie książek do następnego weekendu i wracam do Groovy & Grails. Za tydzień prowadzę warsztaty na Uniwersytecie Opolskim. Sądzę, że panowie ze SpringSource nie będą mieli mi za złe, jeśli oprę swoje na ich materiale szkoleniowym ze strony Groovy & Grails Training Syllabus. Może choć w części uda mi się zbliżyć do ich wiedzy z tego tematu i przekazać solidną porcję Groovy i Grails?! Zaczynam odczuwać presję czasu...

22 listopada 2009

21 listopada 2009

Eclipse DemoCamp we Wrocławiu aż nazbyt emocjonujący

1 komentarzy
Właśnie doświadczyłem niezwykle interesującego zakończenia Eclipse DemoCamp 2009 we Wrocławiu. Siedzę sobie w hotelu Diament, po tym, kiedy odwołano ostatni lot do Warszawy ze względu na niewielką widoczność na lotnisku Okęcie. Zawrócono samolot spod Łodzi, abym ponownie zjawił się we Wrocku i po godzinie zamieszania znalazł miejsce w hotelu na koszt Lotu (taksówka z/na lotnisko i śniadanie w cenie). Hotel nowy i przyzwoity, ale to, że zamiast siedzieć w weekend w domu, siedzę w hotelu do najprzyjemniejszych nie należy. Wykańczający jest również brak pożądnego miejsca, gdzie możnaby coś zjeść na lotnisku. Pozostają kanapki i futrowanie się słodyczami :( Kolejnym razem pomyślę dwa razy zanim wybiorę przelot powrotny do Warszawy ostatnim rejsem.

A wracając do samej konferencji, to byłbym nieprzyzwoicie nieprzyzwoity, gdybym nie napisał, że warto było wstać o 5:30, aby móc w niej uczestniczyć. Możliwość spotkania się z Grzegorzem Białkiem, Krzyśkiem Kowalczykiem, Jackiem Pospychałą i innymi programistami Java z Wrocławia bezsprzecznie kwalifikuję jako bezcenne doświadczenie w moim życiu. Było wiele o wnętrzu platformy Eclipse, że w pewnym momencie mnogość akronimów mnie przygniotła. Nie zdawałem sobie sprawy, że jest tyle projektów pod parasolem Eclipse Foundation - EMF, XPAND, ATF, to tylko niektóre, które odnotowałem. Widać różnicę w podejściu do Eclipse DemoCamp w Warszawie a Wrocławiu. My (Warszawa) proponujemy raczej narzędziową stronę Eclipse IDE, podczas gdy oni (Wrocław) oferuje zajrzenie w głąb Eclipse jako platformy. Ciekawe doświadczenie móc zobaczyć produkt od tej strony. Nie ukrywam, że czułem się lekko zmieszany tą niewiedzą produktową o Eclipse.

Jacek Pospychała rozpoczął EDC z prezentacją na temat niedoskonałości darmowej "oferty" Eclipse IDE, aby pokazać nam swoje cudo oparte o Eclipse Ajax Tools i Web Tools Platform - Zend Studio. Podobało mi się, bo umożliwiało śledzenie wykonywania HTML, CSS i JavaScript, czyli tych technologii, wokół których krążę, ale ze względu na brak narzędzi programistycznych zwykle traktuję notatnikiem, albo innymi zewnętrznymi do IDE narzędziami, jak Firebug. Z Zend Studio możemy mieć to w ramach Eclipse IDE (pomijając fakt, że to narzędzie rodem z PHP).

Później na scenie pojawił się Grzesiek Białek - organizator wrocławskiego EDC i rozpoczął swoją krucjatę nt. Eclipse Modeling Framework (EMF). Generatory rządzą. Tak mogłem odebrać prezentację Grześka. To, że nie tylko ja odjechałem na jego prezentacji niech świadczy, że komputer wiedział, jaki materiał go czeka i chyba zlitował się nad publiką prezentując...Blue Screen of Death. I to na samym początku! Grzesiek rozpoczął od prezentacji swojego dzieła licencjackie - ruch ręką w 2001, później 2003 większa aplikacja na modelu, aby w 2004+ wszedł na Eclipse Platform.
Na sali była część osób, które buduje/-owały rozwiązania na Eclipse Platform. Zdaniem Grześka, Eclipse EMF napędza niektóre zmiany w samej Java SDK, np. w Java 7 będzie coś co powstało początkowo w EMF, a teraz jest "wczytywane" w Java SE (niestety nie pamiętam, co to było). Jako podsumowanie jego wystąpienia niech przytoczę zdanie, które padło po kilku moich pytaniach - "Nie brakuje mi niczego, co mógłbym otrzymać od Eclipse EMF, bo jeszcze nie wiem, czego mogłoby mi brakować" :)

Po Grześku pizza i moja prezentacja nt. powiązania Enterprise JavaBeans i OSGi z Apache OpenEJB. Po zaplanowanych 1,25h mógłbym skończyć, ale nie wykazano zainteresowania tym planem, więc skończyłem po 2h. Miałem wrażenie, że przekazywałem wiedzę składnie (brak skromności to moje drugie ja) i kontakt z publicznością został nawiązany, więc liczę na kilka ciekawych inicjatyw wokół tematu EJB3, OSGi i OpenEJB z kierunku południowo-zachodniej strony Polski. Ja jestem zadowolony z dyskusji, jakie się wywiązały i pomijając odpowiedź z XMLem było cacy (pozdrowienia dla zwycięzcy wafelka :)). Chciałbym wierzyć, że publika również wyszła zadowolona z mojej prezentacji zakończonej demonstracją rozwiązania w akcji.

A faktycznie wyszła, więc kiedy pojawił się Krzysiek Kowalczyk było już ciemno za oknem i część publiki się rozeszła. Pewnie trochę zmęczyłem ich tym moim gadaniem i jeszcze pora, więc sorry Krzysiek za przepłoszenie potencjalnych zainteresowanych tematyką, którzy nie mogli doświadczyć cudów techniki w Eclipse z Twojej perspektywy. Ponownie pojawił się EMF i...niestety, ale odpuściłem sobie występ Krzyśka. Odsiedziałem swoje przed kompem na holu.

W międzyczasie wywiązała się dyskusja na tematy różne, która zakończyła się dyskusją nt. anglicyzmów w naszym języku branżowym. Argumenty padały za i przeciw stosowaniu polskich odpowiedników, ale te, które użyłem w mojej prezentacji OSGi zostały zaakceptowane bez dwóch zdań. Ufff.

Bardzo ucieszyłem się, kiedy widziałem grupki rozmawiających ze sobą osób. Czuć było klimat społecznościowy EDC. Było około 35 osób. Z tego, co mówił Grzesiek chciało przyjść więcej, ale ze względu na wymogi żywieniowe zdecydował się na zamknięcie rejestracji przy 40tu zarejestrowanych.

Podsumowując, było fajnie. Były również zdjęcia, ale na nie poczekamy, aż Grzesiek i Krzysiek wrzucą je na Sieć. Dziękuję Grześkowi za zaproszenie na EDC i możliwość wystąpienia z prezentacją o moich ostatnich dokonaniach w Apache OpenEJB. Nie żałuję!

Włączam tryb oczekiwania na foty...

p.s. Jesienny Eclipse DemoCamp 2009 w Warszawie już w nadchodzący wtorek, 24.11 od 18tej na MIMUWie.

20 listopada 2009

Od dzisiaj zwą mnie "IBM Certified System Administrator - WebSphere Application Server, Network Deployment V6.1"

2 komentarzy
"Jak się zwał, tak się zwał, byleby się dobrze miał!"

Po prawie 4 latach pracy w IBM z produktami z rodziny IBM WebSphere mam swój pierwszy certyfikat produktowy "Test 000-253: IBM WebSphere Application Server Network Deployment V6.1, Core Administration" i tym samym przywdziałem szaty "IBM Certified System Administrator - WebSphere Application Server, Network Deployment V6.1".

Z wynikiem 64% mam jeszcze wiele do nauki w temacie administracji WASem 6.1, ale jak to się mówi "dobrego złe początki" i wierzę, że przy kolejnym teście z WASa, tym razem już na poziomie wersji V7.0, będzie zdecydowanie lepiej. Tak przynajmniej zamierzam tłumaczyć niski wynik przyszłym klientom :)

18. grudnia jestem zapisany na test "Test 000-375 - IBM WebSphere Process Server V6.2, System Administration", który, wraz z dzisiejszym, da mi tytuł "IBM Certified Deployment Professional - WebSphere Process Server V6.2". Po tych kilku latach zbierania doświadczeń z tym produktem (od wersji 6.0.2, przez 6.1 i 6.1.2) powiedziałbym "W końcu!".

Nauka do egzaminów, jak i one same, są jednym z wielu sposobów na poprawienie wiedzy technologicznej i nawet po nieudanym podejściu wiemy więcej. Można je krytykować za błędy, niejasne sformułowania pytań, itp., ale dla mnie stanowią sposób na poprawienie własnego samopoczucia technologicznego. Kiedy już w czasie mojego rentierskiego życia spojrzę na te wszystkie certyfikaty produktów, które już dawno wycofano z rynku, pewnie uśmiechnę się i pomyślę, że nie było warto. Cóż zrobić, kiedy człowiek taki małostkowy? :)

18 listopada 2009

Makro wplatania -> raz jeszcze i macroexpand

2 komentarzy
To pewnie jedno z ostatnich wpisów dotyczących Clojure przed rozpoczęciem wspomnianego egzaminu technologicznego, w której na niego nie będzie po prostu miejsca (patrz wpis OSGi, EJB, Eclipse, OpenEJB, Groovy i Grails we Wrocławiu, Warszawie i Opolu).

OSGi i OpenEJB na wrocławski DemoCamp mam opanowane, więc pozostaje jedynie przygotować prezentację - kilka slajdów zdecydowanie wystarczy. Będzie dużo kodu źródłowego, więc dobrze byłoby znaleźć sposób, aby jego prezentacja była w stopniu zadowalającym. Tutaj chętnie zaczerpnąłbym jakiś pomysł z doświadczeń innych. Jeśli widziałeś/widziałaś prezentację, w której gro materiału to kod źródłowy, wesprzyj mnie i wskaż te techniki prezentacji, które są istotne i wpłyną na jego odbiór. Może być w komentarzu, albo na skrzynkę jacekXlaskowski.net.pl (uwaga na X!).

Z wtyczką do OpenEJB na warszawską edycję DemoCamp nie będzie czego prezentować inaczej niż interaktywnie, aczkolwiek zastanawiam się, czy zrzuty ekranu jako slajdy nie byłyby ciekawszą alternatywą. Wiadomo wtedy, ile zajmą czasu, a jeśli zostanie go trochę po slajdach, można uruchomić środowisko i przeklikać to tu, to tam.

Najbardziej jednak przerażony jestem 2-dniowym maratonem z Groovy i Grails. Niby możnaby mówić o nich nawet przez cały tydzień przechodząc od podstaw języka Groovy i jego bardziej zaawansowanych możliwości, aby później zająć się Grailsami, w których tematów do omówienia/prezentacji w działaniu co nie miara, a mimo wszystko mam obawy do właściwego przygotowania. To w końcu będzie 2 dni i jakby to nie nazwać będzie miało to znamiona szkolenia/warsztatów. Kiedy się nad tym zastanowię, obawiam się najbardziej zmęczenia słuchaczy, więc dobrze byłoby przygotować coś odświeżającego, co jakiś czas. I tu ponownie zwracam się z prośbą do osób, które zamierzają uczestniczyć w spotkaniu, bądź mają doświadczenie w przygotowaniu tego typu imprez o wskazówki odnośnie dynamiki wprowdzania materiału. Niejednokrotnie brałem udział w szkoleniach jako prowadzący, ale po prostu zgodnie z materiałem, czasem musiał być teoretyczny i nudny. Wolałbym uniknąć takich sytuacji. Sugestie mile widziane.

Wspomniałem, że może to być ostatni wpis o Clojure przez najbliższe 3 tygodnie, bo po prostu nie będzie on tematem najbliższych prezentacji. I tutaj mam pewien sprytny plan, aby powiązać Clojure, a przynajmniej funkcyjne mechanizmy w stylu map, reduce i filter, z Groovy i Grails. Sam Groovy wspiera konstrukcje funkcyjne i czuję, że warto o nich wspomnieć podczas tych 2-dniowych warsztatów, bo nie tylko ja mógłbym się czymś odmiennym niż OO podzielić z uczestnikami, ale skoro jestem na uniwersytecie, to potencjalnie w zamian ja mógłbym dowiedzieć się czegoś ciekawego o programowaniu funkcynym od słuchaczy. W końcu co dwie głowy, to nie jedna. W Groovy mamy konstrukcje funkcyjne, a w Grails nawet wtyczkę do Clojure - Grails Clojure. W ten sposób mógłbym związać Groovy, Grails i Clojure. Być może nie ma to większego sensu poza skomplikowaniem prostoty tandemu Groovy i Grails, ale możliwość integracji istnieje i kto wie, jakie niesie to ze sobą możliwości. Pomysł jest, a wyjdzie w praniu jak pójdzie jego realizacja.

Wracając do Clojure, to dzisiaj poznawałem tajniki programowania w nim przez pryzmat wątku swap two elements in an arbitrary collection na grupie dyskusyjnej użytkowników Clojure. W nim pojawiło się omawiane wcześniej makro wplatania -> ("thread"), więc choćby z tego powodu warto do niego zajrzeć. Pojawił się tam następujący zapis:
 (defn swap [v i j]
(-> v (assoc i (v j)) (assoc j (v i))))
Wiemy już, że jest on równoważny następującemu zapisowi:
 (defn swap [v i j]
(assoc (assoc v i (v j)) j (v i))
Co mnie jednak zaintrygowało w tym wątku to możliwość rozwiązania makro za pomocą macroexpand-1, tak jak ma to miejsce w trakcie kompilacji. Teraz pamiętam, że czytałem o tym w książce Clojure Programming, ale tam było tyle tego, że się zapomniało.
 user=> (doc macroexpand-1)
-------------------------
clojure.core/macroexpand-1
([form])
If form represents a macro form, returns its expansion,
else returns form.
Zatem możemy naocznie przekonać się, czy faktycznie oba w/w zapisy są równoznaczne. W końcu makro jest rozwijane do pewnej formy w Clojure, a za pomocą macroexpand-1 dowiemy się do jakiej.

Zacznijmy od sprawdzenia, czy makro wplatania jest faktycznie makrem w Clojure (a nie tylko tak się nazywa).
 user=> (doc ->)
-------------------------
clojure.core/->
([x] [x form] [x form & more])
Macro
Threads the expr through the forms. Inserts x as the
second item in the first form, making a list of it if it is not a
list already. If there are more forms, inserts the first form as the
second item in second form, etc.
Każde makro jest specjalnie traktowane w Clojure i fakt bycia makrem jest wskazane przez funkcję (doc) przez wypisanie "Macro". To wystarczy. Sprawdźmy, co będzie wynikiem rozwinięcia makra -> w przypadku przykładu wyżej ze swap.
 user=> (macroexpand-1 '(-> v (assoc i (v j)) (assoc j (v i))))
(clojure.core/-> (clojure.core/-> v (assoc i (v j))) (assoc j (v i)))
Warto zauważyć, że aby zadziałało makro musimy przekazać mu listę do rozwinięcia (jak ma to miejsce w fazie wczytywania kodu przez analizatorem składniowym Clojure). Stąd skorzystałem z konstrukcji '(), która tworzy listę będącej postacią formy podczas wczytywania kodu przed kompilacją (faza rozwijania makr).

Jak widać samo macroexpand-1 nie wystarczy, bo rozwija jedynie pierwsze wystąpienie makra. Zdecydowanie za mało, aby zorientować się w jego działaniu. Sądziłem, że potrzebujemy kolejnej funkcji macroexpand, która wywołując macroexpand-1 wielokrotnie rozwinęłaby serię form do postaci "bezmakrowej".
 user=> (doc macroexpand)
-------------------------
clojure.core/macroexpand
([form])
Repeatedly calls macroexpand-1 on form until it no longer
represents a macro form, then returns it. Note neither
macroexpand-1 nor macroexpand expand macros in subforms.

user=> (macroexpand '(-> v (assoc i (v j)) (assoc j (v i))))
(assoc (clojure.core/-> v (assoc i (v j))) j (v i))
Jakież było moje zdziwienie, kiedy przekonałem się, że nie, a przecież nie powinienem się dziwić, bo wyraźnie napisane w dokumentacji macroexpand "neither macroexpand-1 nor macroexpand expand macros in subforms" :( Może jednak się da, a ja o tym nie wiem?! Pomysły?

OSGi, EJB, Eclipse, OpenEJB, Groovy i Grails we Wrocławiu, Warszawie i Opolu

2 komentarzy
Nadchodzące 3 tygodnie staną się moim sprawdzianem technologicznym, w którym pojawię się dwukrotnie na Eclipse DemoCamp we Wrocławiu i Warszawie, aby zakończyć z Groovy i Grails na Uniwersytecie Opolskim.

Najpierw będzie Wrocław. W nadchodzącą sobotę, 21.listopada 2009, podczas 2. edycji Eclipse DemoCamp przedstawię temat "Enterprise JavaBeans (EJB) na OSGi". Agendę zaplanowałem na 1,25h:
  1. Wstęp do OSGi (pakunek, aktywator, MANIFEST.MF, usługi, różne implementacje - Apache Felix, Eclipse Equinox - 15 minut)
  2. Uruchomienie pakunku na platformie OSGi (15 minut)
  3. "OSGi jako platforma SOA (pojedynczej JVM)" - uruchomienie pakunku usługowego (15 minut)
  4. Uruchomienie EJB3 jako pełnoprawnego pakunku OSGi z OSGifikowanym kontenerem EJB3 - Apache OpenEJB 3.1.2 (30 minut)
Będzie to relacja z moich ostatnich doświadczeń z kontenerem EJB3 - Apache OpenEJB i jego migracji na platformę OSGi. Przedstawię problemy, głównie mentalne, z jakimi borykałem się, aby ostatecznie uruchomić paczkę EJB jako pakunek OSGi i wdrożyć ją na OpenEJB, który również działa jako zestaw pakunków OSGi. Podszedłem do tematu około miesiąca temu i jedynym celem było dotarcie do tej konfiguracji wszelkimi sposobami. Udało się i teraz będę mógł to zaprezentować szerszemu gronu.

Póżniej, już w Warszawie, podczas Jesiennego Eclipse DemoCamp 2009 we wtorek, 24. listopada 2009 20 minut z tematem "OpenEJB Eclipse Plugin - EJB 3.1 z Apache OpenEJB w Eclipse IDE". Tym razem przedstawię wtyczkę eclipsową do pracy z EJB 3.1 i Apache OpenEJB. Więcej informacji na temat tego rozwiązania w nagraniu OpenEJB Eclipse Plugin Alpha Released!. Uczestnicy zobaczą wtyczkę na żywo.

Wstęp wolny, aczkolwiek rejestracja na oba Eclipse DemoCamp zalecana (linki są na ich stronach).

Ostatnie 2 dni - 3-4. grudnia 2009 - jestem w Opolu na Uniwersytecie Opolskim, gdzie przedstawię możliwości tandemu Groovy i Grails. Wstępna agenda prezentuje się następująco:

Czwartek 3.12
9:00-10:30 - pierwsza sesja
10:30-10:45 - przerwa kawowa
10:45-12:15 - druga sesja
12:15:13:30 - przerwa obiadowa
13:30-15:00 - trzecia sesja
15:00-15:15 - przerwa kawowa
15:15-16:45 - czwarta sesja

(+ ewentualne spotkanie relaksacyjne po 19:00)

Piątek 4.12
9:00-10:30 - pierwsza sesja
10:30-10:45 - przerwa kawowa
10:45-12:15 - druga sesja
12:15:13:30 - przerwa obiadowa
13:30-15:00 - trzecia sesja
15:00-15:15 - przerwa kawowa
15:15-16:45 - czwarta sesja

i wyjazd do Warszawy. Będzie ciekawie technologicznie. Wszelkie informacje u liderów wspomnianych JUGów. Zapraszam!

p.s. Podczas nauki Clojure na YouTube znalazłem zestaw 10-ciu 10-minutówek o nim (aż mi się język łamię, jak to czytam :)) Tak mi się spodobały prezentacje, że zapożyczyłem sobie ich szablon, który zamierzam wykorzystać podczas moich nadchodzących prezentacji. Zobaczymy, czy uatrakcyjni to odbiór. Dla mnie super!

13 listopada 2009

Funkcyjne wyjście z REPL z (exit) i ankieta językowa

11 komentarzy
Już dawno nie czułem takiej radości z tak niewielkiej ilości kodu. Chyba wciąż jestem przerażony liczbą nawiasów w Clojure, więc kiedy napisałem funkcję (exit) bezbłędnie za pierwszym razem, można sobie wyobrazić, jaki byłem szczęśliwy.
 user=> (def exit (fn [] (. System exit 0)))
#'user/exit
user=> (exit)
Brakowało mi tej funkcji w Clojure REPL, bo ^C, czy ^Z + ENTER pachniały mi jakąś niedoróbką. W tak niewielkiej funkcji udało mi się wykorzystać 3 istotne możliwości Clojure - definiowanie zmiennej przez def, której przypisano funkcję anonimową przez fn, która z kolei wykorzystuje integrację Clojure z Javą za pomocą specjalnej formy . (kropka). Ale ze mnie programista, co? :)

Można to jednak lekko podrasować i wykorzystać specjalną formę #(), która również definiuje funkcję anonimową. Owa funkcja anonimowa w niektórych kręgach nazywana jest...domknięciem (ang. closure). Domknięcie w Clojure nie różni się bardzo w porównaniu do tradycyjnego wywołania funkcji, ale tym razem owe wywołanie fn kończy się stworzeniem nowej. Funkcja, która operuje na innych, w tym zwraca je, nazywamy funkcją wyższego poziomu (ang. higher-order function).

Wracając do naszego #() to możnaby powyższe zapisać tak:
 user=> (def exit #(. System exit 0))
#'user/exit
user=> (exit)
Przeglądając kod źródłowy "Game of Life" Scotta Frasera trafiłem na metodę java.lang.Runtime.availableProcessors(), o której istnieniu nie wiedziałem. W zasadzie o wielu metodach jeszcze nie wiem i wiele z nich wywrze na mnie podobne, pozytywne wrażenie, aczkolwiek ta ma tą zaletę, że utwierdziła mnie w przekonaniu, że mój laptop faktycznie posiada procesor 2-rdzeniowy i 2 wątki powinny działać równolegle (biorąc pod uwagę działanie wszystkich innych programów w tle, pewnie tak nie będzie i jeden z wątków i tak będzie szybszy).
 user=> (def available-procs (.. java.lang.Runtime getRuntime availableProcessors))
#'user/available-procs
user=> (println available-procs)
2
nil
Zadanie dla wytrwałych: Jak zmienić def powyżej, aby możliwe było wykonanie (available-procs), który zwróci 2, tj.
 user=> (available-procs)
2
p.s. Rozpocząłem kolejną ankietę odnośnie języków programowania "Jaki język programowania używasz poza Javą?" (jest na blogu po prawej u góry). Nie ma znaczenia, czy do zabawy, w projekcie, własnej ciekawości, czytasz o nim książkę, czy podobnie. Poświęcasz swój czas, więc wystarczy, aby określić go jako "używasz". Interesuje mnie, czy chociażby rozważasz alternatywę dla Javy i jaki to jest język. Wszystkie języki poza JVM wpadły do kategorii "Inne (poza JVM)". Głosujcie!

12 listopada 2009

56. spotkanie Warszawa JUG - Jesienny Eclipse DemoCamp 2009

0 komentarzy
Warszawska Grupa Użytkowników Technologii Java (Warszawa JUG) zaprasza na 56. spotkanie, które odbędzie się we wtorek, 24. listopada o godzinie 18:00 w sali 5440 Wydziału MIMUW przy ul. Banacha 2 w Warszawie.

Temat: Jesienny Eclipse DemoCamp 2009
Prelegenci: Michał Margiel, Łukasz Lenart, Jacek Laskowski, Sebastian Pietrowski, Tomasz Bujok

Tym razem forma spotkania będzie minikonferencją wokół produktów Eclipse Foundation, w której 5 prelegentów zaprezentuje rozwiązania w ciągu...20 minut każdy. Jeśli to nie przekonuje Cię o spędzeniu wtorkowego wieczoru w niezwykle porywającej atmosferze w gronie entuzjastów javowych, to może agenda?

18:00-18:20 Bądź leniwy - wykorzystaj ukrytą moc Eclipse, czyli jak robić by się nie narobić i wycisnąć max ze środowiska Michał Margiel
18:25-18:45 GoogleAppEngine - chmura na Ja(v)wie Łukasz Lenart
18:50-19:10 OpenEJB Eclipse Plugin - EJB 3.1 z Apache OpenEJB w Eclipse IDE Jacek Laskowski
19:15-19:35 Wprowadzenie do Cloud Foundry Sebastian Pietrowski
19:40-20:00 Po prostu monitoring, czyli jak zbudować skalowalną architekturę monitoringu w 20 minut za pomocą Spring, AOP i ActiveMQ Tomasz Bujok

Harmonogram niezwykle napięty, więc o nudzie nie może być mowy. W miłej atmosferze wiedza sama wchodzi do głowy, mimo późnej godziny.

Wstęp wolny, ale rejestracja wskazana.

Zapraszam w imieniu prelegentów i grupy Warszawa JUG!

11 listopada 2009

(-> Clojure zrozumieć-makro-thread przeczytać-artykuł opisać-na-blogu)

1 komentarzy
Zgodnie z sugestią Michaela zabrałem się za poznawanie Clojure od strony jego kodu źródłowego i podążając słowami mojego mistrza zabrałem się za makro ->, zwane również w kręgach Clojure jako makro "thread".

Kod źródłowy jest niezwykle mały i znajduje się w repozytorium Git - core.clj.
 (defmacro ->
"Threads the expr through the forms. Inserts x as the
second item in the first form, making a list of it if it is not a
list already. If there are more forms, inserts the first form as the
second item in second form, etc."
([x form] (if (seq? form)
`(~(first form) ~x ~@(next form))
(list form x)))
([x form & more] `(-> (-> ~x ~form) ~@more)))
Forma doc zwraca Clojure doc, czyli dokumentację funkcji będącej jej argumentem wejściowym, więc i bez kodu źródłowego możnaby się doczytać, co autor miał na myśli tworząc makro -> (mi to nie wystarczyło, ale pomyślałem, że wspomnę i o tej możliwości).
 user=> (doc ->)
-------------------------
clojure.core/->
([x form] [x form & more])
Macro
Threads the expr through the forms. Inserts x as the
second item in the first form, making a list of it if it is not a
list already. If there are more forms, inserts the first form as the
second item in second form, etc.
nil
Czytając dokumentację dosłownie, makro -> ma za zadanie wpleść wyrażenie do listy form. Wciąż mi to jednak niewiele mówi. Definicja -> składa się z dwóch przypadków - kiedy makro dostaje na wejściu dwa parametry i więcej. Forma (ang. form) to po prostu dwa nawiasy, w których są wywołania funkcji czy makr, lub ponownie form. I tak rekurencyjnie mamy całą masę par nawiasów. W Clojure *wszystko* jest w nawiasach, albo zastąpione pewnymi specjalnymi konstrukcjami - uproszczeniami rozpoznawanymi przez kompilator, które wychodzą poza ten schemat, np. przywoływana już konstrukcja tworzenia kluczy :nazwa jest równoznaczna z wywołaniem funkcji (keyword "nazwa") (często nazywanymi po angielsku "syntactic sugar").

Wykonanie -> z jednym parametrem, to po prostu jego zwrócenie.
 user=> (-> 2)
2
To było proste! :) Teraz będzie znacznie trudniej. Jeśli na wejściu -> mamy dwa parametry, to rozpatrujemy przypadki - 1) forma jest sekwencją (seq? zwraca prawdę) i 2) kiedy nie jest. Przy okazji, nazwy funkcji, których wynikiem jest wartość logiczna true/false są zakończone ? (znak zapytania).

Weźmy ponownie coś równie prostego jak poprzednio.
 user=> ; w nawiasie mamy funkcję minus i jej jedyny argument 3
user=> (-> 2 (- 3))
-1
Dlaczego? Analizując kod źródłowy -> dochodzimy do wniosku, że jest to równoznaczne z poniższym.
 user=> (- 2 3)
-1
Pierwszy argument dla -> jest na drugiej pozycji w pierwszej formie, którą było (- 3). Można jeszcze sprawdzić, jaki był wynik if'a w makro ->.
 user=> (seq? (- 3))
false
Zatem wyliczenie (-> 2 (- 3)) sprowadza się do konstrukcji (list form x), tj. (list - 3 2), a to daje:
 user=> (list - 3 2)
(#<core$___4506 clojure.core$___4506@16de49c> 3 2)
Sprawdźmy, co da wywołanie tego funkcją eval.
 user=> (eval (list - 3 2))
1
Źle! Chyba popełniłem jakiś błąd w rozumowaniu, jaki argument jest przekazywany do seq?, bo w końcu zgodnie z definicją formy, zapis (- 3) nią jest! Biorąc więc pod uwagę moje niedoświadczenie i możliwe pomyłki w rozumowaniu, wchodzimy w sekcję if'a, bo wtedy wszystko jest cacy - 2 staje się drugim argumentem dla odejmowania, a 3 trzecim. Owe szlaczki w makro to sposób na tworzenie kodu w fazie wczytywania programu w Clojure (zaraz przez kompilacją i uruchomieniem), w której następuje rozwiązywanie makr, których celem jest uproszczenie życia programistom przez generowanie bardziej złożonego kodu (po co klepać kilkakrotnie to samo w wielu liniach, jeśli możemy zdefiniować makro raz i wywoływać wielokrotnie w jednej?! "Cudo" znane programistom C/C++).

Wciąż jednak nie rozumiałem, co jest takiego specjalnego w tym makro, aż trafiłem na LexParse, gdzie padła wzmianka o potoku (ang. pipeline). Teraz było znacznie łatwiej zrozumieć, co autor miał na myśli. Aczkolwiek do pełnego zrozumienia daleko (pewnie za mało wciąż napisanych programów w Clojure).
 user=> (-> 2 {2 "dwa"} {"dwa" "DWA"})
"DWA"
Spróbuj samodzielnie znaleźć odpowiedź dlaczego w wyniku otrzymaliśmy "DWA", albo poniżej true:
 user=> (-> '(0 0 0) (count) (odd?))
true
Doświadczenia z Clojure skończyłem artykułem Clojure - Functional Programming for the JVM, którego autorem jest R. Mark Volkmann. Tam znalazłem wzmiankę o Simon Peyton-Jones, który włożył wiele wysiłku w Haskella (czysty język funkcyjny) i miał powiedzieć w OSCON 2007 - Simon Peyton-Jones - A Taste of Haskell Part I:

"In the end, any program must manipulate state. A program that has no side effects whatsoever is a kind of black box. All you can tell is that the box gets hotter."

i dalej już od autora artykułu: The key is to limit side effects, clearly identify them, and avoid scattering them throughout the code.

Warto również wspomnieć o leniwym rozwiązywaniu/wyliczaniu sekwencji - leniwych sekwencjach (ang. lazy sequences) (a może trafniej będzie nazywać je opóźnionymi czy nawet ospałymi czy w końcu uśpionymi sekwencjami?). Elementy w sekwencji nie są wyliczane, aż do momentu ich użycia, co pozwala na tworzenie nieskończonych ciągów danych bez narażania się na wysycenie sterty pamięci JVM. Ta cecha Clojure uzmysłowiła mi o możliwym podejściu w Javie, w której zwykle (zawsze?) wyliczamy wszystkie elementy, nawet jeśli ich nie potrzebujemy. Weźmy za przykład tablicę 150-elementową, albo jeszcze dłuższą. W Javie, w zależności od typu elementów, wielkość potrzebna na ich przechowanie musi być dostępna w trakcie deklaracji. Alternatywą mogłoby być stworzenie takiej kolekcji, w której podajemy liczbę elementów i tyle, a kiedy potrzebny będzie piąty, dziesiąty, czy którykolwiek inny element, wyliczamy go dokładnie w momencie zapytania o niego. Nie sądzę, abym kiedykolwiek myślał o programowaniu w Javie w ten sposób (może dlatego, że po prostu nie miałem okazji?!). Na szczęście nie musimy już tego implementować w Javie, bo mamy Clojure, więc chociażby dla tego warto zwrócić się ku niemu.

Bardzo przypadł mi do gustu następujący akapit:

Is Clojure code hard to understand? Imagine if every time you read Java source code and encountered syntax elements like if statements, for loops, and anonymous classes, you had to pause and puzzle over what they mean. There are certain things that must be obvious to a person who wants to be a productive Java developer. Likewise there are parts of Clojure syntax that must be obvious for one to efficiently read and understand code.

Podobnie będzie z dowolnym językiem mówionym - angielski prosty, niemiecki również, pewnie podobnie z francuskim, czy hiszpańskim, nie wspominając o rosyjskim czy w ogóle słowiańskich. Nasłuchaliśmy się ich wokoło i teraz po prostu przywykliśmy do ich konstrukcji. Brakuje nam zrozumienia ich semantyki, więc chodzimy na drogie kursy licząc, że cudem bez specjalnego wysiłku mentalnego wejdą nam w przysłowiowe 5 minut. Wtedy również zadamy sobie pytanie o sensowność nauki kolejnego języka skoro mówimy, piszemy i czytamy po angielsku. Przypomina mi to pytanie o sensowność uczenia się Clojure. Po co się go uczyć skoro znamy Javę? Po co uczyć się kolejnego języka mówionego, znając angielski? Dla mnie, odpowiedź nasuwa się sama - z ciekawości, co tracimy nie potrafiąc posługiwać się językiem, którym władają inni. Czy Clojure jest tym językiem, który należałoby poznać? Nie wiem. Wiem jednak, że należy chociażby spróbować zrozumieć programowanie funkcyjne, aby zastosować go tam, gdzie programowanie obiektowe czy imperatywne nie przystaje. Jeśli znamy tylko OO, to jak tu mówić o zdrowym rozsądku? Dobrze ujął to Abraham Maslow:

I suppose it is tempting, if the only tool you have is a hammer, to treat everything as if it were a nail.

bądź, jak to jest częściej przywoływane:

If the only tool you have is a hammer, you tend to see every problem as a nail.

Niestety nie wiem, jak miałoby to brzmieć po polsku :(

Właśnie kiedy miałem opublikować wpis, zajrzałem jeszcze do źródeł Clojure i trafiłem na funkcję clojure-version. Trywialna, aczkolwiek wciąż pouczająca implementacja (której pewnie jeszcze samodzielnie nie dałbym rady napisać):
 user=> (clojure-version)
"1.1.0-alpha-SNAPSHOT"
Jeśli doczytałeś/-aś do tego miejsca, to może i wytrwałeś/-aś z czytaniem podanego wyżej artykułu o Clojure. Jeśli tak, to w sekcji o mapach (Maps) jest wzmianka o...makrze -> (!)

The -> macro, referred to as the "thread" macro, calls a series of functions, passing the result of each as an argument to the next. For example the following lines have the same result:

(f1 (f2 (f3 x)))
(-> x f3 f2 f1)


Teraz już jest jasne, co makro -> robi. W ramach nauki Clojure pozostaje więc nauczyć się jego implementacji na pamięć, aby kolejnym razem napisać podobne.

10 listopada 2009

Środowisko programistyczne dla Clojure i poprzedni przykład funkcjonalniej

0 komentarzy
Nasze praktyczne przygody z Clojure możemy zacząć od instalacji wymaganego oprogramowania i/lub uruchomienia Clojure REPL lokalnie, albo skorzystać z Lord of the REPLs. Interesująca alternatywa, nie tylko pomocna w nauce Clojure, ale i Groovy, Ruby czy Scala.

Kiedy jednak nasze doświadczenie w programowaniu funkcyjnym w Clojure zacznie wykraczać poza proste aplikacje będące złożeniem kilku funkcji i spróbujemy wyjść poza ramy REPL możemy skorzystać ze wsparcia udostępnianego przez zintegrowane środowiska programistyczne, np. NetBeans IDE, Eclipse IDE czy IntelliJ IDEA. Wystarczy doszukać się właściwej wtyczki (rozszerzenia) i możemy czerpać garściami z pomocy IDE - możemy chociażby znieść z siebie trud dbania o nawiasy. Dla NetBeans IDE mamy Enclojure. Ostatnia wersja z 3.11, więc dostatecznie świeża, aby uwierzyć w aktywny jej rozwój. Dla środowiska Eclipse IDE mamy Clojure plug-in for Eclipse (clojure-dev), o której dowiedziałem się w artykule The Clojure programming language - Take advantage of the Clojure plug-in for Eclipse. Stawiam na NetBeans IDE i Enclojure.

Dla bloggerów istnieje podświetlanie składni dla Clojure w ramach Syntax Highlighter 2.0 - All Syntax Highlighter 2.0 brushes collected, described and downloadable. Można zobaczyć go w działaniu w moich wpisach dotyczących Clojure, chociażby ten. Jeśli więc przyjdzie zaprezentować swoje cudo w Clojure szerokiej publiczności na własnym blogu warto podeprzeć się stylem clojure. Znacznie uatrakcyjnia prezentację kodu.

A skoro mamy środowisko możemy powrócić do naszego przykładu z surowcami, której wersja bardziej przypominająca wersję funkcjonalną (dosłownie i w przenośni) wygląda teraz następująco:
 (ns pl.jaceklaskowski.clojure)

(defn czas-zwiekszenia-produkcji
"Wylicza potrzebny czas (w minutach) do osiagniecia stanu magazynowego na uruchomienie rozbudowy do poziomu przy danej produkcji"
[docelowo, magazyn, produkcja]
(let [teraz (java.util.Calendar/getInstance)]
(. teraz (add (java.util.Calendar/MINUTE)
(* 60 (reduce max (map / (map - (map #(.getValue %) docelowo) (map #(.getValue %) magazyn)) (map #(.getValue %) produkcja))))))
(. teraz getTime)))
Widać wyraźne zwiększenie konstrukcji PF z reduce i map. Poza samym wyliczeniem, za ile nastąpi zwiększenie (w linii 8.) mamy również wyliczoną dokładną godzinę, kiedy to nastąpi (linie 6., 7. i 9.)

Zamiast dłubania w REPL zapisujemy cały program w pliku czas-zwiekszenia-produkcji.clj. Zwyczajowo skrypty w Clojure zapisywane są z rozszerzeniem .clj.

Tworzymy kolejny skrypt testowy skrypt-testowy.clj, który zweryfikuje poprawność działania.
 (load-file "czas-zwiekszenia-produkcji.clj")

(ns pl.jaceklaskowski.clojure)

(def magazyn {:drewno 10 :glina 10 :zelazo 10 :zboze 10})
(def docelowo {:drewno 20 :glina 20 :zelazo 20 :zboze 20})
(def produkcja {:drewno 5 :glina 5 :zelazo 5 :zboze 5})

(println (czas-zwiekszenia-produkcji docelowo magazyn produkcja))
Uruchomienie to po prostu wykonanie:
 $ java -jar clojure-1.1.0-alpha-SNAPSHOT.jar skrypt-testowy.clj
#<Date Tue Nov 10 23:36:07 CET 2009>
I tak kończy się moje poszukiwanie ładniejszej (=bardziej funkcyjnej) wersji czas-zwiekszenia-produkcji. Oczywiście nie kończy to mojej przygody z Clojure i jeśli kiedykolwiek pomyślałem, aby sobie odpuścić, bo i po co mi PF, to wizyta na blogu BEST IN CLASS jest faktycznie najlepszym w swojej klasie i nie pozwala zapomnieć o możliwościach Clojure. Warto tam zajrzeć w wolnej chwili, szczególnie w chwilach zwątpienia. Mnie zachwycił i upewnił w postanowieniu poznania go dokładniej.

W kolejnym podejściu postaram się zrozumieć o co chodzi w makro -> oraz funkcji line-seq z core.clj jak zasugerował Michael w komentarzu do ostatniego mojego wpisu o Clojure - Programowanie w Clojure - część 2 - pierwszy przykład z wyliczaniem surowców.

08 listopada 2009

Programowanie w Clojure - część 2 - pierwszy przykład z wyliczaniem surowców

6 komentarzy
Nasze ćwiczenia z programowania w Clojure zaczniemy od uruchomienia Clojure REPL (Read-Eval-Print-Loop). Clojure REPL jest niczym innym jak interaktywnym interpreterem dla Clojure.
 jlaskowski@work /cygdrive/c/oss/clojure
$ java -jar clojure-1.1.0-alpha-SNAPSHOT.jar
Clojure 1.1.0-alpha-SNAPSHOT
user=>
Od tej pory zakładam, że wiemy, w jaki sposób dostać znak zachęty jak wyżej.

Powiedzmy, że chcemy wyliczyć liczbę surowców do wybudowania pewnej jednostki (w szczególności podniesienia poziomu samego surowca, aby dawał znacznie większą produkcję niż obecnie). Mamy 4 rodzaje surowców, które nazwiemy: drewno, glina, żelazo i zboże. Całkiem typowe w wielu grach strategicznych. Na celownik weźmiemy Traviana. Trochę czasu mi z nim zeszło i zawsze zastanawiałem się, czy jestem w stanie stworzyć system-bota, który podpowiadałby mi najlepszą strategię. Ktoś kiedyś wspominał coś o programowaniu nieliniowym odnośnie tego rodzaju kalkulacji, ale pojawiała się również wzmianka o programowaniu funkcyjnym. Ile w tym prawdy nigdy nie doszedłem, jednakże tym razem mam możliwość choć po części sprawdzić się w Clojure jako języku funkcyjnym do rozwiązania, albo chociaż próby rozwiązania, tego problemu. To byłby taki system ekspertowy, który podpowiadałby mi różne strategie (pewnie za nim stoi cała masa teorii matematycznej z różnymi modelami, ale ja wybieram podejście naiwne bez zebrania wcześniej wystarczającej wiedzy, tj. "na żywioł" :)). Do zbudowania gliny na 1. poziomie (tak, z każdą jednostką mamy związaną cechę - poziom) potrzeba 80 drewna, 40 gliny, 80 żelaza i 50 zboża (patrz 1.1.11 Kopalnia gliny). Każda wioska ma swoją produkcję i zakładam, że początkowo produkcja jest na 0. Najpierw spróbuję odpowiedzieć na pytanie, ile czasu potrzeba, abym podniósł produkcję gliny przy aktualnym stanie magazynu i produkcji surowców.

Mamy więc założenia do funkcji, którą w Javie moglibyśmy nazwać obliczCzasDoZwiekszeniaProdukcji(surowca, naPoziom, przyObecnymStanieMagazynowym, przyObecnejProdukcji). Nazwy funkcji w Clojure są zazwyczaj ciągiem słów oddzielonych myślnikami, co daje w naszym przypadku czas-zwiekszenia-produkcji (zakładając, że celem funkcji jest obliczenie czegoś nie widzę potrzeby powtarzania tego w nazwie funkcji).

Zaczynam od definicji magazynu. Będzie to mapa, która w Clojure deklarowana jest przez {} (nawiasy klamrowe), między którymi ciąg elementów tworzy pary klucz-wartość. Przecinki są opcjonalne i traktowane dokładnie jak spacja, czyli taki zapis
 user=> (def magazyn {:drewno 0 :glina 0 :zelazo 0 :zboze 0})
#'user/magazyn
jest równoznaczny takiemu:
 user=> (def magazyn {:drewno 0, :glina 0, :zelazo 0, :zboze 0})
#'user/magazyn
W definiowaniu mapy skorzystałem z możliwości definiowania słów kluczowych w Clojure z użyciem : (dwukropek). Wartością słów kluczowych są one same, więc idealnie nadają się na klucze w mapie.
 user=> :cokolwiek
:cokolwiek
Jak większość (wszystko?) w Clojure, tak i mapa jest funkcją, której pojedynczym argumentem jest klucz.
 user=> (magazyn :drewno)
0
Również odwrotne spojrzenie jest poprawne, tj. słowa kluczowe są również funkcją, której argumentem jest mapa, w której się odszukują (!)
 user=> (:drewno magazyn)
0
Takie spojrzenie na mapę i jej kluczy było dla mnie niezwykłym doświadczeniem mentalnym :) W sumie to logiczne, aby potraktować w ten sposób struktury danych, a zmienia całkowicie moje dotychczasowe spojrzenie obiektowe. Skoro wszystko jest funkcją, jedynym problemem pozostaje poznanie ich zasady działania (semantyki). Niby proste i pamiętam, że kiedy uczyłem się żonglować, co wydawało mi się początkowo niezwykle trudne i w zasadzie poza zasięgiem, kiedy oduczyłem się złego sposobu podawania piłeczki z ręki do ręki, nauczenie się poprawnie przez przerzucanie piłeczek było dziecinnie proste. Mówi się, że jedynym problemem w nauce nowego są nasze własne przyzwyczajenia i obawy. Chyba dlatego tak trudno jest się uczyć z wiekiem - zbyt wiele doświadczenia, które nas ogranicza?!

Do definicji funkcji w Clojure używamy defn, w której w cudzysłowach dodajemy opis funkcji, a w nawiasach kwadratowych parametry wejściowe.
 (defn czas-zwiekszenia-produkcji
"Wylicza potrzebny czas do zwiekszenia produkcji surowca na danym poziom przy danym stanie magazynowym i produkcji"
[surowiec, poziom, stanMagazynowy, produkcja]
...
)
Chwilowo zamiast parametru wejściowego poziom będącym liczbą całkowitą przekażemy mapę z potrzebnymi surowcami do przejścia na dany poziom.
 user=> (def poziom1 {:drewno 80 :glina 40 :zelazo 80 :zboze 50})
#'user/poziom1
W takim przypadku sam surowiec nie ma znaczenia, bo w końcu na wejściu mamy stan początkowy (stan magazynowy), stan docelowy i produkcję (przyrost jednostek w czasie 1h). Definicja funkcji mogłaby wyglądać tak:
  (defn czas-zwiekszenia-produkcji
"Wylicza potrzebny czas do osiagniecia stanu magazynowego na uruchomienie rozbudowy do poziomu przy danej produkcji"
[stanDocelowy, stanMagazynowy, produkcja]
...
)
Wszystkie parametry wejściowe są mapami.

Wywołanie funkcji w Clojure jest listą, której pierwszym elementem jest nazwa funkcji, a po nim następują parametry wejściowe.
 user=> (czas-zwiekszenia-produkcji docelowo magazyn produkcja)
Dodając do tego możliwość importowania typów javowych przez import oraz ich wywoływania przez . (kropka) czy / (ukośnik) otrzymujemy ostatecznie następujący program w Clojure do obliczania czas potrzebnego do zwiększenia produkcji surowca przy danym magazynie i bieżącej produkcji.
 (def magazyn {:drewno 10 :glina 4 :zelazo 15 :zboze 0})

(def produkcja {:drewno 5 :glina 2 :zelazo 5 :zboze 4})

(def glina1 {:drewno 80 :glina 40 :zelazo 80 :zboze 5})

(import '(java.util Calendar))

(def teraz (Calendar/getInstance))

(defn czas-zwiekszenia-produkcji
"Wylicza potrzebny czas (w minutach) do osiagniecia stanu magazynowego na uruchomienie rozbudowy do poziomu przy danej produkcji"
[docelowo, magazyn, produkcja]
(max
(/ (- (docelowo :drewno)(magazyn :drewno)) (produkcja :drewno))
(/ (- (docelowo :glina)(magazyn :glina)) (produkcja :glina))
(/ (- (docelowo :zelazo)(magazyn :zelazo)) (produkcja :zelazo))
(/ (- (docelowo :zboze)(magazyn :zboze)) (produkcja :zboze)))
)

(. teraz add (Calendar/MINUTE) (* 60 (czas-zwiekszenia-produkcji glina1 magazyn produkcja)))

(. teraz getTime)
Kopiując każdą z linii do REPL mamy:
 $ java -jar clojure-1.1.0-alpha-SNAPSHOT.jar
Clojure 1.1.0-alpha-SNAPSHOT
user=> (def magazyn {:drewno 10 :glina 4 :zelazo 15 :zboze 0})
#'user/magazyn
user=> (def produkcja {:drewno 5 :glina 2 :zelazo 5 :zboze 4})
#'user/produkcja
user=> (def glina1 {:drewno 80 :glina 40 :zelazo 80 :zboze 5})
#'user/glina1
user=> (import '(java.util Calendar))
java.util.Calendar
user=> (def teraz (Calendar/getInstance))
#'user/teraz
user=> (defn czas-zwiekszenia-produkcji
"Wylicza potrzebny czas (w minutach) do osiagniecia stanu magazynowego na uruchomienie rozbudowy do poziomu przy danej produkcji"
[docelowo, magazyn, produkcja]
(max
(/ (- (docelowo :drewno)(magazyn :drewno)) (produkcja :drewno))
(/ (- (docelowo :glina)(magazyn :glina)) (produkcja :glina))
(/ (- (docelowo :zelazo)(magazyn :zelazo)) (produkcja :zelazo))
(/ (- (docelowo :zboze)(magazyn :zboze)) (produkcja :zboze)))
)
#'user/czas-zwiekszenia-produkcji
user=> (. teraz add (Calendar/MINUTE) (* 60 (czas-zwiekszenia-produkcji glina1 magazyn produkcja)))
nil
user=> (. teraz getTime)
#<Date Mon Nov 09 07:16:59 CET 2009>
Wersja bardziej funkcyjna z map i reduce w kolejnym wpisie. Zdecydowanie zbyt wiele w tej wersji argumentów do max. Można się zapisać na śmierć z tymi kluczami w mapach i samym wprowadzaniem programu do wykonania. Wasze propozycje mile widziane, bo moja przygoda z programowaniem funkcyjnym z Clojure dopiero się zaczęła i wpadki są wręcz oczekiwane.