<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Drogomir</title>
    <link>http://blog.drogomir.com</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description></description>
    <item>
      <title>Google chce przy&#347;pieszy&#263; internet</title>
      <description>&lt;p&gt;Nie od dzi&#347; wiadomo, &#380;e pr&#281;dko&#347;&#263; &#322;adowania strony ma wp&#322;yw na akcje u&#380;ytkownik&#243;w. Badania prowadzone miedzy innymi przez Yahoo, Google i Amazon wskaza&#322;y, &#380;e zmniejszenie czasu &#322;adowania strony ma bezpo&#347;redni wp&#322;yw na ilo&#347;&#263; akcji wykonanych przez u&#380;ytkownik&#243;w (wyszukiwa&#324; lub w wypadku Amazona zakupionych przedmiot&#243;w).&lt;/p&gt;


	&lt;p&gt;Google odpali&#322; niedawno stron&#281;, na kt&#243;rej &lt;a href="http://code.google.com/speed/index.html"&gt;zach&#281;ca i uczy jak przy&#347;pieszy&#263; dzia&#322;anie naszych stron i serwis&#243;w&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Dodatkowo Google wypu&#347;ci&#322; narz&#281;dzie &lt;a href="http://code.google.com/speed/page-speed/"&gt;Page Speed&lt;/a&gt;, kt&#243;re jest rozszerzeniem do Firebuga i podobnie jak &lt;a href="http://developer.yahoo.com/yslow/"&gt;YSlow&lt;/a&gt; pomaga zbada&#263; stron&#281; pod k&#261;tem pr&#281;dko&#347;ci &#322;adowania si&#281; poszczeg&#243;lnych komponent&#243;w. Oba te narz&#281;dzia dostarczaj&#261; od razu praktycznych porad i opis&#243;w pomagaj&#261;cych zrozumie&#263; jak zoptymalizowa&#263; stron&#281;. Dla mnie s&#261; to niezb&#281;dne narz&#281;dzia przy pracy z serwisami internetowymi. Do tej pory u&#380;ywa&#322;em g&#322;&#243;wnie YSlow, ale przy nast&#281;pnych optymalizacjach na pewno skorzystam z Page Speed.&lt;/p&gt;


	&lt;p&gt;Je&#380;eli jeszcze nie znacie tych narz&#281;dzi, gor&#261;co polecam zapoznanie si&#281; z nimi.&lt;/p&gt;</description>
      <pubDate>Fri, 26 Jun 2009 21:11:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:bf0c93ec-7da9-47ca-aafb-4723feba7e15</guid>
      <author>Piotr Sarnacki</author>
      <link>http://blog.drogomir.com/articles/2009/06/26/google-chce-przy%C5%9Bpieszy%C4%87-internet</link>
      <category>Javascript</category>
      <category>Programowanie</category>
      <category>optymalizacja</category>
      <category>html</category>
      <category>pagespeed</category>
      <category>yslow</category>
      <trackback:ping>http://blog.drogomir.com/articles/trackback/61</trackback:ping>
    </item>
    <item>
      <title>YUI 3 beta</title>
      <description>&lt;p&gt;We wczorajszym po&#347;cie na blogu &lt;span class="caps"&gt;YUI&lt;/span&gt; &lt;a href="http://www.yuiblog.com/blog/2009/06/24/yui3b1/"&gt;og&#322;oszono wersj&#281; beta &lt;span class="caps"&gt;YUI3&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;&lt;span class="caps"&gt;YUI&lt;/span&gt;&lt;/strong&gt; (Yahoo User Interface) jest frameworkiem javascript rozwijanym przez &lt;span class="caps"&gt;YAHOO&lt;/span&gt;, kt&#243;ry dostarcza nie tylko niskopoziomowe funkcje pomagaj&#261;ce przy pisaniu kodu javascript, ale te&#380; zestaw komponent&#243;w (takich jak r&#243;&#380;nego rodzaju okienka dialog, color picker, czy nawet &lt;a href="http://developer.yahoo.com/yui/editor/"&gt;bardzo dobry edytor &lt;span class="caps"&gt;WYSIWYG&lt;/span&gt;&lt;/a&gt;). &lt;span class="caps"&gt;YUI&lt;/span&gt; jest dojrza&#322;&#261; bibliotek&#261; u&#380;ywan&#261; na stronach &lt;span class="caps"&gt;YAHOO&lt;/span&gt;, co zapewnia bardzo dobr&#261; jako&#347;&#263;. Sam team &lt;span class="caps"&gt;YUI&lt;/span&gt; to jedni z najlepszych specjalist&#243;w od frontendu &amp;#8211; zach&#281;cam do czytania wpis&#243;w na &lt;a href="http://developer.yahoo.com/yui/editor/"&gt;ich blogu&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;To co najbardziej przekonywa&#322;o mnie do u&#380;ywania &lt;span class="caps"&gt;YUI&lt;/span&gt;, to fakt dostarczenia ca&#322;ego zestawu narz&#281;dzi do budowania interfejs&#243;w u&#380;ytkownika w javascripcie. W przypadku np. jQuery lekko mo&#380;e denerwowa&#263; bardzo du&#380;e rozstrzelenie poszczeg&#243;lnych bibliotek. S&#261; oczywi&#347;cie takie projekty jak &lt;a href="http://jqueryui.com/"&gt;jqueryUI&lt;/a&gt;, ale wi&#281;kszo&#347;&#263; plugin&#243;w trzeba &#347;ci&#261;gn&#261;&#263; z innych &#378;r&#243;de&#322;, a ich kod cz&#281;sto pozostawia wiele do &#380;yczenia. W przypadku &lt;span class="caps"&gt;YUI&lt;/span&gt; mamy zwarty zestaw komponent&#243;w, &#322;atwy do rozszerzania i rozwijany przez specjalist&#243;w w celu wykorzystania na stronach odwiedzanych codziennie przez miliony internaut&#243;w.&lt;/p&gt;


	&lt;p&gt;Z drugiej strony to co by&#322;o banalne w jQuery cz&#281;sto by&#322;o ci&#281;&#380;kie do uzyskania w &lt;span class="caps"&gt;YUI&lt;/span&gt;. A jak wszyscy wiedz&#261; je&#380;eli chodzi o zabaw&#281; z &lt;span class="caps"&gt;DOM&lt;/span&gt;, animacjami i ajaxem z jQuery jest ci&#281;&#380;ko wygra&#263;. Dlatego gdy u&#380;ywa&#322;em komponent&#243;w &lt;span class="caps"&gt;YUI&lt;/span&gt; w jednym z projekt&#243;w, w kt&#243;rym przy okazji u&#380;ywa&#322;em jQuery, to do manipulacji element&#243;w &lt;span class="caps"&gt;DOM&lt;/span&gt; u&#380;ywa&#322;em jQuery, a z &lt;span class="caps"&gt;YUI&lt;/span&gt; wybiera&#322;em tylko komponenty.&lt;/p&gt;


	&lt;p&gt;Wersja trzecia &lt;span class="caps"&gt;YUI&lt;/span&gt; mo&#380;e to zmieni&#263;. Zesp&#243;&#322; z Yahoo postanowi&#322; przepisa&#263; bibliotek&#281; zupe&#322;nie od nowa z naciskiem na lekko&#347;&#263; i szybko&#347;&#263;. Najwa&#380;niejsze zmiany&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;zmienione &lt;span class="caps"&gt;API&lt;/span&gt; do manipulacji &lt;span class="caps"&gt;DOM&lt;/span&gt;, czyli &amp;#8220;jQueryzacja&amp;#8221; &amp;#8211; &#322;a&#324;cuchy komend, proste funkcje typu addClass, remove, append itp.&lt;/li&gt;
		&lt;li&gt;u&#322;atwiona praca z eventami&lt;/li&gt;
		&lt;li&gt;modularyzacja biblioteki&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Najbardziej obiecuj&#261;co wygl&#261;da ostatni punkt. Do tej pory poszczeg&#243;lne komponenty nie by&#322;y modularne, co prowadzi&#322;o do powtarzaj&#261;cego si&#281;  kodu w r&#243;&#380;nych komponentach. Dodatkowo je&#380;eli kto&#347; chcia&#322; stworzy&#263; Tooltip dziedzicz&#261;cy po Overlay, to musia&#322; wykorzysta&#263; wszystkie elementy, kt&#243;re Overlay zawiera. Jest to oczywi&#347;cie zb&#281;dne wykorzystywanie pami&#281;ci i &lt;a href="http://developer.yahoo.com/yui/container/tooltip/index.html"&gt;Tooltip, kt&#243;ry jest obecnie dost&#281;pny w &lt;span class="caps"&gt;YUI&lt;/span&gt;&lt;/a&gt; w&#322;a&#347;nie z tego powodu nie jest najlepsz&#261; mo&#380;liw&#261; implementacj&#261;.&lt;/p&gt;


	&lt;p&gt;&lt;span class="caps"&gt;W YUI3&lt;/span&gt; poszczeg&#243;lne funkcjonalno&#347;ci s&#261; rozbite do modu&#322;&#243;w. Dlatego, &#380;eby zbudowa&#263; wspomniany wy&#380;ej tooltip nie trzeba dziedziczy&#263; po Overlay, tylko zmiksowa&#263; (czy to nie brzmi znajomo?) na przyk&#322;ad: modu&#322; pozycjonowania i modu&#322; animacji. Dodatkowo mo&#380;na wmiksowa&#263; poszczeg&#243;lne modu&#322;y nie tylko do klas, ale tak&#380;e instancji poszczeg&#243;lnych obiekt&#243;w. Je&#380;eli b&#281;dzie to rzeczywi&#347;cie dzia&#322;a&#322;o tak fajnie jak m&#243;wi&#261; programi&#347;ci z &lt;span class="caps"&gt;YUI&lt;/span&gt; (polecam obejrze&#263; video ze &lt;a href="http://www.yuiblog.com/blog/2009/06/24/yui3b1/"&gt;zlinkowanego wcze&#347;niej posta&lt;/a&gt;), to &lt;span class="caps"&gt;YUI3&lt;/span&gt; na pewno zago&#347;ci w moich projektach.&lt;/p&gt;


	&lt;p&gt;To co najbardziej denerwuje mnie obecnie w r&#243;&#380;nego rodzaju bibliotekach do jQuery czy prototype, to ca&#322;kowite oderwanie poszczeg&#243;lnych bibliotek od siebie. U&#380;ywam na przyk&#322;ad jqueryUI i &#380;eby u&#380;y&#263; tooltipa, musz&#281; &#347;ci&#261;gn&#261;&#263; zupe&#322;nie inn&#261; bibliotek&#281;, kt&#243;ra jest napisana zupe&#322;nie inaczej i nie dzieli &#380;adnego kodu z innymi bibliotekami (tutaj te&#380; wychodzi swoboda javascriptu, je&#380;eli kto&#347; pr&#243;bowa&#322; por&#243;wnywa&#263; implementacje r&#243;&#380;nych bibliotek, to na pewno wie na ile r&#243;&#380;nych sposob&#243;w mo&#380;na zaimplementowa&#263; te same funkcje). Jeszcze gorzej jest gdy trzeba napisa&#263; w&#322;asne komponenty &amp;#8211; lekko&#347;&#263; jQuery i brak oficjalnych bibliotek pomagaj&#261;cych w takich wypadkach jest do&#347;&#263; du&#380;&#261; przeszkod&#261;.&lt;/p&gt;


	&lt;p&gt;W tym momencie &lt;span class="caps"&gt;YUI&lt;/span&gt; team zach&#281;ca programist&#243;w do u&#380;ywania &lt;span class="caps"&gt;YUI3&lt;/span&gt; w nowych projektach, szczeg&#243;lnie tych, kt&#243;re nie planuj&#261; wykorzystywa&#263; du&#380;ej ilo&#347;ci widget&#243;w obecnych w &lt;span class="caps"&gt;YUI2&lt;/span&gt;. Oficjalna wersja ma by&#263; dost&#281;pna w 3 kwartale tego roku. Rozw&#243;j mo&#380;na biblioteki &#347;ledzi&#263; &lt;a href="http://yuilibrary.com/projects/yui3/roadmap"&gt;tutaj&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Thu, 25 Jun 2009 16:46:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:b3e80028-c073-453e-a9e1-c47d3a9dcb26</guid>
      <author>Piotr Sarnacki</author>
      <link>http://blog.drogomir.com/articles/2009/06/25/yui-3-beta</link>
      <category>Javascript</category>
      <category>jQuery</category>
      <category>javascript</category>
      <category>YUI</category>
      <category>Yahoo</category>
      <category>YUI3</category>
      <trackback:ping>http://blog.drogomir.com/articles/trackback/60</trackback:ping>
    </item>
    <item>
      <title>Co nowego w Rails3?</title>
      <description>&lt;p&gt;Ponad 4 miesi&#261;ce temu &#347;wiatem Ruby&amp;#8217;iego zatrz&#281;s&#322;a wiadomo&#347;&#263; o po&#322;&#261;czeniu si&#281; 2 popularnych framework&#243;w &amp;#8211; Ruby on Rails i Merba. Dzisiaj, tylko kilka dni dzieli nas od ujrzenia &lt;a href="http://en.oreilly.com/rails2009/public/schedule/detail/7785"&gt;pierwszych aplikacji, kt&#243;re b&#281;d&#261; napisane w Rails 3&lt;/a&gt;. Carl Lerche (tw&#243;rca mi&#281;dzy innymi routera do merba) oraz Yehuda Katz na tegorocznym RailsConf b&#281;d&#261; m&#243;wi&#263; o Rails3 i mountable apps.&lt;/p&gt;


	&lt;p&gt;Na stabiln&#261; wersj&#281; b&#281;dzie trzeba jeszcze troch&#281; poczeka&#263;, ale trzymam kciuki, &#380;eby na RailsConf rzeczywi&#347;cie uda&#322;o im si&#281; pokaza&#263; dzia&#322;aj&#261;c&#261; aplikacj&#281;.&lt;/p&gt;


	&lt;p&gt;W tym po&#347;cie chcia&#322;bym kr&#243;tko opisa&#263; to co ma si&#281; znale&#378;&#263; w Rails 3. Z niema&#322;&#261; niecierpliwo&#347;ci&#261; &#347;ledz&#281; newsy i doniesienia o nowych railsach i nie mog&#281; si&#281; ju&#380; doczeka&#263; niekt&#243;rych usprawnie&#324;.&lt;/p&gt;


	&lt;h3&gt;ActionORM (wcze&#347;niej ActiveORM)&lt;/h3&gt;


	&lt;p&gt;Zwolennicy Merba bardzo podkre&#347;laj&#261; w swoim frameworku niezale&#380;no&#347;&#263; od konkretnych technologii. By&#322;o to reklamowane g&#322;&#243;wnie jako &amp;#8220;ORM agnosticism&amp;#8221; czyli mo&#380;liwo&#347;&#263; podpi&#281;cia do Merba jednego z wielu &amp;#8220;ORM&#243;w&amp;#8221; (DataMapper, ActiveRecord, Sequel) w por&#243;wnaniu do Railsowej monolityczno&#347;ci w postaci jednego s&#322;usznego ActiveRecorda.&lt;/p&gt;


	&lt;p&gt;Jaki w&#322;a&#347;ciwie jest problem w u&#380;ywaniu innego ORMa w naszej aplikacji? Na poziomie modeli i kontroler&#243;w nie ma to z regu&#322;y wi&#281;kszego znaczenia. Przecie&#380; Rails&#243;w nie obchodzi czy klasa w katalogu app/models dziedziczy po &lt;code&gt;ActiveRecord::Base&lt;/code&gt;, czy do&#322;&#261;cza modu&#322;: &lt;code&gt;include DataMapper::Resource&lt;/code&gt;&lt;/p&gt;


	&lt;p&gt;K&#322;opot zaczyna si&#281; kiedy chce si&#281; korzysta&#263; z wielu helper&#243;w, kt&#243;re jako argument przyjmuj&#261; obiekt ActiveRecord. Najprostszy przyk&#322;ad:&lt;/p&gt;


&lt;pre class="brush: ruby"&gt;
&amp;lt;% form_for @article do |f| %&amp;gt;
  &amp;lt;%= f.text_field :title %&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/pre&gt;

	&lt;p&gt;Je&#380;eli &lt;code&gt;@article&lt;/code&gt; nie jest obiektem AR, to poprawno&#347;&#263; dzia&#322;ania tej metody zale&#380;y tylko od tego czy interfejs danego ORMa tutaj u&#380;ywany jest taki sam. W tym akurat przypadku problemem mo&#380;e by&#263; sprawdzanie b&#322;&#281;d&#243;w w walidacji. Railsy domy&#347;lnie dodaj&#261; wrapper do p&#243;l z b&#322;&#281;dami, wi&#281;c je&#380;eli &lt;span class="caps"&gt;ORM&lt;/span&gt; ma inny interfejs do pobrania informacji o b&#322;&#281;dach, to metoda po prostu nie zadzia&#322;a.&lt;/p&gt;


	&lt;p&gt;W tym momencie jest to w Railsach zrobione &lt;a href="http://github.com/rails/rails/blob/17e712d3a3d3934bb1f694d449d9a76a3ac715c1/actionpack/lib/action_view/helpers/active_record_helper.rb#L247"&gt;z u&#380;yciem alias_method_chain&lt;/a&gt; i je&#380;eli obiekt nie ma zaimplementowanej metody errors, to tag pozostaje niezmieniony, wi&#281;c mo&#380;na samemu do&#322;&#261;czy&#263; swoj&#261; w&#322;asn&#261; implementacj&#281; lub doda&#263; potrzebne metody do modelu. Jednak wszyscy chyba si&#281; zgodz&#261;, &#380;e nie jest to najbardziej elegancki spos&#243;b.&lt;/p&gt;


	&lt;p&gt;Je&#380;eli chodzi o Merba, to sprawa wygl&#261;da tylko troch&#281; lepiej ni&#380; w railsach. Jest co prawda wsparcie dla 3 najpopularniejszych &lt;span class="caps"&gt;ORM&lt;/span&gt;&#243;w, ale implementacja nie pozwala na &#322;atwe dodanie kolejnych &lt;span class="caps"&gt;ORM&lt;/span&gt;&#243;w bez grzebania w kodzie. Je&#380;eli &lt;span class="caps"&gt;ORM&lt;/span&gt;, kt&#243;rego chcesz u&#380;ywa&#263; ma interfejs zgodny z DataMapperem, Sequelem lub ActiveRecordem, to wszystko jest ok, ale je&#380;eli jest to co&#347; innego, to masz problem.&lt;/p&gt;


	&lt;p&gt;Odpowiedzi&#261; na to ma by&#263; ActionORM. Czym jest ActionORM? Jest to proste proxy dla obiekt&#243;w. ActionORM udost&#281;pnia &lt;span class="caps"&gt;API&lt;/span&gt; takie jak ActiveRecord (dzi&#281;ki temu w kodzie rails&#243;w nie b&#281;dzie trzeba wiele zmienia&#263;). W prostych s&#322;owach ActionORM ma sprawi&#263;, &#380;e obiekty innych &lt;span class="caps"&gt;ORM&lt;/span&gt;&#243;w b&#281;d&#261; wygl&#261;da&#322;y jak obiekty ActiveRecord (czyli klasyczne wykorzystanie &lt;a href="http://en.wikipedia.org/wiki/Duck_typing"&gt;duck typing&lt;/a&gt;)&lt;/p&gt;


	&lt;p&gt;Tutaj jest przyk&#322;ad proxy dla Datamappera: &lt;a href="http://github.com/lancecarlson/rails/blob/0faae5b971c3dbf3b1c4ead19504580233bbc7fa/activeorm/lib/active_orm/proxies/datamapper_proxy.rb"&gt;http://github.com/lancecarlson/rails/blob/0faae5b971c3dbf3b1c4ead19504580233bbc7fa/activeorm/lib/active_orm/proxies/datamapper_proxy.rb&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;R&#243;&#380;nice s&#261; jak wida&#263; niewielkie, ale podejrzewam, &#380;e b&#281;dzie mo&#380;na doda&#263; wi&#281;cej metod, kt&#243;re si&#281; r&#243;&#380;ni&#261; pomi&#281;dzy implementacjami (oczywi&#347;cie w granicach rozs&#261;dku, sprowadzanie ca&#322;ego interfejsu do jednego przypadku by&#322;o by pozbawione sensu, chodzi o proste operacje, kt&#243;re ka&#380;dy &lt;span class="caps"&gt;ORM&lt;/span&gt; ma rozwi&#261;zane podobnie, ale r&#243;&#380;ni si&#281; &lt;span class="caps"&gt;API&lt;/span&gt;).&lt;/p&gt;


	&lt;h3&gt;Rack Middleware&lt;/h3&gt;


	&lt;p&gt;Railsy od jakiego&#347; czasu wykorzystuj&#261; w pe&#322;ni dobrodziejstwa &lt;a href="http://radarek.jogger.pl/2008/06/27/rack-niech-aplikacje-przemowia-wspolnym-jezykiem/"&gt;Rack&lt;/a&gt;. Co wi&#281;cej, r&#243;&#380;ne cz&#281;&#347;ci frameworka s&#261; zaimplementowane jako rack middlewares. Kontroler, router, obs&#322;uga sesji i wiele innych rzeczy to teraz po prostu kolejne middlewares (przepraszam za te angloj&#281;zyczne wstawki, ale naprawd&#281; nie mam poj&#281;cia jak to &#322;adnie przet&#322;umaczy&#263;). Dzi&#281;ki temu i dodaniu &lt;a href="http://weblog.rubyonrails.org/2008/12/17/introducing-rails-metal"&gt;Rails metal&lt;/a&gt; aplikacje s&#261; coraz bardziej modularne.&lt;/p&gt;


	&lt;p&gt;Programi&#347;ci rails&#243;w d&#261;&#380;&#261; w tej chwili do jeszcze szerszego wykorzystania racka. Wszystko to idzie w stron&#281; jak naj&#322;atwiejszego po&#322;&#261;czenia komponent&#243;w r&#243;&#380;nego typu. Na przyk&#322;ad mo&#380;liwo&#347;&#263; pod&#322;&#261;czenia do routera kontroler&#243;w railsowych, aplikacji sintatry i aplikacji merba (jako jedn&#261; aplikacj&#281; oczywi&#347;cie).&lt;/p&gt;


	&lt;h3&gt;Optymalizacja i refaktoryzacja&lt;/h3&gt;


	&lt;p&gt;Najwi&#281;ksz&#261; i najlepsz&#261; wed&#322;ug mnie zmian&#261; w railsach jest refaktoryzacja kodu ActionPack. Na czym ona polega? W bardzo prostych s&#322;owach: stworzony jest AbstractController, z kt&#243;rego dziedziczy&#263; b&#281;d&#261; inne kontrolery, a w samym kodzie jest zastosowana du&#380;o wi&#281;ksza enkapsulacja. Jakie to ma znaczenie dla u&#380;ytkownik&#243;w rails&#243;w? B&#281;dzie istnia&#322; jeden interfejs dla wszystkich kontroler&#243;w, dzi&#281;ki czemu na przyk&#322;ad ActionController i ActionMailer b&#281;d&#261; mog&#322;y wsp&#243;&#322;dzieli&#263; funkcjonalno&#347;&#263; (&#380;eby nie i&#347;&#263; daleko, dopiero niedawno do mailera dodana zosta&#322;a obs&#322;uga layout&#243;w). Bardzo &#322;atwe b&#281;dzie te&#380; dodanie Parts znanych z merba (PartsController r&#243;wnie&#380; dziedziczy w Merbie z AbstractControllera).&lt;/p&gt;


	&lt;p&gt;W chwili obecnej podobn&#261; funkcjonalno&#347;&#263; do Merb Parts udost&#281;pniaj&#261; &lt;a href="http://cells.rubyforge.org/"&gt;Rails Cells&lt;/a&gt;, ale nie jest to rozwi&#261;zanie idealne (implementacja jest zagmatwana, w cellach widoczne s&#261; zmienne instancji z kontroler&#243;w i innych celli, podejrzewam, &#380;e jest to wolniejsze ni&#380; parts).&lt;/p&gt;


	&lt;p&gt;Co jeszcze? Yehuda Katz wzi&#261;&#322; si&#281; mi&#281;dzy innymi za &lt;a href="http://yehudakatz.com/2009/01/16/status-update-a-fresh-look-at-callbacks/"&gt;optymalizacj&#281; callback&#243;w&lt;/a&gt;, czy bloku respond_to. Polecam r&#243;wnie&#380; inne artyku&#322;y na temat refaktoryzacji na jego blogu.&lt;/p&gt;


	&lt;p&gt;Na pewno szybszy b&#281;dzie te&#380; router. W chwili obecnej najwi&#281;kszym problemem jest to, &#380;e router generuje bardzo du&#380;o metod (wszystkie metody _url i _path), co w rezultacie przyczynia si&#281; do bardzo wolnego startu aplikacji. W czasach mongreli nie mia&#322;o to du&#380;ego znaczenia, bo aplikacje by&#322;y odpalane raz i tylko sporadycznie restartowane. Teraz kiedy na wielu serwerach zainstalowany jest mod_passenger, czas startu aplikacji jest du&#380;o wa&#380;niejszy &amp;#8211; instancje, kt&#243;re nie dostaj&#261; request&#243;w przez 5 minut (domy&#347;lne ustawienie) s&#261; wy&#322;&#261;czane dzi&#281;ki czemu nie zajmuj&#261; zasob&#243;w.&lt;/p&gt;


	&lt;p&gt;Nowy router mo&#380;na przetestowa&#263; ju&#380; teraz. Po wi&#281;cej odsy&#322;am na &lt;a href="http://merbist.com/2009/04/14/merb-11-delayed/"&gt;the merbist&lt;/a&gt;&lt;/p&gt;


	&lt;h3&gt;Mountable apps&lt;/h3&gt;


	&lt;p&gt;Jest to jedna z tych rzeczy, na kt&#243;re czekam w Railsach 3 najbardziej. Dos&#322;ownie licz&#281; godziny do rails conf i prezentacji na ich temat (mam nadziej&#281;, &#380;e b&#281;d&#261; nagrywane, bo niestety nie mia&#322;em wolnych kilku tysi&#281;cy z&#322;otych, &#380;eby si&#281; pojawi&#263; osobi&#347;cie na konferencji ;-).&lt;/p&gt;


	&lt;p&gt;Jakie&#347; namiastki mountable apps s&#261; ju&#380; dost&#281;pne w postaci Rails Engines i Merb Slices. Jest to jakie&#347; rozwi&#261;zanie, ale na pewno dalekie od idealnego. &#379;eby skorzysta&#263; z kt&#243;rej&#347; z tych opcji trzeba napisa&#263; specyficzny rodzaj aplikacji, a ka&#380;de z tych rozwi&#261;za&#324; jest w niekt&#243;rych miejscach niedopracowane. Celem mountable apps b&#281;dzie mo&#380;liwo&#347;&#263; &#322;atwego po&#322;&#261;czenia 2 aplikacji bez &#380;adnych zmian w kodzie.&lt;/p&gt;


	&lt;h3&gt;&lt;span class="caps"&gt;API&lt;/span&gt; dla plugin&#243;w&lt;/h3&gt;


	&lt;p&gt;Jedn&#261; z rzeczy, kt&#243;r&#261; wypromowa&#322; Merb jest publiczne i prywatne &lt;abbr title="Application Programming Interface"&gt;api&lt;/abbr&gt;. Dzi&#281;ki temu pisanie plugin&#243;w nie wi&#261;&#380;e si&#281; tam z u&#380;ywaniem alias_method_chain i og&#243;lnie poj&#281;tym monkey patchingiem na ka&#380;dym kroku. A je&#380;eli czego&#347; nie da si&#281; zrobi&#263; u&#380;ywaj&#261;c tylko publicznego api, to jest to bug. Jest to chyba jedna z trudniejszych rzeczy w ca&#322;ej refaktoryzacji. Nie wiadomo dok&#322;adnie czego b&#281;d&#261; potrzebowa&#263; tw&#243;rcy plugin&#243;w, niekt&#243;re metody trzeba b&#281;dzie dopiero stworzy&#263;.&lt;/p&gt;


	&lt;p&gt;Ogromnym plusem takiego podej&#347;cia jest to, &#380;e tw&#243;rcy frameworka nie musz&#261; si&#281; martwi&#263; o prywatne metody, wa&#380;ne &#380;eby publiczne &lt;span class="caps"&gt;API&lt;/span&gt; si&#281; nie zmienia&#322;o. Dzi&#281;ki temu pluginy napisane zgodnie z wytycznymi, czyli nie u&#380;ywaj&#261;c prywatnego &lt;span class="caps"&gt;API&lt;/span&gt; nie b&#281;d&#261; si&#281; wysypywa&#322;y na ka&#380;dej kolejnej wersji (co bardzo cz&#281;sto mo&#380;na zaobserwowa&#263; w tym momencie), a je&#380;eli co&#347; si&#281; zmieni w publicznym &lt;span class="caps"&gt;API&lt;/span&gt; przy okazji wi&#281;kszych zmian, to tw&#243;rcy plugin&#243;w b&#281;d&#261; mogli si&#281; o tym &#322;atwo dowiedzie&#263; bez &#347;ledzenia commit&#243;w na githubie.&lt;/p&gt;


	&lt;h3&gt;Podsumowanie&lt;/h3&gt;


	&lt;p&gt;Jestem zdania, &#380;e po&#322;&#261;czenie merba i rails&#243;w to jedna z najlepszych rzeczy, kt&#243;ra mog&#322;a si&#281; przytrafi&#263; programistom webowym. Railsy b&#281;d&#261; szybsze, bardziej modularne i &#322;atwiejsze w rozszerzaniu. Tylko czeka&#263; na wyniki refaktoryzacji :)&lt;/p&gt;


	&lt;p&gt;Postaram si&#281; w najbli&#380;szych tygodniach pisa&#263; o tym co dzieje si&#281; z Railsami3, jak id&#261; prace i co jeszcze ciekawego b&#281;dzie mo&#380;na zobaczy&#263;.&lt;/p&gt;</description>
      <pubDate>Sun, 03 May 2009 20:10:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:2f0ea69a-8dda-49a1-b302-d5249e52dfdc</guid>
      <author>Piotr Sarnacki</author>
      <link>http://blog.drogomir.com/articles/2009/05/03/co-nowego-w-rails3</link>
      <category>Ruby on Rails</category>
      <category>rails</category>
      <category>rubyonrails</category>
      <category>ruby</category>
      <category>refaktoryzacja</category>
      <category>rails3</category>
      <category>merb</category>
      <trackback:ping>http://blog.drogomir.com/articles/trackback/59</trackback:ping>
    </item>
    <item>
      <title>Git - co zrobi&#263; gdy si&#281; scommituje za du&#380;o zmian?</title>
      <description>&lt;p&gt;&lt;ins&gt;Jak zauwa&#380;y&#322; s&#322;usznie Radarek w komentarzu taki sam efekt mo&#380;na uzyska&#263; poleceniem &lt;code&gt;git reset --mixed HEAD~1&lt;/code&gt;. W tym wypadku mo&#380;na by tre&#347;&#263; ca&#322;ego posta wyrzuci&#263; do kosza, ale zostawi&#281; dla potomnych, &#380;eby mo&#380;na by&#322;o zobaczy&#263; jak trzeba si&#281; nagimnastykowa&#263; je&#380;eli si&#281; nie zajrzy do dokumentacji ;-)&lt;/ins&gt;&lt;/p&gt;


	&lt;p&gt;Czasami podczas pracy nad jakimi&#347; wi&#281;kszymi zmianami warto rozbi&#263; prac&#281; na mniejsze commity. Zdarza mi si&#281; czasami doda&#263; prze&#322;&#261;cznik -a z rozp&#281;du, kt&#243;ry commituje wszystkie zmiany. Najgorzej jest gdy wrzucam przy okazji now&#261; wersj&#281; jakiego&#347; plugina do rails&#243;w. W takim wypadku zmiany w aplikacji s&#261; przeplatane zmianami w pluginie. P&#243;&#378;niej gdy trzeba spojrze&#263; na co&#347; w logach gita, mo&#380;e to do&#347;&#263; znacznie utrudni&#263; prac&#281;.&lt;/p&gt;


	&lt;p&gt;Na szcz&#281;&#347;cie git jest bardzo elastyczny i &#322;atwo jest takie co&#347; odwr&#243;ci&#263;.&lt;/p&gt;


	&lt;p&gt;Wyobra&#378;my sobie tak&#261; sytuacj&#281;:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
  # przechodz&#281; do nowej ga&#322;&#281;zi, &#380;eby zaimplementowa&#263; nowy feature
  git checkout -b feature_200

  #....
  # tutaj du&#380;o zmian, mi&#281;dzy innymi dodanie 
  # nowego pluginu, uaktualnienie innego, 
  # zmiany w samym kodzie itp. itd.

  # a teraz chcemy scommitowa&#263; tylko zmiany w 
  # danym pluginie:
  git add vendor/plugins/acts_as_foobar
  git commit -m "Nowa wersja acts_as_foobar kompatybilna z railsami 2.3" -a
  # oj... doda&#322;em -a, scommitowa&#322;y si&#281; te&#380; 
  # zmiany w kodzie
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Co teraz? Nic trudnego :)&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
  # tworzymy patche wzgl&#281;dem mastera
  git format-patch master
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;W tym momencie powinno pojawi&#263; si&#281; sporo plik&#243;w o nazwach na przyk&#322;ad:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
0001-Nowa-wersja-acts_as_foobar-kompatybilna-zrailsami-2.3.patch
#... ewentualnie wi&#281;cej
&lt;/pre&gt;&lt;/code&gt;

Teraz trzeba wyrzuci&#263; &amp;#8220;zepsuty&amp;#8221; commit:
&lt;pre&gt;&lt;code&gt;
  git rebase -i HEAD~3
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Teraz powinien otworzy&#263; si&#281; edytor, w kt&#243;rym widniej&#261; linijki zaczynaj&#261;ce si&#281; od s&#322;owa pick. Kasujemy linijk&#281; z niechcianym commitem (tutaj uwaga &amp;#8211; je&#380;eli nie jeste&#347;cie pewni, &#380;e wszystko gra, to najlepiej zrobi&#263; backup repo, po takim zabiegu commit po prostu zniknie). Po zapisaniu zmian commit powinien zosta&#263; wyrzucony z drzewka i mo&#380;na zaaplikowa&#263; wcze&#347;niej stworzonego patcha:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
git apply 0001-Nowa-wersja-acts_as_foobar-kompatybilna-zrailsami-2.3.patch
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;W tym momencie wszystko powinno wygl&#261;da&#263; tak jak przed commitem &amp;#8211; mo&#380;na teraz poprawi&#263; sw&#243;j b&#322;&#261;d.&lt;/p&gt;


	&lt;p&gt;Wiem, &#380;e to mo&#380;e si&#281; wydawa&#263; skomplikowane (szczeg&#243;lnie rebase), ale w praktyce zajmuje kr&#243;tk&#261; chwil&#281;, a dzi&#281;ki takiemu zabiegowi nie ma ba&#322;aganu w repozytorium.&lt;/p&gt;


	&lt;p&gt;A mo&#380;e Wy macie jakie&#347; ciekawe metody na rozwi&#261;zywanie problem&#243;w z gitem? Mo&#380;e inny spos&#243;b na powy&#380;szy problem?&lt;/p&gt;</description>
      <pubDate>Tue, 07 Apr 2009 11:40:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:22fc6e08-8dbd-4299-838c-3bd58c09c67e</guid>
      <author>Piotr Sarnacki</author>
      <link>http://blog.drogomir.com/articles/2009/04/07/git-co-zrobi%C4%87-gdy-si%C4%99-scommituje-za-du%C5%BCo-zmian</link>
      <category>Programowanie</category>
      <category>git</category>
      <category>rebase</category>
      <category>patch</category>
      <trackback:ping>http://blog.drogomir.com/articles/trackback/58</trackback:ping>
    </item>
    <item>
      <title>Refaktoryzacja Rails&#243;w</title>
      <description>&lt;p&gt;Niestety nie b&#281;dzie to wpis o tym jak refaktoryzowa&#263; swoj&#261; aplikacj&#281;, ale raczej post o refaktoryzacji samego frameworka w ramach przygotowa&#324; do Rails 3.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://railsenvy.com/2008/12/31/rails-envy-podcast-episode-061-12-31-2008"&gt;Railsy po&#380;ar&#322;y m&#243;zg Merba i posi&#261;d&#261; jego tajemne moce&lt;/a&gt; (zach&#281;cam do wys&#322;uchania tego podcastu, ch&#322;opaki od railsenvy genialnie m&#243;wi&#261; o tym co si&#281; dzieje w &#347;wiecie rails&#243;w) &amp;#8211; o tym ju&#380; &lt;a href="http://nhw.pl/pl/2008/12/rails-i-merb-w-jednym-staly-domu"&gt;ka&#380;dy na pewno wie&lt;/a&gt;. Czy to dobrze? Oczywi&#347;cie, &#380;e tak :)&lt;/p&gt;


	&lt;p&gt;Je&#380;eli kto&#347; dalej ma problemy z t&#261; decyzj&#261; (podejrzewam, &#380;e mo&#380;e tak by&#263; w wypadku fan&#243;w merba), polecam prezentacj&#261; &lt;a href="http://railsconfeurope.blip.tv/file/1555560/"&gt;Living with legacy software&lt;/a&gt; wyg&#322;oszon&#261; przez Davida Heinemeiera Hanssona &amp;#8211; nie jest w &#380;aden spos&#243;b bezpo&#347;rednio zwi&#261;zana z po&#322;&#261;czeniem, ale zmienia podej&#347;cie do aplikacji i ich kodu.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://www.youtube.com/watch?v=UwI307EC63c&amp;#38;feature=related"&gt;Ale nie o to, nie o to, nie o to&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://yehudakatz.com/"&gt;Yehuda Katz&lt;/a&gt; ostro wzi&#261;&#322; si&#281; do pracy jeszcze podczas &#347;wi&#261;t i co jaki&#347; czas wrzuca na bloga informacje o tym jak refaktoryzuje i jakie ma plany wobec Rails&#243;w. Informacje traktuj&#261;ce o projektowaniu, refaktoryzacji i architekturze ci&#281;&#380;ko jest znale&#378;&#263; w sieci, wi&#281;c gor&#261;co polecam &#347;ledzenie tego co pisze Yehuda &amp;#8211; do tej pory mo&#380;na przeczyta&#263; mi&#281;dzy innymi o enkapsulacji ActionView i ActionController czy o optymalizacji respond_to. Dodajcie sobie tego bloga do czytnika, naprawd&#281; warto.&lt;/p&gt;


	&lt;p&gt;Co najlepsze, wiele z tych zmian dotyka tylko wewn&#281;trznej implementacji rails&#243;w, wi&#281;c mo&#380;na liczy&#263;, &#380;e b&#281;d&#261; one dost&#281;pne dla ruby on rails 2.3.0.&lt;/p&gt;</description>
      <pubDate>Sat, 03 Jan 2009 21:45:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:d00a3c7e-d91a-4748-882a-02f5cd701d78</guid>
      <author>Piotr Sarnacki</author>
      <link>http://blog.drogomir.com/articles/2009/01/03/refaktoryzacja-rails%C3%B3w</link>
      <category>Ruby on Rails</category>
      <category>Programowanie</category>
      <category>rails</category>
      <category>rubyonrails</category>
      <category>refaktoryzacja</category>
      <category>rails3</category>
      <category>merb</category>
      <category>yehudakatz</category>
      <category>katz</category>
      <trackback:ping>http://blog.drogomir.com/articles/trackback/57</trackback:ping>
    </item>
    <item>
      <title>To self or not to self?</title>
      <description>&lt;p&gt;Czasami przegl&#261;daj&#261;c kod r&#243;&#380;nych aplikacji mo&#380;na zauwa&#380;y&#263; kawa&#322;ki wygl&#261;daj&#261;ce mniej wi&#281;cej tak:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
  attr_accessor :price

  def total_price
    p = items.inject(0) {|sum, item| sum + item.price }
    # wi&#281;cej kodu
    p
  end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;W prawdziwej aplikacji mo&#380;na to zobaczy&#263; &lt;a href="http://github.com/schof/spree/tree/master/app/models/order.rb#L100"&gt;na przyk&#322;ad w Spree&lt;/a&gt; (u&#380;ycie tot zamiast total)&lt;/p&gt;


	&lt;p&gt;p oznacza tutaj zapewne price, ale autor kodu intuicyjnie stwierdzi&#322;, &#380;e pisz&#261;c &amp;#8220;price =&amp;#8221;, zamiast stworzenia nowej zmiennej przypisze warto&#347;&#263; na atrybut price.&lt;/p&gt;


	&lt;p&gt;Rzeczywi&#347;cie jest to intuicyjne i ca&#322;kiem bezpieczne, ale zupe&#322;nie niepotrzebne. Spokojnie i bez &#380;adnego problemu mo&#380;na u&#380;y&#263; price. Dlaczego?&lt;/p&gt;


	&lt;p&gt;W rubim mo&#380;na opu&#347;ci&#263; s&#322;owo self je&#380;eli chodzi o odczytanie warto&#347;ci metody. Je&#380;eli wi&#281;c bez zadeklarowania zmiennej price kto&#347; napisa&#322;by puts(price), to ruby zinterpretowa&#322;by to jako ch&#281;&#263; wy&#347;wietlenia self.price. Inaczej jest z zapisywaniem. Je&#380;eli wywo&#322;ana jest metoda price=, to ruby stworzy now&#261; zmienn&#261;.&lt;/p&gt;


Na przyk&#322;ad taki kod:
&lt;pre&gt;&lt;code&gt;
  class Product
    attr_accessor :price

    def initialize(price)
      self.price = price
    end

    def do_something_with_price
      price = 10
      puts price
      puts self.price
    end
  end

  p = Product.new(20)
  p.do_something_with_price
&lt;/code&gt;&lt;/pre&gt;

Wypisze:
&lt;pre&gt;&lt;code&gt;
10
20
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Na koniec napisz&#281; tylko, &#380;e mam mieszane uczucia co do korzystania z tych w&#322;a&#347;ciwo&#347;ci j&#281;zyka. Z jednej strony nie lubi&#281; jak w kodzie pa&#322;&#281;taj&#261; si&#281; skr&#243;towe nazwy zmiennych, ale z drugiej strony taki zapis pokazuje, &#380;e chodzi nam o co&#347; innego ni&#380; self.costam.&lt;/p&gt;


	&lt;p&gt;Ja z regu&#322;y staram si&#281; nie skraca&#263; nazw w takich wypadkach. Jakie jest wasze zdanie?&lt;/p&gt;</description>
      <pubDate>Sat, 15 Nov 2008 19:12:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:27a6da68-e7ae-4c93-8818-7e3e9ebb3dec</guid>
      <author>Piotr Sarnacki</author>
      <link>http://blog.drogomir.com/articles/2008/11/15/to-self-or-not-to-self</link>
      <category>Programowanie</category>
      <category>ruby</category>
      <category>self</category>
      <trackback:ping>http://blog.drogomir.com/articles/trackback/56</trackback:ping>
    </item>
    <item>
      <title>Jak u&#380;y&#263; jQuery na stronie bez jQuery?</title>
      <description>&lt;p&gt;Czasami gdy chodz&#281; po sieci chcia&#322;bym mie&#263; mo&#380;liwo&#347;&#263; wykonania jakiego&#347; kodu na stronie, na kt&#243;rej aktualnie si&#281; znajduj&#281;. Do tego wystarczy konsola javascript w firebugu. Niestety mo&#380;na wtedy u&#380;ywa&#263; jedynie bibliotek, kt&#243;re s&#261; do&#322;&#261;czone do strony. Co je&#380;eli nie ma tam jakiego&#347; prototype&amp;#8217;a czy innego jquery? Najcz&#281;&#347;ciej potrzebne mi s&#261; selectory i traversing &amp;#8211; ostatnio na przyk&#322;ad chcia&#322;em na szybko policzy&#263; jakie&#347; dane na podstawie sporej tabeli na stronie internetowej. I co wtedy? Bawi&#263; si&#281; w getElementById i inne tego typu historie? Niefajne to, szczeg&#243;lnie je&#380;eli strona to jedna wielka tabelka bez prawie &#380;adnych id, klas czy innych element&#243;w pomocnych w wybraniu upragnionego kawa&#322;ka.&lt;/p&gt;


	&lt;p&gt;Troch&#281; ponad rok temu z kilkoma lud&#378;mi pisa&#322;em startupa (po 2-3 miesi&#261;cach wszystko si&#281; rozpad&#322;o, ale by&#322;o ciekawie), w kt&#243;rym du&#380;y nacisk by&#322; na dostarczenie prostych narz&#281;dzi (co&#347; w rodzaju ma&#322;ego toolbara) do dowolnej strony internetowej. Oczywi&#347;cie nie mo&#380;na zmusi&#263; w&#322;a&#347;cicieli stron do wklejenia czegokolwiek na swoj&#261; stron&#281;, ale mo&#380;na u&#380;y&#263; zak&#322;adek przegl&#261;darki, &#380;eby co&#347; takiego udost&#281;pni&#263;.&lt;/p&gt;


	&lt;p&gt;Przegl&#261;darki mog&#261; obs&#322;ugiwa&#263; adresy w postaci &amp;#8220;javascript: alert(&amp;#8216;Why are you so serious?&amp;#8217;);&amp;#8221;. Wystarczy wklei&#263; co&#347; takiego w pasku adresu &amp;#8211; oczywi&#347;cie wyskoczy alert. A skoro u&#380;ytkownik mo&#380;e doda&#263; zak&#322;adk&#281; do dowolnego adresu, to adres tej postaci te&#380; przejdzie.&lt;/p&gt;


	&lt;p&gt;Ca&#322;y myk polega&#322; wi&#281;c na tym, &#380;eby w kodzie javascript, kt&#243;ry by&#322; dodawany do zak&#322;adek do&#322;&#261;czy&#263; jak&#261;&#347; bibliotek&#281; (wtedy akurat u&#380;ywa&#322;em jQuery) i sam&#261; aplikacj&#281;, kt&#243;ra wy&#347;wietla&#322;a toolbar z r&#243;&#380;nymi opcjami.&lt;/p&gt;


	&lt;p&gt;U&#380;ywaj&#261;c tej techniki mo&#380;na zrobi&#263; ca&#322;kiem fajne rzeczy, ale w tym momencie ogranicz&#281; si&#281; do pokazania jak za&#322;&#261;czy&#263; sam&#261; bibliotek&#281; jQuery.&lt;/p&gt;


Kod wygl&#261;da mniej wi&#281;cej tak:
&lt;pre&gt;&lt;code&gt;
(function( {
  var s = document.createElement('script');
  s.src="http://drogomir.com/jquery.js";
  document.body.appendChild(s);
})()
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Mo&#380;na jeszcze dodatkowo zrobi&#263; drugi skrypt, kt&#243;ry do&#322;&#261;czymy po jQuery, a w nim doda&#263; na przyk&#322;ad jQuery.noConflict, albo jaki&#347; inny kod wykonany po za&#322;&#261;czeniu jQuery.&lt;/p&gt;


	&lt;p&gt;Dodajcie do zak&#322;adek &lt;a href="javascript:(function()%20{%20var%20s%20=%20document.createElement('script');%20s.src='http://drogomir.com/jquery.js';%20document.body.appendChild(s);%20})()"&gt;tego linka&lt;/a&gt; i po wybraniu go na jakiekolwiek stronie jQuery zostanie dodane do skrypt&#243;w na stronie.&lt;/p&gt;


	&lt;p&gt;Mam nadziej&#281;, &#380;e komu&#347; si&#281; przyda. Pr&#243;bowa&#322;em znale&#378;&#263; kod, o kt&#243;rym pisa&#322;em powy&#380;ej, kt&#243;ry wy&#347;wietla&#322; warstw&#281; z toolboxem, z r&#243;&#380;nymi fajnymi opcjami, ale cholera chyba znikn&#261;&#322; w pomroce dziej&#243;w. B&#281;d&#281; musia&#322; bardziej dba&#263; o kod starych projekt&#243;w, fajnie by&#322;oby si&#281; teraz przyjrze&#263; pracy sprzed roku ;-)&lt;/p&gt;</description>
      <pubDate>Thu, 06 Nov 2008 23:07:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:3df02ffa-7d99-431f-95c1-2041b1a0bd84</guid>
      <author>Piotr Sarnacki</author>
      <link>http://blog.drogomir.com/articles/2008/11/06/jak-u%C5%BCy%C4%87-jquery-na-stronie-bez-jquery</link>
      <category>Javascript</category>
      <category>javascript</category>
      <trackback:ping>http://blog.drogomir.com/articles/trackback/55</trackback:ping>
    </item>
    <item>
      <title>Named scope</title>
      <description>&lt;p&gt;W railsach od jakiego&#347; czasu mo&#380;na u&#380;ywa&#263; &lt;a href="http://ar.rubyonrails.com/classes/ActiveRecord/NamedScope/ClassMethods.html"&gt;named_scope&lt;/a&gt;. Jest to bardzo fajny mechanizm umo&#380;liwiaj&#261;cy &#322;atwiejsze skonstruowanie zapytania u&#380;ywaj&#261;c wcze&#347;niej zdefiniowanych metod. Wcze&#347;niej by&#322; dost&#281;pny jako plugin has_finder.&lt;/p&gt;


Wygl&#261;da to mniej wi&#281;cej tak:
&lt;pre&gt;&lt;code class="ruby"&gt;
  named_scope :active, :conditions =&amp;gt; { :active =&amp;gt; true }
  named_scope :paid, :conditions =&amp;gt; { :paid =&amp;gt; true }
  named_scope :recent, lambda { { :conditions =&amp;gt; ['created_at &amp;gt;= ?', 1.week.ago] } }

&lt;/code&gt;&lt;/pre&gt;

Po zdefiniowaniu takich sope&amp;#8217;&#243;w (macie pomys&#322; jak to spolszczy&#263;?) mo&#380;na ich u&#380;ywa&#263; w ten spos&#243;b (zak&#322;adam, &#380;e scope&amp;#8217;y zosta&#322;y zadeklarowane w modelu Product):
&lt;pre&gt;&lt;code class="ruby"&gt;
  Product.active.paid.recent
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Jak mo&#380;na &#322;atwo zauwa&#380;y&#263;, scope&amp;#8217;y mo&#380;na &#322;&#261;czy&#263; w &#322;a&#324;cuchy. Dzi&#281;ki takiej konstrukcji otrzymujemy prosty i tre&#347;ciwy kod, kt&#243;ry &#322;atwo zrozumie&#263;. Teraz co&#347; lekko trudniejszego:&lt;/p&gt;


&lt;pre&gt;&lt;code class="ruby"&gt;
  named_scope :in_category, lambda { |category| { :conditions =&amp;gt; { :category_id =&amp;gt; category } } }

  # i u&#380;ycie
  Product.active.recent.in_category(category)
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;O co chodzi? Jako 2 argument mo&#380;na przekaza&#263; lambd&#281;, kt&#243;ra zostanie wywo&#322;ana przy u&#380;yciu scope&amp;#8217;a i powinna zwr&#243;ci&#263; Hash.&lt;/p&gt;


	&lt;p&gt;Ale to nie s&#261; jedyne zastosowania scope&amp;#8217;&#243;w. Mo&#380;na do nich przekaza&#263; te&#380; inne parametry, kt&#243;re mo&#380;e przyj&#261;&#263; metoda find.&lt;/p&gt;


Na przyk&#322;ad order, offset i limit:
&lt;pre&gt;&lt;code class="ruby"&gt;
  named_scope :order, lambda { |*args| { :order =&amp;gt; args.first || "created_at DESC" } } 
  named_scope :offset lambda { |offset| { :offset =&amp;gt; offset } } 
  named_scope :limit, lambda { |*args| { :limit =&amp;gt; args.first || 10 } } 

  # i u&#380;ycie:
  Product.active.order("id DESC").offset(10).limit
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;W pierwszym i trzecim scope&amp;#8217;ie zastosowa&#322;em trick, kt&#243;ry pozwala na u&#380;ycie zdefiniowanej warto&#347;ci domy&#347;lnej w razie gdy &#380;adna nie zostanie podana. `*args` pakuje argumenty do tablicy. Je&#380;eli args.first zwr&#243;ci nil, to znaczy, &#380;e tablica jest pusta, czyli nie zosta&#322;y podane &#380;adne argumenty i trzeba zaaplikowa&#263; warto&#347;&#263; domy&#347;ln&#261;.&lt;/p&gt;


	&lt;p&gt;Co&#347; jeszcze? Fajnie by by&#322;o, &#380;eby mo&#380;na by&#322;o sortowa&#263; nie tylko po warto&#347;ciach z jednej tablicy&amp;#8230; a do tego wypada&#322;oby u&#380;y&#263; joins/include. Nic prostszego.&lt;/p&gt;


&lt;pre&gt;&lt;code class="ruby"&gt;
  named_scope :joins, lambda { |joins| { :joins =&amp;gt; joins } } 

  # a teraz mo&#380;na tak:
  Product.active.joins(:user).order('users.email')
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;How cool is that?&lt;/p&gt;


	&lt;p&gt;No i na koniec co&#347; co ostatecznie przekona&#322;o mnie, &#380;e named_scope jest genialnym wynalazkiem. Je&#380;eli kto&#347; robi&#322; kiedy&#347; formularze, w kt&#243;rych mo&#380;na wybra&#263; kilka opcji i na ich podstawie trzeba zbudowa&#263; zapytanie, zapewne wie, &#380;e jest to nieco upierdliwe. U&#380;ywaj&#261;c `named_scopes` mo&#380;na to zrobi&#263; bardzo &#322;atwo.&lt;/p&gt;


	&lt;p&gt;Ryan Bates napisa&#322; plugin &lt;a href="http://github.com/ryanb/scope-builder/tree/master"&gt;scope_builder&lt;/a&gt;, dzi&#281;ki kt&#243;remu mo&#380;na to zrobi&#263; jeszcze &#322;atwiej. Przypu&#347;&#263;my, &#380;e mamy form&#281;, w kt&#243;rej mo&#380;na zaznaczy&#263; kilka p&#243;l i po ich wys&#322;aniu nale&#380;y na ich podstawie pobra&#263; odpowiednie rekordy z bazy.&lt;/p&gt;


&lt;pre&gt;&lt;code class="ruby"&gt;
  # przygotowujemy list&#281; parametr&#243;w, kt&#243;re u&#380;ytkownik mo&#380;e ustawi&#263;
  parameters = [:active, :paid, :recent, :title]
  # Tworzymy scope
  @products = Product.scope_builder
  # teraz mo&#380;na sprawdzi&#263;, kt&#243;re pola zosta&#322;y zazanczone
  parameters.each do |param|
    @products.send(param) if params[param]
  end
  # na koniec mo&#380;na na przyk&#322;ad doda&#263; paginacj&#281;
  @products = @products.paginate(:per_page =&amp;gt; 10, :page =&amp;gt; params[:id])
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Dla mnie genialne. :) Mo&#380;na dzi&#281;ki temu &#322;atwiej tworzy&#263; zaawansowane wyszukiwanie, sortowanie i inne tego typu rzeczy.&lt;/p&gt;


	&lt;p&gt;Oczywi&#347;cie najlepiej jest zamkn&#261;&#263; taki kawa&#322;ek kodu jako metod&#281; modelu, zgodnie ze &lt;a href="http://www.youtube.com/watch?v=91C7ax0UAAc"&gt;skinny controller, fat model&lt;/a&gt;, ale to pozostawi&#281; jako &#263;wiczenie ;-)&lt;/p&gt;</description>
      <pubDate>Fri, 03 Oct 2008 12:37:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:022e0d90-6941-4703-b442-78b95f508c04</guid>
      <author>Piotr Sarnacki</author>
      <link>http://blog.drogomir.com/articles/2008/10/03/named-scope</link>
      <category>Ruby on Rails</category>
      <category>Programowanie</category>
      <category>rails</category>
      <category>ruby</category>
      <category>named_scope</category>
      <trackback:ping>http://blog.drogomir.com/articles/trackback/54</trackback:ping>
    </item>
    <item>
      <title>Po d&#322;u&#380;szej przerwie</title>
      <description>&lt;p&gt;Przez jaki&#347; czas nie pisa&#322;em nic na blogu. D&#322;ugo zbiera&#322;em si&#281; do napisania czegokolwiek, od dawien dawna mia&#322;em przet&#322;umaczy&#263; wpisy na moim &lt;a href="http://drogomir.com/blog"&gt;angielskoj&#281;zycznym blogusiu&lt;/a&gt;. Tak bardzo mi si&#281; nie chcia&#322;o, &#380;e jak tylko siada&#322;em do kompa z zamiarem przet&#322;umaczenia czy napisania czego&#347; podobnego co&#347; mnie odrzuca&#322;o.&lt;/p&gt;


	&lt;p&gt;Dlatego, &#380;eby wi&#281;cej si&#281; nie m&#281;czy&#263; podsumuj&#281; ten temat i podam linki &amp;#8211; wi&#281;kszo&#347;&#263; ludzi, kt&#243;rzy tutaj trafi&#261; i tak na pewno zna angielski.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://github.com/drogus/apache-upload-progress-module/tree/master"&gt;Napisa&#322;em apache upload progress module&lt;/a&gt; do apacha. Modu&#322;, dzi&#281;ki kt&#243;remu mo&#380;na pobra&#263; dane o wysy&#322;anych plikach. Format odpowiedzi opar&#322;em o modu&#322;y tego typu dla &lt;a href="http://wiki.codemongers.com/NginxHttpUploadProgressModule"&gt;nginxa&lt;/a&gt; i &lt;a href="http://upload.lighttpd.net/index.html"&gt;lighttpd&lt;/a&gt; dlatego je&#380;eli wcze&#347;niej kto&#347; u&#380;ywa&#322; kt&#243;rego&#347; z nich, przesiadka b&#281;dzie ca&#322;kowicie bezbolesna. Sam u&#380;ywa&#322;em wcze&#347;niej nginx upload progress (g&#322;&#243;wnie dlatego napisa&#322;em modu&#322; do apacha) i po przerzuceniu aplikacji na apacha z nowym modu&#322;em nie trzea by&#322;o zmienia&#263; ani jednej linijki. Na angielskim blogu zamie&#347;ci&#322;em opis &lt;a href="http://drogomir.com/blog/2008/6/18/upload-progress-bar-with-mod_passenger-and-apache"&gt;instalacji i konfiguracji modu&#322;u&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;&#379;eby mo&#380;na by&#322;o w miar&#281; &#322;atwo u&#380;ywa&#263; modu&#322;u napisa&#322;em tak&#380;e pluginy do &amp;#8220;prototype&amp;#8217;a&amp;#8221;http://github.com/drogus/prototype-upload-progress/tree/master i &lt;a href="http://github.com/drogus/jquery-upload-progress/tree/master"&gt;jquery&lt;/a&gt;, kt&#243;re obs&#322;uguj&#261; pasek post&#281;pu. Przyk&#322;ady s&#261; w repozytoriach, umie&#347;ci&#322;em je tak&#380;e &lt;a href="http://drogomir.com/files/blog/jquery-upload-progress/example/"&gt;na serwerze&lt;/a&gt; dla obczajenia w akcji. Pope&#322;ni&#322;em tak&#380;e tekst o tym &lt;a href="http://drogomir.com/blog/2008/6/30/upload-progress-script-with-safari-support"&gt;jak hackowa&#322;em plugin, &#380;eby dzia&#322;a&#322; w safari&lt;/a&gt; &amp;#8211; safari w tym momencie nie by&#322;o wcale lepsze od IE&amp;#8230; nawet powiedzia&#322;bym, &#380;e gorsze. Swoj&#261; drog&#261; plugin nie dzia&#322;a w najnowszej operze (dzia&#322;a&#322; w 9.5 zdaje si&#281;), wi&#281;c je&#380;eli kto&#347; ma chwile czasu i m&#243;g&#322;by sprawdzi&#263; dlaczego i co mo&#380;na zrobi&#263;, &#380;eby dzia&#322;a&#322;, to mo&#380;e wnie&#347;&#263; sw&#243;j wk&#322;ad w rozw&#243;j (dodam, &#380;e nie jest to ta sama kwestia co dla safari, bo to ju&#380; sprawdzi&#322;em) &amp;#8211; nie s&#261;dz&#281; &#380;ebym mia&#322; teraz czas sam na tym siedzie&#263;.&lt;/p&gt;


	&lt;p&gt;Dodatkowo napisa&#322;em jeszcze tekst o tym jak mo&#380;na fajnie &lt;a href="http://drogomir.com/blog/2008/7/3/tweaking-rails-app-with-jquery-part-i"&gt;uatrakcyjni&#263; aplikacj&#281; u&#380;ywaj&#261;c jQuery&lt;/a&gt;. Cz&#281;&#347;&#263; pierwsza. Cz&#281;&#347;&#263; druga b&#281;dzie jak b&#281;d&#281; mia&#322; wi&#281;cej czasu, czyli pewnie niezbyt szybko.&lt;/p&gt;


	&lt;p&gt;Pozdrowienia ze s&#322;onecznego Wroc&#322;awia, gdzie mam zamiar mieszka&#263; przez najbli&#380;szy rok (mi&#322;a odmiana od Pruszkowa :).&lt;/p&gt;</description>
      <pubDate>Tue, 30 Sep 2008 16:38:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:c70cc150-5a63-42e3-a8d6-f3611a2c355e</guid>
      <author>Piotr Sarnacki</author>
      <link>http://blog.drogomir.com/articles/2008/09/30/po-d%C5%82u%C5%BCszej-przerwie</link>
      <category>Javascript</category>
      <category>Ruby on Rails</category>
      <category>Programowanie</category>
      <category>rails</category>
      <category>javascript</category>
      <category>apache</category>
      <category>upload</category>
      <category>progress</category>
      <trackback:ping>http://blog.drogomir.com/articles/trackback/53</trackback:ping>
    </item>
    <item>
      <title>Mod passenger i Ruby Enterprise Edition</title>
      <description>&lt;p&gt;Dzisiaj opowiem wam bajeczk&#281; o tym jak mod_passenger zeswata&#322; ze sob&#261; Apache&amp;#8217;a i Railsy. :)&lt;/p&gt;


Je&#380;eli kto&#347; s&#261;dzi, &#380;e z tego zwi&#261;zku nic nie b&#281;dzie, to rzucam kilka zalet:
	&lt;ul&gt;
	&lt;li&gt;nie trzeba bawi&#263; si&#281; w konfiguracj&#281; proxy i martwi&#263; o zaj&#281;te porty&lt;/li&gt;
		&lt;li&gt;nie trzeba monitorowa&#263; mongreli (ja &lt;a href="http://blog.drogomir.com/articles/2008/01/05/god-rb"&gt;u&#380;ywa&#322;em do tego goda&lt;/a&gt;)&lt;/li&gt;
		&lt;li&gt;og&#243;lna prostota u&#380;ycia&lt;/li&gt;
		&lt;li&gt;dzi&#281;ki ruby enterprise mo&#380;na zaoszcz&#281;dzi&#263; 33% pami&#281;ci&lt;/li&gt;
		&lt;li&gt;upload buffering, czyli nie musimy si&#281; martwi&#263; o upload du&#380;ych plik&#243;w &amp;#8211; pliki s&#261; przesy&#322;ane do aplikacji railsowej dopiero, gdy zostan&#261; w ca&#322;o&#347;ci uploadowane na serwer&lt;/li&gt;
		&lt;li&gt;fair load balancing &amp;#8211; zapytania s&#261; wysy&#322;ane do proces&#243;w, kt&#243;re maj&#261; najmniej klient&#243;w w kolejce. &#380;eby uzyska&#263; co&#347; takiego u&#380;ywaj&#261;c nginxa trzeba by&#322;o &lt;a href="http://brainspl.at/articles/2007/11/09/a-fair-proxy-balancer-for-nginx-and-mongrel"&gt;instalowa&#263; dodatkowy plugin&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;liczba instancji aplikacji nie jest sztywno okre&#347;lone. u&#380;ywaj&#261;c nginxa trzeba by&#322;o przewidzie&#263; jaka liczba serwer&#243;w rails&#243;w b&#281;dzie potrzebna dla danej aplikacji, je&#380;eli na dany serwis wchodzi&#322;o ma&#322;o os&#243;b niewykorzystane serwery zjada&#322;y pami&#281;&#263;. mod_passenger uruchamia kolejne instancje w miar&#281; potrzeb.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Dodatkowo napisa&#322;em &lt;a href="http://github.com/drogus/apache-upload-progress-module/tree/master"&gt;apache upload progress module&lt;/a&gt; , dzi&#281;ki czemu z mod_passengerem mo&#380;na skleci&#263; pasek post&#281;pu wysy&#322;ania plik&#243;w na serwer (forma dok&#322;adnie taka sama jak z Nginx Upload Progress, wi&#281;c je&#380;eli kto&#347; go u&#380;ywa&#322;, to nawet nic nie b&#281;dzie musia&#322; zmienia&#263; w skryptach).&lt;/p&gt;


	&lt;h3&gt;Mod Passenger&lt;/h3&gt;


	&lt;p&gt;Aktualnie najnowsz&#261; wersj&#261; mod_passengera jest 1.9.1 (RC2), &lt;a href="http://blog.phusion.nl/2008/06/16/phusion-passenger-20-rc-2-released/"&gt;instrukcja instalacji jest na blogu phusion&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Po odpaleniu instalatora u&#380;ytkownik jest prowadzony za r&#261;czk&#281;, wi&#281;c nikt nie powinien mie&#263; proble&#243;w &amp;#8211; lubi&#281; takie podej&#347;cie, nie musz&#281; si&#281; zastanawia&#263; nad tym co i jak mam zrobi&#263; i kopiowa&#263; i wkleja&#263; kolejnych komend.&lt;/p&gt;


	&lt;p&gt;Mod passenger sprawuje si&#281; na serwerze bardzo fajnie, do tej pory nie mia&#322;em &#380;adnych problem&#243;w. &#379;eby zrestartowa&#263; aplikacj&#281; rails wystarczy utworzy&#263; plik tmp/restart.txt w katalogu aplikacji.&lt;/p&gt;


Po instalacji mo&#380;na jeszcze doda&#263; w configu apacha linijk&#281;:
&lt;pre&gt;&lt;code&gt;PassengerMaxPoolSize X&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Zamiast X wstawiamy maksymaln&#261; liczb&#281; instancji aplikacji odpalonych na raz. W dokumentacji twierdz&#261;, &#380;e dla VPSa z 256 megabajtami pami&#281;ci ram dobr&#261; warto&#347;ci&#261; b&#281;dzie tutaj 2, a dla serwera dedykowanego z 2GB ramu 30. Wi&#281;ksza liczba aplikacji to wi&#281;cej zaj&#281;tego ramu, ale te&#380; wi&#281;cej request&#243;w do obs&#322;u&#380;enia w danej chwili.&lt;/p&gt;


	&lt;h3&gt;Ruby Enterprise Edition&lt;/h3&gt;


	&lt;p&gt;O ile o mod passengerze jest du&#380;o informacji, to o ruby enterprise edition jeszcze niewiele. Wed&#322;ug niekt&#243;rych nazwa jest nietrafiona i niefajna, niekt&#243;rym nie podoba si&#281;, &#380;e &lt;a href="http://judofyr.net/posts/ruby-fishy-edition.html"&gt;phusion chce si&#281; na &lt;span class="caps"&gt;REE&lt;/span&gt; wypromowa&#263;&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Mi to w zasadzie wszystko jedno jak si&#281; ch&#322;opaki z Phusion promuj&#261;, kto na tym zarobi i jaka jest nazwa, o ile ta wersja b&#281;dzie dobrze dzia&#322;a&#322;a i rzeczywi&#347;cie zmniejsza&#322;a zu&#380;ycie pami&#281;ci.&lt;/p&gt;


&#379;eby zainstalowa&#263; ruby enterprise edition nale&#380;y &#347;ci&#261;gn&#261;&#263; paczk&#281; (najnowsz&#261; wersj&#281; paczki mo&#380;na znale&#378;&#263; &lt;a href="http://rubyforge.org/projects/emm-ruby/"&gt;tutaj&lt;/a&gt;): 
&lt;pre&gt;&lt;code&gt;wget http://rubyforge.org/frs/download.php/38777/ruby-enterprise-1.8.6-20080623.tar.gz&lt;/code&gt;&lt;/pre&gt;

Nast&#281;pnie j&#261; rozpakowa&#263;:
&lt;pre&gt;&lt;code&gt;tar -zxvf ruby-enterprise-1.8.6-20080623.tar.gz&lt;/code&gt;&lt;/pre&gt;

i uruchomi&#263; installer:
&lt;pre&gt;&lt;code&gt;./ruby-enterprise-1.8.6-20080623/installer&lt;/code&gt;&lt;/pre&gt;

Tyle m&#243;wi opis na stronie &lt;span class="caps"&gt;REE&lt;/span&gt;, ale to jeszcze nie wszystko. Na pocz&#261;tek mo&#380;na stworzy&#263; dowi&#261;zanie symboliczne dla &lt;span class="caps"&gt;REE&lt;/span&gt;:
&lt;pre&gt;&lt;code&gt;ln -sf /opt/ruby-enterprise-1.8.6-20080623/bin/ruby /usr/bin/ruby-enterprise&lt;/code&gt;&lt;/pre&gt;

U&#380;ytkownicy gentoo musz&#261; r&#243;wnie&#380; skopiowa&#263; plik auto_gem, kt&#243;ry automatycznie jest w tej dystrybucji dodawany do &lt;span class="caps"&gt;RUBYOPT&lt;/span&gt;:
&lt;pre&gt;&lt;code&gt;cp /usr/lib/ruby/site_ruby/auto_gem.rb /opt/ruby-enterprise-1.8.6-20080623/lib/ruby/site_ruby&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Po zainstalowaniu rubiego instaluje si&#281; te&#380; kilka gem&#243;w, ale to tylko podstawowe &amp;#8211; reszt&#281; trzeba zainstalowa&#263; samemu. Oczywi&#347;cie mo&#380;na odpali&#263; gem list i instalowa&#263; kolejne gemy w danych wersjach, ale od czego mamy rubiego. Dos&#322;ownie w 2 minuty napisa&#322;em prosty skrypcik, kt&#243;ry wyci&#261;ga nazwy i wersje gem&#243;w po czym instaluje je dla Ruby Enterprise Edition:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
`gem list`.split("\n").each do |line|
  if line =~ /([0-9a-zA-Z_\-]*) \((.*)\)/
    gem, versions = $1, $2.split(", ")
    versions.each do |version|
      puts "Installing #{gem}, version: #{version}" 
      puts `ruby-enterprise /opt/ruby-enterprise-1.8.6-20080623/bin/gem install #{gem} -y --version '#{version}' 2&amp;gt;&amp;#38;1`
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

Teraz wystarczy doda&#263; w configu apacha linijk&#281;:
&lt;pre&gt;&lt;code&gt;RailsRuby /opt/ruby-enterprise-1.8.6-20080623/bin/ruby&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;I mo&#380;emy cieszy&#263; si&#281; naszym w&#322;asnym wypicowanym apachem z mod_passengerem w korporacyjnej wersji ;-)&lt;/p&gt;</description>
      <pubDate>Tue, 17 Jun 2008 20:50:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:8b35d5b4-2cdf-49b2-831b-e0d041873b24</guid>
      <author>Piotr Sarnacki</author>
      <link>http://blog.drogomir.com/articles/2008/06/17/mod-passenger-i-ruby-enterprise-edition</link>
      <category>Ruby on Rails</category>
      <category>ruby</category>
      <category>enterprise</category>
      <category>instalacja</category>
      <category>mod_passenger</category>
      <category>apache</category>
      <trackback:ping>http://blog.drogomir.com/articles/trackback/51</trackback:ping>
    </item>
  </channel>
</rss>
