Streemo ze spotkania…

luty 14th, 2007 by Paweł Rutkowski

Ostatnio na forum rubyonrails pojawiło się pytanie, czy prezentacje wygłaszane na spotkaniach będą jakoś nagrywane i udostępniane w sieci.

Dzięki serwisowi streemo udało się zrealizować tę prośbę. Streemo udostępniło kamerę oraz zmontowało materiał (moim zdaniem w sposób idealny dla prezentacji).

Narazie dostępna jest tylko prezentacja Marcina Jagodzińskiego pt. “Identity 2.0″. Niedługo powinna się pojawić także prezentacja Adama Hościło o django.

Chętnych do obejżenia zapraszam tutaj.

Lutowe spotkanie Bootstrap (dawne RoR)

luty 8th, 2007 by Paweł Rutkowski

W sobotę 10.02.2007 o godzinie 12:00 w lokalu Chłodna 25 odbędzie się kolejne spotkanie z serii RubyOnRails. Ponieważ podczas kilku poprzednich spotkań okazało się że większość uczestników oprócz językiem Ruby, interesuje się biznesem, innym frameworkami, trendami - zmieniona zostałą trochę formuła. Mianowicie oprócz prezentacji technicznych, pojawią się prezentacje “trendowe” oraz biznesowe - opisujące case-study, wybranych projektów. Jak zawsze jednym z najważniejszych elementów naszych spotkań są rozmowy po prezentacjach - ostatnio trwały one około 8h.

Podczas spotkań można poznać wielu ciekawych ludzi oraz nawiązać znajomości które mogą się przerodzić w realne projekty.

Oto prezentacje które zostaną przestawione na najbliższym spotkaniu:

  1. “Django vs Rails - co lepsze na startup?” - Adam Hościło (django.pl)
  2. “Identity 2.0 - autoryzacja user-centric w oparciu o OpenID” - Marcin
    Jagodziński (netto.blox.pl)

Zapraszam zatem wszystkich chętnych.

Powstała także oficjalna strona spotkań: http://www.bootstrap.pl

Czym są szablony HAML ?

styczeń 19th, 2007 by Paweł Rutkowski

Razem z pojawieniem się nowych railsów o których pisałem w poprzednim poście, pojawiła się także informacja o nowym “formacie” templatów - “Haml”. Generalnie jest to nowy meta-język doskonale wpisujący się w ideologię railsów - DRY i Simplifying - upraszczania.

Odrazu przejdę do przykładu, żeby nie trzymać Was w niepewności. Oto jakby wyglądał kod w standardowym RHTMLu:


<table id="userdata">
<tr>
<td class="label"> Dane użytkownika </td>
<td> <%= @user.name %> </td>
<td> <%= @user.surname %> </td>
</tr>
</table>

Krótkie wyjaśnienie dla osób nie znających szablonów Erb (używanych w RHTMLu). Znacznik <= służy do wykonania kodu ruby i wstawienia wyniku w dane miejsce. Jak widać mamy tabelke z jakimś id i jeden z znaczników <td> ma ustawioną klase “label”. Jak by zatem wyglądał powyższy kod w Hamlu. Moim zdaniem znacznie przyjemniej:


table#userdata
%tr
%td.label Dane użytkownika
%td= @user.name
%td= @user.surname

Dzięki temu skracamy kod i czas jego pisania o mniej więcej połowę (nie trzeba zamykać znaczników). Ponieważ Haml został stworzony z myślą o XHTMLu/XMLu, kod przez niego wygenerowany będzie spełniał założenia tego formatu. Drugą rzeczą która mi się bardzo spodobała to selektory zgodne z formatu CSS - bardzo to ułatwia zapamiętanie składni. Trzecia rzecz - znak “równa się” odrazu uwidacznia podstawienie efektu wykonania kodu w Ruby.

Uproszczono także wstawianie dowolnych atrybutów do kodu - co jest niezwykle ważne w przypadku generowania XMLa:


%person { :name => "Pawel", :surname => @user.surname }
%children/

Powyższy kod zostanie przekształcony na:


<person name="Pawel" surname="Rutkowski" >
<children/>
</person>

Jak widać na powyższym przykładzie dodawanie atrybutów jest bardzo proste i można w nich używać wyrażeń języka. W RHTMLu powyższy szablon wygłądał by tak:


<person name="Pawel" surname="<%= @user.name %>" >
<children/>
</person>

Zagnieżdżanie kodu Ruby wewnątrz tagów zawsze mnie irytowało ze względu na mała czytelność takiego kodu. Natomiast w tym rozwiązaniu wygląda to świetnie.

To jest mała porcja tego co potrafi Haml. Dokumentacja jest obszerna i dość długa - jeszcze nie zapoznałem się z jej całą treścią. Haml jest dostępny dla Rubego w postaci gemów, zaś dla railsów na razie w w postaci pluginu który można pobrać stąd:


./script/plugin install svn://hamptoncatlin.com/haml/tags/stable

Niestety nie miałem jeszcze czasu na przepisanie którejś z aplikacji na te szablony i porównania czasów generowania i ogólnej wydajności, ale jak tylko to zrobię na pewno opublikuję

Strona projektu Haml (razem z dokumentacją i tutorialem) - tutaj

A na koniec jeszcze przykładowa strona w Hamlu :)


!!!
%html
%head
%title= controller.controller_name
= stylesheet_link_tag 'main'
%body
#header
%h1 BoBlog
#content= yield
#footer
%p All content copyright © Bob

Czyż to nie jest piękne ?:)

Rails 1.2.1

styczeń 19th, 2007 by Paweł Rutkowski

Wszyscy o tym trąbią, więc ja tylko ograniczę się do stwierdzenia “są nowe rails w wersji 1.2.1″. Oficjalna wiadomość tutaj

Prezentacja “Plug me in” - o pluginach słów kilka

styczeń 14th, 2007 by Paweł Rutkowski

W sobotę obyło się kolejne spotkanie z cyklu RoR PL. Miałem przyjemność poprowadzić prezentację należącą do technicznej części tego spotkania. Temat był trudny zarówno do przedstawienia, jak i w odbiorze przez osoby nie obeznane z programowaniem obiektowym - ale mam nadzieję że udało mi się przybliżyć Wam aspekty omówione podczas prezentacji.

Jak zwykle po prezentacji, udostępniam materiały tutaj.

Styczniowe spotkanie Railsowe (Warszawa)

styczeń 4th, 2007 by Paweł Rutkowski

Zapraszam na kolejne spotkanie użytkowników RubyOnRails. Odbędzie się ono 13 stycznia 2007 roku o godzinie 12:00 w lokalu Chłodna 25. Tym razem wyjątkowo w sobotę, ponieważ pojawiły się głosy że mieszkańcy innych miast też chcieli by się spotkać, co było nie możliwe przy naszych wieczornych spotkaniach w środku tygodnia.

Prawdopodobnie będę miał przyjemność wygłosić prelekcję na temat tworzenia pluginów w Ruby dla Ruby oraz jak robić pluginy w RubyOnRails.

Zapraszamy nie tylko zagorzałych zwolenników RoR ale także sympatyków oraz osoby “ciekawe”.

Jak sobie ułatwić pisanie aplikacji ?

styczeń 1st, 2007 by Paweł Rutkowski

Wstęp

Obecnie pisanie aplikacji wygląda w zupełnie inny sposób niż kiedyś. Terminy są bardziej napięte, Klienci bardziej wymagający, kod coraz większy i sami mamy też wobec własnego kodu coraz większe wymagania. Jak do tego dorzucimy kilka równolegle rozwijanych wersji to już zupełnie można się w tym wszystkim pogubić.

Dlatego też chciałbym przybliżyć Wam kilka aplikacji bez których nie wyobrażam sobie obecnie developmentu. O systemach kontroli wersji już pisałem więc nie będę się powtarzał. Opowiem o trzech narzędziach: trac, Todo (zwany też devTodo) oraz SVNmerge.

Trac

Trac jest aplikacją webową integrującą się z repozytorium Subversion. Posiada wbudowaną przeglądarkę repozytorium, wiki dotyczące danego projektu, system ticketów (bugów) oraz tzw Timeline zawierający chronologiczne informacje dotyczące commitów, dodanych ticketów, zamknięcia bugów itp.

Aplikacja wygląda ładnie (w przeciwieństwie do BugZilli, której wygląd wręcz straszy :). Przy odrobinie nakładu pracy ładnie się integruje ze środowiskiem wieloużytkownikowym, co jest bardzo ważne przy śledzeniu błędów w projekcie i ich naprawianiu. Integracja z Subversion pozwala na używanie automatycznych linków. Np.: jeżeli w commicie jakiejś poprawki napiszemy “poprawka #43″ to przy wyświetlaniu danych z tego changesetu (commity w Subversion są nazywane changesetami czyli zestawem zmian, wgranych do repozytorium) w opisie automatycznie pojawi się link do strony z ticketem numer 43. Drugi przydatny auto-link służy do oznaczenia changesetu - np.: r166 lub [166] automatycznie stworzą link do strony zawierającej informacje na temat tej zmiany. Wśród tych informacji można zobaczyć które pliki zmieniono (i jakie zmiany zawierały), które dodano a któe usunięto - oczywiście jest dostępny także opis danego commita.

Kolejną ciekawą funkcją jest możliwość tworzenia ticketów i przypisywania ich do milestone’ów (zazwyczaj jest to moment w projekcie kiedy uzyskuje on konkretną funkcjonalność) i śledzenie ile pracy jeszcze trzeba wykonać aby osiągnąć dany punkt. Pozwala to na lepsze planowanie implementowanych funkcjonalności jeżeli widzimy zbliżający się deadline.

Wiki jest pomocne przy tworzeniu dokumentacji projektowej. Ponieważ każdy z developerów może edytować strony - przy zachowaniu odpowiedniego poziomu dyscypliny - będzie ona zawsze aktualna i obszerna. Mechanizm ten jest znany z Wikipedii więc nie będę się nad nim rozwodził.

Każdy projekt który zaczynamy ma automatycznie tworzony serwis opraty na tracu do śledzenia tego projektu i nie wyobrażam sobie pracy bez narzędzia tego typu. Na rynku istnieje oczywiście kilka podobnych rozwiązań ale żadne z mi znanych nie integruje się tak dobrze z Subversion i nie jest tak kompletne. Jedyną wadą trac jest brak możliwości zgłaszania problemów/błędów w aplikacji przez e-mail (choć można to “doskryptować”).

Strona projektu: http://trac.edgewall.org/

devTodo

Drugim narzędziem z którego korzystam jako developer jest devTodo. Przez długi czas szukałem narzędzia które umożliwiało by mi bardzo szybkie dodanie nowych zadań do listy. Ponieważ pracuje głównie na konsoli, szukałem czegoś co by pracowało w trybie tekstowym na serwerze. No i znalazłem. devTodo jest właśnie prostą listą zadań z priorytetyzacją zadań, napisaną w C, pracującą w trybie tekstowym. Sprawdza się idealnie gdy nie chcę przerywać pracy żeby zapisać jakąś rzecz do zrobienia. Przy połączeniu z wpisywaniem zadań “ogólnych” do traca tworzą cudowny tandem.

Ciekawą opcją jest możliwość podczepienia skryptu pod powłokę bash który automatycznie wyświetli listę zadań z pliku .todo przy wejściu do dowolnego katalogu go zawierającego. Dzięki temu trudno jest zapomnieć co się ma do zrobienia.

Podczas pisania tego artykułu przyszedł mi do głowy pomysł na integrację traca i todo. Można napisać skryp który wyciągnie przypisane tickety do danego użytkownika i doda je do listy devTodo. Drugi skrypt sprawdzał by które zadania zostały rozwiązane i uaktualniał wpisy w tracu.

SVNmerge

Ostatnie narzędzie jest mniej uniwersalne w przeciwieństwie do dwóch poprzednich. Wręcz jest narzędziem które pomaga w specyficznych sytuacjach. Mianowicie musisz używać Subversion i Twoj projekt musiał rozdzielić się kiedyś na dwie gałęzie (np.: w wyniku rozpoczęcia prac nad klonem serwisu). Jeżeli byłeś kiedyś w takiej sytuacji wiesz ile trudu zajmuje przenoszenie zmian pomiędzy wersjami. Jest to bardzo trudna i żmudna praca. Na szczęście jest narzędzie które to ułatwia. Jest to skrypt napisany w pythonie, dostępny w standardowej dystrybucji subversion w katalogu contrib.

Narzędzie to znacząco ułatwia przeglądanie zmian które nie są przeniesione do drugiej wersji, ich nanoszenie oraz blokowanie zmian które nigdy nie powinny być przeniesione. Skrypt ten jest generalnie nakładką na podstawowe narzędzia subversion, usprawniając ich użycie. Informacje na temat wszelakich zmian są umieszczne repozytorium Subversion (z wykorzystaniem mechanizmu svn:properties”). Jeżeli Twój projekt spełnia założenia użycia SVNmerge, polecam skorzystanie z niego - tak jak kiedyś starałem się nie rozdzielać projektów w czasie prac developerskich, tak od momentu kiedy go używam nie stanowi to dla mnie problemu.

A czy Wy znacie jakieś narzędzia które ułatwiają pisanie (pomijam edytory :) którymi warto było by się zainteresować?

Jak zrobić mechanizm pluginów w Ruby

grudzień 12th, 2006 by Paweł Rutkowski

Podczas pracy przy ostatnim projekcie napisałem kilka programów w Ruby. Jeden z nich był frameworkiem udostępniającym pewne API. Głównym zadaniem tego frameworku było usprawnienie operacji na bazie SQL które co jakiś czas musieliśmy wykonywać ręcznie - co było bardzo pracochłonne i wymagało wielkiej uwagi.

Założenia dla frameworku były następujące:

  • udostępniać minimalną funkcjonalność - wspólną dla innych operacji
  • obsługiwać pluginy które realizowały by poszczególne operacje
  • pluginy powinny “myśleć” za użytkownika, tzn weryfikować dane ew. podpowiadać dostępne rozwiązania (ale to będzie temat na oddzielny wpis)

Musiałem zatem wymyślić jakiś mechanizm pluginów. Ponieważ Ruby jest językiem bardzo elastycznym nie było z tym większego problemu.

Pierwszą rzeczą było stworzenie klasy Action - z której będą dziedziczyć wszystkie pluginy. Następnie zaimplementowałem dwie metody: self.description i self.run. Pierwsza z nich była odpowiedzialna za wyświetlanie opisu pluginu, druga zaś uruchamiała właściwy plugin. Ponieważ klasa Action sama w sobie nie była wykorzystywana powyższe metody zwracały tylko informacje że należy je zaimplementować w klasie dziedziczącej.

Drugą rzeczą było udostępnienie jednego z obiektów dla każdego z pluginów. Tutaj sprawa nie była skomplikowana - wystarczyło dodać parametr do konstruktora, przypisać do zmiennej zaś przy tworzeniu obiektu przekazać odpowiednią zmienną.

Oto jak wygląda w uproszczeniu ta klasa


class Action
def initialize(api_object)
@api = api_object
end
def self.description
puts "desc method have to be overriden"
end
# method execute to run plugin
def run
puts "run method have to be overriden"
end
end

Narazie prosto prawda ? No to teraz trzeba było by jakoś ładować pluginy do aplikacji. Stwierdziłem że najlepszą metodą będzie utworzenie katalogu plugins i wczytywanie wszystkich plików które się tam znajdują (z definicją nowej klasy która de facto jest pluginem). Do tego posłuzyłem się następującym kawałkiem kodu:


def load_actions
Dir["plugins/*.rb"].sort.each { |plugin|
require plugin
}
end

I zaraz potem trafiłem na problem. Jak wyciągnąć klasy które dziedziczą z innej klasy ? Pomimo że ruby ma bardzo dobrze rozwinięte “reflections” (jest to możliwość dynamicznego metaprogramowania - np.: sprawdzanie dostępnych metod w obiektach, informacji o zmiennych, ich typach itp) to nie udało mi się znaleźć funkcji oferującej taką funkcjonalność. Trochę czasu mi zajęło przejrzenie metod dostępnych w klasach Object, ObjectSpace, Class i wyszukanie tych z których można skorzystać. Oto jak wyglądał kod (a pod spodem jego omówienie).


class Class
def self.find_by_super(sclass)
ret = []
ObjectSpace.each_object(Class) { |klass|
ret << klass if klass.superclass == sclass
}
return ret
end
end

Jak widać powyżej do klasy Class została dodana metoda find_by_super która jako parametr przyjmuję klasę nadrzędną w stosunku do klas które szukamy. Następnie przechodzimy przez wszystkie obiekty typu Class (czyli wszystkie klasy) i sprawdzamy które z nich dziedziczą z klasy określonej w parametrze funkcji.

Właśnie podczas pisania tego postu zauważyłem że można zrobić z powyższego kodu “jednolinijkowca”.


def self.find_by_super(sclass)
ObjectSpace.each_object(Class).find_all { |klass| klass.superclass == sclass }
end

Następnie należało już tylko dokonać iteracji po pluginach i wyświetlić ich listę w celu dokonania wyboru. Trick polegał na załadowaniu listy pluginów do tablicy, ich wyświetlenie a następnie zinterpretowanie wejścia użytkownika jako indeksu do konkretnego miejsca w tablicy, wskazującego na plugin który go interesuje.


[...]
# szukamy klass < Action
@actions = Class.find_by_super(Action)
[...]
# licznik na 0
n=0
actions.each { |action|
# dla kazdej akcji wywolujemy jej metode
# description i pokazujemy na ekranie
puts "#{n} - #{action.description}"
# zwiekszamy licznik :)
n=+1
}
[...]
printf("Please choose action: ")
# odczytujemy co podal user
@user_choose = $stdin.gets.to_i
# tworzymy obiekt na podstawie wybranej klasy i
# do konstruktora przekazujemy @api
action = @actions[user_choose].new(@api)
[...]
action.run

Proste ? Pewnie po przeczytaniu tego artykułu tak :) Natomiast dla mnie było to swego rodzaju wyzwanie, które trochę czasu zajęło. Było to jednak ciekawe zagadnienie a dzięki Ruby i mozliwością tego języka bardzo przyjemne do zaimplementowania. Oczywiście cały framework oferował znacznie więcej i pojawiło się wiele innych problemów, ale nie chciałem ich tu zamieszczać żeby nie zaćmić ogólnej ideii.

Wykład na MeetBSD - BGP - Praktyczny poradnik migracyjny

listopad 26th, 2006 by Paweł Rutkowski

W weekend miała miejsce kolejna edycja konferencji MeetBSD poświęconej systemom z rodziny *BSD. Dzięki zaproszeniu organizatorów miałem szansę poprowadzić wykład pod tytułem “BGP - praktyczny poradnik migracyjny”.

Podczas wykładu poruszyłem następujące kwestie:

  • co to jest BGP i kiedy jest on używany
  • kiedy rozważyć zmianę jednego łącza na kilka innych z użyciem BGP
  • Jak się przygotować do zmiany i jakie formalności należy załatwić
  • Konfiguracja OpenBGPd

Jak zwykle po konferencji, prezentacje możecie sciągnąć tutaj

Prezentacja - TOP SECRET

październik 21st, 2006 by Paweł Rutkowski

Dzisiaj miałem przyjemność wygłosić wykład pt. “TOP SECRET - co oznacza klauzula tajnosci w polskich realiach” na konferencji SecureCON. Slajdy z prezentacji są dostępne tutaj.