Entries Tagged 'Ruby on Rails' ↓

Ruby on Rails 2.2 (a nawet 2.2.2)

Ruby on Rails 2.2Jako że Ruby on Rails doczekało się kilka dni temu (a dokładniej 21-go listopada) kolejnej odsłony, wypadałoby opisać co ważniejsze lub co ciekawsze rzeczy, które pojawiły się w tej wersji. Poniżej więc są rzeczy, które zwróciły moją uwagę, posortowane w miarę losowo i zdecydowanie nie jest to kompletna lista poprawek, ale moje spojrzenie na to, co uważam za przydatne (lub mniej przydatne, ale warte odnotowania z różnych względów).

Z luźnych i nie związanych z tematem skojarzeń to niedawno oprogramowanie firmware dla iPhone’a też doczekało się wersji 2.2, a wtyczka Akismet do WordPressa trafiła jeszcze dokładniej – aktualnie jest w wersji 2.2.2. Ciekawy zbieg okoliczności.

* i18n (Internationalization)
Jaki jest polski odpowiednik tego? Internacjonalizacja? Brzmi zdecydowanie zbyt sztucznie. Pozostanę więc przy i18n – prostsze, szybsze i bardziej naturalne.
Tak czy owak, Ruby on Rails trochę urosło, wyedukowało się i w efekcie nauczyło się mówić w wielu językach. W tym oczywiście po polsku. Skończą się wreszcie różne dziwne sztuczki i triki, żeby oduczyć swoje aplikacje od angielskiego i przekabacić na polski. Teraz to jest wbudowane we framework i można się skupić na ważniejszych rzeczach. Bardzo duży plus dla wszystkich piszących aplikacje w innych językach. Ze swego doświadczenia wiem jak duży jest komfort kiedy się pisze aplikację po angielsku (praktycznie nic nie trzeba poprawiać i wszystko jest naturalne) i ile się trzeba napoprawiać i o ile rzeczach pamiętać, kiedy się pisze np. po polsku.
Tuż po wyjściu wersji 2.2 nie było jeszcze polskiej lokalizacji, więc ja i oki postanowiliśmy przetłumaczyć co było do przetłumaczenia i wrzucić to do oficjalnego repozytorium Ruby on Rails. Spóźniliśmy się o jakiś dzień lub dwa, bo ubiegł nas Jacek Becela z trix.pl i dzięki temu Rails już nie ma problemu z dogadaniem się po szczebrzeszyńsku.
Dla zainteresowanych – dużo materiałów na temat i18n jest zebranych na oficjalnej stronie: Rails I18n. Warto się zapoznać.

* Zgodność z Ruby 1.9 i JRuby
Z JRuby nie korzystam i w najbliższym czasie prawdopodobnie jeszcze nie skorzystam, ale warto o tym wspomnieć, bo JRuby nabiera coraz bardziej rumieńców i jest już dostatecznie szybkie i stabilne, żeby działać w trybie produkcyjnym.
Bardziej interesuje mnie zgodność z Ruby 1.9. Co prawda nie przesiądę się jeszcze na 1.9, bo nie jest to jeszcze wersja stabilna, ale dobrze wiedzieć, że jak tylko Ruby 1.9 dojdzie do wersji końcowej, to Ruby on Rails już będzie na to gotowe. A jest na co czekać, bo Ruby 1.9 jest dużo, dużo szybsze od Ruby 1.8.x.

* Dokumentacja
Dużo dobrego dzieje się w działce dokumentacji. Jedna z ważniejszych inicjatyw ostatnich miesięcy to uruchomienie Ruby on Rails Guides. Jest to zbiór niby-tutoriali, niby-opisów, niby-zbiorów-informacji o najważniejszych komponentach Ruby on Rails. Trzeba przyznać, że ich jakość jest lepsza, niż się spodziewałem i zdecydowanie warto do nich zajrzeć.
Oprócz tego moim zdaniem najlepsze źródło dla API, czyli APIdock już ma dokumentację dla Ruby on Rails 2.2, więc można śmiało korzystać i się cieszyć.

* Wsparcie dla ETag i last_modified
Od teraz łatwiej będzie unikać zasobochłonnych zapytań poprzez porównywanie ETag i last_modified oraz wysyłania „304 Not Modified”

* Transakcje w migracjach
Koniec z problemami kiedy migracje wywalały się w połowie i mimo iż żadna z migracji po błędzie nie została wykonana, to w bazie została zapisywana nieodpowiednia wersja i albo trzeba było ręcznie zmieniać numer wersji albo kasować wszystko i zaczynać od nowa. Teraz wszystko wygodnie jest pakowane w transakcję i jak coś ma nie działać, to nie zaśmieca to nam bazy częściowymi migracjami i po poprawieniu błędu możemy spokojnie migrować raz jeszcze.

* Łatwiejsza praca z łączonymi tabelami (JOIN)
Teraz do łączonych tabel można dodawać tablicę asocjacyjną (hash) z dodatkowymi warunkami wyszukiwania, co znacznie ułatwi zapytania na skomplikowanie połączonych tabelach.
Prosty przykład dla unaocznienia:

# Znajdź wszystkie książki z twardą okładką
Book.all(:joins => :covers, :conditions => { :covers => { :hard => true }})

Nasuwa mi się od razu tematyczny dowcip. Może i znany, ale niezmiennie dobry:
Zapytanie SQL wchodzi do baru, podchodzi do dwóch tabel i mówi: „Can I join you?”

* find_last_by_<atrybut>
Dopiero niedawno (zdaje się w wersji 2.0 albo 2.1) zostało wprowadzone ‘last’, a już jest find_last_by. Jest to odpowiednik tego kodu:

Model.last(:conditions => {:attribute => value})

# Znajdź ostatnią książkę Gladwella
Book.find_last_by_author['Malcolm Gladwell']

* Układy stron w Action Mailer (layouts)
Kto trochę dłużej pracował z Action Mailerem, ten wie, że generowanie i wysyłanie maili jest delikatnie mówiąc zrobione „trochę naokoło”. Ja przynajmniej zawsze odnosiłem takie wrażenie. Od teraz jest to ułatwione poprzez stosowanie layout’ów. Łatwiej się będzie teraz tym zarządzało, aczkolwiek ciągle uważam, że wysyłanie maili jest niepotrzebnie przekombinowane w Ruby on Rails.

* Pomocne szczególiki
- Dodane metody past?, today? i future? dla klas Date i Time, dla łatwiejszego porównywania czasów i dat
- Time rozpoznaje teraz ułamkowe wartości w konstrukcjach takich jak: 2.3.hours.ago albo 3.6.weeks.since

* Dziwoląg
Stworzono aliasy Array#second do Array#tenth dla Array#[1]Array#[9]
Po co? Nie mam najmniejszego pojęcia. Jak dla mnie to jedynie niepotrzebne zaśmiecanie frameworka. Więcej zachodu niż to jest tego warte.

Dla dalszego zgłębiania szczegółów polecam ten link. Jest tam naprawdę dużo przydatnych rzeczy i szczegółowych opisów.

Podsumowując
Ruby on Rails 2.2 jest – szczególnie dla międzynarodowej części społeczności Ruby on Rails – dużym i ważnym krokiem do przodu. Rails 2.1 był w sieci dość mocno nagłośniony, jednak uważam, że to 2.2 jest większym krokiem do przodu w porównaniu do poprzedniej wersji, niż 2.1 w stosunku do 2.0. Rzeczy wyżej wymienione to tylko część zmian. Dużo więcej się dzieje pod maską, tam gdzie nie jest to tak widoczne, a co jest równie ważne.
W najbliższym czasie mam zamiar napisać prostą aplikację w Rails 2.2.2. Żeby potestować nową wersję i żeby napisać coś użytecznego (tak przynajmniej to postrzegam). Jeśli będą jakieś nietypowe rzeczy, to się nimi podzielę. Jak aplikacja będzie gotowa, to również nie omieszkam o tym wspomnieć.
A teraz zapraszam do kodowania w nowej odsłonie Rails. Miłego klawiaturowego i intelektualnego szaleństwa.

Boolean w Ruby on Rails czyli czy chciałbyś zaoszczędzić 2 dni swego życia?

booleanChciałbym, żeby mi ktoś zaoszczędził 2 dni z mojego życia. Jeden z weekendów mógłby być o 2 dni dłuższy. Wyjazd na deskę mógłby trwać tyle ile by się chciało. Byłoby więcej czasu na czytanie książek, spędzanie czasu z bliskimi itp.
Ten „ktoś” jednak postanowił mi te 2 dni zabrać zamiast sprezentować… A tym „kimś” jest sposób interpretacji kolumny boolean przez Ruby on Rails.

Nie ma co jednak wybiegać do przodu, więc wszystko po kolei.

We wszystkich swoich dotychczasowych projektach używałem bazy MySQL, więc na tym będę bazował swoje rozważania.

Tworzę więc sobie model Person i daję mu atrybut friend, który może być true albo false. W migracjach, zgodnie z konwencją Rails, w modelu Person przy polu :friend daję typ :boolean. Wszystko na razie idzie zgodnie z planem. Po wykonaniu rake:db pojawia się tabela „people” i w niej pole ‘friend’ ma typ tinyint(1). Tu w sumie też wszystko idzie z planem, gdyż kolumna o typie tinyint(1) przez ActiveRecord rozpoznawana jest jako ‘boolean’.

MySQL ciągle się nie dopracował prawdziwego typu ‘boolean’, więc nawet w natywnym MySQL gdy się tworzy kolumnę typu BOOLEAN, to jest to równoznaczne ze stworzeniem kolumny o typie tinyint(1). Wartość zerowa jest traktowana jako false, a każda inna wartość jako true. (MySQL 5.0 Reference Manual – Overview of Numeric Types)

No i gdybym nie był „sprytniejszy”, niż trzeba, albo może gdybym kodował to nie będąc w pełni sił umysłowych, to nie byłoby żadnego problemu. Będąc jednak pomysłowym Dobromirem spojrzałem w strukturę bazy danych, zauważyłem typ tinyint(1), doszedłem do wniosku, że ani true ani false w tinyint się nie zmieści, więc będą tam tylko zera lub jedynki. I dalej szczęśliwie wrzucałem sobie do kodu tu i ówdzie takie oto kwiatki:

if Person.friend == 1 ...
if Person.friend == 0 ...

W kodzie miałem oczywiście zmienne, a nie nazwy modeli, ale podaję dla zobrazowania. W każdym bądź razie te kawałki aż prosiły się o poprawienie, ale nów umysłowy (antonim pełni) był silniejszy i z zadowoleniem pisałem sobie dalej.
Można łatwo sobie dopowiedzieć czym to się skończyło. Absolutnie bezsensownymi dwoma dniami, gdzie aplikacja „dziwnie się zachowywała”.

Jeśli więc ktoś kiedyś również będzie pisał kod nie wkładając w niego za wiele myśli (z braku sił czy też jakiegokolwiek innego powodu), to chciałbym, żeby poniższe przykłady zapadły dostatecznie w pamięć, żeby napisać to dobrze. Jak się na to patrzy, to wszystko to powinno być proste i logiczne, ale rzeczy proste i logiczne daleko nie zawsze są proste.

Znajdujemy więc sobie dwie osoby, jedną która jest moim przyjacielem, a druga – niekoniecznie.

t = Person.find(:first, :conditions => ["..."])     # atrybut friend o typie tinyint(1) ma wartość 1
f = Person.find(:first, :conditions => ["..."])     # atrybut friend o typie tinyint(1) ma wartość 0

Sprawdzamy czy te osoby naprawdę są przyjaciółmi czy też nie.

t.friend    # true
f.friend    # false

t.friend?    # true
f.friend?    # false

I właśnie sposób powyższy (najlepiej ze znakiem zapytania, bo jest bardziej czytelny i jasny w przekazie) jest prawidłowym i najlepszym sposobem na testowanie wartości boolean w Rails. Prawda, że proste?
Warto jednak rozpatrzyć jeszcze kilka przykładów, które czasami dają nam rezultaty, których oczekujemy, a czasem nas zaskakują. I to w niemiły sposób.

t.friend.blank?     # false
f.friend.blank?     # true

t.friend.empty?     # NoMethodError: undefined method `empty?' for true:TrueClass

f.friend.empty?     # NoMethodError: undefined method `empty?' for false:FalseClass

Tutaj blank? działa, natomiast empty? odmawia współpracy. Jednak mimo iż blank? działa poprawnie, to jest to raczej niefortunny i nieklarowny zapis, więc lepiej go unikać.
Poniżej zaś to, co próbowałem robić w swoim kodzie. Dziecinny błąd. Children, don’t try this at home! :)

t.friend == 0     # false
t.friend == 1     # false
t.friend == "0"   # false
t.friend == "1"   # false

t.friend.to_i   # NoMethodError: undefined method `to_i' for true:TrueClass
f.friend.to_i   # NoMethodError: undefined method `to_i' for false:FalseClass

Jak widać ani porównywanie tego do wielkości integer, ani string nie daje oczekiwanych rezultatów. Nawet próba konwersji wyrzuca błąd. Wniosek: nigdy nie porównywać boolean do wielkości liczbowych (i konkretnie do zer i jedynek).
Można porównywać je do wartości true/false (ale koniecznie nie jako string), ale to też jest mało eleganckie.

t.friend == true  # true
f.friend == true  # false

t.friend == "true"    # false
f.friend == "true"    # false
t.friend == "false"   # false
f.friend == "false"   # false

t.friend.to_s   # "true"
f.friend.to_s   # "false"

Jeśli więc ktoś kiedyś dzięki powyższemu użyje formy prawidłowej zamiast niepoprawnej i zaoszczędzi przynajmniej kilka godzin (nie mówiąc już o dwóch dniach), to… przynajmniej nie będzie musiał pisać postów rozpoczynających się słowami „Chciałbym, żeby mi ktoś zaoszczędził 2 dni z mojego życia”.

Ruby on Rails: szlachetny kamień na szynach czy duchowny w pociągu?

Ruby vs RabbiPewnego słonecznego dnia szedł sobie stary i mądry rabin przez pola i łąki. Rozmyślał nad Torą, nad niebezpiecznie rozluźniającymi się obyczajami w swojej gminie (młodzi już nie kłaniają się starszym tak nisko jak drzewiej bywało) i nad nadmiernie wzrastającym autorytetem rabina z sąsiedniej gminy za rzeką. Będąc dotychczas najbardziej szanowaną osobistością w całej okolicy między rzeką a tą miejscowością, dokąd czasem się zapuszczał dokonać bardziej nietypowych zakupów, niż chleb czy mięsiwo (np. kałamarze czy płótno), oczywistością było, że rosnący u boku autorytet jest co najmniej powodem do niespokojnego snu w nocy i podczas siesty. Idąc więc przez łąkę i bezwiednie muskając dłonią czubki wyższych traw, podświadomie poszukiwał „znaku”, który by go wewnętrznie umocnił w przekonaniu, że jego pozycja jest niezagrożona i że nieoczekiwane drgawki nie będą go wyrywały z błogiego stanu siesty.
Tak niepostrzeżenie doszedł aż do nasypu, który biegł wzdłuż rzeki. W swym zamyśleniu i trosce zabrnął dalej, niż zwykle. Wspiął się więc po nasypie (a trzeba zaznaczyć, że nie był to nasyp zwykły, lecz kolejowy) i wzdłuż tego nasypu podążył powoli z powrotem w kierunku swej siedziby.
Aż tu raptem z zadumy wyrwał go nieoczekiwany czerwony blask, strzelający wprost spod nóg. Ku jego bezgranicznemu zdumieniu był to… dorodnej wielkości rubin leżący wprost na torach kolejowych.
- Cóż za wspaniały rubin! – wykrzyknął rabin, podniósł go z torów i już ze spokojnym umysłem i uśmiechem na twarzy dziarsko potruchtał w kierunku unoszącego się dymu, zwiastującego rychły obiad.

A jaki jest morał tej historii?
Otóż apeluję szczerze, żebyśmy nie zamieniali ról w tej historii i nie pozwalali rubinowi znaleźć rabina na torach, tylko pozostawili to w takiej wersji jak powyżej, nawet nie zważając na fakt, że nie jest to najwybitniejsza przypowieść tego roku.

Jak bowiem brzmiałoby kluczowe zdanie przypowieści w języku angielskim?
- What a nice ruby! – exclaimed rabbi, took it off the rails and merrily trotted home. (tłum. wolne)

Ze szczegółami:
[hwuht] [a] [nahys] [roo-bee]! – [ik-skleymd] [rab-ee]
Źródło: Dictionary.com Unabridged (v 1.1)

[roo-bee] (pol. rubi) – Rubin
[rab-ee] (pol. rabi) – Rabin

Jeśli więc jesteśmy w tej branży, programujemy w tym języku, inwestujemy w projekty związane z tą technologią czy wręcz posiadamy firmy, które się zajmują programowaniem m.in. w tym języku, to ja bardzo proszę… nie mieszajmy w to religii i duchownych :)

Ruby on Rails :include i ‘eager loading’ w akcji

eager loadingJako że ostatnie kilka tekstów było natury dywagacyjnej, a Ruby on Rails było poruszone tylko pobieżnie i niejako powierzchownie, tym razem będzie bardziej „technicznie”.

Nie czytam literatury dotyczącej RoR w języku innym, niż angielski, więc większość terminów będzie po angielsku, co mam nadzieję nie obrazi żadnych purystów językowych. Jako że nie znalazłem polskiego odpowiednika „eager loading„, będę się więc posługiwał taką właśnie formą. No chyba że bym się trochę wysilił z kreatywnością i przynajmniej spróbował to przetłumaczyć.
Może więc „chętne ładowanie”?
Albo – co brzmi dużo bardziej interesująco i ekstrawagancko – „skwapliwe ładowanie„?

Czym jest więc skwapliwe ładowanie? (Spodobał mi się ten termin, więc będę go stosował naprzemiennie z jego anglojęzycznym odpowiednikiem).

Otóż Rails daje nam proste i skuteczne narzędzia do tworzenia aplikacji internetowych. Jednakże prostota i skuteczność często pociąga za sobą mniejszą skłonność do myślenia i wręcz lenistwo.

Może więc na początek szybki quiz w stylu 1 z 10, kiedy na odpowiedź ma się około 5 sekund.
Sznuk: Kiedy stosuje się eager loading?
Programista RoR: Eager loading jest stosowany kiedy mamy do czynienia z powiązanymi modelami.

Sznuk: Do czego służy eager loading?
Programista RoR: Służy do zmniejszenia liczby zapytań do bazy danych i tym samym do usprawnienia i przyśpieszenia aplikacji. [ding!] Przynajmniej w większości przypadków. (Ostatnie zdanie, mimo iż prawdziwe, było już po „ding!”, sygnalizującym koniec czasu na odpowiedź, jednakże odpowiedź zaliczona).

Załóżmy więc, że mamy restaurację i w niej kilku dobrych kucharzy, którzy robą świetne dania i używają do tego swoich ulubionych składników

class Cook
  has_many :dishes
  has_many :ingredients, :through => :dishes

class Dish
  belongs_to :cook
  has_many :ingredients

class Ingredient
  belongs_to :dish

Jeśli więc chcielibyśmy sobie sprawdzić jakich to składników używa każdy z kucharzy (i dlaczego schodzi tak dużo rumu mimo iż nie jest składnikiem prawie żadnej potrawy), to będąc leniwymi programistami możemy sobie upichcić takie oto zapytanko:

@cooks = Cook.find(:all)

Później w widoku (view) pokażemy te składniki dla każdego z kucharzy:

<% for cook in @cooks %>
  <%= cook.name %>:<br />
  <% cook.ingredients.each do |i| %>
    <%= i.name %>
  <% end %>
<% end %>

I nic nie będzie w tym złego. Bo w końcu mamy tylko jedną restaurację, więc najwyżej kilku kucharzy. Nic więc strasznego, że dla każdej iteracji będzie generowane nowe zapytanie do bazy, żeby wydobyć listę składników. Jednakże jeśli byśmy mieli sieć restauracji w całej Europie i chcielibyśmy wiedzieć który kucharz spośród nich wszystkich używa więcej chili, niż przeciętny kucharz mąki, to już mielibyśmy problem, bo przy tak dużej ilości kucharzy nasza baza danych nie byłaby tak szybka w zaserwowaniu nam pysznych wyników.
Jednakże skwapliwe ładowanie stoi tuż za rogiem, machając nieśmiało ręką i próbując zwrócić na siebie uwagę. Przywołujemy więc je, pokazujemy mielącą dyskami i RAMem bazę danych i mówimy: „Zrób z tym coś”. Skwapliwe zabrawszy się za robotę, eager loading w końcu daje nam coś tak idealnie prostego, aczkolwiek skutecznego:

@cooks = Cook.find(:all, :include => :ingredients)
@cooks = Cook.find(:all, :include => [:dishes, :ingredients])

Skutkuje to tym, że do bazy danych zostaje wystosowane jedno jedyne, długie jak spagetti zapytanie, które wszystkie potrzebne nam dane wyciąga za jednym zamachem. Przykładowe zapytanie (z kategorii innej niż kuchenna, ale żeby zobrazować długość możliwego zapytania) może być np. takie jak poniżej.
Jest to zapytanie wygenerowane przez ten niewinny kod:

@user_categories = current_user.categories.find(:all,
                :include => [ :children => [ :children, :parent ]], :order => "categories.name")

SELECT `categories`.`id` AS t0_r0,
`categories`.`cat_type` AS t0_r1,
`categories`.`name` AS t0_r2,
`categories`.`description` AS t0_r3,
`categories`.`created_at` AS t0_r4,
`categories`.`updated_at` AS t0_r5,
`categories`.`parent_id` AS t0_r6,
`categories`.`user_id` AS t0_r7,
`childrens_categories`.`id` AS t1_r0,
`childrens_categories`.`cat_type` AS t1_r1,
`childrens_categories`.`name` AS t1_r2,
`childrens_categories`.`description` AS t1_r3,
`childrens_categories`.`created_at` AS t1_r4,
`childrens_categories`.`updated_at` AS t1_r5,
`childrens_categories`.`parent_id` AS t1_r6,
`childrens_categories`.`user_id` AS t1_r7,
`childrens_categories_2`.`id` AS t2_r0,
`childrens_categories_2`.`cat_type` AS t2_r1,
`childrens_categories_2`.`name` AS t2_r2,
`childrens_categories_2`.`description` AS t2_r3,
`childrens_categories_2`.`created_at` AS t2_r4,
`childrens_categories_2`.`updated_at` AS t2_r5,
`childrens_categories_2`.`parent_id` AS t2_r6,
`childrens_categories_2`.`user_id` AS t2_r7,
`parents_categories`.`id` AS t3_r0,
`parents_categories`.`cat_type` AS t3_r1,
`parents_categories`.`name` AS t3_r2,
`parents_categories`.`description` AS t3_r3,
`parents_categories`.`created_at` AS t3_r4,
`parents_categories`.`updated_at` AS t3_r5,
`parents_categories`.`parent_id` AS t3_r6,
`parents_categories`.`user_id` AS t3_r7
FROM `categories`
LEFT OUTER JOIN `categories` childrens_categories ON childrens_categories.parent_id = categories.id
LEFT OUTER JOIN `categories` childrens_categories_2 ON childrens_categories_2.parent_id = childrens_categories.id
LEFT OUTER JOIN `categories` parents_categories ON `parents_categories`.id = `childrens_categories`.parent_id
WHERE (categories.user_id = 3)
ORDER BY categories.name

Przy większej ilości danych średnia poprawa wydajności (nie według żadnych benchmarków, a według moich własnych i często subiektywnych obserwacji) jest co najmniej 2-3-krotna. Iterować po takich wynikach możemy dokładnie tak samo jak w poprzednim przypadku, tyle że tym razem już nie będą wysyłane żadne dodatkowe zapytania do bazy.

Sznuk: Pytanie finałowe dla Pana: czego nie potrafi eager loading?
Programista RoR: Eager loading nie potrafi gotować, prać, robić masażu i wybierać tylko poszczególne pola poprzez :select, bo tak bardzo jest skwapliwy, że [ding!] ładuje wszystko…
Sznuk: To jest poprawna odpowiedź! Gratuluję Panu wygranej w naszym programie. Wygrał Pan darmowe skwapliwe ładowanie trzech ciężarówek w malowniczym porcie w Gdyni. Pozdrawiam i do zobaczenia!

Trochę odbiegając już od tematu, jednak potwierdzę, że w przypadku eager loading opcja :select jest stanowczo i ostentacyjnie ignorowana. Jeśli nam jednak zależy na tej opcji, to możemy zrezygnować z :include na rzecz :joins, uzyskując pożądany wynik, aczkolwiek w trochę mniej elegancki sposób.

@posts = Post.find(:all,
:select => "posts.id, posts.title, posts.subject, users.username",
:joins => "left outer join users on users.id = posts.user_id")

Nie bądźmy więc leniwi bardziej niż to konieczne lub zdrowe i używajmy częściej skwapliwego ładowania, a baza danych będzie nam za to wdzięczna i w przyszłości, jak będziemy bardzo potrzebować jej dobrej pracy, spojrzy na nas łaskawszym okiem, westchnie głęboko i się zabierze za ładowanie.

Ruby on Rails: analiza SWOT

Kiedyś jak na zajęciach z ekonomii na pierwszym roku studiów trzeba było robić analizy SWOT dla wyimaginowanych firm, byłem przekonany, że był to jedyny raz kiedy coś takiego robię i że nigdy więcej na pewno tego nie będę potrzebował.

Minęło lat ileś i kiedy wpadł mi do głowy pomysł oceny Ruby on Rails, do głowy samoistnie nasunęła mi się analiza SWOT, jako dość dobrze nadające się narzędzie do pokazania różnych aspektów tego zjawiska.

Krótka definicja analizy SWOT (gdyby ktoś nie wiedział albo chciał sobie odświeżyć swoją wiedzę).

Strengths (Mocne strony)
Weaknesses (Słabe strony)
Opportunities (Szanse)
Threats (Zagrożenia)

Słownikowo (Wikipedia):
Analiza SWOT – jedna z najpopularniejszych heurystycznych technik analitycznych, służąca do porządkowania informacji. Bywa stosowana we wszystkich obszarach planowania strategicznego jako uniwersalne narzędzie pierwszego etapu analizy strategicznej. Np w naukach ekonomicznych jest stosowana do analizy wewnętrznego i zewnętrznego środowiska danej organizacji, (np. przedsiębiorstwa), analizy danego projektu, rozwiązania biznesowego itp.”

SWOT_en

Poniżej pokrótce moje opinie i obserwacje na temat słabych i mocnych stron RoR, ich szans i zagrożeń. Każdy z punktów (o ile nie jest ewidentny) rozwinę i wytłumaczę dlaczego tak uważam.

Mocne strony
1. Proste i szybkie w budowaniu
2. Standardowa struktura aplikacji
3. Wbudowane testowanie
4. Społeczność
5. Dobry marketing (na świecie)
Słabe strony
1. Problemy przy uruchamianiu na serwerze
2. Wolne działanie niektórych elementów frameworka
3. Dokumentacja
4. Słaby marketing (w Polsce)
Szanse
1. Rails 2.0 (dodatkowy buzz)
2. Potrzeba bardzo szybkiego tworzenia i szybkich zmian aplikacji
3. Rosnąca ilość dużych serwisów napisanych w Rails
Zagrożenia
1. Nie zdobędzie masy krytycznej użytkowników
2. Nie zdobędzie masy krytycznej firm hostingowych
3. Wejście nowego gracza lub umocnienie się istniejącego
4. Brak (dobrych) programistów
5. Zaniedbanie / pominięcie Ruby (i/lub Rails) przez uczelnie

Na początek plusy, które są dość powszechnie znane, bo są wałkowane na lewo i prawo jak część „buzzu”, który jest wytwarzany wokół Rails.

Prostota i szybkość developmentu. Struktura MVC (Model – View- Controller) narzuca pewne standarty, przez co nie trzeba się zbytnio zastanawiać gdzie co ma być, jakie to ma uzasadnienie i czy następna osoba będzie miała takie samo spojrzenie na to, gdzie muszą być poszczególne elementy aplikacji. Pomaga to w równoległym tworzeniu aplikacji przez kilku programistów albo w miarę bezproblemowym wdrożeniu się lub przejęciu projektu przez nowego programistę.
Wbudowane testy oraz niejako integralna i wpojona część filozofii Rails (TDD / BDD) ułatwia życie na dalszych etapach dużych projektów, kiedy to już nie da się wszystkiego przetestować ręcznie albo ogarnąć wszystkiego naraz.

Społeczność i dobry marketing. Nie widzę nic złego w tym, że ktoś na wiele możliwych sposobów promuje swoje rozwiązanie, o ile oczywiście to rozwiązanie jest dobre. Nie mam więc nic przeciwko temu, że chłopaki z 37 Signals (skąd wywodzi się Ruby on Rails) bardzo dobrze pokierowali społecznością railsową i umiejętnie wytworzyli szum, który pozwolił dość szybko i skutecznie wybić się ponad inne rozwiązania, zostać zauważonym i dzięki temu coraz szerzej stosowanym i akceptowanym.

Słabe strony

Nadal odpalanie serwisów (deployment) nie jest czynnością banalną, jak to jest chociażby w przypadku PHP (wrzucam na FTP’a i mi to działa). Istnieją narzędzia, które ten proces znacznie ułatwiają, jednak ciągle nie jest to tak bezproblemowe, jak mogłoby być „w idealnym świecie”.
Ostatnio pojawiły się dość burzliwe i intensywne dyskusje na ten temat, kwestia stała się dość powszechnie znana, a taki „PR” danej kwestii powinien moim zdaniem tylko zmobilizować społeczność railsową do znalezienia skutecznych rozwiązań.

Wolne działanie niektórych elementów frameworka. Przykładem może tu być chociażby named routes (nie jestem dobry w tłumaczeniu technologicznych pojęć na polski, więc nawet nie próbuję). W Rails 2.0 jest to jeden z kluczowych elementów, więc problem nie jest banalny. Są już jednak wprowadzane na to ulepszenia, które praktycznie niwelują ten problem, więc prawdopodobnie w najbliższej podwersji Rails powinno to działać dużo lepiej.
Nie będę zabierał teraz głosu w sprawie odwiecznych zarzutów typu „Rails doesn’t scale”, gdyż uważam, że dostatecznie dużo zostało na ten temat napisane. Nadmienię tylko, że jest to moim zdaniem problem w bardzo znacznej części rozdmuchany ponad to, jak jest rzeczywiście.


Dokumentacja.
Standardowa dokumentacja API jest często niewystarczająca, ale chociażby projekt Noobkit ten problem stara się rozwiązać i to z dość dobrym skutkiem. Poza tym, jak wynika z punktów pozytywnych, społeczność jest dość pomocna. Grupy dyskusyjne czy kanały IRC zawsze okazywały mi nieocenioną pomoc kiedy niechcący skręciłem gdzieś w ślepą uliczkę i nie wiedziałem co zrobić dalej.


Sytuacja w Polsce
zmienia się cały czas (i to dość szybko) na lepsze, aczkolwiek jeszcze widzę sporo miejsca na poprawę sytuacji, jeśli chodzi o polepszenie rozpoznawalności i akceptacji Ruby on Rails chociażby wśród większych firm w Polsce.

Szanse i zagrożenia

Serwisy internetowe są teraz tworzone w coraz większej ilości i coraz szybciej. Im bardziej cykl tworzenia serwisu jest zbliżony (czasowo) do cyklu wypieku świeżych bagietek, tym lepiej – z punktu widzenia twórców oczywiście.
Poprzednie narzędzia i metody powoli przestają dawać gwarancję tworzenia w takim tempie, mając cykl bardziej zbliżony do dojrzewającego wina, niż gorących bagietek.
Im większe więc będzie zapotrzebowanie na świeże pieczywo, tym większa szansa dla Ruby on Rails na rozwinięcie skrzydeł i uzyskanie dodatkowego uznania (na świecie i w Polsce).
Trzeba tylko zadbać, żeby była odpowiednia ilość dobrych piekarzy i poprawić system dystrybucji bułek (czyt. deployment).

Uczelnie też mogą mieć w tym swój spory udział. Wystarczy uznać, że Ruby (i Rails) są warte tego, żeby postawić na nich dość mocny akcent, a już samo to powinno dać w Polsce spore efekty. Pozostaje mieć nadzieję, że skostniałe (oby jak najmniej) struktury uczelniane jak najszybciej dojdą do takich samych wniosków.

No i ciągle trzeba dbać o to, żeby za kilka lat ludzie nie uznali, że wolą np. nie ciepłe bułeczki, a choćby fastfood. Na razie to nie grozi i maszyna marketingowa (wraz z produktem, który sam się broni) działa należycie, ale nie można tego elementu zaniedbać.

Wnioski

Podsumowując (bądź streszczając dla leniwych, którym nie chciało się czytać powyższych wywodów):

Jest dobrze, może być jeszcze lepiej.
Idealnie nie jest (bo nic nie jest idealnie), ale jest do czego dążyć.
I jest to wniosek dla Rails ogólnie, jak i dla RoR w Polsce.

Pogodnie.pl – nowy serwis pogodowy

  • Czy sprawdzanie pogody musi być uciążliwe?
  • Czy naprawdę potrzebne są wszystkie dane o kierunku wiatru, niżach, wyżach innych anomaliach, o których nawet nie mam pojęcia?
  • Czy można ten proces maksymalnie uprościć i przyśpieszyć?
  • Co można zrobić, żeby dodatkowo umilić ten proces?

Kiedy już miałem pytania – znalezenie na nie odpowiedzi było już tylko kwestią czasu.

Tak więc moim zdaniem najważniejsze w każdym nowym przedsięwzięciu nie są kwestie techniczne, zawiłości tworzenia czy problemy z pomysłem.

Najważniejsze są odpowiednio postawione pytania.

Zakładam, że jakiś czas temu zadałem te odpowiednie i teraz przedstawiam efekt moich prac: http://pogodnie.pl

pogodnie-logo

Serwis jest już w 90% procentach gotowy. Planuję dodać jeszcze kilka szczegółów, ale podstawowa funkcjonalność już działa, więc zapraszam do używania, testowania, wyrażania opinii i ocen pozytywnych lub nie, w zależności od subiektywnych wymagań w stosunku do serwisów tego typu.

Zaznaczam od razu, że większość sugestii dotyczących dodania nowych funkcji niestety będzie „rozpatrzona ze skutkiem negatywnym”, gdyż zamysłem jest „co jeszcze można odjąć, żeby mieć dostatecznie info o pogodzie”, a nie „jaką by tu jeszcze funkcję dodać oprócz mikropaskali, natężenia pyłków i prawdopodobieństwa zorzy polarnej”.

Kilka szczegółów technicznych:

  • Serwis oczywiście stoi na Ruby on Rails
  • Wykorzystuje Weatherbug API
  • Sporo wachlowania i „rozczłonkowywania” plików XML (API nie jest zbytnio developer-friendly, a dokumentacji jak na lekarstwo, na dodatek już nieaktualna w większości)
  • Zminimalizowana ilość zapytań do API

Radość z budowania i tworzenia tego projektu: MAX :)

Dlaczego powstaje mało serwisów mimo ciągle zmniejszającej się bariery wejścia?

kabelek Czy w Polsce są ludzie mniej zdolni niż w USA czy chociażby nawet w Niemczech? Czy mają mniej determinacji, umiejętności albo czasu? Jeśli nie, to dlaczego w innych krajach powstaje dużo więcej firm, serwisów czy usług internetowych (nie używając niemodnego już buzzwordu), niż w Polsce? Poniżej postaram się odpowiedzieć na te pytania, wraz z wyszczególniem co wpływa na taki właśnie stan rzeczy.

Bariery z niedawnej przeszłości

  • Hosting
    Serwery są drogie, niedostępne dla przeciętnego śmiertelnika i na dodatek wybór był niemalże pomiędzy kontami typu „Geocities” (co najwyżej można wrzucić obrazek i napisać kilka słów) a serwerem dedykowanym. Opcje pomiędzy – pominięte albo w ilościach śladowych.

  • Znajomość serwerów
    Jeśli się miało serwer, to trzeba było albo być guru linuxa albo mieć takiego kolegę. Bez tego nic większego, niż postawienie bloga nie dawało się zrobić.

  • Czas tworzenia
    Od powstania koncepcji do stworzenia produktu końcowego mijało co najmniej od kilku do kilkunastu miesięcy – nawet jeśli pracowała przy tym spora grupa ludzi.

  • Sposoby dotarcia do szerszego grona
    Albo się było portalem albo zamiast tworzenia serwisów wybierało się koszykówkę, imprezy, podróże, alkohol – co kto wolał. Brak pierwszego warunku dawał szeroki wachlarz możliwości. Wszystkie z nich z dala od klawiatury (co oczywiście daleko nie zawsze jest złe).

  • Mały rynek docelowy
    Mało tego, że stosunkowo mały, to na dodatek skrzętnie podzielony pomiędzy wyżej wspomniane portale, które w oczach chcącego coś zrobić zapaleńca wyrastały na krwiożercze bestie winne całemu złu – od zgarniania wszystkich przychodów reklamowych po trądzik.

  • Brak możliwości finansowania
    Albo pieniądze masz… albo je zdobywasz w taki sposób, który po pierwsze skutecznie zabiera kilkanaście godzin na dobę, a po drugie starcza tylko na to, by podtrzymać się w stanie pozwalającym na dalsze poświęcanie tych kilkunastu godzin dzień w dzień i może jeszcze na to, by twoja dziewczyna / narzeczona / żona była dostatecznie zadowolona (czyt. „tolerowała taki stan rzeczy”).
    Mała dygresja: użyłem płci żeńskiej, bo po pierwsze w tej branży mało jest kobiet, a po drugie w przypadku mężczyzny to nie brzmiałoby tak samo dobrze.

  • Konieczność postawienia wszystkiego na jedną kartę
    Powyższe punkty niejako prowadzą do tego, że trzeba włożyć naprawdę mnóstwo wysiłku, czasu i pieniędzy, żeby z czymś wystartować (ukierunkowane studia, zdobywanie finansowania, długi czas tworzenia etc.) Jeśli mimo to produkt / usługa / interes nie wypali, to nie pozostaje wiele innych opcji.

  • Małe możliwości monetyzacji
    Jeśli nie uda mi się zdobyć kawałeczka tortu reklamowego, to tak jakby mnie w ogóle nie było. A tego kawałeczka nie uda mi się zdobyć, bo nie mam sposobów dotarcia do szerszego grona. A nie mam tego sposobu, bo nie mam pieniędzy, z którymi to dotarcie nieodwołalnie się wiąże. A nie mogę długo czekać aż stopniowo zbuduję bazę użytkowników, bo hosting i ogólne koszty utrzymania są drogie itd.

Teraz

  • Tani hosting
    Nie wypiję kilku piw miesięcznie, nie pójdę raz na imprezę albo nie kupię raz zbędnego gadżetu i już spokojnie mnie stać na miesięczne opłacenie serwera, na którym bez najmniejszego problemu można postawić początkujący serwis, który powinien sobie poradzić z pierwszymi, nawet większymi „falami” użytkowników.

  • Łatwość wdrażania
    Nie muszę się znać na serwerach, znać wszystkie komendy linuxa, od podszewki znać TCP/IP i DNS, żeby móc odpalić wreszcie swój serwis. W PHP jest to wręcz dziecinnie łatwe, a i do niedawna słynące z problematycznego wdrażania Ruby on Rails ma takie narzędzia jak Capistrano, które również upraszczają to jak tylko się da. Wczoraj od wymyślenia nazwy domeny do działającej na serwerze wersji serwisu napisanego w Ruby on Rails (z działającą domeną włącznie) minęło około pół godziny.
    Więcej na temat serwisu w jednym z kolejnych postów. Oczywiście każdy nie może już się doczekać, jakżeby inaczej?

  • Frameworki
    Nie ma potrzeby pisania wszystkiego w tasiemcowych plikach lub tworzenia własnych frameworków w celu automatyzacji najczęściej używanych funkcji lub zadań. Ogromna większość tej żmudnej pracy została już za nas zrobiona przez autorów różnych frameworków. Na dodatek mamy logicznie ułożoną strukturę serwisu, gdzie nie tylko programista to piszący się połapie, ale i ten, który przyjdzie po nim. Chyba że ten poprzedni do niczego się nie nadawał, ale w takim przypadku nawet najlepszy następca jedyne co może zrobić, to najwyżej zacząć wszystko od nowa. Albo oczywiście, jeśli ma ochotę – może wybrać koszykówkę, imprezy, podróże, alkohol… jednak to odbiega już nieco od tematu.

  • Kanały dotarcia
    Już nie trzeba mieć dużych pieniędzy, żeby dotrzeć do szerszego grona. Wystarczy dobry wykonanie pomysłu, z którym się startuje i przemyślane działania pseudomarketingowe. Z pomocą tu oczywiście idą wszelkiej maści serwisy mniej lub bardziej społecznościowe (tu umownie niech to będzie nazwane Web 2.0) W mniejszym stopniu Web 1.0, a najbardziej oczywiście Web 0.0 (czyli zero webu, a dużo hype’u i szumu wokół tematu lub serwisu – działa świetnie).

  • Rosnący rynek
    Tym łatwiej jest używać powyższych kanałów, im więcej jest ludzi z nich korzystających. A grupa docelowa rośnie. Tort do podzielenia puchnie. I choć portale nadal mają dla siebie największe kawałki, to jednak coraz większe okruchy spadają i od czasu do czasu nawet wisienka się znajdzie.

  • Brak konieczności finansowania
    Po pierwsze wystartować można już bez finansowania. To jest przydatne tudzież potrzebne gdy serwis się rozwinie i zacznie generować ruch (i jeśli dobrze pójdzie, to przychody). Mimo jednak iż nie zawsze jest koniecznośś finansowania, to teraz dużo łatwiej o możliwość finansowania. Fundusze VC, anioły biznesu i ogólna większa chęć inwestowania w technologie i przestanie postrzaganie internetu jako zabawki dla dużych chłopców. Wszystko działa na korzyść tych, którzy chcieliby tą kasę wziąć i coś z nią zrobić.

  • Kupujące portale
    Nie jest to zjawisko masowe ani też nie padają spektakularne sumy, ale „podwaliny zostały podłożone” i precedensy ustanowione. Co prawda nie wszystkie portale kupują (niektóre wręcz mają „politykę niekupowania”, jednak lody się zaczęły kruszyć i widać ruch w interesie.

  • Możliwość utworzenia / zbudowania / uzyskania zysku w więcej niż jednej firmie
    Nie trzeba już stawiać wszystkiego na jedną kartę. Można zbudować kilka serwisów, spróbować w kilku niszach, zawalczyć na więcej niż jednym froncie. I na dodatek nie trzeba poświęcać wcześniej wielu lat na to, żeby osiągnąć poziom pozwalający na stworzenie tych serwisów. Nauczenie się jednego z framework’ów to kwestia około kilku miesięcy. Później to już kwestia praktyki i wprawienia się.

  • Jeśli chcesz – globalny rynek do podbicia
    Jeśli nie wystarcza jednak rodzimy tort i okazyjne wisienki na nim dostępne, to równie dobrze można sięgnąć po tort o wiele większy. Wystarczy tylko mieć dobry przepis na ulepszenie takiego tortu. Wtedy można spokojnie sprawić sobie dużo większą łyżkę i czerpać nią do woli. Oczywiście trzeba mieć trochę więcej sił, żeby taką łyżkę dźwignąć, ale wszystkie składniki przecież są dostępne: mamy tu i możliwość szybkiego tworzenia, są i dostępne finanse, łatwość wdrażania i tani hosting też mogą to tylko ułatwić…

Dlaczegoż więc tak mało tych serwisów powstaje? Już nawet nie mówiąc o tych skierowanych na rynek globalny (nie ma tu praktycznie o czym mówić, poza kilkoma chlubnymi wyjątkami – Nozbe, częściowo Polar Rose), to na rynku polskim również wszystkie wymienione powyżej pozytywy nie przekładają się na lawinowy przyrost ilości nowo tworzonych serwisów. Przyczyn może być kilka. Spróbuję przeanalizować kilka z nich.

Możliwe powody

  • Chęć posiadania dorobienia się na jak najwcześniejszym etapie
    Przykład hipotetyczny:
    Kończę studia („branżowe”). Moi koledzy, nazwijmy ich „spoza branży”, idą do swojej pierwszej lub drugiej pracy. W każdym bądź razie są na początkowym etapie swojej kariery. Zarabiają 1-4K brutto, w zależności od branży czy stopnia fartu. Ja zaś od razu po studiach mogę na starcie zarobić więcej, niż moi koledzy po innych studiach, bo tyle mi proponują tzw. korporacje. Pewna kasa, pewny dochód. W wieku dwudziestu paru lat mogę już sobie wziąć kredyt na mieszkanie, żyć na całkiem innej stopie, niż moi koledzy. Powstaje pytanie: dlaczego niby miałbym z tego rezygnować i przez dłuższy czas inwestować swoją pracę i czas w coś, co nie jest tak pewne i co do czego nie wiadomo czy przyniesie w przyszłości zysk czy też okaże się niewypałem. Mogę mieć chęć zrobienia czegoś ciekawego, ale raczej nigdy nie będę miał na to czasu, bo przecież pracuję.
    Koniec przykładu hipotetycznego.
    Czy branie kredytu i wiązanie się umowami na kilkadziesiąt lat jest rozwiązaniem sensownym, to już jest całkiem inny temat. Chodzi tylko o to, że taka możliwość istnieje. I w młodym wieku, na dodatek na początku drogi „na swoim”, dość trudno jest ludziom takiej możliwości się oprzeć.

  • Duże zapotrzebowanie ze strony „biznesu” na programistów
    Gdyby bohater „hipotetycznego przykładu”rozpoczynał karierę od 2K brutto, jak jego inni koledzy, moim zdaniem byłoby dużo więcej startupów. Dużo więcej osób nie chciałoby pracować po 8-10 godzin za takie pieniądze i byłoby skłonnych podjąć ryzyko i spróbować czegoś na własną rękę. Zapotrzebowanie na takich pracowników jest jednak spore, różnice w zarobkach na starcie również. Na dodatek nie zmieni to się raczej w najbliższym czasie.

  • Awersja do ryzyka i niepewność sukcesu
    Muszę włożyć dużo wysiłku w coś, co nie wiadomo czy wypali, a jeśli wypali, to nie wiadomo kiedy. I na jaką skalę. Na razie jest za mało w Polsce przykładów typu nasza-klasa.pl, które są nagłaśniane przez media i przemawiają do wyobraźni ludzi poprzez liczby. Nawet jeśli te liczby idą na rozwój serwisu, a nie do kieszeni właściciela – ważny jest szum wokół tego, ważne jest dotarcie z taką informacją do mas i ważne jest, że takie liczby robią wrażenie. Poza Polską jest dużo więcej takich przykładów, co przechyla szalę na stronę wypróbowania czegoś własnego. W Polsce to jest na stadium początkującym, ale jeszcze przyjdzie na to czas. Może nawet niedługo.

  • Status
    Przykład hipotetyczny #2:
    - Cześć, jestem Piotrek.
    - Cześć, Marcin jestem.
    - Jestem CTO / system analyst / chief programmer / inny-fancy-stuff w XYZ.pl, a Ty?
    - Eeeee… jestem freelancerem / robię taką stronkę / pracuję nad takim serwisem, którego jeszcze nie ma / eeee… (?)
    Koniec przykładu.
    Status w życiu wielu ludzi jest jednak ważny. A przykład pierwszy zawsze dużo lepiej „brzmi” i wygląda na wizytówce, niż przykład drugi, gdzie nawet nie ma wizytówki.

  • Brak rozwiniętego ekosystemu startup’ów
    Dobrze, że nie ma rozwiniętego ekosystemu startup’ów, bo jeszcze niedawno nie było żadnego. Już się coś dzieje w temacie spotkań branżowych (wreszcie!), zaczyna działać więcej VC i aniołów biznesu. Jednak jeśli np. chcę sobie załatwić jakiekolwiek kwestie prawne dotyczące mojej obecnej tudzież przyszłej firmy, to praktycznie nie ma takiej osoby, do której bym się zwrócił, bo ma już doświadczenie w działaniu ze startupami i zna specyfikę rynku. A takich firm / osób powinno być wiele. Podobnie z księgowością. W dziedzinach pozatechnicznych jest jeszcze wiele do zrobienia w tym temacie.

Podsumowanie i wnioski

Z jednej strony wiele warunków potrzebnych lub koniecznych do powstawania nowych przedsięwzięć jest już spełnionych. Z drugiej jednak jest wiele aspektów, które ciągle jeszcze działają na niekorzyść. Dobrze jednak, że są te przeciwstawne siły. Że pozytywne aspekty już istnieją. Z czasem i wraz z rozwojem tych pozytywów coraz większa będzie też aktywność, coraz większa społeczna akceptacja i coraz większa chęć do robienia takich rzeczy. Coraz częstsza obecność tematów startupowych w miediach, tworzący się powoli ekosystem, aktywność portali na rynku akwizycji – coraz więcej tych jaskółek na niebie technologicznym. Oby wskazały drogę innym z ciepłych krajów.

Disclaimer: na potrzeby artykułu niektóre warunki zostały uproszczone bądź przejaskrawione, niektóre szczegóły i aspekty pominięte. Temat jest zbyt skomplikowany i szeroki, by zamknąć go w kilku punktach, więc specjalnie zastosowałem wersję uproszczoną, ale odzwierciedlającą pewne trendy. Proszę wziąć to pod uwagę przy ewentualnym komentowaniu. Zapraszam tym samym do dyskusji – poznanie zdania i dyskuja uczestników samego „ekosystemu” są jak najbardziej wskazane.

Porównanie IDE / edytorów dla Ruby on Rails

Porównanie Rails IDEŻeby firma odniosła sukces, najpierw musi w ogóle powstać. Tu więc najważniejszym elementem jest faza początkowa, czyli startup.
Żeby startup mógł powstać, ktoś musi najpierw go zbudować. Mowa tu o startupie technologicznym / internetowym, więc kluczowym elementem jest w tym przypadku zespół developerski.
Żeby ten zespół mógł stworzyć swój wymuskany produkt końcowy, musi mieć w czym pracować. I tu elementem niezbędnym i koniecznym jest edytor lub środowisko programistyczne (IDE).
Jako że piszę tu o Ruby on Rails, to zanim przejdę do tematów bardziej technicznych, najpierw się skupię na elemencie niezbędnym (pomijając umiejętność myślenia, bo bez tej nawet najlepsze środowisko programistyczne nie spłodzi nawet jednej sensownej linijki kodu, może oprócz scaffold‘ów).

Zróżnicowanie systemów operacyjnych jest widoczne również w przypadku edytorów i IDE (w dalszej części będę tych pojęć używał zamiennie, żeby za każdym razem nie podkreślać, że coś jest edytorem, a coś innego jest środowiskiem programistycznym).
Użytkownicy Mac’ów mają „owiany legendą” TextMate.
Linux ma sporo opcji: jEdit, vim, Cream (bazujący na vim), 3rdRail (płatny, $299) i in.
Jako że jednak uznałem, że wydanie kilku tysięcy złotych na Mac’a tylko po to, żeby mieć dobry edytor dla projektów Railsowych, mija się z celem, pracuję więc pod Windowsami i dla tego właśnie systemu przygotowałem zestawienie porównujące dostępne opcje dla środowisk programistycznych dla Ruby on Rails.
Wraz z upływem czasu i rosnącym „zamieszaniem” wokół Rails (w pozytywnym tego słowa znaczeniu), rośnie również dostępna ilość edytorów. Stopniowo dołączają coraz bardziej znane marki i są tworzone coraz bardziej zaawansowane narzędzia. Jest więc w czym wybierać, w porównaniu choćby do okresu sprzed roku.

Ze wszystkich możliwych opcji dostępnych na dzień dzisiejszy pod Windows, zdecydowałem się wybrać cztery i przyjrzeć im się bliżej. Są to: Aptana / RadRails, Netbeans, e oraz Komodo Edit.
Oto jakie wersje miałem zainstalowane podczas testowania:

  • Aptana IDE build build 0.2.9.17048 (plugin RadRails 0.8.0.200707021211)
  • NetBeans Ruby IDE 20071020152017 (Ruby and Rails plugin v. 0.102.0)
  • e v. 1.0.3
  • Komodo Edit, version 4.2.0, build 281898

Po kolei, dlaczego akurat te:

  • Aptana, bo wcześniej używałem i polubiłem RadRails. Niestety nie mogę stwierdzić, że od kiedy RadRails został przejęty przez Aptanę, wyszło to na korzyść dla tego pierwszego. Możliwe jednak, że z czasem dojdą do ładu i produkt będzie tylko coraz lepszy.
  • Netbeans, bo jest to prawie kompletne, rozbudowane i profesjonalne środowisko programistyczne, które ostatnio zauważyło Ruby i dość dynamicznie szlifuje swoje funkcje w tym kierunku.
  • e (lub też „e texteditor”), bo jest to chyba najbardziej zbliżony „klon TextMate’a” pod Windows. Mimo iż jest płatne (po okresie testowym 30 dni licencja kosztuje $34,95)
  • Komodo, bo mimo iż może mniej znane, ale jest to szybkie i wygodne narzędzie dla projektów w Ruby.

Dość dużym zainteresowaniem cieszy się też jEdit, ale miałem z nim zbyt dużo problemów dostosowując go do przynajmniej znośnej pracy w Rails, żeby poważnie rozważać jego kandydaturę, przynajmniej na tym etapie rozwoju. Poza tym jego wygląd naprawdę nie powala, a skoro mam wiele godzin dziennie patrzeć na to, co mam przed sobą na ekranie, to siłą rzeczy wolę, żeby był to twór jeśli nie piękny, to przynajmniej miły. Podobnie z kobietami – jak nie jest piękna, to niech chociaż będzie miła. jEdit niestety w mój gust nie trafił w żadnej z tych kategorii, więc nie ma go w tym zestawieniu.

Wracając więc do pięknych, miłych i czasami nawet posiadających obie cechy naraz. Poniżej zestawienie funkcji i właściwości każdej z czterech opcji. Nie jest to w żadnym wypadku kompletna lista możliwości w żadnym z czterech przypadków – jest tego o wiele, wiele więcej. Jednak te są moim zdaniem ważne pod tym względem, że – bardziej lub mniej – przyczyniają się do pożądanego efektu końcowego, jakim jest przyjemna, szybka i efektywna praca w miłym środowisku (tym razem nie ludzkim, a komputerowym).

Na Google Docs zamieściłem wersję również z angielskimi nazwami właściwości, na wypadek gdyby moje wysiłki tłumaczeniowe okazały się nie do końca jasne dla wszystkich. Oto link: Porównanie IDE / edytorów dla Ruby on Rails: Rails IDE.

Porównanie IDE i edytorów dla Ruby on Rails

Po kolei więc podsumowanie, od „ostatniego miejsca” w tym zestawieniu.

  • Komodo Edit

Komodo Edit jest darmową wersją Komodo IDE ($295,00), jednak nawet wersja darmowa jest dostatecznie dobrym narzędziem, żeby móc polecić go ludziom zajmującym się Ruby on Rails. Może nie jest jeszcze najlepszym rozwiązaniem dla dużych i skomplikowanych projektów, ale dla mniejszych prac na pewno spełni pokładane w nim oczekiwania. Na jego korzyść na pewno przemawia szybkość działania. Stosunkowo prosty i niezaśmiecony interfejs również jest na plus. Możliwość definiowania własnych makr oraz spora ilość już dostępnych pozwala na dostosowanie go do swoich potrzeb. Ocena końcowa: 6. Dla mnie sporym minusem jest brak snippets (z braku polskiego odpowiednika, zostawiam angielską nazwę), który przy dłuższej pracy z Rails jednak daje się we znaki. Wygląd, mimo iż prosty i nienachalny, też mógłby być jednak trochę lepszy. Poniżej screeny wszystkich edytorów, więc można porównać.

  • Aptana / RadRails

Prosty w użyciu i w miarę szybki RadRails po przejęciu przez Aptanę trochę stracił na swojej prostocie, bo zostało dodane dużo moim zdaniem zbędnych rzeczy. Jednak jest to dosyć logiczne, zważając na fakt, że RadRails był przystosowany tylko do pracy z Rails, a Aptana to środowisko programistyczne dla dużo większej ilości języków i framework’ów. Mimo iż na tej zmianie RadRails sporo stracił, to jednak ciągle posiada większość swoich pozytywnych cech. Jeśli chodzi o wygląd, to brak motywów jest tu minusem (wolę pracować na ciemnym tle, więc wszędzie gdzie tylko można zmieniam wygląd – oczy się mniej męczą przy ciemnym tle, szczególnie w nocy). Możliwość dostosowania do swoich potrzeb jest dość spora, więc na upartego można zmusić, żeby Aptana pracowała tak, jak się chce. Ocena końcowa: 7.

  • e i Netbeans

Obecnie pracuję w Ruby on Rails pół na pół, jeśli chodzi o edytory: połowę czasu (mniejsze projekty, szybkie zmiany, początkowe fazy) w „e”, połowę w Netbeans. Dlatego dałem równe oceny dla obu tych opcji.
Za „e” przemawia jego prostota, szybkość działania, zintegrowanie z SVN (działające trochę bardziej intuicyjnie i prościej, niż w Netbeans), ciągły i szybki rozwój (co bardzo ważne), możliwość zaznaczania również kolumnowo (w pionie) i oczywiście snippets, które działają bardzo dobrze i są ciągle dodawane nowe.
Netbeans natomiast jest według mnie środowiskiem najbliższym tego, żeby można go było nazwać kompletnym. Dobrze rozwiązna nawigacja pomiędzy poszczególnymi plikami (jej brak jest bardzo uciążliwy przy otwartej dużej ilości plików), dokumentacja dostępna bez wychodzenia z edycji (dostępna razem z funkcją autouzupełniania), smart views (podział na kontrolery, widoki, pliki konfiguracyjne itp. według ich funkcji, a nie struktury folderu), nawigacja w dokumencie i powiązanych z nim plikami oraz setki innych funkcji, które są dostępne, jeśli tylko dusza zapragnie.
Na niekorzyść „e” może działać brak podświetlania błędów czy brak możliwości otworzenia kilku projektów jednocześnie, jednak jest to edytor, a nie IDE, więc nie jest to jego celem. W ciągu ostatnich kilku miesięcy od kiedy używam tego edytora, zmiany są wprowadzane szybko i jest ich sporo, więc komfort pracy z „e” rośnie.
Minusem Netbeans jest szybkość. Często się zdarza, że nie jest „błyskawiczny” i trzeba trochę poczekać. Skutki Javy. Jest jednak również bardzo intensywnie rozwijany pod kątem Rails, więc jeśli chodzi o przyjemność użytkowania, ilość funkcji, poprawność ich działania i szybkość dodawania nowych, naprawdę warto mu się przyjrzeć i poważnie rozważyć jako swoje główne narzędzie w podbijaniu świata (oprócz umiejętności myślenia oczywiście, co już jednak wspominałem).

Narzędzia programistyczne są w naprawdę wielu smakach. Każdy lubi inny smak lodów, więc nie widzę dlaczego miałoby być inaczej z IDE. W efekcie końcowym liczy się to, czy dobrze się nam pracuje w tym czy innym środowisku. Radzę więc samemu przynajmniej na krótko wypróbować każdą z opcji i zdecydować się na tą, która będzie „najsmaczniejsza”.
Poniżej – dla porównania – ilość RAM, jaką aktualnie zużywa wszystkie powyższe opcje na moim komputerze. Na ten wynik może wpływać wiele czynników, ale podaję poglądowo, przynajmniej dla zobaczenia jaki jest rząd wielkości. Każdy z edytorów ma otwartych około 10 dokumentów.
// Konfiguracja mojego komputera: 2 GB RAM, Intel Core2 1,83 GHz //

Aptana: 130 MB
Netbeans: 161 MB
e: 28 MB
Komodo: 88 MB

Poniżej screeny (dla tych, co nie chcą ściągać i instalować, a chcieliby obejrzeć). Wszystkie edytory miały ustawione domyślnie białe tło, ale jak już wspomniałem – wolę czarne i dbam o oczy, więc widać tego efekty.

Aptana IDE Aptana IDE

e texteditor e texteditor

Komodo Komodo Edit

Netbeans API Netbeans API

Jeśli macie jakieś inne godne uwagi edytory lub IDE dla Ruby on Rails albo nie zgadzacie się co do którychś moich stwierdzeń (co byłoby całkowicie logiczne, ja np. nie lubię lodów orzechowych albo truskawkowych), zapraszam do zostawienia swojej opinii w komentarzach.