<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Marioosh&#039;s developer diary</title>
	<atom:link href="http://marioosh.5dots.pl/feed" rel="self" type="application/rss+xml" />
	<link>http://marioosh.5dots.pl</link>
	<description></description>
	<lastBuildDate>Sun, 13 May 2012 11:31:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Sqlite dla niecierpliwych</title>
		<link>http://marioosh.5dots.pl/2012/05/13/sqlite-dla-niecierpliwych.html</link>
		<comments>http://marioosh.5dots.pl/2012/05/13/sqlite-dla-niecierpliwych.html#comments</comments>
		<pubDate>Sun, 13 May 2012 11:30:55 +0000</pubDate>
		<dc:creator>marioosh</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[sqlite]]></category>
		<category><![CDATA[sqlite3]]></category>

		<guid isPermaLink="false">http://marioosh.5dots.pl/?p=475</guid>
		<description><![CDATA[SQLite jest opensource&#8217;ową, relacyjną bazą danych, która nie potrzebuje serwera zewnętrznego do działania. Wszystkie dane są przechowywane lokalnie a biblioteka obsługująca bazę to niewielki pojedyńczy plik. Aby zacząć z tej bazy korzystać wystarczy skorzystać z tego pojedyńczego pliku. SQLite nie &#8230; <a href="http://marioosh.5dots.pl/2012/05/13/sqlite-dla-niecierpliwych.html">czytaj dalej...</a>]]></description>
			<content:encoded><![CDATA[<p>SQLite jest opensource&#8217;ową, relacyjną bazą danych, która nie potrzebuje serwera zewnętrznego do działania. Wszystkie dane są przechowywane lokalnie a biblioteka obsługująca bazę to niewielki pojedyńczy plik. Aby zacząć z tej bazy korzystać wystarczy skorzystać z tego pojedyńczego pliku.</p>

<p>SQLite nie jest nowym projektem, jednak wraz ze wzrostem popularności aplikacji mobilnych zainteresowanie tą bazą także rośnie. Dzieje się tak dlatego, że najbardziej popularne platformy mobilne (Android i IOS) natywnie wspierają ten slinik.</p>

<p>SQLite nie bezpodstawnie ma opinię bardzo łatwej w użytkowaniu, wydajnej bazie danych.</p>

<p>Jeżeli potrzebujecie także do swojego projektu małej wbudowanej bazy danych to SQLite jest godny sprawdzenia.
<span id="more-475"></span>
Zaczynamy:</p>

<h2>1. Instalacja.</h2>

<p>Wszystkie niezbędne pliki znajdziemy na stronie <a href="http://www.sqlite.org/download.html">SQLite Download Page</a></p>

<p><strong>MacOSX:</strong><br />
Nie trzeba nic instalować, <code>SQLite</code> już jest w systemie.</p>

<p><strong>Linux:</strong><br />
Aby zainstalować w systemie <code>Linux</code> możemy skorzystać z linku powyżej aby pobrać odpowiedni plik, ale większość dystrybucji ma <code>SQLite</code> w swoich dystrybucjach gotowe do zaisntalowania. Np.:</p>

<pre class="prettyprint"><code>/* Debian lub Ubuntu */
sudo apt-get install sqlite3 sqlite3-dev

/* RedHat, CentOS, Fedora */
yum install SQLite3 sqlite3-dev
</code></pre>

<p><strong>Windows</strong><br />
Tu nie ma tak prostych metod jak powyższe. W przypadku tej platformy musimy skorzystać z powyższego linku, pobrać tam odpowiednie pliki i umieścić je w obrębie zmiennej <code>PATH</code> (lub też ustawić <code>PATH</code> aby wskazywało na folder z bazą). Niestety nie posiadam <em>Windows</em> nie więc dla bardziej szczegółowych instrukcji proszę udać się na stronę <a href="http://sqlite.org">SQLite</a></p>

<h2>2. Tworzymy pierwszą bazę</h2>

<p>Gdy mamy zainstalowane pliki binarne <strong>SQLite</strong>  jesteśmy gotowi do utworzenia swojej pierwszej bazy.</p>

<p>Aby utworzyć nową bazę nazwaną <code>test.db</code> wpisujemy w lini komend:</p>

<pre class="prettyprint"><code>sqlite3 test.db
</code></pre>

<p>Aby teraz utworzyć tabelę w naszej bazie wpisujemy:</p>

<pre class="prettyprint"><code>sqlite&gt; create table firsttable(id integer primary key, value text);
</code></pre>

<p>Została utworzona tabla <code>firsttable</code> z dwoma kolumnami. Pierwsza <code>id</code> jako Klucz Główny która ma możliwość autogenerowania wartości, oraz druga kolumna <code>value</code> która przechowuje wartości tekstowe.</p>

<p>Musimy tu pamiętać o dwóch rzeczach:<br />
1. Wszystkie komendy <strong>muszą</strong> kończyć się znakiem średnika <code>;</code><br />
2. komendy systemowe zaczynają się od znaku kropki <code>.</code>, np. <code>.help .quit</code><br />
3. baza danych <strong>NIE</strong> zostanie zapisana na dysku dopóki nie utworzymy conajmniej jednej tablicy.</p>

<p>Czas na dodanie trochę danych do naszej tablicy:</p>

<pre class="prettyprint"><code>sqlite&gt; insert into firsttable(id, value) values(1, 'Stefan');
sqlite&gt; insert into firsttable(id, value) values(2, 'Maria');
sqlite&gt; insert into firsttable(value) values('Franek');
sqlite&gt; insert into firsttable(value) values('Krysia');
</code></pre>

<p>Sprawdzamy czy wszystko się zapisało:</p>

<pre class="prettyprint"><code>sqlite&gt; select* from firsttable;
1|Stefan
2|Maria
3|Franek
4|Krysia
</code></pre>

<p>Nie do końca czytelnie, możemy trochę przeformatować wyświetlanie:</p>

<pre class="prettyprint"><code>sqlite&gt; .mode column
</code></pre>

<p>Wyświetli dane w postaci kolumnowej</p>

<pre class="prettyprint"><code>sqlite&gt; .header on
</code></pre>

<p>Pokaże nagłówki tabeli. 
Pamiętajmy jednak, że w przeciwieństwie do komend <code>sql</code>, komendy systemowe <strong>nie</strong> mogą kończyć się znakiem średnika <code>;</code><br />
Pobieramy dane jeszcze raz:</p>

<pre class="prettyprint"><code>sqlite&gt; select * from firsttable;
id          value     
----------  ----------
1           Stefan    
2           Maria     
3           Franek    
4           Krysia 
</code></pre>

<p>Aby dodać dodatkową kolumnę do naszej tableli:</p>

<pre class="prettyprint"><code>sqlite&gt; alter table firsttable add column email text not null default '' collate nocase;
</code></pre>

<p>Dodaliśmy kolumnę <strong>email</strong>, która nie może mieć wartości <code>NULL</code> domyślnie pusty string, podczas sortowania wiekość znaków nie ma znaczenia.</p>

<p>Tworzenie widoków jest tak samo proste:</p>

<pre class="prettyprint"><code>sqlite&gt; create view firstview as select * from firsttable;
</code></pre>

<p>Tak samo proste jest tworzenie indeksów:</p>

<pre class="prettyprint"><code>sqlite&gt; create index first_idx on firsttable(value);
</code></pre>

<h2>3. Kilka przydatnych komend systemowych:</h2>

<p>Przede wszystkim <code>.help</code> chyba wiadomo po co ? ;)</p>

<p>Sprawdzenie struktury bazy:</p>

<pre class="prettyprint"><code>sqlite&gt; .schema
</code></pre>

<p>Albo struktury tabeli (lub widoku)</p>

<pre class="prettyprint"><code>sqlite&gt; .schema firsttable
</code></pre>

<p>Lista tablic i widoków:</p>

<pre class="prettyprint"><code>sqlite&gt; .tables
</code></pre>

<p>Lista indeksów:</p>

<pre class="prettyprint"><code>sqlite&gt; .indices
</code></pre>

<p>Export bazy danych do pliku SQL:</p>

<pre class="prettyprint"><code>sqlite&gt; .output nazwa_pliku.sql
sqlite&gt; .dump
sqlite&gt; .output sdtout
</code></pre>

<p>Import danych z pliku SQL:</p>

<pre class="prettyprint"><code>sqlite&gt; .read nazwa_pliku.sql
</code></pre>

<p>Export wyników zapytania do pliku CSV:</p>

<pre class="prettyprint"><code>sqlite&gt; .mode csv
sqlite&gt; .output nazwa_pliku.csv
sqlite&gt; select * from firsttable;
sqlite&gt; .output stdout
</code></pre>

<p>Import danych z pliku CSV (dane rozdzielone przecinkiem) do tablicy:</p>

<pre class="prettyprint"><code>sqlite&gt; create table secondtable(id integer primary key, value text);
sqlite&gt; .separator ,
sqlite&gt; .import dane_w_pliku.csv secondtable;
</code></pre>

<p>Zrzut całej bazy:</p>

<pre class="prettyprint"><code>/* Formuła: sqlite3 [nazwa_bazy] .dump &gt; [nazwa_pliku] */
sqlite3 test.db .dump &gt; backup.sql
</code></pre>

<p>Import całej bazy:</p>

<pre class="prettyprint"><code>/* Formuła: sqlite3 [baza] &lt; [plik] */
sqlite3 test.db &lt; backup.sql
</code></pre>

<h2>4. Koniec.</h2>

<p>To tylko preludium możliwości tej małej bazy danych, mam nadzieję, że zachęciłem do używania.</p>
]]></content:encoded>
			<wfw:commentRss>http://marioosh.5dots.pl/2012/05/13/sqlite-dla-niecierpliwych.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vim: poprawianie wcięć w całym pliku.</title>
		<link>http://marioosh.5dots.pl/2012/04/20/vim-poprawianie-wciec-w-calym-pliku.html</link>
		<comments>http://marioosh.5dots.pl/2012/04/20/vim-poprawianie-wciec-w-calym-pliku.html#comments</comments>
		<pubDate>Fri, 20 Apr 2012 18:05:10 +0000</pubDate>
		<dc:creator>marioosh</dc:creator>
				<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[Vim]]></category>

		<guid isPermaLink="false">http://marioosh.5dots.pl/?p=415</guid>
		<description><![CDATA[Długo nic nie pisałem, zwłaszcza o vimie &#8211; czas się poprawić i zacząć coś regularnie skrobać. O tym, że Vim jest moim ulubieńcem, wie chyba każdy kto tu zagląda. Mam dzisiaj nowy tips na temat jego działania. Edytor ten doskonale &#8230; <a href="http://marioosh.5dots.pl/2012/04/20/vim-poprawianie-wciec-w-calym-pliku.html">czytaj dalej...</a>]]></description>
			<content:encoded><![CDATA[<p>Długo nic nie pisałem, zwłaszcza o <a href="http://vim.org">vimie</a> &#8211; czas się poprawić i zacząć coś regularnie skrobać.</p>

<p>O tym, że <strong>Vim</strong> jest moim ulubieńcem, wie chyba każdy kto tu zagląda. Mam dzisiaj nowy tips na temat jego działania.
Edytor ten doskonale układa wcięcia w plikach. Jednak gdy pracujemy trochę dłużej na jednym pliku (np. html) to porządek we wcieciach może zostać nieco zachwiany.</p>

<p>Aby poprawić wcięcia w całym pliku musimy wykonać pewną sekwencję komend &#8211; nie ma jednej uniwersalnej komendy. Wpierw musimy przesunąć kursor do pierwszej linii, potem przeformatować tekst aż do ostatniej linijki, na koniec najlepiej by było aby kursor wrócił na ostatnią pozycję edytowania. Powyższa sekwencja wygląda tak: <code>gg=Gg``</code></p>

<p>Jeżeli często korzystamy z tego to możemy ustawić jako macro i np. wpisać w <code>.vimrc</code></p>

<p><code>map <C-G> gg=Gg``</code> &#8211; Poprawiam plik po wciśnięciu Ctrl-G</p>
]]></content:encoded>
			<wfw:commentRss>http://marioosh.5dots.pl/2012/04/20/vim-poprawianie-wciec-w-calym-pliku.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Git &#8211; zdalne branche</title>
		<link>http://marioosh.5dots.pl/2012/02/02/git-zdalne-branche.html</link>
		<comments>http://marioosh.5dots.pl/2012/02/02/git-zdalne-branche.html#comments</comments>
		<pubDate>Thu, 02 Feb 2012 13:24:32 +0000</pubDate>
		<dc:creator>marioosh</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[Git]]></category>

		<guid isPermaLink="false">http://marioosh2.5dots.pl/?p=404</guid>
		<description><![CDATA[Praca z Git jest bardzo wygodnia &#8211; o czym wspominałem niejednokrotnie. Całe repozytorium mamy na lokalnym komputerze więc możemy bez dostępu do sieci tworzyć własne branche i na nich pracować. Model pracy grupowej jednak poleca używanie jednego centralnego repozytorium, które &#8230; <a href="http://marioosh.5dots.pl/2012/02/02/git-zdalne-branche.html">czytaj dalej...</a>]]></description>
			<content:encoded><![CDATA[<p>Praca z Git jest bardzo wygodnia &#8211; o czym wspominałem niejednokrotnie.
Całe repozytorium mamy na lokalnym komputerze więc możemy bez dostępu do sieci tworzyć własne <em>branche</em> i na nich pracować.
Model pracy grupowej jednak poleca używanie jednego centralnego repozytorium, które jest miejscem zbiorczym na wspólny kod
wszystkich programistów.</p>

<p>W mojej obecnej pracy używam dwóch komputerów. Jednego w domu i drugiego w pracy. Z tego też powodu chciałbym mieć możliwość
aby mój prywatny <em>branch</em> był w centralnym repozytorium jednak aby nie bałaganił kodu głównego.
Za pomocą Git jest to możliwe i łatwe do wykonania.</p>

<span id="more-404"></span>

<p>Jest nawet kilka sposobów na wykonanie tej operacji,</p>

<h3>Opiszę ten z nich, który używam i działa dla mnie wyśmienicie.</h3>

<p>Przyjmijmy, że pracujemy już z kodem, lokalne i zdalne repozytoria są ustawione.
W pierwszej kolejności tworzymy gałąź w zdalnym repozytorium, nazwijmy ją <code>new_feature</code></p>

<pre class="prettyprint"><code>git push origin origin:refs/heads/new_feature
</code></pre>

<p>To spowoduje skopiowanie zdalnej gałęzi <code>master</code> do nowoutworzonej <code>new_feature</code></p>

<p><strong>Sprawdzamy czy kod jest aktualny</strong></p>

<pre class="prettyprint"><code>git fetch origin
</code></pre>

<p>teraz na liście branch&#8217;y możemy znaleźć tą zdalną</p>

<pre class="prettyprint"><code>git branch -r
</code></pre>

<p>na liście powinniśmy zobaczyć: <code>origin/new_feature</code></p>

<h3>Kopiowanie zdalnego branch&#8217;a do lokalnego repozytorium</h3>

<pre class="prettyprint"><code>git checkout --track -b new_feature origin/new_feature
</code></pre>

<p>Powyższa komenda utworzy nową gałąź <code>new_feature</code> która opiera się na zdalnej o tej samej nazwie.
Dodatkowo lokalny <em>branch</em> będzie śledził ten zdalny.</p>

<h4>Co to znaczy <em>śledził</em>?</h4>

<p>To oznacza, że przy wykonywaniu komend bez argumentów <strong>push</strong> czy <strong>pull</strong> gałęzie te będą automatycznie się synchronizowały
Git wie, że lokalny <em>branch</em> jest połączony ze zdalnym.</p>

<p>Ponownie sprawdzamy czy wszystko jest aktualne</p>

<pre class="prettyprint"><code>git pull
</code></pre>

<p>I to wszystko</p>

<h3>Kasowanie zdalnego branch&#8217;a</h3>

<p>Gdy branch, którego wykorzystywaliśmy przestanie nam być potrzebny, możemy go usunąć:</p>

<pre class="prettyprint"><code>git push origin :heads/new_feature
</code></pre>

<h3>A co w przypadku gdy mamy skonfigurowany zdalny branch, ale ten lokalny go nie śledzi?</h3>

<p>Możemy to zrobić ręcznie</p>

<pre class="prettyprint"><code>git config branch.new_feature.remote new_feature
git config branch.new_feature.merge refs/heads/new_feature

git push
</code></pre>

<p>Może komuś się przyda</p>
]]></content:encoded>
			<wfw:commentRss>http://marioosh.5dots.pl/2012/02/02/git-zdalne-branche.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Statyczne(prawie) strony w playframework</title>
		<link>http://marioosh.5dots.pl/2011/09/27/semi-static-pages-w-play-framework.html</link>
		<comments>http://marioosh.5dots.pl/2011/09/27/semi-static-pages-w-play-framework.html#comments</comments>
		<pubDate>Tue, 27 Sep 2011 13:20:00 +0000</pubDate>
		<dc:creator>marioosh</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Play Framework]]></category>

		<guid isPermaLink="false">http://marioosh2.5dots.pl/?p=401</guid>
		<description><![CDATA[Większość aplikacji czy też systemów zarządzania treścią posiada dymanicznie tworzoną treść. Jednak niekiedy część tej treści jest mniej dynamiczna. Zmienia się rzadko lub też wogóle. Przykładem mogą być takie strony jak &#8222;Regulamin&#8221; czy też &#8222;Polityka Prywatności&#8221;. Gdy do tworzenia aplikacji &#8230; <a href="http://marioosh.5dots.pl/2011/09/27/semi-static-pages-w-play-framework.html">czytaj dalej...</a>]]></description>
			<content:encoded><![CDATA[<p>Większość aplikacji czy też systemów zarządzania treścią posiada
dymanicznie tworzoną treść. Jednak niekiedy część tej treści jest mniej
dynamiczna. Zmienia się rzadko lub też wogóle. Przykładem mogą być
takie strony jak &#8222;Regulamin&#8221; czy też &#8222;Polityka Prywatności&#8221;.</p>

<p>Gdy do tworzenia aplikacji używamy dowolnego frameworka zgodnego z
wzorcem MVC, treść takich stron powinna być przechowywana w bazie a
pobierana przez kontroler.</p>

<p>Innym rozwiązaniem jest napisanie oddzielnej metody dla każdej strony i
treść umieszczać w odpowiednim widoku. Pracując z <a href="http://playframework.org">Play
Framework</a> można to zrobić o wiele prościej.</p>

<span id="more-401"></span>

<p>Przypuśćmy, że mamy aplikację która ma stronę &#8222;Regulamin&#8221; jako
semistatyczna.</p>

<p>Treść regulaminu umieszczamy w pliku <code>app/views/Pages/regulamin.html</code>.</p>

<p>W routes wpisujemy:</p>

<pre class="prettyprint"><code>GET     /pages/{pageName}                 Pages.show
</code></pre>

<p>Tworzymy kontroler <code>Pages</code> ze zdefiniowaną metodą <code>show</code>:</p>

<pre class="prettyprint"><code>public class Pages extends Controller

    public static void show(String pageName){

        String filePath = String.format("app/views/Pages/%s.html", pageName);

        notFoundIfNull(Play.getVirtualFile(filePath));

        renderTemplate(filePath);

    }
}
</code></pre>

<p>Jak to działa? Nie wiem czy trzeba tłumaczyć, ale w kilku zdaniach: 
Gdy w przeglądarce wpiszemy adres <code>/pages/costam</code> zostaniemy
przekierowani do metody <code>show</code> kontrolera <code>Pages</code> gdzie <code>costam</code>
zostanie użyte jako parametr metody.</p>

<p>Kontroler wtedy szuka pliku <code>costam.html</code> w folderze <code>app/views/Pages</code> i
gdy znajduje &#8211; wyświetla go, w przeciwnym razie wyrzuca błąd <strong>404 Not
Found</strong>.</p>
]]></content:encoded>
			<wfw:commentRss>http://marioosh.5dots.pl/2011/09/27/semi-static-pages-w-play-framework.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Find czy Where?</title>
		<link>http://marioosh.5dots.pl/2011/04/27/find-czy-where.html</link>
		<comments>http://marioosh.5dots.pl/2011/04/27/find-czy-where.html#comments</comments>
		<pubDate>Wed, 27 Apr 2011 13:17:02 +0000</pubDate>
		<dc:creator>marioosh</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[Activerecords]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://marioosh2.5dots.pl/?p=399</guid>
		<description><![CDATA[Wraz z pojawieniem się Rails 3 &#8211; ActiveRecord dość mocno się zmieniło. Zniknęło kilkanaście metod, któr dość często były wykorzystywane w ich miejsce pojawiły się inne: where (:conditions) having (:conditions) select group order limit offset joins includes (:include) lock readonly &#8230; <a href="http://marioosh.5dots.pl/2011/04/27/find-czy-where.html">czytaj dalej...</a>]]></description>
			<content:encoded><![CDATA[<p>Wraz z pojawieniem się Rails 3 &#8211; ActiveRecord dość mocno się zmieniło.
Zniknęło kilkanaście metod, któr dość często były wykorzystywane w ich
miejsce pojawiły się inne:</p>

<pre class="prettyprint"><code>where (:conditions)
having (:conditions)
select
group
order
limit
offset
joins
includes (:include)
lock
readonly
from
</code></pre>

<p>Natomiast zniknęły takie metody jak :</p>

<pre class="prettyprint"><code>find(:all, :limit =&gt; 1)
find(:all)
find(:first)
first(:conditions =&gt; {:name =&gt; "Jaś"})
all(:joins =&gt; :products)
</code></pre>

<span id="more-399"></span>

<p>Metody, które najczęściej służyły do wyszukwiania w bazie rekordów nie
zostały przeterminowane i dalej są dostępne w Rails 3</p>

<pre class="prettyprint"><code>find(1)
find(1,2,3)
</code></pre>

<p>Nasuwa się pytanie, której metody powinniśmy używać? <code>find</code> czy <code>where</code>,
przecież ten sam efekt uzyskamy gdy użyjemy:</p>

<pre class="prettyprint"><code>Item.find(283746)
</code></pre>

<p>jak i:</p>

<p>Item.where(:id => 283746).first</p>

<p>Pomiędzy tymi dwoma formułkami jest jedna subtelna różnica, w przypadku
gdy szukamy rekordu, którego nie ma w bazie, użycie <code>where</code> zwróci nam
<code>nil</code>. Użycie <code>find</code> natomiast rzuci błąd <code>ActiveRecord::RecordNotFound</code>
i przerwie wykonywanie dalszego kodu. Jeżeli tego błędu nie wyłapiemy to
pojawi się nam wspaniały stacktrace na ekranie.</p>

<p>Miejmy to na uwadze.</p>
]]></content:encoded>
			<wfw:commentRss>http://marioosh.5dots.pl/2011/04/27/find-czy-where.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails 3 Way</title>
		<link>http://marioosh.5dots.pl/2011/04/18/rails-3-way.html</link>
		<comments>http://marioosh.5dots.pl/2011/04/18/rails-3-way.html#comments</comments>
		<pubDate>Mon, 18 Apr 2011 13:13:53 +0000</pubDate>
		<dc:creator>marioosh</dc:creator>
				<category><![CDATA[MiszMasz]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[książki]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://marioosh2.5dots.pl/?p=397</guid>
		<description><![CDATA[W ostatni weekend przegryzłem książkę Obie Fernadeza Rails 3 Way. Chciałbym napisać kilka słów na temat tej pozycji. Przyznam szczerze, czekałem z niecierpliwością na to wydanie. Pierwsza edycja miała bardzo dobre recenzje więc mogłem się domyślić czego się spodziewać. Czekałem &#8230; <a href="http://marioosh.5dots.pl/2011/04/18/rails-3-way.html">czytaj dalej...</a>]]></description>
			<content:encoded><![CDATA[<p>W ostatni weekend przegryzłem książkę Obie Fernadeza <a href="http://tr3w.com/">Rails 3 Way</a>. Chciałbym napisać kilka słów na temat tej pozycji.</p>

<p>Przyznam szczerze, czekałem z niecierpliwością na to wydanie. Pierwsza
edycja miała bardzo dobre recenzje więc mogłem się domyślić czego się
spodziewać. Czekałem także z tej przyczyny, że książka ta jest jedną z
nielicznych typu Reference Book. Większość pozycji omawiających Rails 3
czy rails 2 to książki tutorialowe, gdzie wykonujemy poszczególne
zadania przez całą książkę a na koniec otrzymujemy gotową aplikację.
W tej książce jest inaczej.</p>

<span id="more-397"></span>

<p>Rails 3 Way opisuje dokładnie framework Rails 3. W kolejnych rozdziałach
poznajemy poszczególne jego elementy. 
Na początku autor opisuje Bundler i zasadę uruchamiania aplikacji.
Znajdujemy tu opis poszczególnych elementów startowych &#8211; application.rb,
pliki konfiguracji środowisk, initializery itp.
Poznajemy routing i zasady działania kontrolerów wraz ze sposobem działania filtrów. Dokładnie opisane modele &#8211; przeczytamy jak działa
relacja Modelu z bazą danych, cykl życia modelu i callbacki.
Można przeczytać o migracjach i konfiguracji kilku baz danych. Opisane są
także Observery i walidatory. Nauczymy się także tworzyć własny
walidator dla modeli. Następnie znajdziemy opisy Mailerów i poznamy jak
konfigurować połączenie naszej aplikacji z kontem pocztowym. Nauczymy
się jak wysyłać i odbierać maile. Ajax i zarządzanie sesją także
znalazły tutaj swoje miejsce.
Opisane także są widoki i layouty, jak z nich korzystać, jakie są
relacje pomiędzy widokiem i kontolerem. Znajdziemy tu także opis
Helperów.
Fajnie jest opisany sposób na Cacheowanie aplikacji i jak ją rozszerzać
za pomocą pluginów.</p>

<p>Co więcej, autor także postarał się opisać elementy, które nie są bezpośrednio związane z railsami, ale
tworzenie webaplikacji bez nich się nie obejdzie. Przykładem jest tu
autoryzacja &#8211; sam framework nie posiada narzędzi autoryzujących sam w
sobie. Musimy skorzystać z oddzielnych gemów. Autor opisuje w książce
dwa najpopularniejsze: <a href="http://github.com/binarylogic/authlogic">Authlogic</a> i 
<a href="http://github.com/plataformatec/devise">Devise</a>.</p>

<p>Oprócz gemów do autoryzacji autor pokusił się także o opisanie gemów do
wykonywania zadań w tle i gemów do uploadu plików. Jeden rozdział został
także poświęcony RSpec jako alternatywy dla TestUnit.</p>

<p>Na końcu jest opis API, przynajmniej jego najważniejszych elementów.</p>

<p>Zawartość książki opisuje zatem każdy z elementów powstawania
aplikacji. Znalazłem tutaj nawet kilka rzeczy, o których nie miałem
pojęcia.</p>

<p>Szczerzę polecam tą książkę każdemu, zarówno początkującym programistom
jak i bardziej zaawansowanym. Przeczytanie tej książki pozwoli nam na
zrozumienie &#8222;jak to właściewie działa&#8221;. Fajnie jest ją mieć pod ręką.
Jak będziemy chcieli kiedyś przypomnieć sobie dany element wystarczy po
nią sięgnąć.</p>

<p>Miłej lektury.</p>
]]></content:encoded>
			<wfw:commentRss>http://marioosh.5dots.pl/2011/04/18/rails-3-way.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vim: pluginy bez których ciężko żyć &#8211; Surround</title>
		<link>http://marioosh.5dots.pl/2011/04/09/vim_pluginy_bez_ktorych_ciezko_zyc-surround.html</link>
		<comments>http://marioosh.5dots.pl/2011/04/09/vim_pluginy_bez_ktorych_ciezko_zyc-surround.html#comments</comments>
		<pubDate>Sat, 09 Apr 2011 12:46:14 +0000</pubDate>
		<dc:creator>marioosh</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[Surround]]></category>
		<category><![CDATA[Vim]]></category>

		<guid isPermaLink="false">http://marioosh2.5dots.pl/?p=392</guid>
		<description><![CDATA[Surround Dzisiejszym artykułem rozpocznę nową, krótką serię mającą na celu przedstawienie naważniejszych moim zdaniem pluginów do edytora Vim. Pierwszym z nich jest surround Plugin ten skupia się na jednej funkcjonalności: otaczanie (surrounding). Pisząc kod niejednokrotnie otaczamy (fatalnie to brzmi :) &#8230; <a href="http://marioosh.5dots.pl/2011/04/09/vim_pluginy_bez_ktorych_ciezko_zyc-surround.html">czytaj dalej...</a>]]></description>
			<content:encoded><![CDATA[<h3>Surround</h3>

<p>Dzisiejszym artykułem rozpocznę nową, krótką serię mającą na celu
przedstawienie naważniejszych moim zdaniem pluginów do edytora
<a href="http://vim.org">Vim</a>.</p>

<p>Pierwszym z nich jest <a href="http://www.vim.org/scripts/script.php?script_id=1697">surround</a>
Plugin ten skupia się na jednej funkcjonalności: otaczanie
(surrounding). Pisząc kod niejednokrotnie otaczamy (fatalnie to brzmi :) )
swój kod. Otaczamy wyrazy cudzysłowami, nawiasami, klamrami albo tagami.
Surround dba o wszystkie te aspekty. Możemy bardzo łatwo nimi
manipulować.</p>

<span id="more-392"></span>

<p>Surround działa przeważnie w <a href="http://marioosh.5dots.pl/2010/08/18/vim-poczatek.html">trybie komend</a> chociaż w trybie wizualnym też dodaje kilka funkcjonalności. 
Jego podstawową zaletą jest bardzo zwięzła składnia, posiada tylko kilka komend, których
odpowiednia kombinacja wykonuje tą magiczną robotę</p>

<ul>
<li><code>s</code> &#8211; podstawowa komenda: oznacza sorround</li>
<li><code>c</code> &#8211; modyfikator surrounda oznaczający zmianę</li>
<li><code>y</code> &#8211; modyfikator surrounda oznaczający wprowadzanie</li>
<li><code>d</code> &#8211; modyfikator surrounda oznaczający usuwanie</li>
<li><code>t</code> &#8211; oznacza tag używany w plikach html/xml</li>
</ul>

<p>to wszystko do tego dochodzi znajomość <a href="http://marioosh.5dots.pl/2010/08/19/vim-selektory.html">selektorów</a> i czasem użycie trybu wizualnego: <code>v</code></p>

<ul>
<li><code>v</code> &#8211; tryb wizualny</li>
<li><code>p</code> &#8211; selektor paragrafu</li>
<li><code>w</code> &#8211; selektor słowa</li>
</ul>

<h3>Przykłady</h3>

<p>Kursor generalnie może być w obrębie
otaczanego fragmentu więc nie trzeba się restrykcyjnie trzymać zgodnie z
naszym przykładem (W przykładach kursor oznaczamy <code>|</code>). Pierwsze komendy postaram się
łopatologicznie rozłożyć na części pierwsze.</p>

<p>Zacznijmy od początku &#8211; mamy proste zdanie <code>Surround jest super</code> i chcemy pierwszy wyraz (Surround)
otoczyć cudzysłowem. Skoro chcemy dodać to używamy <code>y</code> potem <code>s</code> jako
klucz i selektor (iw) na koniec czym czym chcemy otoczyć (&#8222;)</p>

<pre class="prettyprint"><code>Surr|ound is super
ysiw"
"Surround" is super
</code></pre>

<p>yh, Chyba miał być pojedyńczy cudzysłów&#8230;. musimy to zmienić. <code>c</code>
Zmiana, <code>s</code> &#8211; klucz, selektor już nie potrzebny (bo plugin sam odnajdzie
oataczającą parę znaków) i co chcemy zmienić (&#8222;) na co (&#8216;)</p>

<pre class="prettyprint"><code>"Surr|ound" is super
sc"'
'Surround' is super
</code></pre>

<p>a właściwie po co on wogóle, usuwamy cudzysłowy</p>

<pre class="prettyprint"><code>'Surro|und' is super
ds'
Surround is super
</code></pre>

<p>i wracamy do stanu początkowego. Właściwie to cała wiedza, którą musimy
znać. Kwestia tylko doboru selektora i znakdu otaczającego. Możemy
wybrać dowolny: <code>"</code>, <code>'</code>, <code>(</code>,<code>[</code>, <code>{</code> , <code>&lt;p&gt;</code></p>

<h3>Dla łatwego zapamiętania</h3>

<ul>
<li><code>dst</code> &#8211; <strong>d</strong>elete <strong>s</strong>elected <strong>t</strong>ag</li>
<li><code>cst</code> &#8211; <strong>c</strong>hange <strong>s</strong>elected <strong>t</strong>ag</li>
</ul>

<h3>Nieparzyste</h3>

<p>Nieparzyste znaki to takie, które są inne na początku i na końcu, dobrym
przykładem są tagi HTML/XML.
Otaczając tekst tagiem zostaje on automatycznie zamknięty na końcu.</p>

<pre class="prettyprint"><code>Surround
ysiw&lt;b&gt;
&lt;b&gt;Surround&lt;/b&gt;
cst&lt;p&gt;
&lt;p&gt;Surround&lt;/p&gt;
cst&lt;p class="highlight"&gt;
&lt;p class="highlight"&gt;Surround&lt;/p&gt;
</code></pre>

<p>Innym przykładem są znaki nawiasów, klamer itp. Generalną zasadą jest
to, że możemy użyć znaku otwierającego lub zamykającego. Różnica jest taka,
że w przypadku użycia znaku zamykającego zostanie dodana dodatkowa
spacja.</p>

<pre class="prettyprint"><code>Surround
ysiw(
( Surround )
</code></pre>

<p>lub</p>

<pre class="prettyprint"><code>Surround
ysiw)
(Surround)
</code></pre>

<h3>Tryb wizualny</h3>

<p>Surround dodaje trochę funkcjonalności także w trybie wizualnym
Możemy w tym trybie zaznaczyć fragment tekstu, wcisnąć <code>s</code> i dodać czym
chcemy otaczać.</p>

<pre class="prettyprint"><code>Surround jest super
Vs&lt;p&gt;
&lt;p&gt;Surround jest super&lt;/p&gt;
</code></pre>

<p>Ostanią czynnością, którą warto wspomnieć jest zaznaczanie za pomocą
surround. Otóż w trybie wizualnym możemy zaznaczyć tekst zgodnie z
symbolami otaczającymi. Dodatkowo mamy wybór czy zaznaczamy tekst
wewnątrz tych znaków czy też razem z nimi. 
Gdy chcemy zaznaczyć tekst wewnątrz używamy <code>i</code> (<strong>i</strong>nner) natomiast na
zewnątrz &#8211; <code>a</code> (<strong>a</strong>round)</p>

<p>symbol <code>|</code> oznacza pozycję kursora</p>

<pre class="prettyprint"><code>&lt;p&gt; Najlepszym pluginem do Vim jest &lt;b&gt;Suror|und&lt;/b&gt; (Tim Pope)&lt;/p&gt;
vitcSurround
&lt;p&gt; Najlepszym pluginem do Vim jest &lt;b&gt;Surround&lt;/b&gt; (Tim Pope)&lt;/p&gt;
</code></pre>

<p><code>v</code> &#8211; wejście w tryb wizualnym
<code>i</code> &#8211; wybór aby zaznaczało wewnątrz
<code>t</code> &#8211; wybieramy w obrębie tagu
<code>c</code> &#8211; zaznaczenie zmieniamy na
<code>Surround</code></p>

<pre class="prettyprint"><code>&lt;p&gt; Najlepszym pluginem do Vim jest &lt;b&gt;Surround&lt;/b&gt; (Tim |Pope)&lt;/p&gt;
va(d
&lt;p&gt; Najlepszym pluginem do Vim jest &lt;b&gt;Surround&lt;/b&gt; &lt;/p&gt;
</code></pre>

<h3>Zakończenie</h3>

<p>Warto używać surround, bardzo warto nawet nie wiecie jak szybko idzie
się do tego pluginu przyzwyczaić. Polecam korzystać.</p>
]]></content:encoded>
			<wfw:commentRss>http://marioosh.5dots.pl/2011/04/09/vim_pluginy_bez_ktorych_ciezko_zyc-surround.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RVM w skryptach powłoki</title>
		<link>http://marioosh.5dots.pl/2011/04/06/rvm-w-skryptach-powloki.html</link>
		<comments>http://marioosh.5dots.pl/2011/04/06/rvm-w-skryptach-powloki.html#comments</comments>
		<pubDate>Wed, 06 Apr 2011 12:18:43 +0000</pubDate>
		<dc:creator>marioosh</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[Bash]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[RVM]]></category>

		<guid isPermaLink="false">http://marioosh2.5dots.pl/?p=390</guid>
		<description><![CDATA[Wielokrotnie piszę skrypty powłoki, które automatyzują pewne czynności. Z resztą kto tego nie robi. Czasem jednak zdaża się, że w skryptach potrzebuję wykonać czynność na określonym gemsecie. Np. coś takiego: #!/bin/bash rvm use ruby-1.9.2-p180@moj_gemset rvm info &#124; grep gemset wynik: &#8230; <a href="http://marioosh.5dots.pl/2011/04/06/rvm-w-skryptach-powloki.html">czytaj dalej...</a>]]></description>
			<content:encoded><![CDATA[<p>Wielokrotnie piszę skrypty powłoki, które automatyzują pewne czynności.
Z resztą kto tego nie robi. Czasem jednak zdaża się, że w skryptach
potrzebuję wykonać czynność na określonym gemsecie. Np. coś takiego:</p>

<pre class="prettyprint"><code>#!/bin/bash

rvm use ruby-1.9.2-p180@moj_gemset
rvm info | grep gemset

wynik:
# Using (...snip...)/gems/ruby-1.9.2-p180@moj_gemset
# gemset:   ""
</code></pre>

<p>Czyli pokazuje, że przełączyło na odpowiedni gemset jednak następna
komenda już jest wykonywana poza nim.</p>

<p>Mieliście coś takiego?</p>

<span id="more-390"></span>

<p>Otóż przyczyną takiego zachowania jest to, że RVM może działać w dwóch
trybach: binarnie lub skryptowo.</p>

<p>Tryb binarny wykorzystany w skryptach nie potrafi zmienić zmiennych
powłoki a skryptowy tak, z tego powodu występują takie problemy.</p>

<p>Jeżeli zatem chcemy użyć RVM w naszym skrypcie powinniśmy dopisać gdzieś
na początku coś takiego:</p>

<pre class="prettyprint"><code>if [[ -s "/usr/local/rvm/scripts/rvm" ]] ; then
  source "/usr/local/rvm/scripts/rvm"
fi

# mam zainstalowane RVM globalnie w /usr/local/rvm
# jeżeli używamy normalnie to skryptu trzeba szukać w ~/.rvm/scripts/rvm
</code></pre>

<p>Od dzisiaj miną problemy z RVM wykorzystywanym w skryptach :)</p>
]]></content:encoded>
			<wfw:commentRss>http://marioosh.5dots.pl/2011/04/06/rvm-w-skryptach-powloki.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zmiana nazwy branch w Git</title>
		<link>http://marioosh.5dots.pl/2011/04/05/zmiana-nazwy-branch-w-git.html</link>
		<comments>http://marioosh.5dots.pl/2011/04/05/zmiana-nazwy-branch-w-git.html#comments</comments>
		<pubDate>Tue, 05 Apr 2011 12:10:52 +0000</pubDate>
		<dc:creator>marioosh</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[Git]]></category>

		<guid isPermaLink="false">http://marioosh2.5dots.pl/?p=388</guid>
		<description><![CDATA[Nigdy nie wierzyłem w takieg cuda, że ktoś może źle nazwać gałąź w systemie kontroli wersji albo że wogóle to ma dla kogoś aż takie znaczenie. Nie wierzyłem&#8230; do dzisiaj. Podczas pracy z ostatnim projektem kod został rozdzielony na dwie &#8230; <a href="http://marioosh.5dots.pl/2011/04/05/zmiana-nazwy-branch-w-git.html">czytaj dalej...</a>]]></description>
			<content:encoded><![CDATA[<p>Nigdy nie wierzyłem w takieg cuda, że ktoś może źle nazwać gałąź w
systemie kontroli wersji albo że wogóle to ma dla kogoś aż takie
znaczenie.</p>

<p>Nie wierzyłem&#8230; do dzisiaj. Podczas pracy z ostatnim projektem kod
został rozdzielony na dwie części aby móc opracować anglojęzyczną
wersję. Po kilkudniowej przerwie miałem podjąć się tego zadania i
znalazłem wyodrębniony kod we wszystkomówiącej nazwie gałęzi &#8222;Polish&#8221; :)</p>

<p>Na szczęście git umożliwia zmianę nazwy gałęzi bez niepotrzebnej
kompromitacji i tłumaczenia przed szefem ;)</p>

<pre class="prettyprint"><code>git branch -m obecna_nazwa nowa_nazwa
</code></pre>

<p>Co jednak ze zdalnym repozytorium?</p>

<span id="more-388"></span>

<p>To już nie jest sparawa aż tak prosta. Nie idzie zmienić nazwy zdalnego
repozytorium jedną komendą. Najprostrzym sposobem jest usunięcie gałęzi
pod złą nazwą i opublikowanie pod nową nazwą.</p>

<pre class="prettyprint"><code>git push origin :stara_nazwa
git push origin nowa_nazwa
</code></pre>

<p>Czasami jednak dochodzi do sytuacji gdzie chcemy zmienić nazwę gałęzi
master. Na przykład zmienić nazwę na master-old. Zarówno zdalnie jak i
lokalnie. Co wtedy?</p>

<pre class="prettyprint"><code># zmiana nazwy lokalnie
git branch -m master master-old
# usunięcie zdalnej gałęzi master
git push remote :master
# stworzenie master-old na zdalnym repozytorium
git push remote master-old
# stworzenie nowego lokalnego master
git checkout -b master galaz_z_ktorej_tworzymy_mater
# tworzymy master w zdalnym repozytorium
git push remote master
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://marioosh.5dots.pl/2011/04/05/zmiana-nazwy-branch-w-git.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Polonizacja Devise 1.2</title>
		<link>http://marioosh.5dots.pl/2011/03/29/polonizacja_devise_1-2.html</link>
		<comments>http://marioosh.5dots.pl/2011/03/29/polonizacja_devise_1-2.html#comments</comments>
		<pubDate>Tue, 29 Mar 2011 11:35:57 +0000</pubDate>
		<dc:creator>marioosh</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[Devise]]></category>
		<category><![CDATA[I18N]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://marioosh2.5dots.pl/?p=384</guid>
		<description><![CDATA[Jeżeli ktokowiek budował aplikację w Rails, która opiera się na devise i aplikacja ta nie była tylko w języku angielskim to na pewno natrafił na problem lokalizacji tego gema. Autorzy devise nie przyłożyli się do tej kwestii zbyt poważnie. Mimo, &#8230; <a href="http://marioosh.5dots.pl/2011/03/29/polonizacja_devise_1-2.html">czytaj dalej...</a>]]></description>
			<content:encoded><![CDATA[<p>Jeżeli ktokowiek budował aplikację w Rails, która opiera się na devise i
aplikacja ta nie była tylko w języku angielskim to na pewno natrafił na
problem lokalizacji tego gema. Autorzy <a href="http://github.com/plataformatec/devise">devise</a> nie przyłożyli się do tej kwestii zbyt poważnie.
Mimo, iż istnieje plik <code>devise.en.yml</code> w którm występuje cześć tekstów
to nie są to wszystkie.</p>

<p>Wiele tekstów wyświetlanych zarówno w widokach jak i w wysyłanych
wiadomościach email są &#8216;hardcoded&#8217; &#8211; czyli na sztywno umieszczone w
miejscach, które utrudniają ich edycję.</p>

<p>Kilka dni temu na światło dzienne wyszła nowa wersja tego gema oznaczona
numerem 1.2, która po części naprawiła powyższe problemy. Jednocześnie
jednak stworzyła kilka kolejnych.</p>

<span id="more-384"></span>

<p>Udało mi się uzupełnić stare tłumaczenia o nowe i umieściłem całość w
<a href="http://gist.github.com/891279">tym miejscu</a>.</p>

<h3>Nowy problem</h3>

<p>Domyślnie w Devise, gdy rejestrujemy się w systemie, to automatycznie
zostajemy do niego zalogowani. Chyba, że w opcjach mamy ustawiony
obowiązek aktywacji konta poprzez email. W takiej sytuacji nowa wersja
wyświetla nam komunikat:
&#8222;Rejestracja zakończyła się pomyślnie. Nie zostałeś jednak zalogowany ponieważ konto jest %{reason}.&#8221;</p>

<p>No właśnie czym jest ten <strong>reason</strong>?</p>

<p>Reason jak łatwo się domyśleć jest powodem dlaczego nie zostaliśmy
zalogowani automatycznie. Domyślnie, gdy nie aktywujemy konta to reason
jest równe &#8222;unconfirmed&#8221;.</p>

<p>Niestety komunikat o treści:
&#8222;Rejestracja zakończyła się pomyślnie. Nie zostałeś jednak zalogowany ponieważ konto jest unconfirmed.&#8221;
nie brzmi zbyt dobrze. Próbowałem kilku sposobów umieszczenia
tłumaczenia w pliku polonizacyjnym, zawsze w innym miejscu jednak ciągle
kończyło się to fiaskiem.</p>

<p>Jak zatem uzyskać ładne tłumaczenie?
Znalazłem winowajcę w module <code>Confirmable</code>. Otóż jest tam metoda
<code>inactive_message</code>, która jest wywoływana gdy musi umieścić coś w treści
podanej wyżej wiadomości jako <code>reason</code>.</p>

<pre class="prettyprint"><code>    def inactive_message
       !confirmed? ? :unconfirmed : super
    end
</code></pre>

<p>Zwracany symbol jest zamieniany na string i umieszczany w treści
wiadomości.</p>

<p>Jeżeli zatem chcemy cieszyć się ładnym, w pełni polskim komunikatem to
musimy albo skorzystać z <code>monkey patching</code> tej metody, albo zmienić
komunikat wiadomości w pliku polonizującym tak aby nie używał
<code>%{reason}</code>.</p>

<p>Ja skorzystałem z pierwszego sposobu i gdzieś w initializatorach
umieściłem kawałek kodu:</p>

<pre class="prettyprint"><code>module Devise
  module Models
    module Confirmable

      def inactive_message
        !confirmed? ? "niekatywne" : super
      end

    end
  end
end
</code></pre>

<p>Działać &#8211; działa. Jednak czy <code>monkey patching</code> jest odpowiednim sposobem
na coś tak prostego?</p>
]]></content:encoded>
			<wfw:commentRss>http://marioosh.5dots.pl/2011/03/29/polonizacja_devise_1-2.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

