Biznes i kod w jednym mieszkali domu

Jakiś czas temu pisałem o relacji tzw. „biz guy” versus „tech guy” w tekście Mam pomysł, potrzebuję tylko programisty. Ostatnio trafiłem na dość dobry tekst, który pokrótce podsumowuje to, co starałem się przekazać. Jako że nie ma sensu wszystkiego przepisywać, to podam tylko to, co uważam za esencję. Jest to też niejako skondensowana myśl przewodnia mojego wyżej wspomnianego tekstu. No i na dodatek świetne zobrazowanie graficzne tejże teorii. Jestem zagorzałym zwolennikiem przejrzystego przedstawiania treści w formie graficznej.

„(…) the product entrepreneurs have an increasingly marginal role as a startup evolves and becomes more successful. In fact, I’d argue that they are in a rude awakening – they either need to evolve into business entrepreneurs (as Gates and Jobs did, for example – both shrewd business guys) or hire people to play that role (a la Eric Schmidt at Google). Building an asset is the first (and most important) challenge. But finding the customer for that asset and maximizing the revenue/profit is also a challenge (and one that many builders are ill-suited to handle).” 

Dobre podsumowanie tego, co również uważam za prawdziwe. W artykule jest trochę więcej na ten temat i rozwinięcie powyższego akapitu. Polecam zapoznanie się z całością.

Na początku trzeba zbudować produkt i tylko to się liczy. „Tech guy” i jego wartość są zbliżone do maksimum. Kiedy jednak produkt jest już gotowy i działa, to na początku oczywiście trzeba robić jakieś poprawki i wprowadzać funkcje, które są naprawdę potrzebne i przydatne dla użytkowników. Poprawki jednak z biegiem czasu powinny (przynajmniej w teorii) się zmniejszać, a funkcji też nie ma sensu dodawać w nieskończoność. Przykład: czy ktoś, tak jak ja, tęskni za WinAmpem sprzed ładnych kilku lat, kiedy to był on małym i prostym programikiem idealnie spełniającym jedną funkcję: odtwarzanie muzyki? Teraz to ledwo dający się używać kombajn do wszystkiego i jeszcze trochę. Sens? Brak…

Na początku, kiedy produkt nie jest dostępny publicznie i dopiero jest budowany, wartość „biznesowego partnera” ogranicza się do generowania pomysłów na funkcje, a nie do generowania kodu, czyli samego mięsa produktu. Oczywiście w bardzo dużym uproszczeniu. Z biegiem czasu jednak, kiedy programista już tylko wprowadza poprawki i dodaje nowe funkcje, to wtedy zaczyna się prawdziwa praca partnera od biznesu. I to w przeważającej części od niego będzie zależało czy produkt (który równie dobrze może być rewolucyjny) odniesie jakikolwiek sukces. Czy dotrze tam, gdzie jest potrzebny. Czy przekona tych, których trzeba przekonać, żeby dali szansę temu produktowi.

Idealnie oczywiście kiedy jedna osoba (lub kilka) skupia w sobie cechy jak z jednego partnera, tak i z drugiego. Jednak daleko nie zawsze tak się dzieje.

Tak na marginesie, to jest artykuł napisany przez autora RescueTime, czyli najważniejszego konkurenta dla polskiego TimeCamp. I moim zdaniem chłopaki z RescueTime niestety wygrywają bezapelacyjnie. 
Kilka miesięcy temu (zdaje się na jakimś *campie) we Wrocławiu dyskutowałem o tym publicznie z autorem serwisu, ale od tamtego czasu nie widzę żadnych zmian. Chyba że pracuje nad backendem (oby tak było) i dlatego efektów nie widać gołym okiem. Z niedawnej dyskusji z autorem serwisu wynika, że skupiają się bardziej na niszy monitorowania pracowników, niż na modnym ostatnio i dość nasyconym już rynku personal productivity (nie znajduję naturalnie brzmiącego polskiego odpowiednika). Ukierunkowanie się na monitoring i odejście od programu stricte dla użytkownika publicznego jest moim zdaniem dobrym posunięciem. Chłopaki jednak nie mają polskiej wersji – od początku stawiają tylko na angielską. Polskiej nie ma nawet w najbliższych planach. Co najwyżej dalszych. Czy to słuszne posunięcie? Niekoniecznie.

Nie mając sensownego zaplecza sprzedażowego, dość trudno jest od razu uderzać z ofertą międzynarodową. Na dodatek skierowaną do firm, do których się jednak dociera inaczej, niż do użytkowników prywatnych.

Na miejscu ekipy z TimeCamp spróbowałbym więc najpierw spenetrować rynek polski, tu się trochę doszlifować i ewentualnie później wypływać na szersze wody. Po pierwsze – łatwiej dotrzeć do grupy docelowej, po drugie – mniejsze będą koszty alternatywne ewentualnych pomyłek. No i zdobyte doświadczenie na pewno nie zaszkodzi.

Podsumowując: zarówno TimeCamp’owi, jak i innym polskim firmom – jak najlepszej mieszanki kodu i biznesu życzę.

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.

Democamp 2008 Poznań – wrażenia i refleksje

Na Democamp wybrałem się z Wrocławia zachęcony przede wszystkim mocną obsadą panelu komentatorów. Miało to mi zagwarantować „zwrot z inwestycji”, czyli nawet jeśli będą słabsze startupy i ich prezentacje, to przynajmniej ciekawie będzie posłuchać komentatorów. Wcześniej bywałem tylko na wrocławskich spotkaniach, przeważnie spod egidy Grill IT. Wyprawa do Poznania była więc pierwszym moim przedsięwzięciem międzymiastowym.

Sama organizacja była dość dobra. Ciężko jest ogarnąć ponad stuosobową grupę osób (nie wiem ile było dokładnie uczestników, więc tylko szacuję), ale chłopakom z Netguru i Ubik BC to się udało. Odbyło się to niestety czasami kosztem jakości, a mianowicie:

* dobrze, że starano się trzymać ram czasowych, czyli każda prezentacja trwała dokładnie 5 minut.
* gorzej, że prezentujący nie widział nigdzie ile czasu mu zostało i czasami efektem było wyrywanie mikrofonu na 2 zdania przed zakończeniem prezentacji, niejako zawieszając ją w powietrzu.
* a można… byłoby uniknąć tego dając chociażby jakiś timer albo na ekranie albo gdzieś przed oczami prezentującego, żeby wiedział czy minęło dopiero 1,5 minuty i jeszcze może wdawać się w jakieś szczegóły, czy też już ma za sobą ponad 4 minuty i to ostatnia chwila, żeby podać jakieś wnioski i najważniejsze rzeczy o swoim startupie (te najważniejsze powinny być na początku oczywiście, ale nie każdy wybierał najbardziej optymalny sposób prezentowania).

* dobrze, że zgromadziło się różnorodny i adekwatny panel komentatorów, którzy bardzo dobrze wywiązali się ze swego zadania, dając wartościowe komentarze i sugestie.
* gorzej, że nie dano możliwości odniesienia się do komentarzy samym prezentującym, nawet choćby jednym zdaniem.
* a można… dać możliwość polemiki jeśli już nie widowni z prezentującymi, to przynajmniej komentatorów. Zajęłoby to raptem 1-2 minuty więcej na każdym startupie, a dodałoby o wiele więcej kolorytu i na pewno przyniosłoby o wiele więcej korzyści przedstawicielom startupów. Brak tej możliwości zminimalizował ich udział do roli biernego odbiorcy treści – niewiele więcej, niż otrzymanie maila, na dodatek bez możliwości odpowiedzenia na niego.

* dobrze, że zebrano sporą widownię (choć spodziewałem się, że może być więcej osób).
* gorzej, że sprowadzono widownię do stricte biernej roli, nie dając możliwości zadania choćby jednego pytania.
* a można… dać głos ludowi. Tutaj może to być trochę trudniejsze z ogarnięciem logistyczno-czasowym, ale parę pytań do każdej prezentacji tragedii by nie zrobiło. Tutaj można byłoby śmielej stosować przerywanie w pół zdania, jeśli to konieczne.

Odnosząc się do samej zawartości merytorycznej, to po pierwszej połowie czułem spory niedosyt, jednak startupy prezentujące w drugiej połowie to nadrobiły. Bardzo nierówny był sam sposób prezentowania (poczynając od show, poprzez czytanie z kartki, zdarzały się też bardzo dobre prezentacje, a kończąc na całkowitym nieporadzeniu sobie z tematem). Jak jednak słusznie zauważył Michał Brański (jeden z komentatorów), większość startupów to były przedsięwzięcia, gdzie większość pracy została włożona w backend, a nie we frontend, co daje im sporą przewagę konkurencyjną w stosunku do firm, które chciałyby skopiować ich działalność. Dobrze to wróży na przyszłość, bo wcześniej bywało przeważnie odwrotnie – zdecydowana większość pracy była wkładana we frontend, a backend był prostą aplikacją, bez głębszej logiki i skomplikowanych algorytmów.

Dobrym pomysłem były też stoiska startupów. Każdy miał do zagospodarowania stół i było wiele przykładów na wykorzystanie tej sposobności i pokazanie swego startupu dużo bardziej szczegółowo i dogłębnie, niż to miało miejsce podczas prezentacji. Dodatkowo ci, którzy „zainwestowali” w jakiekolwiek materiały promocyjne, mieli większą szansę na bycie zapamiętanym. Obok naoczny tego przykład: zdjęcie materiału promocyjnego jednego ze startupów połączonego z zabijaniem nudy na jednej z tych nudniejszych prezentacji.

Kilka startupów, które z różnych względów zapadły mi w pamięć:

Redlink
Imponujące możliwości produktu i dopracowany zarówno layout, jak również model biznesowy, zaplecze i cała reszta. Bez wątpienia jeden z najbardziej godnych uwagi produktów. Jednakże… ciężko to nazwać startupem. Cytując chociażby ze strony firmy, zakładka „O firmie„:

Platforma Redlink.pl została w całości stworzona przez firmę Vercom. Bazując na własnych doświadczeniach związanych z telefonią VOIP, Web Services oraz aplikacjami webowymi zintegrowaliśmy różne kanały komunikacji elektronicznej tworząc w ten sposób nowatorskie narzędzie marketingu bezpośredniego.
Firma Vercom Sp. z o.o. powstała w roku 2005 w Poznaniu i od początku działalności skoncentrowała się na tworzeniu innowacyjnych rozwiązań IT dla biznesu.

Konkurowanie głęboko osadzonej w biznesie i działającej od kilku lat firmy ze startupami, które działają od kilku miesięcy czy nawet tygodni jest moim zdaniem trochę mijające się z celem. Stąd też mimo najlepszego produktu nie oddałem swojego głosu na Redlink.

Flux
Najbardziej dopracowany wizualnie produkt. Konkurencja na rynku światowym jest jednak bardzo duża w tej dziedzinie, a naprawdę innowacyjnych rzeczy niezbyt wiele.
Moim zdaniem jednym z rozwiązań mogłoby być postawienie na sprzedaż produktu dla firm (na początek polskich) i na podkreślaniu funkcji sprzyjających współpracy, współdzieleniu zadań i lepszej kontroli nad całym przepływem informacji. Po pierwsze – do firm jest łatwiej to sprzedać, a po drugie – w tej właśnie działce (przepływ informacji w firmie) są najbardziej innowacyjne funkcje produktu (przynajmniej takie mam wrażenie po obejrzeniu prezentacji i przedstawieniu funkcji).
Sposób i przebieg prezentacji o wiele lepszy, niż poprzednio (zdaje się na którymś z Barcampów), więc chłopaki idą w tej dziedzinie do przodu.
Strona główna wygląda jednak jakby ktoś ją stworzył we Front Page’u 1997. W 3 minuty. Z przerwą na herbatę. Wiadomo, że nie na stronie głównej powinno się skupiać swoje wysiłki, ale jak na razie jest to jedyna dostępna strona dla potencjalnych przyszłych użytkowników i dla tak dopracowanego produktu taka wizytówka jest prawie jak obelga. Wierzę, że bardzo szybko to się zmieni.

e-podroznik.pl
Bardzo przydatny produkt, widać sporą pracę w backendzie, jest zapał twórców, jest duża przewaga nad możliwymi przyszłymi konkurentami (umowa z firmą dostarczającą rozkłady), więc składając to wszystko do kupy powinna wyjść bardzo przyjemna mieszanka. Z prezentacji nt. planów na przyszłość wynika, że wszystko jest na dobrej drodze, pozostaje więc tylko życzyć powodzenia. I poprawienia wyglądu serwisu.
No i jak to zauważyli zgodnie komentatorzy – przejęciami konkurencji lepiej chwalić się po fakcie, a nie przed nim. Po co dawać stronie przejmowanej dodatkowe argumenty podczas negocjacji? Szczególnie że nawet chyba została podana suma, jaką mają zamiar przeznaczyć na przejęcia.

Opiekun Inwestora
Serwis, który całkowicie zmarnował szansę zaprezentowania się w dobrym świetle. Z prezentacji nie wynikło praktycznie nic, w przeważającej części z powodu tego, że kiedy miało dojść do wyłuszczania najważniejszych rzeczy, czas się skończył i mikrofon został zabrany.
Rozmawiałem później z przedstawicielem serwisu przy stoisku i się okazuje, że stoi za tym przemyślany produkt, w który włożono sporo pracy i który jest na dodatek efektywny w tym, co robi. A robi to, co jest na dzień dzisiejszy (w czasach bessy) niemodne: podpowiada w jakie fundusze inwestycyjne inwestować. Temat dość szeroki, więc nie będę go rozwijał.
Może brakuje im kogoś, kto potrafiłby dobrze sprzedać pomysł? Może zrobiliby to, gdyby mieli więcej czasu? Może publiczność nie była „targetem” takiego serwisu? Każda z opcji jest możliwa. Uważam jednak, że jest to jeden z najbardziej niedocenionych startupów, które się zaprezentowały.

Szuku
Usługa, która ciągle czeka (na poziomie światowym również) na dobrą implementację. Jeśli ta okaże się dobra, a przynajmniej dostatecznie dobra, to powinna bez problemu odnieść sukces. To, co widziałem, wyglądało obiecująco. Wytrwałości i powodzenia więc w finalizacji tego, co zaczęliście. Tylko ta domena jakaś nie najbardziej fortunna…

EcooSystem
To z kolei moim zdaniem najbardziej przeszacowany pomysł wśród wszystkich zaprezentowanych. Wygrał na podstawie samej prezentacji (choć trzeba przyznać, że dość dobrze zrobionej) i luźnych pomysłów o współpracy. Szeroki zakres pomysłów może budzić pewne obawy czy to będzieć działać zgodnie z zamysłem twórców. Do dzisiaj nie było możliwości, żeby się o tym przekonać, bo strona główna była tylko screenshotem, ale teraz serwis otworzył już swoje podwoje i można zacząć weryfikować czy to, co chcieli stworzyć pomysłodawcy, udało im się osiągnąć. Idea szczytna, ale trudna, więc oby jak najwięcej ze swojej wizji udało im się spełnić.

Wniosek z Democamp jest taki, że coraz lepiej się dzieje wśród startupów i choć nie widać żadnych rewolucji na skalę chociażby europejską, to jednak coraz więcej pracy jest wkładane w startupy, co tworzy większą barierę wejścia dla potencjalnej konkurencji. Mniej już jest serwisów bazujących na czystej kopii pomysłu, którą ktokolwiek inny z kolei może skopiować w ciągu kilku tygodni. Oby ten trend został podtrzymany.

Inne relacje z Democamp:
http://netto.blox.pl/2008/11/democamp-state-of-mind.html
http://netto.blox.pl/2008/11/democamp-hall-of-fame.htm
http://antyweb.pl/democamp-o-startupach-i-generlanie-jak-bylo
http://www.internetstandard.pl/news/175789/Redlink.i.Ecoosystem.docenione.na.Democamp.html
http://blog.ecoosystem.com/democamp-wrazenia/

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.

Mam pomysł, potrzebuję tylko programisty

Czy tego szukam? Czytałem ostatnio sporo branżowych blogów, przeglądałem odpowiednie fora, trafiłem na kilka artykułów w Newsweeku / Time / Polityce / Fortune, przejrzałem polskie poletko Web 2.0 i wpadłem na świetny pomysł!
Teraz potrzebuję tylko programisty, który mi to szybciutko skleci i będę kolejnym złotym dzieckiem polskiego Internetu. Na szczęście w Polsce takowych jest jeszcze bardzo mało, więc tym bardziej mam spore szanse.

Taki mniej więcej tok zdarzeń i rozumowania jest aż nazbyt częsty. Zarówno w Polsce, jak i w innych krajach, ale na innych się skupiać nie będę, więc będę pisał o rodzimym rynku.

Jest niestety bardzo dużo przypadków jak powyżej i odpowiednich ogłoszeń "szukam programisty". Przy czym dalszy tok rozumowania wygląda następująco:
- Zrób mi proszę prosty serwis (a i tak dobrze, jeśli pada słowo "proszę")
- taki coś w stylu Allegro / Nasza-Klasa / Web 2.0 / Flickr (w zależności na jaki genialny pomysł się wpadło)
- to przecież powinno być proste
- trochę PHP, trochę MySQL, oczywiście AJAX i powinno być gotowe (ilość i stopień wyszukania akronimów odpowiedni do stopnia oczytania branżowych blogów i znajomości aktualnych topowych buzzwordów)
- jako że to jest proste, to jestem nawet skłonny zapłacić 1000-2000 PLN (co też jest wspaniałomyślne, bo równie często prosi się znajomego programistę o sklecenie podobnego serwisu po znajomości)
- dodaj jeszcze do tego serwisu funkcje X, Y i Z i po sprawie (przy czym te właśnie funkcje, nawet jeśli są całkowicie pozbawione sensu z punktu widzenia przeznaczenia serwisu, powinny z niego zrobić co najmniej drugiego eBay’a, jak nie lepiej)

Kwestie, o których się nawet nie myślało
- godne wynagrodzenie za wykonanie pomysłu (to 1-2K nie jest godne?!)
- podział zysków z programistą / developerem
- udziały w przedsięwzięciu dla programisty / developera
- no i oczywiście najważniejsze – zasadność tworzenia takiego serwisu

Kwestie, o których w wielu wypadkach się nawet nie słyszało
- User Interface
- Pageflow
- Struktura bazy danych
- Bezpieczeństwo (serwisu, serwera, danych użytkowników)
- Skalowalność

Powyższe kwestie nie zostały wyssane z palca – widziałem zbyt wiele ogłoszeń typu "1-2K PLN za serwis o funkcjonalności Allegro", przy czym zawarte jest w tym wszystko od zarejestrowania domenu do uruchomienia serwisu. Zbyt wiele, żeby uznać to za jednostkowe przypadki.

Jeśli już nawet zasadne byłyby przypadki, kiedy tzw. "biz guy" szuka "tech guy" do zrobienia roboty, to rozumowanie powinno się zaczynać od końca:
- Jaka jest zasadność tworzenia takiego serwisu? (pytanie to powinno być zadane wielokrotnie i pod wieloma kątami, dopiero później można przechodzić do pytań kolejnych)
- jak będzie wyglądał / kto stworzy UI
- jaka będzie struktura serwisu (pageflow)
- jaki będzie podział ról między biz / tech guy
- jaki będzie podział zysków / udziałów między nimi
- jak znaleźć dobrego programistę / developera, który na dodatek będzie chciał pracować z kimś, kto ze strony technicznej nic nie wniesie do przedsięwzięcia (równie dobrze może to być na pierwszym miejscu, jeśli chodzi o wpływ, jaki ma to na powodzenie projektu)
- dopiero później cała reszta

Ciekawe dlaczego nie ma pytań ze strony programistów potrzebuję tylko człowieka do generowania pomysłów, a z resztą sobie poradzę, prawda?

Zawsze źle oceniamy to, czego nie rozumiemy. A to, co rozumiemy, możemy zrobić sami.
Dlatego też powinno być tak, że to developerzy powinni poszukiwać ludzi, którzy się zajmą "stroną biznesową" serwisu, który już stworzyli, a nie odwrotnie. Dlaczego tak nie jest? W dużej mierze przedstawiłem to tutaj: Dlaczego powstaje mało serwisów mimo ciągle zmniejszającej się bariery wejścia?

Moim zdaniem jeśli już, to właśnie w odwrotną stronę powinno to działać, czyli do gotowego serwisu powinna być poszukiwana osoba, która się zajmie żmudną pracą wprowadzania go na szerokie wody. zakładając oczywiście, że osoba, która go stworzyła, chce się zajmować tylko techniczną stroną i dlatego takiej osoby poszukuje. Tudzież z braku czasu na obie role naraz. Jednak takiego ogłoszenia, nawet jednego, jeszcze w Polsce nie widziałem…

Idealnym rozwiązaniem jednak jest współpraca dwóch takich osób od samego początku. Nie szukanie kogoś tylko do zrobienia czegoś, a wspólne i ukierunkowane działania od etapu generowania pomysłu, poprzez projektowanie interfejsu, poszukiwania potencjalnych źródeł przychodów, do wyprowadzania projektu na szerokie wody. Jako że jest to jednak sytuacja idealna i wymagająca całkowitego poświęcenia dwóch osób, co w Polsce jeszcze jest rzadko spotykane, poświęciłem temu zagadnieniu powyższy post.

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.