<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.zabiello.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.zabiello.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>Jarosław Zabiełło - BLOG</title>
    <link>http://blog.zabiello.com</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>moje notatki, linki, komentarze</description>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.zabiello.com/hipertracker" type="application/rss+xml" /><item>
      <title>Agile 3 - jednak wyjdzie</title>
      <description>&lt;p&gt;Mimo, że wcześniej &lt;span class="caps"&gt;DHH&lt;/span&gt; niezbyt entuzjastycznie wypowiadał się na temat pisania kolejnej edycji bestseleru &lt;a href="http://helion.pl/ksiazki/agilep.htm"&gt;Agile Web Development in Rails&lt;/a&gt;, to jednak ugiął się pod ciężarem oczekiwań i trzecie wydanie będzie! Ci, co nie chcą czekać, mogą już teraz kupić &lt;a href="http://pragprog.com/titles/rails3/agile-web-development-with-rails-third-edition"&gt;&lt;span class="caps"&gt;PDF&lt;/span&gt; z wersją beta książki&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Jeśli autorzy będą jak zwykle opisywać wersję edge, to książka powinna opisywać &lt;a href="http://weblog.rubyonrails.org/2008/4/30/rails-2-1-release-candidate-is-imminent"&gt;mający wkrótce wyjść Rails 2.1&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Dobrą wieścią jest też to, że Ezra Zygmuntowicz, twórca konkurencyjnego &lt;a href="http://merbivore.com/"&gt;Merba&lt;/a&gt;) postanowił ostatnio poświęcić trochę czasu aby &lt;a href="http://brainspl.at/articles/2008/04/25/hey-rails-nice-rack"&gt;ulepszyć kod Railsów&lt;/a&gt;. Najwyraźniej oba developerzy obu frameworków się nie zwalczają ale chcą ze sobą współpracować. Ezra &lt;a href="http://brainspl.at/articles/2008/04/18/deferred-requests-with-merb-ebb-and-thin"&gt;dodał ostatnio&lt;/a&gt; ciekawy mechanizm do obsługi asynchronicznych adapterów Thin i Ebb, pozwalający na tworzenie oddzielnego wątku w wypadku gdy zapytanie jest długie (aby nie blokowała się asynchroniczna pętla).&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=8AZPZH"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=8AZPZH" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=C4Ejzh"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=C4Ejzh" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=qcm0iH"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=qcm0iH" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Thu, 01 May 2008 20:15:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:2fd10714-776e-4b9a-aa15-6483d939307f</guid>
      <author>Jarosław Zabiełło</author>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/281608285/agile3</link>
      <category>rails</category>
      <category>merb</category>
    <feedburner:origLink>http://blog.zabiello.com/articles/2008/05/01/agile3</feedburner:origLink></item>
    <item>
      <title>Passenger mod_rails</title>
      <description>&lt;p&gt;Choć sam &lt;a href="http://rubyonrails.pl"&gt;Rails&lt;/a&gt; jest intuicyjny i prosty w użyciu, to już sposób użycia go na serwerze produkcyjnym (gdzie liczy się głównie szybkość i stabilność) nie jest takie oczywiste z powodu istnienia wielu, alternatywnych rozwiązań. Powstały niedawno moduł dla Apache &amp;#8211; &lt;a href="http://www.modrails.com"&gt;mod_rails&lt;/a&gt; &amp;#8211; może wszystko zmienić. Dzięki niemu uruchomienie Rails na serwerze staje się praktycznie tak samo trywialne jak w przypadku &lt;span class="caps"&gt;PHP&lt;/span&gt; i modułu mod_php!&lt;/p&gt;


	&lt;p&gt;Muszę przyznać, że początkowo byłem dosyć sceptycznie nastawiony do pomysłu mod_rails. Przede wszystkim, dziwnym wydawało się tworzyć moduł do Apache&amp;#8217;a dla frameworka, czyli w sumie aplikacji, a nie dla samego języka Ruby. Niestety, istniejący od jakiegoś czasu mod_ruby był niedopracowany i krytykowany do tego stopnia że użycie go do Rails jest po prostu niezalecane. Dlatego od samego początku, gdy pojawił się Rails, promowano inne rozwiązanie (oparte na FastCGI). Pierwsze wydanie &amp;#8220;Agile Web Development with Rails&amp;#8221; jeszcze to promowało. W drugim wydaniu (wydanym również &lt;a href="http://helion.pl/ksiazki/agilep.htm"&gt;po polsku&lt;/a&gt;) autorzy przyznali że to rozwiązanie nie było wolne od szerego problemów. Na szczęście pojawił się Mongrel i bardzo szybko kombinacja szybkiego serwera &lt;span class="caps"&gt;HTTP&lt;/span&gt; z przodu + load balancing do klastera z mongreli stała się główną metodą używania Rails na serwerze produkcyjnym. I choć później pojawiły się jeszcze rozwiązania asynchroniczne (Swiftiply i evented_mongrel, Thin, Ebb), to  zasadniczo niewiele wnosiły do rozwiązania standardowego poza trochę większą szybkością i innym (właśnie asynchronicznym) typem pracy.&lt;/p&gt;


	&lt;p&gt;Do tej pory sympatycy Ruby on Rails trochę smętnie poglądali na prostotę uruchamiania aplikacji &amp;#8220;tego paskudnego pehapa&amp;#8221; za pomocą modułu mod_php. To dzięki niemu &lt;span class="caps"&gt;PHP&lt;/span&gt; zdobył swoją popularność. Stworzenie prostej strony webowej stało się banalnie proste i nie wymagało dodatkowej wiedzy o load balancingu, ustawianiu buforowania, sposobie restartu klastera mongreli itp. Po prostu wrzucam plik i działa. Nawet sam &lt;span class="caps"&gt;DHH&lt;/span&gt; &lt;a href="http://www.loudthinking.com/posts/23-the-immediacy-of-php"&gt;zaczął ostatnio wzdychać&lt;/a&gt; za taką prostotą uruchamiania aplikacji.&lt;/p&gt;


	&lt;p&gt;Stworzony mod_rails ma ambicję aby uruchomienie Railsów było tak proste jak to tylko możliwe. Z tego co mogłem sprawdzić, faktycznie działa to świetnie. Praktycznie nie jest wymagana żadna konfiguracja. Wystarczy raz ustawić Apache&amp;#8217;a i można skupić się na budowaniu aplikacji. Domyślnie mod_rails uruchamia Rails w trybie produkcyjnym więc zmiana kodu wymaga przeładowanie aplikacji. Jednakże cała taka operacja sprowadza się do stworzenia pustego pliku &lt;code&gt;restart.txt&lt;/code&gt; w podkatalogu tmp. Gdy Apache znajdzie taki plik, błyskawicznie przeładowuje pliki Rubiego i usuwa plik. Nie trzeba też zastanawiać się jak wyklucząć przetwarzanie plików statycznych i tworzonych przez mechanizm cache w RoR, mod_rails robi to automatycznie. Do tego zapewniona jest także ładna obsługa błędów. Po prostu wygląda to rewelacyjnie.&lt;/p&gt;


	&lt;p&gt;Jak z wydajnością? Jest całkiem nieźle. Autorzy twierdzą, że mod_rails jest trochę szybszy od thin&amp;#8217;a. Mnie wyszło trochę odwrotnie, ale też nie robiłem zbyt drobiazgowych porównań. Nawet jeśli klaster serwerów thin czy ebb pracuje trochę wydajniej, to pokusa prostoty i wygody użycia mod_rails jest trudna do odparcia. Szkoda tylko, że mod_rails, jak sama nazwa wskazuje, pracuje tylko z Ruby on Rails. Dobrze by było, żeby później powstała podobna obsługa dla &lt;a href="http://merbivore.com/"&gt;Merb&amp;#8217;a&lt;/a&gt; (Choć Rails się także rozwija, Merb wciąż go mocno wyprzedza wydajnościowo. Tak z prostych testów mi wyszło, że potrafi być szybszy nawet 2-3 razy). Nie można jednak autorom mod_rails mieć przecież za złe, że poświęcili się najpopularniejszemu frameworkowi.&lt;/p&gt;


	&lt;p&gt;Passenger mod_rails to nie ostatnie słowo w sprawie deployingu Railsów. Podobną prostotą charakteryzuje się JRuby on Rails, ale o tym następnym razem.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=q33H4UG"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=q33H4UG" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=bPNS0Xg"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=bPNS0Xg" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=ngcOrlG"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=ngcOrlG" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Sat, 19 Apr 2008 05:31:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:9896a167-4e71-4fe5-863a-aa17527bc110</guid>
      <author>Jarosław Zabiełło</author>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/273334896/passenger-mod_rails</link>
      <category>mod_rails</category>
      <category>ruby</category>
      <category>rails</category>
      <category>apache</category>
    <feedburner:origLink>http://blog.zabiello.com/articles/2008/04/19/passenger-mod_rails</feedburner:origLink></item>
    <item>
      <title> Google App Engine</title>
      <description>&lt;p&gt;Od niedawna Google oferuje dosyć atrakcyjną możliwość pisania aplikacji webowych wykorzystujących potęgę ich infrastruktury &amp;#8211; &lt;a href="http://code.google.com/appengine/"&gt;Google App Engine&lt;/a&gt;. Usługa jest darmowa i jeszcze testowa. Można stworzyć do 3 aplikacji z których każda może używać do 500MB danych trzymanych w BigTable i Google obiecuje że bez problemu będzie można uzyskać do 5 mln odsłon miesięcznie i niezły traffic 10 TB/m-c.&lt;/p&gt;


	&lt;p&gt;W tej chwili jedynym językiem dostępnym jest Python ale mają przybyć kolejne. Wykorzystywany jest &lt;span class="caps"&gt;WSGI&lt;/span&gt;. Dostępny jest też &lt;a href="http://code.google.com/appengine/articles/django.html"&gt;okrojony framework Django&lt;/a&gt; (nie można używać djangowego &lt;span class="caps"&gt;ORM&lt;/span&gt;&amp;#8217;a ani wszystkich możliwości jakie dają djangowe szablony).&lt;/p&gt;


	&lt;p&gt;To co się bardzo zmienia, to podejście do bazy danych. Baza kolumnowa &lt;a href="http://en.wikipedia.org/wiki/Bigtable"&gt;BigTable&lt;/a&gt; &lt;strong&gt;nie jest bazą relacyjną&lt;/strong&gt; (nie istnieje tam pojęcie joinów). Trzeba więc trochę inaczej przemyśleć sposób tworzenia swoich danych. Pewnym problemem może być nie tylko uzależnienie od infrastruktury Google ale też trudność z późniejszym przeniesienia tak składowanych danych na inną platformę (choć istnieje z drugiej strony open-source&amp;#8217;owy odpowiednik BigTable &amp;#8211; &lt;a href="http://hadoop.apache.org/hbase/"&gt;HBase&lt;/a&gt;). W zamian jednak użycie platformy Google daje bardzo wysoką wydajność i odporność na błędy (jak padnie jeden serwer to jego pracę przejmuje automatycznie inny). Trochę nie jest dla mnie jeszcze jasne jak składować i usuwać dane z plikami statycznymi (obrazki, style kaskadowe, flash itp) skoro Google nie daje dostępu do systemu plików. Zablokowane są też sockety, wątki, używanie modułów napisanych w C, możliwość odpalania podprocesów, możliwości używania innych baz niż BigTable.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=RJJjRMG"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=RJJjRMG" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=Ad6Lblg"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=Ad6Lblg" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=YLyvOGG"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=YLyvOGG" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Sun, 13 Apr 2008 21:12:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:b7f3ea40-77de-4b1d-b122-3799c876ab80</guid>
      <author>Jarosław Zabiełło</author>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/269594988/google-app-engine</link>
      <category>google</category>
      <category>python</category>
      <category>django</category>
    <feedburner:origLink>http://blog.zabiello.com/articles/2008/04/13/google-app-engine</feedburner:origLink></item>
    <item>
      <title>GitHub oficjalnie</title>
      <description>&lt;p&gt;Po okresie pilotażowym, &lt;a href="http://github.com"&gt;GitHub&lt;/a&gt; wystartował &lt;a href="http://github.com/blog/40-we-launched"&gt;oficjalnie&lt;/a&gt;. GitHub udostępnia wygodne zarządzanie projektami korzystającymi z &lt;a href="http://git.or.cz/"&gt;Git&amp;#8217;a&lt;/a&gt; &amp;#8211; rozproszonego systemu wersjonowania kodu. Poza opcjami komercyjnymi jest dostępne &lt;em&gt;darmowe&lt;/em&gt; konto dla projektów open source (tzn. nie można w nim trzymać prywatnych, zamkniętych repozytoriów, ale poza tym jest w wystarczająco funkcjonalne). Na Git&amp;#8217;a migruje coraz więcej projektów. Poza &lt;a href="http://www.merbivore.com/"&gt;Merbem&lt;/a&gt; i (&lt;a href="http://weblog.rubyonrails.org/2008/4/2/rails-is-moving-from-svn-to-git"&gt;wkrótce&lt;/a&gt;) &lt;a href="http://rubyonrails.org"&gt;Railsami&lt;/a&gt;, na GitHuba przeniosły się już: &lt;a href="https://github.com/nex3/haml/tree"&gt;Haml&lt;/a&gt;, &lt;a href="https://github.com/ry/ebb/tree"&gt;Ebb&lt;/a&gt;, &lt;a href="https://github.com/wycats/jspec/tree"&gt;JSpec&lt;/a&gt;, &lt;a href="http://github.com/jamis/capistrano/tree/master"&gt;Capistrano&lt;/a&gt;, &lt;a href="https://github.com/sam/dm-core/tree"&gt;DataMapper&lt;/a&gt; itd.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=i8gFxGG"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=i8gFxGG" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=9yQdPLg"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=9yQdPLg" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=duUrRPG"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=duUrRPG" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Fri, 11 Apr 2008 01:38:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:2e77f8d5-21d8-49cb-86cc-c064818b75e6</guid>
      <author>Jarosław Zabiełło</author>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/268022613/github-oficjalnie</link>
      <category>git</category>
      <category>rails</category>
      <category>merb</category>
    <feedburner:origLink>http://blog.zabiello.com/articles/2008/04/11/github-oficjalnie</feedburner:origLink></item>
    <item>
      <title>Nadchodzi Rails 2.1</title>
      <description>&lt;p&gt;Jest bardzo bardzo niewiele książek opisujących aktualny stan Railsów 2.0.2 a już &lt;a href="http://weblog.rubyonrails.org/2008/4/1/a-taste-of-what-s-coming-in-rails-2-1"&gt;szykuje się kolejna wersja &amp;#8211; 2.1&lt;/a&gt; (nawet &lt;a href="http://www.rubyonrails.pl/ksiazki"&gt;The Rails Way&lt;/a&gt; nie opisuje 2.0.2, ale tylko trochę z wersji edge, sprzed wydania 2.0) Jaką książkę nie zaczęto by pisać, staje się szybko nieaktualna.  Co za czasy&amp;#8230;&lt;/p&gt;


	&lt;p&gt;Zmian jest całkiem sporo, do ważniejszych należą różne poprawki w Active Record. Np. w końcu ma być możliwa  &lt;a href="http://ryandaigle.com/articles/2008/3/31/what-s-new-in-edge-rails-dirty-objects"&gt;selektywna aktualizacja wybranych kolumn&lt;/a&gt; (do tej pory AR, podczas zmiany jedneego atrybutu aktualizował je wszyskie w bazie) Co prawda tą funkcjonalność od dawna mają &lt;a href="http://datamapper.org/docs/create_and_destroy.html"&gt;DataMapper&lt;/a&gt; i Sequel, ale dobrze że AR się wkońcu tu obudził.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;article&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Article&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;find&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:first&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
&lt;span class="ident"&gt;article&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;changed?&lt;/span&gt;  &lt;span class="comment"&gt;#=&amp;gt; false&lt;/span&gt;

&lt;span class="comment"&gt;# Zmiany poszczególnych atrybutów możliwe jest za &lt;/span&gt;
&lt;span class="comment"&gt;# pomocą akcesora attr_name_changed?&lt;/span&gt;
&lt;span class="ident"&gt;article&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;title&lt;/span&gt;  &lt;span class="comment"&gt;#=&amp;gt; &amp;quot;Title&amp;quot;&lt;/span&gt;
&lt;span class="ident"&gt;article&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;title&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;New Title&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="ident"&gt;article&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;title_changed?&lt;/span&gt; &lt;span class="comment"&gt;#=&amp;gt; true&lt;/span&gt;

&lt;span class="comment"&gt;# Jest też dostęp do poprzedniej wartości atrybutu &lt;/span&gt;
&lt;span class="comment"&gt;# zapomocą akcesora attr_name_was&lt;/span&gt;
&lt;span class="ident"&gt;article&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;title_was&lt;/span&gt;  &lt;span class="comment"&gt;#=&amp;gt; &amp;quot;Title&amp;quot;&lt;/span&gt;

&lt;span class="comment"&gt;# Zobacz wcześniejszą i późniejszą wartość za pomocą&lt;/span&gt;
&lt;span class="comment"&gt;# akcesora attr_name_change&lt;/span&gt;
&lt;span class="ident"&gt;article&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;title_change&lt;/span&gt;  &lt;span class="comment"&gt;#=&amp;gt; [&amp;quot;Title&amp;quot;, &amp;quot;New Title&amp;quot;]&lt;/span&gt;

&lt;span class="comment"&gt;# Zapis atrybutu wykonuje zapytanie dotyczące tylko jednej, &lt;/span&gt;
&lt;span class="comment"&gt;# odpowiadającej mu kolumny w tabeli:&lt;/span&gt;
&lt;span class="ident"&gt;article&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;save&lt;/span&gt;
  &lt;span class="comment"&gt;#=&amp;gt;  &amp;quot;UPDATE articles SET title = 'New Title' WHERE id = 1&amp;quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Dodano też coś, co funkcjonalnie &amp;#8220;od zawsze&amp;#8221; było obecne w &lt;a href="http://code.google.com/p/ruby-sequel/wiki/FilteringRecords"&gt;Sequel&amp;#8217;u&lt;/a&gt;, SQLAlchemy czy Django &lt;span class="caps"&gt;ORM&lt;/span&gt;, mianowicie tu nazywa się to &lt;a href="http://ryandaigle.com/articles/2008/3/24/what-s-new-in-edge-rails-has-finder-functionality"&gt;named scope&lt;/a&gt; (Rails wchłonęło popularny plugin &lt;a href="http://pivots.pivotallabs.com/users/nick/blog/articles/284-hasfinder-it-s-now-easier-than-ever-to-create-complex-re-usable-sql-queries"&gt;has_finder&lt;/a&gt; pozwalając w końcu na łatwiejsze budowanie bardziej skomplikowanych warunków odpytywania bazy).&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;User&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ActiveRecord&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Base&lt;/span&gt;
  &lt;span class="ident"&gt;named_scope&lt;/span&gt; &lt;span class="symbol"&gt;:active&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:conditions&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt;&lt;span class="symbol"&gt;:active&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;&lt;span class="punct"&gt;}&lt;/span&gt;
  &lt;span class="ident"&gt;named_scope&lt;/span&gt; &lt;span class="symbol"&gt;:inactive&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:conditions&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt;&lt;span class="symbol"&gt;:active&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;false&lt;/span&gt;&lt;span class="punct"&gt;}&lt;/span&gt;
  &lt;span class="ident"&gt;named_scope&lt;/span&gt; &lt;span class="symbol"&gt;:recent&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;lambda&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="symbol"&gt;:conditions&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;['&lt;/span&gt;&lt;span class="string"&gt;created_at &amp;gt; ?&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;week&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;ago&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="comment"&gt;# Typowe użycie:&lt;/span&gt;
&lt;span class="constant"&gt;User&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;active&lt;/span&gt;    &lt;span class="comment"&gt;# to samo co User.find(:all, :conditions =&amp;gt; {:active =&amp;gt; true})&lt;/span&gt;
&lt;span class="constant"&gt;User&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;inactive&lt;/span&gt; &lt;span class="comment"&gt;# to samo co User.find(:all, :conditions =&amp;gt; {:active =&amp;gt; false})&lt;/span&gt;
&lt;span class="constant"&gt;User&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;recent&lt;/span&gt;   &lt;span class="comment"&gt;# to samo co User.find(:all, :conditions =&amp;gt; ['created_at &amp;gt; ?', 1.week.ago])&lt;/span&gt;

&lt;span class="comment"&gt;# Możliwe są w końcu kolejne zagnieżdżenia warunków:&lt;/span&gt;
&lt;span class="constant"&gt;User&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;active&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;recent&lt;/span&gt;
  &lt;span class="comment"&gt;# to samo co:&lt;/span&gt;
  &lt;span class="comment"&gt;# User.with_scope(:conditions =&amp;gt; {:active =&amp;gt; true}) do&lt;/span&gt;
  &lt;span class="comment"&gt;#   User.find(:all, :conditions =&amp;gt; ['created_at &amp;gt; ?', 1.week.ago])&lt;/span&gt;
  &lt;span class="comment"&gt;# end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Autorzy Rails pozazdrościli &lt;a href="http://merbivore.org/documentation/merb-core/head/index.html?a=M000275&amp;#38;name=dependency"&gt;Merbowi&lt;/a&gt; i dodali też możliwość ładowania gemów o konkretnej wersji (być może będzie to też początek końca pluginów w obecnej postaci i Rails pójdzie i tu ścieżką Merba?)&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="constant"&gt;Rails&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Initializer&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;run&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;config&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; 

  &lt;span class="comment"&gt;# Załaduj najnowszą wersję haml&lt;/span&gt;
  &lt;span class="ident"&gt;config&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;gem&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;haml&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;

  &lt;span class="comment"&gt;# Załaduj konkretną wersję chronic&lt;/span&gt;
  &lt;span class="ident"&gt;config&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;gem&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;chronic&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:version&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;0.2.3&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

  &lt;span class="comment"&gt;# Załaduj gem z repozytorium innego niż RubyForge&lt;/span&gt;
  &lt;span class="ident"&gt;config&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;gem&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;hpricot&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:source&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;http://code.whytheluckystiff.net&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;

  &lt;span class="comment"&gt;# Załaduj gem którego nazwa pliku jest inna niż nazwa gemu&lt;/span&gt;
  &lt;span class="comment"&gt;# Np. można załadować gem który potrzebuje require 'aws/s3' zamiast &lt;/span&gt;
  &lt;span class="comment"&gt;# require 'aws-s3'&lt;/span&gt;
  &lt;span class="ident"&gt;config&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;gem&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;aws-s3&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:lib&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;aws/s3&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; 
&lt;span class="keyword"&gt;end&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Cieszy też, że poprawiono &lt;a href="http://ryandaigle.com/articles/2007/12/19/what-s-new-in-edge-rails-pluggable-controller-caching"&gt;sposób działania buforowania&lt;/a&gt; oraz wbudowano &lt;a href="http://ryandaigle.com/articles/2008/1/25/what-s-new-in-edge-rails-easier-timezones"&gt;lepszą obsługę dat i stref czasowych&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Ale z tego wszystkiego najbardziej mnie cieszy informacja inna informacja. Wspominałem o tym &lt;a href="http://blog.zabiello.com/articles/2008/03/30/rubyconf2008-merb"&gt;trzy dni temu&lt;/a&gt;, teraz zostało to &lt;a href="http://weblog.rubyonrails.org/2008/4/2/rails-is-moving-from-svn-to-git"&gt;oficjalnie ogłoszone&lt;/a&gt;: &lt;strong&gt;Rails migruje z Subversion na Gita.&lt;/strong&gt;  W końcu będzie można liczyć na poważniejsze przyśpieszenie prac i szybsze nanoszenie zgłaszanych poprawek (do tej pory to było tragicznie wolne, np. zgłoszony przeze mnie patch uwzględniono po 8 miesiącach). Rails, identycznie jak Merb, będzie używał tego samego serwera &lt;a href="http://github.com/"&gt;GitHub&lt;/a&gt; dla kodu i &lt;a href="http://www.lighthouseapp.com/"&gt;LightHouse&lt;/a&gt;. Więc ci, co nie mają tam kont, mogą już teraz o to zadbać. Praca z Git różni się też bardzo do &lt;span class="caps"&gt;SVN&lt;/span&gt;. Trochę przydatnych linków:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://git.or.cz/"&gt;Git homepage&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://git.or.cz/course/svn.html"&gt;Git for &lt;span class="caps"&gt;SVN&lt;/span&gt;’ers crash course&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://jointheconversation.org/railsgit"&gt; 
Using Git to Manage and Deploy your Rails Apps&lt;/a&gt; (video)&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://utsl.gen.nz/talks/git-svn/intro.html"&gt;An introduction to git-svn for Subversion/SVK users and deserters&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://eagain.net/articles/git-for-computer-scientists/"&gt;Git for Computer Scientists&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://evil.che.lu/projects/braid"&gt;Braid, a Piston clone for Git&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://brian.maybeyoureinsane.net/blog/2008/01/31/git-sake-tasks" title="Rake tasks for performing git operations"&gt;Git Sake Tasks&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://kurt.karmalab.org/articles/2008/02/18/the-power-of-git-git-stash"&gt;The Power of Git: git stash&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://kurt.karmalab.org/articles/2008/02/19/the-power-of-git-part-2"&gt;The Power of Git, Part 2&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://peepcode.com/products/git"&gt;PeeCode: Git&lt;/a&gt; (video)&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;W komentarzach do newsu na stronie Railsów można znaleźć głosy rozczarowania tych, co używają system Windows. Woleli by aby wybrano bardziej multiplatformowy Mercurial, ale &lt;span class="caps"&gt;DHH&lt;/span&gt; uciął dyskusję mówiąc, że decyzja została już podjęta a kolejne wersje Rails będą i tak dostępne standardowo w gemach. Poza tym na razie Git może być od biedy używany pod Cygwinem i jest też projekt &lt;a href="http://code.google.com/p/msysgit/"&gt;msysgit&lt;/a&gt;. No cóż, mnie to mało interesuje. Każdy wie, że windows i tak &lt;em&gt;sucks&lt;/em&gt; i najlepiej pracuje tylko ze samym sobą. Rails ma zaś silniejsze związki z światem &lt;span class="caps"&gt;POSIX&lt;/span&gt;, dlatego najlepiej używać Ubuntu, Mac &lt;span class="caps"&gt;OS X&lt;/span&gt; czy innych systemów uniksowych. &lt;span class="caps"&gt;BTW&lt;/span&gt;, nowy Kubuntu 8.0.4 beta nawet nieźle śmiga na VMWare pod Win32. :)&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=qcxTL9G"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=qcxTL9G" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=30Vcfag"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=30Vcfag" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=JsZ0L6G"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=JsZ0L6G" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Thu, 03 Apr 2008 04:58:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:e24d08c2-c810-4335-92fd-77e5394c849c</guid>
      <author>Jarosław Zabiełło</author>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/263090736/rails21-coming</link>
      <category>rails</category>
      <category>ruby</category>
    <feedburner:origLink>http://blog.zabiello.com/articles/2008/04/03/rails21-coming</feedburner:origLink></item>
    <item>
      <title>Merb 0.9.2 - szybki start</title>
      <description>&lt;p&gt;Żyjemy w czasach przeładowania informacją. Większości ludzi nie chce się czytać dokładnych dokumentacji, czy kilkuset stronicowych książek. Nie dziwię się, że Rails spotkał się z entuzjastycznym przyjęciem ze strony osób zmęczonych walką z konfiguracją frameworków Javy czy chaosem i nieelegancją kodu &lt;span class="caps"&gt;PHP&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;Merb pokazał że można jeszcze prościej i czytelniej niż zrobiono w Rails. To dobra informacja dla paranoików bojących się Railsów, którzy chcą czegoś bardzo prostego, aby nie musieć korzystać z &lt;span class="caps"&gt;PHP&lt;/span&gt;. I tu okazuje się, że Merb potrafi stworzyć sprawnie działający projekt prościej (i czytelniej) niż przykład użycia serwletu dostępny na &lt;a href="http://www.webrick.org/#example"&gt;stronie domowej Webricka&lt;/a&gt;. Merb jest też o wiele prostszy i bardziej intuicyjny niż pythonowe frameworki Django, Pylons czy TurboGears (nie mówiąc o pehapowych).&lt;/p&gt;


	&lt;p&gt;Najnowsza wersja stabilna Merba (0.9.2) jest dostępna normalnie w gemach. (Napisałem &amp;#8220;stabilna&amp;#8221;, mimo że formalnie jest to jeszcze wersja developerska, gdyż Ezra Zygmuntowicz uważa ją za wystarczająco dopracowaną aby móc używać do czegoś poważniejszego.) Instalacja jest więc standardowa:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;sudo gem install merb&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Merb w przeciwieństwie do Rails, używa jednego skryptu generatora kodu na wszystko &amp;#8211; &lt;code&gt;merb-gen&lt;/code&gt; (Rails używa skryptu &amp;#8220;rails&amp;#8221; oraz dodatkowych generatorow obecnych w katalogu &lt;code&gt;scripts/&lt;/code&gt;). Standardowo można stworzyć trzy rodzaje projektów. Pełny, okrojony i minimalistyczny.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;merb-gen app pelny
merb-gen app okrojony --flat
merb-gen app minimalny --very-flat&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Zainteresowanym polecam porównanie sobie kodu wygenerowanego w każdym z trzech przypadków. Dla tych, co chcieliby minimum kodu, ostatnia opcja może być dosyć atrakcyjna.&lt;/p&gt;


	&lt;h2&gt;Projekt minimalny&lt;/h2&gt;


	&lt;p&gt;W wypadku użycia opcji &lt;code&gt;--very-flat&lt;/code&gt; zostaną stworzone 2 (słownie: dwa) pliki. Jeden to &lt;span class="caps"&gt;README&lt;/span&gt; (z informacją, że całość odpala się za pomocą komendy: &lt;code&gt;merb -I minimalny.rb&lt;/code&gt;), a drugi to kod Rubiego z całym frameworkiem. Załóżmy, że chcemy prosto przekazać parametry z &lt;span class="caps"&gt;URL&lt;/span&gt; do kontrolera. Wejście na stronę&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;http://localhost:4000/?a=test&amp;amp;b=tt&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

wyświetli w przeglądarce 
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;Dostałem parametry: {&amp;quot;a&amp;quot;=&amp;gt;&amp;quot;test&amp;quot;, &amp;quot;b&amp;quot;=&amp;gt;&amp;quot;tt&amp;quot;, &amp;quot;action&amp;quot;=&amp;gt;&amp;quot;index&amp;quot;, &amp;quot;controller&amp;quot;=&amp;gt;&amp;quot;minimalny&amp;quot;}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Cały kod frameworka sprowadzi się do jednego pliku:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="constant"&gt;Merb&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Router&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;prepare&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;r&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
  &lt;span class="ident"&gt;r&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;match&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;/&lt;/span&gt;&lt;span class="punct"&gt;').&lt;/span&gt;&lt;span class="ident"&gt;to&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:controller&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;minimalny&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="symbol"&gt;:action&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;'&lt;/span&gt;&lt;span class="string"&gt;index&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Minimalny&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;Merb&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Controller&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;index&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Dostałem parametry: &lt;span class="expr"&gt;#{params.inspect}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="constant"&gt;Merb&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Config&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;use&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;c&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
  &lt;span class="ident"&gt;c&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:framework&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;           &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;{},&lt;/span&gt;
  &lt;span class="ident"&gt;c&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:session_store&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;       &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;none&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt;
  &lt;span class="ident"&gt;c&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:exception_details&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;   &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;
&lt;span class="punct"&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;W praktyce oczywiście wygodniej jest używać pełnego projektu, bo daje wygodny dostęp do &lt;span class="caps"&gt;ORM&lt;/span&gt;, szablonów i wszystkich możliwości jakie oferuje Merb.&lt;/p&gt;


	&lt;h2&gt;Projekt pełny &amp;#8211; szybki start&lt;/h2&gt;


	&lt;p&gt;Załóżmy, dla prostoty, że chcemy jakiejś bardzo prostej metody składowania danych i nie chcemy korzystać (przynajmniej na początku) z pełnych serwerów takich jak MySQL czy PostgreSQL. Doskonałym wyborem w takiej sytuacji będzie &lt;a href="ttp://www.sqlite.org/"&gt;SQLite&lt;/a&gt;. Baza sprowadza się do jednego pliku, jest szybka i umożliwia korzystanie z języka &lt;span class="caps"&gt;SQL&lt;/span&gt; (włącznie z transakcjami). Instaluje się ją z gemow:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;sudo gem install sqlite3-ruby&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Tworzymy projekt:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;merb-gen app myproj&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Zostanie stworzony katalog myproj z różnymi plikami i katalogami w środku. To jest &lt;strong&gt;szkielet aplikacji&lt;/strong&gt; i jest nawet prostszy od tego co generują Rails.&lt;/p&gt;


	&lt;p&gt;Domyślnie Merb nie zakłada, że chcemy korzystać z baz danych. Aby uaktywnić obsługę bazy danych, wejdź do pliku &lt;code&gt;config/init.rb&lt;/code&gt; i odkomentować jedną linijkę z trzech dostępnych bibliotek zapewniających obiektowy dostęp do relacyjnej bazy danych: &lt;a href="http://ar.rubyonrails.org/"&gt;Active Record&lt;/a&gt;, &lt;a href="http://datamapper.org/"&gt;DataMapper&lt;/a&gt; lub &lt;a href="http://code.google.com/p/ruby-sequel/"&gt;Sequel&lt;/a&gt;. Załóżmy, że wybraliśmy ten trzeci (mój ulubiony ze względu na prostotę i elastyczność; oczywiście zakładam, że wcześniej zainstalowaliśmy: &lt;code&gt;sudo gem install sequel&lt;/code&gt;)&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;use_orm&lt;/span&gt; &lt;span class="symbol"&gt;:sequel&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Od tej chwili Merb będzie zakładał, że chcemy pracować z bazą danych za pomocą Sequela. To znacznie uprości to pracę z samą bazą SQLite i ułatwi  ewentualne przepięcie aplikacji ze SQLite do MySQL czy innej bazy. Teraz przejdź do konsoli i odpal w katalogu projektu polecenie:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;merb&lt;/span&gt;&lt;span class="punct"&gt;-&lt;/span&gt;&lt;span class="ident"&gt;gen&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Merb już wie, że chcesz używać bazy, więc teraz automatycznie stworzy teraz plik konfiguracyjny &lt;code&gt;config/database.sample.yml&lt;/code&gt;. Należy zmienić jego nazwę &lt;code&gt;database.yml&lt;/code&gt;. Domyślnie tworzone są tam ustawienia dla MySQL. Aby użyć SQLite, zmień go na:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_yaml "&gt;&lt;span class="document"&gt;---
:development: &amp;amp;defaults&lt;/span&gt;
  &lt;span class="symbol"&gt;:adapter&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt; sqlite
  &lt;span class="symbol"&gt;:database&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt; baza.db
  &lt;span class="symbol"&gt;:encoding&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt; utf8

:test:
  &amp;lt;&amp;lt;: *defaults
  &lt;span class="symbol"&gt;:database&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt; baza-testowa.db

:production:
  &amp;lt;&amp;lt;: *defaults&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Teraz stworzmy jakiś przykładowy model danych z użytkownikami i kontroler do ich zarządzania. Stwórzmy od razu cały zasób z obsługą &lt;span class="caps"&gt;REST&lt;/span&gt;.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;merb-gen resource user&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Teraz przejdź do pliku schema/migrations/001_user.rb  i zmień go na&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;UserMigration&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;Sequel&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Migration&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;up&lt;/span&gt;
    &lt;span class="ident"&gt;create_table&lt;/span&gt; &lt;span class="symbol"&gt;:users&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
      &lt;span class="ident"&gt;varchar&lt;/span&gt; &lt;span class="symbol"&gt;:name&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:unique&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;
      &lt;span class="ident"&gt;primary_key&lt;/span&gt; &lt;span class="symbol"&gt;:id&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;down&lt;/span&gt;
    &lt;span class="ident"&gt;execute&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;DROP TABLE users&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; 

	&lt;p&gt;Będąc w katalogu projektu, odpal polecenie: uruchamiające &amp;#8220;proces migracji:http://code.google.com/p/ruby-sequel/wiki/Migrations:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;rake sequel:db:migrate&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; 

	&lt;p&gt;Zostanie stworzona baza (plik: baza.db) oraz tabela users. No to teraz trochę się pobawmy interaktywną konsolą aby dodać jakieś dane do bazy.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="global"&gt;$ &lt;/span&gt;&lt;span class="ident"&gt;merb&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt;&lt;span class="ident"&gt;i&lt;/span&gt;
 ~ &lt;span class="constant"&gt;Loaded&lt;/span&gt; &lt;span class="constant"&gt;DEVELOPMENT&lt;/span&gt; &lt;span class="constant"&gt;Environment&lt;/span&gt;&lt;span class="punct"&gt;...&lt;/span&gt;
 ~ &lt;span class="ident"&gt;loading&lt;/span&gt; &lt;span class="ident"&gt;gem&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;merb_sequel&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="ident"&gt;from&lt;/span&gt;  &lt;span class="punct"&gt;...&lt;/span&gt;
 ~ &lt;span class="constant"&gt;Connecting&lt;/span&gt; &lt;span class="ident"&gt;to&lt;/span&gt; &lt;span class="ident"&gt;the&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;baza.db&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="ident"&gt;database&lt;/span&gt; &lt;span class="ident"&gt;on&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="ident"&gt;using&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;sqlite&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="punct"&gt;...&lt;/span&gt;
 ~ &lt;span class="constant"&gt;Compiling&lt;/span&gt; &lt;span class="ident"&gt;routes&lt;/span&gt;&lt;span class="punct"&gt;...&lt;/span&gt;
 ~ &lt;span class="constant"&gt;Using&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;share-nothing&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="ident"&gt;cookie&lt;/span&gt; &lt;span class="ident"&gt;sessions&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;4&lt;/span&gt;&lt;span class="ident"&gt;kb&lt;/span&gt; &lt;span class="ident"&gt;limit&lt;/span&gt; &lt;span class="ident"&gt;per&lt;/span&gt; &lt;span class="ident"&gt;client&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
&lt;span class="constant"&gt;User&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;create&lt;/span&gt; &lt;span class="symbol"&gt;:name&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Jarek&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="comment"&gt;#&amp;lt;User @values={:name=&amp;gt;&amp;quot;Jarek&amp;quot;, :id=&amp;gt;1}&amp;gt;&lt;/span&gt;
&lt;span class="constant"&gt;User&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;create&lt;/span&gt; &lt;span class="symbol"&gt;:name&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Ewa&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="comment"&gt;#&amp;lt;User @values={:name=&amp;gt;&amp;quot;Ewa&amp;quot;, :id=&amp;gt;2}&amp;gt;&lt;/span&gt;
&lt;span class="constant"&gt;User&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;all&lt;/span&gt;
&lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="comment"&gt;#&amp;lt;User @values={:name=&amp;gt;&amp;quot;Jarek&amp;quot;, :id=&amp;gt;1}&amp;gt;, #&amp;lt;User @values={:name=&amp;gt;&amp;quot;Ewa&amp;quot;, :id=&amp;gt;2}&amp;gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; 

	&lt;p&gt;OK. Ostatni krok. Otwórz plik &lt;code&gt;app/views/users/index.html.erb&lt;/code&gt; i wstaw:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_rhtml "&gt;&amp;lt;p&amp;gt;W bazie mam użytkowników o imionach:&amp;lt;/h1&amp;gt;
&amp;lt;% for user in @users %&amp;gt;
  &amp;lt;p&amp;gt;&amp;lt;%= user.name %&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;% end %&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; 

	&lt;p&gt;To wszystko! Odpal serwer z aplikacją za pomocą komendy: &lt;code&gt;merb&lt;/code&gt;
(więcej: &lt;code&gt;merb --help&lt;/code&gt;) i otwórz stronę http://localhost:4000/users&lt;/p&gt;


	&lt;h2&gt;Dodatkowe informacje&lt;/h2&gt;


	&lt;p&gt;Ezra Zygmuntowicz zapowiedział intensywne prace nad stworzeniem zestawu manuali i dodatkowej dokumentacji dla Merba. Na razie musi wystarczyć to, co jest dostępne na &lt;a href="http://merbivore.com/documentation.html"&gt;stronie projektu&lt;/a&gt; plus informacje dostępne w blogach i na kanale &lt;span class="caps"&gt;IRC&lt;/span&gt; &lt;a href="irc://irc.eu.freenode.net/merb"&gt;#merb&lt;/a&gt; serwera freenode.net. &lt;a href="http://peepcode.com/products/meet-merb-pdf-draft"&gt;Powstaje też książka&lt;/a&gt; która jest dostępna w wersji roboczej przez PeepCode. &lt;a href="http://merbivore.com/documentation.html"&gt;&lt;span class="caps"&gt;API&lt;/span&gt; Merba&lt;/a&gt; jest dosyć przejrzyście opisane i co ważniejsze, przyjęto ścisłe &lt;a href="http://merbivore.com/contribute.html"&gt;zasady tworzenia dokumentacji&lt;/a&gt;, która były opisane wszystkie możliwe parametry dla każdej metody plus jakiś przykład użycia.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=Baaj8vF"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=Baaj8vF" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=PHPFNhf"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=PHPFNhf" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=tsnTs5F"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=tsnTs5F" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Mon, 31 Mar 2008 01:09:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:7ff92e90-078e-4d96-94cf-0a097bf808e4</guid>
      <author>Jarosław Zabiełło</author>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/260961965/merb092-start</link>
      <category>merb</category>
      <category>ruby</category>
    <feedburner:origLink>http://blog.zabiello.com/articles/2008/03/31/merb092-start</feedburner:origLink></item>
    <item>
      <title>JRuby 1.1 final</title>
      <description>&lt;p&gt;Jest w końcu oczekiwana wersja stabilna &lt;strong&gt;JRuby 1.1&lt;/strong&gt;. W chwili pisania tej notki, nie ma o tym jeszcze informacji &lt;a href="http://jruby.codehaus.org/"&gt;na stronie głównej&lt;/a&gt;, ale jest już &lt;a href="http://dist.codehaus.org/jruby/"&gt;do pobrania&lt;/a&gt;. To bardzo dobra wiadomość, bo JRuby 1.1 już w wersjach rozwojowych był znacznie szybszy od poprzedniej 1.0, a w wielu testach bił wydajnością nie tylko Ruby 1.8.6 i 1.9, ale także Pythona 2.5.1. Dzięki JRuby webowe frameworki takie jak &lt;a href="http://rubyonrails.pl"&gt;Rails&lt;/a&gt; czy &lt;a href="http://merbivore.com/"&gt;Merb&lt;/a&gt; uzyskują pełny dostęp do bibliotek Javy i tym samym jakiekolwiek uwagi co do (nie)dojrzałości bibliotek Rubiego stają się nieistotne.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=G3hUHdF"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=G3hUHdF" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=86UwfCf"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=86UwfCf" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=yUwN5NF"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=yUwN5NF" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Mon, 31 Mar 2008 00:51:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:c7b2c8e8-bcd2-484d-b850-9b908c67015e</guid>
      <author>Jarosław Zabiełło</author>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/260943134/jruby11</link>
      <category>jruby</category>
      <category>ruby</category>
      <category>java</category>
    <feedburner:origLink>http://blog.zabiello.com/articles/2008/03/31/jruby11</feedburner:origLink></item>
    <item>
      <title>Wzmacnianie ekosystemu Rubiego - Merb</title>
      <description>&lt;p&gt;Przedwczoraj, w ramach &lt;a href="http://mtnwestrubyconf.org/"&gt;MountainWest Ruby Conference 2008&lt;/a&gt;, miało miejsce ciekawe wystąpienie Ezry Zygmuntowicza na temat &lt;a href="http://merbivore.com/"&gt;Merba&lt;/a&gt;, webowego frameworka stworzonego w języku Ruby. Wersja strumieniowa, pliki wideo oraz slajdy z wykładu, &lt;a href="http://mtnwestrubyconf2008.confreaks.com/02zygmuntowicz.html"&gt;są do pobrania&lt;/a&gt; w internecie. Ezra w prosty sposób pokazał kilka interesujących cech Merba, które odróżniają go od konkurencyjnego Ruby on Rails.&lt;/p&gt;


	&lt;h2&gt;Prostota jest lepsza od magii&lt;/h2&gt;


	&lt;p&gt;Przede wszystkim, Merb zbudowano na założeniu że &lt;strong&gt;prostota jest lepsza od magii&lt;/strong&gt;. Wiele osób nie znających zbytnio Rubiego, które zetknęły się z Railsami, myślą, że permanentnie magiczne (implicite) podejście do kodowania do jakaś integralna część samego języka Ruby. Tymczasem to nie jest problem Rubiego, ale filozofii zastosowanej w Rails. Sam Ruby (z założenia) pozwala na rozwiązanie tego samego problemu na bardzo wiele sposobow. W pełni zgadzam się z Ezrą, że operowanie na otwartych klasach Rubiego może być bardzo użyteczną techniką, ale z drugiej strony, nie powinna to być  główna, ani najważniejsza, technika w arsenale narzędzi programisty Rubiego. W ostatecznym rozrachunku, łatwiej wrócić do kodu który jest prosty niż tylko ładny i magiczny z implementacją zaszytą głęboko w gdzieś includowanej bibliotece.&lt;/p&gt;


	&lt;p&gt;Ale Merb na tym się nie zatrzymuje. Jego mottem przewodnim jest &lt;strong&gt;nie ma szybszego kodu od braku kodu&lt;/strong&gt;. Ezra nie zgadza się za bardzo z rozumowaniem prezentowanym przez &lt;span class="caps"&gt;DHH&lt;/span&gt; i Rails, że skoro czas programisty jest droższy od czasu serwera, to kto martwi się o wydajność, niech sobie dostawi&amp;#8230; więcej serwerów. Nawiązuje to do permanentnie błędnej polityki ignorowania optymalizacji wydajnościowej w Rails na rzecz koncentrowania się na ciągle nowej funkcjonalności, &amp;#8220;a wydajność poprawi się później, lub dostawi więcej sprzętu&amp;#8221;. To prawda, że &amp;#8220;przedwczesna optymalizacja jest korzeniem wielu problemów, komplikacji itp. itd&amp;#8221; Prawdą jest jednakże i to, że &amp;#8220;zbyt późna optymalizacja jest korzeniem wszystkich dodatkowych faktur do zapłacenia dla centrum hostingowego&amp;#8221;. Merb od początku jest tworzony z uwzględnieniem wydajności, modularności, wielowątkowości i elastyczności.&lt;/p&gt;


	&lt;p&gt;Merb (licząc od wersji 0.9 która wnosi ogromne zmiany do wcześniejszej 0.5.x) został podzielony na kilka modułów. Rdzeń frameworka znajduje się w &lt;code&gt;merb-core&lt;/code&gt;. Dodatkowe możliwości są dostępne w &lt;code&gt;merb-more&lt;/code&gt; i &lt;code&gt;merb-plugins&lt;/code&gt;. Nowy Merb jest zbudowany też na fundamencię &lt;a href="http://rack.rubyforge.org/"&gt;Rack&amp;#8217;a&lt;/a&gt; (wzorowanego na pythonowym &lt;a href="http://www.python.org/dev/peps/pep-0333/"&gt;&lt;span class="caps"&gt;WSGI&lt;/span&gt;&lt;/a&gt;, interfejsie dla aplikacji korzystających z protokołu &lt;span class="caps"&gt;HTTP&lt;/span&gt;). Merb może być uruchamiany z kilkoma serwerami: Ebb, asynchroniczny Mongrel (Evented Mongrel), FastCGI, wielowątkowy Mongrel (Merb, w przeciwieństwie do Rails, jest w pełni wielowątkowy), Thin czy Webrick.&lt;/p&gt;


	&lt;h2&gt;Wielowątkowo czy asynchronicznie?&lt;/h2&gt;


	&lt;p&gt;Ezra zwrócił uwagę na dosyć istotny aspekt wydajności dla adappterami asynchronicznymi (Ebb, Evented Mongrel, Thin) a wielowątkowym Mongrelem. Otóż nie zawsze adaptery asynchroniczne są szybsze. Tak jest tylko w wypadku krótko trwających zapytań. Jednakże jeśli mamy sytuację obsługi jakiegoś długiego (kilku sekundowego) requestu, to adapter asynchroniczny ma zablokowaną pętlę i w efekcie, jak to określił Erza, &amp;#8220;pada na pysk&amp;#8221;. Wielowątkowy Mongrel w takiej sytuacji, nie blokuje swojej pracy, ale odpala kolejny wątek dla obsługi następnych requestów. To, więc, co warto użyć zależy od charakteru aplikacji i można powiedzieć że wielowątkowy Mongrel jest najbardziej uniwersalnym, choć nie zawsze najszybszym, rozwiązaniem. Można ewentualnie mieszać podejścia i oczekiwane jako wolne, requesty kierować na Mongrela a resztę na Ebb, czy Thin.  Osobiście tego jeszcze nie testowałem, ale wydaje się to rozsądnym podejściem.&lt;/p&gt;


	&lt;h2&gt;Potężniejszy router adresów&lt;/h2&gt;


	&lt;p&gt;Merb ma kompletnie inaczej napisany resolver adresów &lt;span class="caps"&gt;URL&lt;/span&gt; niż Rails. Po pierwsze, jest dużo szybszy ze względuna stosowaną prekompilację. Po drugie, jest dużo elastyczniejszy od Railsów (czy Django, gdzie który jest równie słaby). Przyjrzyjmy się poniższemu przykładowi.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="constant"&gt;Merb&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Router&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;prepare&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;r&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
  &lt;span class="ident"&gt;r&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;match&lt;/span&gt;&lt;span class="punct"&gt;(%r[&lt;/span&gt;&lt;span class="regex"&gt;^/foor(.+)&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;span class="symbol"&gt;:user_agent&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="regex"&gt;(MSIE|Gecko)&lt;/span&gt;&lt;span class="punct"&gt;/).&lt;/span&gt;
    &lt;span class="ident"&gt;to&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:controller&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;foo&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:title&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;[1]&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;),&lt;/span&gt;
       &lt;span class="symbol"&gt;:action&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;show&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:agent&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;:user_agent[1]&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt;

  &lt;span class="ident"&gt;r&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;match&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;/bar/:baz&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;).&lt;/span&gt;&lt;span class="ident"&gt;defer_to&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;request&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;params&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;bar&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Bar&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;find_by_baz&lt;/span&gt; &lt;span class="ident"&gt;params&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:baz&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;
      &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="symbol"&gt;:controller&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;bar&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;controller&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;
        &lt;span class="symbol"&gt;:action&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;bar&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;action&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;
        &lt;span class="symbol"&gt;:bar&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;bar&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_param&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;W regule pierwszej widać, że router adresów zastosowany w Merbie pozwala filtrować po dowolnych nagłówkach. Np. może wiedzieć czy użyto przeglądarki Internet Explorer czy Firefox i stosownie do tego podejmuje dalsze działania. Drugi przykład jest jeszcze ciekawszy. Z adresu &lt;span class="caps"&gt;URL&lt;/span&gt; wyłuskiwana jest wartość którą Merb wykorzystuje aby odpytać bazę danych i na tej podstawie odpowiednio przekierować sterowanie.&lt;/p&gt;


	&lt;h2&gt;Akcje o składni metod Rubiego&lt;/h2&gt;


	&lt;p&gt;Mimo, że Merb pozwala, w podobny (do Rails) sposób, korzystać z hasza &lt;code&gt;params&lt;/code&gt;, dodano tu trochę syntaktycznego lukru pozwalającego na pisanie kodu akcji w kontrolerze tak jak się pisze zwykłe metody w Rubim.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="constant"&gt;Merb&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;add_mime_type&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:yaml&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:to_yaml&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;%w[&lt;/span&gt;&lt;span class="string"&gt;application/x-yaml text/yaml&lt;/span&gt;&lt;span class="punct"&gt;])&lt;/span&gt;
&lt;span class="constant"&gt;Merb&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;add_mime_type&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:text&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:to_text&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;%w[&lt;/span&gt;&lt;span class="string"&gt;text/plain&lt;/span&gt;&lt;span class="punct"&gt;])&lt;/span&gt;
&lt;span class="constant"&gt;Merb&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;add_mime_type&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:html&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:to_html&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;%w[&lt;/span&gt;&lt;span class="string"&gt;text/html application/xhtml+xml application/html&lt;/span&gt;&lt;span class="punct"&gt;])&lt;/span&gt;
&lt;span class="constant"&gt;Merb&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;add_mime_type&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:xml&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;  &lt;span class="symbol"&gt;:to_xml&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;  &lt;span class="punct"&gt;%w[&lt;/span&gt;&lt;span class="string"&gt;application/xml text/xml application/x-xml&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;span class="symbol"&gt;:Encoding&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;UTF-8&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt;
&lt;span class="constant"&gt;Merb&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;add_mime_type&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:js&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;   &lt;span class="symbol"&gt;:to_json&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;%w[&lt;/span&gt;&lt;span class="string"&gt;text/javascript application/javascript application/x-javascript&lt;/span&gt;&lt;span class="punct"&gt;])&lt;/span&gt;
&lt;span class="constant"&gt;Merb&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;add_mime_type&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:json&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:to_json&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;%w[&lt;/span&gt;&lt;span class="string"&gt;application/json text/x-json&lt;/span&gt;&lt;span class="punct"&gt;])&lt;/span&gt;      
&lt;span class="comment"&gt;#...&lt;/span&gt;
&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Posts&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;Application&lt;/span&gt;
  &lt;span class="ident"&gt;provides&lt;/span&gt; &lt;span class="symbol"&gt;:json&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:yaml&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:xml&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;show&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="attribute"&gt;@post&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Post&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;find&lt;/span&gt; &lt;span class="ident"&gt;id&lt;/span&gt;
    &lt;span class="ident"&gt;display&lt;/span&gt; &lt;span class="attribute"&gt;@post&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;user&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;name&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Jarek&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt;
    &lt;span class="ident"&gt;only_provides&lt;/span&gt; &lt;span class="symbol"&gt;:html&lt;/span&gt;
    &lt;span class="attribute"&gt;@user&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;User&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;find_by_name&lt;/span&gt; &lt;span class="ident"&gt;name&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Przekazywanie parametrów w metodzie zamiast w haszu, moim zdaniem, znacznie zwiększa czytelność kodu. Umożliwia też wygodne stosowanie wartości domyślnych.&lt;/p&gt;


	&lt;p&gt;Słowo wyjaśnienia należy się metodzie display(). Merb w inny (od Rails) sposób rozpoznaje typ &lt;span class="caps"&gt;MIME&lt;/span&gt; przekazany do metody. Zamiast przekazywać w akcji blok do respond_to, Merb definiuje tylko jakie metody mają być wywołane dla odpowiedniego &lt;span class="caps"&gt;MIME&lt;/span&gt;.  Np. akcja odpalana dla adresu &lt;code&gt;/posts/user&lt;/code&gt; przekazuje do metody &lt;code&gt;user&lt;/code&gt; hasz params o wartości &lt;code&gt;{:name =&amp;gt; "Jarek"}&lt;/code&gt;. Pobiera rekord z bazy i zwraca do klienta kod &lt;span class="caps"&gt;HTML&lt;/span&gt; wywołany za pomocą metody &lt;code&gt;to_html&lt;/code&gt; na obiekcie &lt;code&gt;user&lt;/code&gt;. W wypadku metody &lt;code&gt;show&lt;/code&gt; zwracanych jest wiele różnych reprezentacji zależnych od użytego &lt;span class="caps"&gt;MIME&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;Trzeba też dodać, że Merb nie używa żadnych magicznych railsowych metod &lt;code&gt;render&lt;/code&gt; które mogą być wywołane tylko jeden raz (sic!) na request. Merb może kolekcjonować output z kilku miejsc. Zaś jeśli chodzi o samą akcję kontrolera, to zwracane jest po prostu ostatnie wyrażenie (tak, jak w zwykłych metodach Rubiego). Np. można otworzyć plik i zwrócić stworzony obiekt &lt;code&gt;IO&lt;/code&gt; w metodzie kontrolera, a Merb potraktuje to jako przesyłanie &lt;strong&gt;strumieniowe&lt;/strong&gt;.&lt;/p&gt;


	&lt;h2&gt;Git rządzi&lt;/h2&gt;


	&lt;p&gt;Ezra podkreślił sporo korzyści jakie dało przejście na rozproszony system wersjonowania kodu (Git). Znacznie łatwiej można eksperymentować z kodem i zgłaszać poprawki niż w wypadku starego &lt;span class="caps"&gt;SVN&lt;/span&gt;&amp;#8217;a. I co ciekawe, także Ruby on Rails zamierza też przejść na Git&amp;#8217;a w przeciągu jakichś dwóch miesięcu.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=k0tLSYF"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=k0tLSYF" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=NETxeof"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=NETxeof" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=laeV5BF"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=laeV5BF" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Sun, 30 Mar 2008 20:39:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:a9c11a35-7d21-40bf-8df1-207344596196</guid>
      <author>Jarosław Zabiełło</author>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/260841631/rubyconf2008-merb</link>
      <category>ruby</category>
      <category>merb</category>
      <category>rails</category>
    <feedburner:origLink>http://blog.zabiello.com/articles/2008/03/30/rubyconf2008-merb</feedburner:origLink></item>
    <item>
      <title>Merb 0.9.2 i Sake</title>
      <description>&lt;p&gt;&lt;a href="http://merbivore.com/"&gt;Merb&lt;/a&gt; wchodzi w końcową fazę przed wydaniem wersji &amp;#8220;1.0 (RailsConf)&amp;#8221; . Właściwie nie zdziwiłbym się jakby lada dzień ta wesja wyszła bo &lt;a href="http://merb.lighthouseapp.com/projects/7435-merb-more/milestones"&gt;prawie wszystkie&lt;/a&gt; tickety z problemami są już wyczyszczone. Rozproszony system wersjonowania kodu &amp;#8211; &lt;a href="http://pl.wikibooks.org/wiki/Git"&gt;Git&lt;/a&gt; &amp;#8211; sprawdza się doskonale. Rozproszony Rake &amp;#8211; &lt;a href="http://errtheblog.com/posts/60-sake-bomb"&gt;Sake&lt;/a&gt; &amp;#8211; także. Nowy Merb wspiera &lt;a href="http://ebb.rubyforge.org/"&gt;Ebb&lt;/a&gt;. Jest on szybszy od &lt;a href="http://mongrel.rubyforge.org/"&gt;Mongrela&lt;/a&gt;, to najszybszy serwer &lt;span class="caps"&gt;HTTP&lt;/span&gt; dla Rubiego wykorzystujący interfejs &lt;a href="http://rack.rubyforge.org/"&gt;Rack&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Sake&lt;/strong&gt;, to &lt;a href="http://rake.rubyforge.org/"&gt;Rake&lt;/a&gt; tylko, że działający zdalnie! Można plik z taskami dla Rake wstawić gdziekolwiek w internecie i każdy może go używać. Najlepiej zobaczyć to na przykładzie.&lt;/p&gt;


	&lt;p&gt;Stworzyłem w Githubie mini projekt &lt;a href="http://github.com/hipertracker/merb-scripts/tree/master"&gt;merb-scripts&lt;/a&gt; gromadzącym różne wygodne zadania w kontekście Merba.&lt;/p&gt;


	&lt;p&gt;Sprawdzenie dostępnych zadań:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;$ sake -T http://blog.zabiello.com/merb-scripts.sake
sake merb:pull         # Pull merb-core, merb-more, merb-plugins
sake merb:uninstall    # Uninstall all Ruby merb* gems
sake merb:juninstall   # Uninstall all JRuby merb* gems
sake merb:repackage    # Repackage merb-&amp;lt;core|more|plugins&amp;gt; (with all subgems)
sake merb:install      # Install all Merb gems and subgems
sake merb:jinstall     # Install all Merb gems and subgems for JRuby&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Dodanie listy zadań do lokalnego repozytorium Sake (dokładniej: do pliku ~/.sake).&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;sake -i http://blog.zabiello.com/merb-scripts.sake
sake -T # pokaż nową listę zadań&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Sprawdzenie źródła dla danej komendy:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;sake&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt;&lt;span class="ident"&gt;e&lt;/span&gt; &lt;span class="ident"&gt;merb&lt;/span&gt;&lt;span class="symbol"&gt;:pull&lt;/span&gt;

&lt;span class="ident"&gt;desc&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Pull merb-core, merb-more, merb-plugins&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;task&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;merb:pull&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
  &lt;span class="constant"&gt;Rake&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Task&lt;/span&gt;&lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;merb:init&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;].&lt;/span&gt;&lt;span class="ident"&gt;invoke&lt;/span&gt;
  &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;merb-core&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;merb-more&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;merb-plugins&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;].&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;dir&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="constant"&gt;File&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;exists?&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;dir&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;then&lt;/span&gt;
      &lt;span class="ident"&gt;sh&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;cd &lt;span class="expr"&gt;#{dir}&lt;/span&gt;; git pull&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt;
    &lt;span class="keyword"&gt;else&lt;/span&gt;
      &lt;span class="ident"&gt;sh&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;git clone git://github.com/&lt;span class="expr"&gt;#{@git_fork}&lt;/span&gt;/&lt;span class="expr"&gt;#{dir}&lt;/span&gt;.git&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Ściągnięcie najnowszej wersji rozwojowej Merba, kompilacja gemów i instalacja dla JRuby (musi być dostępny w systemie)&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;sake merb:pull merb:repackage merb:jinstall&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Dla tych, co jeszcze nie wiedzą. Jest już dostępny &lt;a href="http://dist.codehaus.org/jruby/"&gt;JRuby &lt;span class="caps"&gt;RC3&lt;/span&gt;&lt;/a&gt; i Merb może być uruchamiany pod JRuby tak jak i Rails.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=fSDINKF"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=fSDINKF" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=A402Ucf"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=A402Ucf" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=Ewm7xzF"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=Ewm7xzF" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Tue, 25 Mar 2008 07:11:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:ac3d5ab1-00e0-46d8-903f-ab6320adc8ce</guid>
      <author>Jarosław Zabiełło</author>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/257505613/merb092-sake</link>
      <category>rake</category>
      <category>sake</category>
      <category>ruby</category>
      <category>merb</category>
      <category>jruby</category>
    <feedburner:origLink>http://blog.zabiello.com/articles/2008/03/25/merb092-sake</feedburner:origLink></item>
    <item>
      <title>Wolne odświeżanie gemów</title>
      <description>&lt;p&gt;Od jakiegoś czasu proces wielu użytkowników Leoparda &lt;a href="http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/4fc65cdd3afbad00"&gt;narzeka na bardzo wolne odświeżanie&lt;/a&gt; gemów Rubiego. Instalacja nowego gemu potrafiła być 10x wolniejsza niż pod Ubuntu. Po małych modyfikacjach, ładowanie gemów na Leopardzie jest teraz dla odmiany szybsze niż na Ubuntu. :)&lt;/p&gt;


	&lt;p&gt;Przede wszystkim, wyłącz protokół IPv6 (System
Preferences -&amp;gt; Network -&amp;gt; Advanced -&amp;gt; &lt;span class="caps"&gt;TCP&lt;/span&gt;/IP -&amp;gt; Configure IPv6) oraz dodać komendę&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;resolv-replace&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="comment"&gt;# Ezra Zygmuntowicz radzi aby dodać:&lt;/span&gt;
&lt;span class="constant"&gt;Socket&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;do_not_reverse_lookup&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;do skryptu &lt;code&gt;/opt/local/bin/gem&lt;/code&gt; (używam tu &lt;a href="http://www.macports.org/"&gt;MacPortów&lt;/a&gt;). Tylko trzeba uważać, bo ta zmiana zniknie po &lt;code&gt;gem update --system&lt;/code&gt;.&lt;/p&gt;


	&lt;p&gt;Jeśli ta zmiana nie wystarczy, to odpal komendę&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;sudo&lt;/span&gt; &lt;span class="ident"&gt;gem&lt;/span&gt; &lt;span class="ident"&gt;list&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt;&lt;span class="ident"&gt;r&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt;&lt;span class="constant"&gt;B&lt;/span&gt; &lt;span class="number"&gt;10000&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;i podmień plik &lt;code&gt;/opt/local/lib/ruby/site_ruby/1.8/rubygems/remote_fetcher.rb&lt;/code&gt; na &lt;a href="http://rubygems.rubyforge.org/svn/trunk/lib/rubygems/remote_fetcher.rb"&gt;najnowszy z repozytorium&lt;/a&gt;.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=tQEMPuF"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=tQEMPuF" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=SMSeL8f"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=SMSeL8f" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.zabiello.com/~f/hipertracker?a=3X8jCXF"&gt;&lt;img src="http://feeds.zabiello.com/~f/hipertracker?i=3X8jCXF" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Sun, 23 Mar 2008 17:57:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:8d4dc32c-62bf-41db-b242-f061c3d3aa75</guid>
      <author>Jarosław Zabiełło</author>
      <link>http://feeds.zabiello.com/~r/hipertracker/~3/256596283/slow-gems</link>
      <category>ruby</category>
      <category>osx</category>
      <category>leopard</category>
      <category>rubygems</category>
    <feedburner:origLink>http://blog.zabiello.com/articles/2008/03/23/slow-gems</feedburner:origLink></item>
  </channel>
</rss>
