<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>myGeeBlog</title>
	
	<link>http://urzenia.net</link>
	<description>czyli kolejny blog programisty</description>
	<lastBuildDate>Sat, 10 Jul 2010 20:21:41 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1-alpha</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/mysz" /><feedburner:info uri="mysz" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>[MySQL] Wybieranie elementów we własnej kolejności</title>
		<link>http://feedproxy.google.com/~r/mysz/~3/PMErLqo8SDI/</link>
		<comments>http://urzenia.net/473/mysql-wybieranie-elementow-we-wlasnej-kolejnosci/#comments</comments>
		<pubDate>Thu, 15 Apr 2010 20:48:10 +0000</pubDate>
		<dc:creator>MySZ</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[programowanie]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://urzenia.net/?p=473</guid>
		<description><![CDATA[Dziś kumpel miał za zadanie zrobić prostą funkcję, która z kolekcji usług spełniających odpowiednie kryteria wybierze jedną, której da specjalne przywileje. Jeśli w wybranym zestawie znajdzie się usługa danego typu, to tej usłudze, pierwszej w kolejności należy te przywileje dać. Tych usług spełniających kryteria nawet w najgorszym wypadku nie ma więcej jak kilkanaście, więc można [...]]]></description>
			<content:encoded><![CDATA[<p>Dziś <a href="http://0x20.pl">kumpel</a> miał za zadanie zrobić prostą funkcję, która z kolekcji usług spełniających odpowiednie kryteria wybierze jedną, której da specjalne przywileje. Jeśli w wybranym zestawie znajdzie się usługa danego typu, to tej usłudze, pierwszej w kolejności należy te przywileje dać.</p>
<p>Tych usług spełniających kryteria nawet w najgorszym wypadku nie ma więcej jak kilkanaście, więc można wybrać sobie wszystkie do (w tym przypadku) Perla, i odpowiednią pętlą z warunkami znaleźć te co trzeba. Zamiast tego, przerzuciliśmy to do MySQL, sortując tych kilka elementów:</p>
<pre><code>[...] ORDER BY `type`, `id` LIMIT 1[...]</code></pre>
<p>Byłoby idealnie, gdyby nie to, że najbardziej potrzebny nam typ wcale nie jest pierwszy w kolejności (niezależnie czy pierwszy od początku czy od końca ;) ). Zakładając, że mamy typy liczbowe: 1, 2, 3, 4, 5, i chcemy mieć je w kolejności: najpierw wszystkie z typu 3, później wszystkie z typu 5, kolejno wszystkie z typu 2, a reszta bez znaczenia, to zaczyna robić się ciekawie ;) Jednym ze sposobów jest użycie <a href="http://dev.mysql.com/doc/refman/5.1/en/union.html">UNII</a>. My użyliśmy innego: <a href="http://dev.mysql.com/doc/refman/5.1/en/string-functions.html#function_field">funkcji FIELD()</a>. Jak działa w ogóle ta funkcja, można przeczytać w podlinkowanym kawałku manuala. Niżej za to jest przykład, jak jej użyć do naszego celu:</p>
<pre><code>SELECT `f1`, `f2`, `type` FROM `table` WHERE [warunki] ORDER BY FIELD(`type`, 3, 5, 2, 1, 4) ASC, `id` ASC</code></pre>
<p>Tym sposobem mamy posortowane <strong>tak jak chcemy</strong> elementy, i mniej zabawy po odebraniu danych ;) Ale uwaga: to nie jest optymalne rozwiązanie, jeśli trzeba przetworzyć większą ilość elementów! Użycie funkcji (w tym wypadku <code>FIELD()</code>) <ins>przy sortowaniu</ins>/w warunku spowoduje że MySQL będzie musiał gdzieś sobie przechować dane do posortowania, i zazwyczaj użyje tabeli tymczasowej (chyba że tych danych będzie niewiele). A jedno z drugim potrafi nieco zamulić maszynę ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://urzenia.net/473/mysql-wybieranie-elementow-we-wlasnej-kolejnosci/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://urzenia.net/473/mysql-wybieranie-elementow-we-wlasnej-kolejnosci/</feedburner:origLink></item>
		<item>
		<title>4Developers</title>
		<link>http://feedproxy.google.com/~r/mysz/~3/nJl20ERWU48/</link>
		<comments>http://urzenia.net/468/4developers/#comments</comments>
		<pubDate>Sat, 27 Mar 2010 12:31:55 +0000</pubDate>
		<dc:creator>MySZ</dc:creator>
				<category><![CDATA[4developers]]></category>
		<category><![CDATA[it]]></category>
		<category><![CDATA[konferencja]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://urzenia.net/?p=468</guid>
		<description><![CDATA[Wczoraj odbyła się druga konferencja z serii 4Developers. I ja tam byłem, Allegro i herbatę piłem, ciastek się najadłem i w ogóle ;) Sama konferencja była podzielona na 4 ścieżki: Zarządzanie projektami IT, Java, .Net &#038; C# oraz PHP. Ja wybrałem sobie kilka wykładów z Zarządzania projektami IT (w sumie większość) i zahaczyłem także o [...]]]></description>
			<content:encoded><![CDATA[<p>Wczoraj odbyła się druga konferencja z serii <a href="http://2010.4developers.org.pl/">4Developers</a>. I ja tam byłem, <em>Allegro</em> i herbatę piłem, ciastek się najadłem i w ogóle ;)</p>
<p>Sama konferencja była podzielona na 4 ścieżki: <a href="http://2010.4developers.org.pl/zarzadzanie-projektami-it-agenda">Zarządzanie projektami IT</a>, <a href="http://2010.4developers.org.pl/java-agenda">Java</a>, <a href="http://2010.4developers.org.pl/net-c-agenda">.Net &#038; C#</a> oraz <a href="http://2010.4developers.org.pl/php-agenda">PHP</a>. Ja wybrałem sobie kilka wykładów z <em>Zarządzania projektami IT</em> (w sumie większość) i zahaczyłem także o wykłady nt. <em>PHP</em>.</p>
<p>Pierwszy wykład na którym byłem, była to zrealizowana w formacie <a href="http://pl.wikipedia.org/wiki/Pecha_Kucha">Pecha Kucha</a> (coś na kształt <a href="http://en.wikipedia.org/wiki/Lightning_talk">Lightning Talk</a>) seria 3 prezentacji na tematy dotyczące, a jakże, zarządzania ;) Podobało mi się, 3 panów z organizacji <a href="http://www.poznan.pmi.org.pl/">PMI Poznań</a> fajnie poopowiadało o tematach takich jak &#8220;Produktywne lenistwo&#8221;, &#8220;Przyczyny porażek startupów&#8221; i &#8220;Projekt w opałach&#8221;. Wykłady dużo nowego mi nie powiedziały, ale kilka rzeczy nazwały po imieniu w miejscach gdzie się czegoś domyślałem, albo zwróciły mi na coś uwagę. Ogólnie zdecydowanie za.</p>
<p>Kolejny wykład który mnie interesował, odbył się w tej samej sali, też z <em>Zarządzania projektem IT</em>. Tym razem <a href="http://2010.4developers.org.pl/prelegenci/monika-konieczny">Monika Konieczny</a> opowiadała o tym, jak można pogodzić/ułatwić współpracę testerów z programistami. Trzeba przyznać, że Monika miała świetny pomysł z ciastem ;) Oprócz tego, że wykład dał mi sporo tematów do przemyśleń i podsunął trochę pomysłów, to z przyjemnością patrzyło się na kogoś kto z łatwością i zaangażowaniem prowadził zajęcia. Widać było, że Monika raz, wiedziała o czym mówi, dwa, ma sporo swoich przemyśleń na ten temat, trzy, była doskonale przygotowana. Myślę że dla mnie to najlepszy wykład na całej konferencji. A Monice tylko pogratulować :)</p>
<p>Na następny wykład miałem dylemat: pójść na <em>PHP</em>: &#8220;Aplikacje internetowe wydajne od początku&#8221;, czy zostać na <em>Zarządzaniu projektami IT</em>: &#8220;Zarządzanie rozwojem oprogramowania – nieco bardziej &#8216;funky&#8217;&#8221;. W końcu stwierdziłem że trochę technikaliów mi nie zaszkodzi, poszedłem sobie na <em>PHP</em>. Jeszcze wtedy nie wiedziałem co czynię&#8230; Panowie niestety nie dość że byli słabo przygotowani do wykładu (więcej czytali ze slajdów niż byli w stanie powiedzieć, patrzyli co chwila na siebie, który ma właśnie mówić etc), to nie do końca mieli pojęcie o czym mówią. Niestety. Być może później wyprostowali trochę swój wizerunek, ale tego już nie wiem, bo wyszedłem po 15 minutach. Po tym jak kilkukrotnie potraktowali wymiennie bufor z cache (używali tych słów jak synonimów), a wcześniej puścili kilka innych bezsensownych stwierdzeń. Najgorszy z możliwych wykładów IMHO.</p>
<p>Po tym jak uciekłem z &#8220;Aplikacji internetowych wydajnych od początku&#8221;, poszedłem na wspomniane &#8220;Zarządzanie rozwojem oprogramowania – nieco bardziej &#8216;funky&#8217;&#8221;. <a href="http://2010.4developers.org.pl/prelegenci/peter-horsten">Peter Horsten</a> poopowiadał nieco o rzeczach które znałem już doskonale, więc sam temat mnie nie do końca zainteresował (myślałem że będzie to nieco głębsze wejście w temat, tutaj było tylko pobieżnie), ale sam sposób prowadzenia wykładu to bajka. Najlepiej poprowadzony wykład na całym 4Developers, z tych na których byłem. Peter z lekkością i wprawą poopowiadał o wszystkim, z humorem, etc. Z przyjemnością go słuchałem :)</p>
<p>Po lunchu znów poszedłem na wykład <em>PHP</em>: &#8220;PHP wysokiej wydajności&#8221;. Tutaj było zdecydowanie lepsze przygotowanie techniczne <a href="http://2010.4developers.org.pl/prelegenci/mariusz-gil">Mariusza Gila</a> niż kolegów od wydajności z poprzedniego wykładu. Nie było już wrażenia że nie wie o czym mówi, wręcz przeciwnie, większość tego o czym wspominał znam z własnych testów, choć nigdy nie miałem tak porywającego serwisu napisanego w PHP żebym musiał to stosować w praktyce :) Ogólnie sam wykład mnie nie szczególnie zainteresował, bo bardzo niewiele nowego miałem okazję się dowiedzieć (zapisałem sobie chyba tylko kilka nazw narzędzi z którymi warto żebym się zapoznał), ale oceniam go znacznie wyżej niż poprzedników ;)</p>
<p>Później już nie wychodziłem ze ścieżki &#8220;Zarządzania projektami IT&#8221;. Najpierw <a href="http://2010.4developers.org.pl/prelegenci/jakub-dabkowski">Jakub Dąbkowski</a> w fajny sposób, z humorem, poopowiadał o jednym z aspektów <a href="http://pl.wikipedia.org/wiki/Scrum">metodyki Scrum</a>, czyli o pytaniach jakie są ważne podczas &#8220;scrum meeting&#8221;. Wykład oceniam wysoko, Jakub zwrócił uwagę na powody dla których te pytania są ważne dla członków zespołu. </p>
<p>Następnie byłem na &#8220;Praktyce zarządzania portfelem projektów IT&#8221;. Okazało się jednak, że temat nie zainteresował mnie tak bardzo jak na to liczyłem. Wygląda na to, że te 40 minut jakie miał <a href="http://2010.4developers.org.pl/prelegenci/szymon-wlochowicz">Szymon Włochowicz</a> to zdecydowanie za mało na omówienie choćby częściowo tego tematu, usłyszeliśmy ledwie zajawkę, więc na sali było sporo osób które, jak mi się wydaje, podobnie jak ja nie zostali przekonani do takiego podejścia.</p>
<p>Ostatnim wykładem był &#8220;Łączenie ognia i wody – proces projektowy w Gratka Technologie&#8221;, ale tutaj było za mało interesujących tematów, ot, prelegent poopowiadał o swoich doświadczeniach, niestety myślę że zrobił to nieco za wcześnie, gdyż jeszcze miał ich nieco za mało. Mam mocno mieszane uczucia odnośnie tej prezentacji.</p>
<p>Ogólnie jestem bardzo zadowolony z całości. Ciekawe wykłady, rewelacyjne hostessy ;) darmowy wyjazd (sponsorowany przez firmę ;) ), i nie za daleko od domu (w sensie: mało czasu straconego w ciapągu) &#8211; zdecydowanie było warto :) Do tego stopnia, że jak tylko będę miał możliwość, to w przyszłym roku na pewno się wybiorę na kolejną edycję &#8211; nawet pomimo tego że konkurs komiksowy wygrał rysunek uzupełniony z oryginalnego Garfielda, a nie nasz :)</p>
]]></content:encoded>
			<wfw:commentRss>http://urzenia.net/468/4developers/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://urzenia.net/468/4developers/</feedburner:origLink></item>
		<item>
		<title>Za Ile Wolne?</title>
		<link>http://feedproxy.google.com/~r/mysz/~3/IoNnyBdWXmE/</link>
		<comments>http://urzenia.net/448/za-ile-wolne/#comments</comments>
		<pubDate>Mon, 01 Mar 2010 21:54:20 +0000</pubDate>
		<dc:creator>MySZ</dc:creator>
				<category><![CDATA[humor]]></category>
		<category><![CDATA[programowanie]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://urzenia.net/?p=448</guid>
		<description><![CDATA[Bawię się ;) Zainspirowany serwisem Kiedy Będzie Wielkanoc by Marcin Kaszyński, zrobiłem sobie bardziej ogólną zabawkę ;) Moja wersja pokazuje najbliższy dzień wolny &#8211; uwzględnia weekendy i święta (według listy z Wikipedii) :) Jeśli ktoś chce, to może kliknięciem sobie wyłączyć wyliczanie dla sobót i/lub niedziel (prawy górny róg), ale nie jest to na razie [...]]]></description>
			<content:encoded><![CDATA[<p>Bawię się ;)</p>
<p>Zainspirowany serwisem <a href="http://kiedybedziewielkanoc.pl">Kiedy Będzie Wielkanoc</a> by <a href="http://marcinkaszynski.com">Marcin Kaszyński</a>, zrobiłem sobie bardziej ogólną zabawkę ;) Moja wersja pokazuje najbliższy dzień wolny &#8211; uwzględnia weekendy i święta (według listy z <a href="http://pl.wikipedia.org/wiki/Dni_wolne_od_pracy">Wikipedii</a>) :) Jeśli ktoś chce, to może kliknięciem sobie wyłączyć wyliczanie dla sobót i/lub niedziel (prawy górny róg), ale nie jest to na razie zapamiętywane (będzie pewnie w ciachu). I tyle ;)</p>
<p>Dostępne pod: <a href="http://zailewolne.pl/">ZaIleWolne.pl</a> &#8211; enjoy! ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://urzenia.net/448/za-ile-wolne/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://urzenia.net/448/za-ile-wolne/</feedburner:origLink></item>
		<item>
		<title>Moje ulubione programy na Mac OS X</title>
		<link>http://feedproxy.google.com/~r/mysz/~3/vxBbdZeXo-o/</link>
		<comments>http://urzenia.net/436/moje-ulubione-programy-na-mac-os-x/#comments</comments>
		<pubDate>Tue, 05 Jan 2010 00:38:08 +0000</pubDate>
		<dc:creator>MySZ</dc:creator>
				<category><![CDATA[mac]]></category>

		<guid isPermaLink="false">http://urzenia.net/?p=436</guid>
		<description><![CDATA[Używałem już Windowsa, używałem przez wiele lat Linuksa. Od ponad roku mam okazję pracować na co dzień na Macu &#8211; i nie wrócę już ani do Linuksa (którego bardzo sobie chwaliłem), ani do Windowsa (którego chwaliłem sobie znacznie mniej :) ). Mac to dla mnie świetne połączenie obydwóch wspomnianych na początku systemów: prostoty obsługi Windowsa, [...]]]></description>
			<content:encoded><![CDATA[<p>Używałem już Windowsa, używałem przez wiele lat Linuksa. Od ponad roku mam okazję pracować na co dzień na Macu &#8211; i nie wrócę już ani do Linuksa (którego bardzo sobie chwaliłem), ani do Windowsa (którego chwaliłem sobie znacznie mniej :) ). Mac to dla mnie świetne połączenie obydwóch wspomnianych na początku systemów: prostoty obsługi Windowsa, i mocy i funkcjonalności Linuksa. Tyle tytułem wstępu :)</p>
<p>Postanowiłem sobie zrobić małą listę programów na Maca (czasem nie tylko), bez których nie wyobrażam sobie pracy &#8211; lub które mi ją po prostu uprzyjemniają :) a jednocześnie spowodować aby coś się w końcu na tym blogu pojawiło ;)</p>
<dl>
<dt>Firefox</dt>
<dd>nie do zastąpienia. 2 tematy: FireBug i AdBlock. Bez żadnego z nich nie wyobrażam sobie codziennej pracy, ani codziennego surfowania po internecie :) I nie, ta namiastka AdBlocka która jest na Safari, nie upoważnia tegoż ostatniego do prób pracy na nim ;)</dd>
<dt>Thunderbird</dt>
<dd>znów nie do zastąpienia. Mail.app może i jest ładny, ale przy takim przemiale poczty jaki czasem mam (potrafię odebrać w ciągu godziny 2-3k wiadomości), średnio się wyrabia. Do tego współpraca z IMAP &#8211; no średnio to działało podczas moich ostatnich testów&#8230; Thunderbird nie ma tych problemów, szczególnie wersja 3.0, którą od wczesnych alf używam już dłuuuugi czas. Śmiga jak ta lala :)</dd>
<dt>ForkLift</dt>
<dd>Finder jest do bani ;) Fork Lift to próba przeniesienia na grunt Macowy Windowsowego Total Commandera. Dwa panele, szybkość, stabilność, funkcjonalność &#8211; nie do zastąpienia :)</dd>
<dt>Things</dt>
<dd>program do GTD (w skrócie: planowanie i szeregowanie zadań). Nie poradziłbym sobie bez niego ;)</dd>
<dt>Adium</dt>
<dd>(multi)komunikator. Dla mnie tylko i wyłącznie jako klient Jabbera.</dd>
<dt>Terminal</dt>
<dd>wspominałem coś o potędze Linuksa? :) Dla mnie terminal i polecenia wydawane na konsoli to codzienność ;)</dd>
<dt>MacVim</dt>
<dd>edytor tekstu, IDE i takie tam. Wcześniej używałem w wersji gVim, teraz w wydaniu Macowym. Ma wszystko czego mi potrzeba, a nawet dużo więcej. Prawie wszystkie tysiące linii kodu które wyklepałem, powstały w którejś wersji Vima :)</dd>
<dt>Caffeine</dt>
<dd>pozwala na wyłączenie wygaszania się ekranu. Czasowe lub do momentu deaktywacji.</dd>
<dt>1Password</dt>
<dd>doskonały program do zarządzania wszystkim co ma być bezpieczne. Domyślnie zarządzał loginami i hasłami do różnych serwisów w internecie, ale od jakiegoś czasu posiada także funkcjonalność zachowywania bezpiecznych notatek, seriali do programów i wielu innych.</dd>
<dt>BetterTouchTool</dt>
<dd>super narzędzie, którego nie widać ;) Pozwala na doskonałą konfigurację gestów gładzika (i/lub Magic Mouse) dla różnych programów, po czym można o nim zapomnieć :)</dd>
<dt>Cog</dt>
<dd>mam nadzieję że nie tylko ja uważam, że iTunes to straszna kobyła, której nie ma jak wygodnie używać? ;) Cog to prosty, wygodny odtwarzacz muzyki. I tylko odtwarzacz muzyki. Zarządzanie moimi muzycznymi zasobami należy do mnie, i tylko do mnie.</dd>
<dt>Desktop 2 Login</dt>
<dd>mini programik, pozwalający na łatwą zmianę tapety na ekranie logowania.</dd>
<dt>FreeMind</dt>
<dd>programik do tworzenia map myśli. Brzydki i w Javie, ale niezwykle funkcjonalny i darmowy :) Pozwala na to co lubię najbardziej: wygodną i szybką pracę z klawiatury.</dd>
<dt>Isolator</dt>
<dd>pozwala na proste odsunięcie w tło wszystkich rozpraszaczy (komunikator, program pocztowy), i ułatwia skupienie się na tym co powinno się w danym momencie robić ;)</dd>
<dt>Skim</dt>
<dd>najlepszy, IMHO, program do czytania PDF.</dd>
<dt>Lingon</dt>
<dd>łatwe zarządzanie demonami. Znacznie wygodniejsze niż launchctl ;)</dd>
<dt>Max</dt>
<dd>ripper płyt Audio. Darmowy i funkcjonalny :)</dd>
<dt>SimplyBurns</dt>
<dd>nagrywanie płyt z danymi, audio, kopiowanie etc.</dd>
<dt>MPlayer OSX</dt>
<dd>czyli MPlayer w wersji dla Mac. Odtwarzanie filmów w najlepszej postaci :)</dd>
<dt>TrueCrypt</dt>
<dd>nie chcę uruchamiać File Vault, który powoduje zakodowanie całego folderu domowego. Wolę mieć zaszyfrowanych kilka folderów (np. z pocztą etc) i podmontowywać je w razie potrzeby.</dd>
<dt>GeekTool</dt>
<dd>pozwala na wyświetlanie na pulpicie zawartości pliku (np. logi), wyniku wykonywania się jakiegoś programu lub obrazka, z dowolnie wybraną szybkością odświeżania zawartości etc.</dd>
<dt>iStatMenus</dt>
<dd>monitoring systemu na bieżąco. Wyświetla dużo ciekawych informacji na temat tego co bieżąco dzieje się z systemem :)</dd>
</dl>
<p>Wyszło tego trochę&#8230; To oczywiście nie wszystkie, ale najważniejsze które mi się rzuciły w oczy podczas przeglądania folderu /Applications ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://urzenia.net/436/moje-ulubione-programy-na-mac-os-x/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://urzenia.net/436/moje-ulubione-programy-na-mac-os-x/</feedburner:origLink></item>
		<item>
		<title>BlipApi.py – 0.02.03</title>
		<link>http://feedproxy.google.com/~r/mysz/~3/qnGKNyz7XbA/</link>
		<comments>http://urzenia.net/424/blipapipy-00203/#comments</comments>
		<pubDate>Sun, 19 Apr 2009 09:27:00 +0000</pubDate>
		<dc:creator>MySZ</dc:creator>
				<category><![CDATA[blip]]></category>
		<category><![CDATA[bliposfera]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://urzenia.net/?p=424</guid>
		<description><![CDATA[Jakiś czas temu chciałem pobawić się Blip!em za pomocą Pythona. Ot, mam w planach zrobienie sobie coś a&#8217;la Sekretarka (która oddaje nieocenione usługi &#8211; dzięki ^TomaszTopa :) ), tyle żeby wysyłał codziennie lisię prywatnych i kierowanych do mnie statusów na maila. Prosta dość sprawa, trzeba tylko do tego zasiąść ;) Ale nadszedł ten dzień, i [...]]]></description>
			<content:encoded><![CDATA[<p>Jakiś czas temu chciałem pobawić się <a href="http://blip.pl">Blip!</a>em za pomocą <a href="http://python.org">Python</a>a. Ot, mam w planach zrobienie sobie coś a&#8217;la <a href="http://szmerybajery.pl/sekretarka/">Sekretarka</a> (która oddaje nieocenione usługi &#8211; dzięki <a href="http://tomasztopa.blip.pl">^TomaszTopa</a> :) ), tyle żeby wysyłał codziennie lisię prywatnych i kierowanych do mnie statusów na maila. Prosta dość sprawa, trzeba tylko do tego zasiąść ;) Ale nadszedł ten dzień, i się zmusiłem. Jako, że wiedziałem że do Blip!a istnieją aż dwie biblioteki napisane w Pythonie (<a href="http://blip.wikidot.com/aplikacje">lista różnych aplikacji</a> znajduje się na <a href="http://blip.wikidot.com/">Blip!owym wiki</a>), to po prostu uznałem że skorzystam z którejś z nich&#8230; Ech, za dobrze by było. Żadna z nich nie jest na tyle kompletnym rozwiązaniem, żeby jej w normalnych warunkach użyć. Oczywiście nie mam pretensji do ich autorów &#8211; stworzyli narzędzie którego potrzebowali, i podzielili się nim ze światem, czyli jest OK :)</p>
<p>Jednak to spowodowało na razie zarzucenie moich planów o Pythonowej Emailowej Sekretarce ™ ;) Owszem, również mógłbym napisać w sumie dwa polecenie do pobierania statusów kierowanych i prywatnych (<em>directed_messages</em> i <em>private_messages</em>) ale ja lubię kompleksowe rozwiązania &#8211; tak samo jak dla <a href="http://wp-blip.googlecode.com">WP-Blip!</a>a napisałem BlipApi.php :)</p>
<p>Jest w tej chwili jeden drobny błąd (zauważony przez <a href="http://mrk.blip.pl">^mrk</a> &#8211; <a href="http://mrk.jogger.pl">jego blog</a>, dzięki :) ) związany z tym, że podczas testowania siedziałem w folderze gdzie są wszystkie pliki bilbioteki, i tak jakoś było łatwiej&#8230; no i w tej chwili nie działa to poprawnie jako osobny moduł Pythona tylko jak luźne pliki które gdzieś w PYTHONPATH trzeba umieścić ;) Błąd ten, jako że zaczynam dochodzić do się, niedługo postaram się naprawić oczywiście, być może zgłoszę też bibliotekę do <a href="http://pypi.python.org/pypi">Python Package Index</a>. A na razie zapraszam do pobierania: <a href="http://code.google.com/p/blipapi/downloads/list?can=2&#038;q=.py">blipapi.googlecode.com</a>, używania i <a href="http://code.google.com/p/blipapi/issues/list">zgłaszania problemów i/lub nowych featur</a> :)</p>
]]></content:encoded>
			<wfw:commentRss>http://urzenia.net/424/blipapipy-00203/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://urzenia.net/424/blipapipy-00203/</feedburner:origLink></item>
		<item>
		<title>PHPPHP</title>
		<link>http://feedproxy.google.com/~r/mysz/~3/8nVtY_zzTU4/</link>
		<comments>http://urzenia.net/410/phpphp/#comments</comments>
		<pubDate>Fri, 17 Apr 2009 16:59:03 +0000</pubDate>
		<dc:creator>MySZ</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[humor]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programowanie]]></category>

		<guid isPermaLink="false">http://urzenia.net/?p=410</guid>
		<description><![CDATA[Dawno tu nie pisałem&#8230; No cóż, (bardzo) dużo pracy, życie osobiste i takie tam &#8211; to odstrasza od blogowania ;) Jeśli już, to od czasu do czasu coś publikuję jeśli chodzi o zdjęcia, a sprawy &#8220;kodowe&#8221; to raczej &#8220;robię&#8221; niż o nich piszę :) Jako że od kilka dni jestem na L4, to się ostro [...]]]></description>
			<content:encoded><![CDATA[<p>Dawno tu nie pisałem&#8230; No cóż, (bardzo) dużo pracy, życie osobiste i takie tam &#8211; to odstrasza od blogowania ;) Jeśli już, to od czasu do czasu coś publikuję jeśli <a href="http://h2o.sztolcman.eu">chodzi o zdjęcia</a>, a sprawy &#8220;kodowe&#8221; to raczej &#8220;<a href="http://code.google.com/u/urzenia/">robię</a>&#8221; niż o nich piszę :)</p>
<p>Jako że od kilka dni jestem na <a href="http://pl.wikipedia.org/wiki/Zwolnienie_lekarskie">L4</a>, to się ostro opierdzielam, ale dopiero dziś jestem w stanie podjąć jakikolwiek intelektualny wysiłek&#8230; No to popatrzyłem sobie m.in. na <a href="http://goldenline.pl">GoldenLine</a>. Dziś na forum PHPowym ktoś poruszył dość banalny problem, ktoś inny podrzucił rozwiązanie (<a href="http://php.net/preg_replace_callback"><code>preg_replace_callback ()</code></a>, a ja zacząłem się zastanawiać czemu wszyscy w PHP tak napierają na <a href="http://pl.wikipedia.org/wiki/Regexp">regexp</a>y (rozumiem w Perlu, ale PHP?). Jak zacząłem się zastanawiać jak to zrobić bez regexpów, to zacząłem się bawić w zakodowanie tego ;)</p>
<p>Najpierw zrobiłem dość banalną wersję, przy użyciu <a href="http://php.net/strlen">strlen ()</a>, <a href="http://php.net/strpos">strpos ()</a> i <a href="http://php.net/substr">substr ()</a>, i chciałem ją podać jako wersję <em>hardcore</em> ;) Wtedy pomyślałem sobie, że prawdziwa wersja <em>hardcore</em>, to byłaby bez użycia tychże funkcji&#8230; najprostsza postać tego to zastąpienie tychże funkcji swoimi ;) I o ile <code>substr ()</code> i <code>strpos ()</code> są dość banalne, o tyle dla mnie prawdziwym <em>hardcorem</em> jest <code>strlen ()</code> ;)</p>
<p>Oczywiście nie są to najbardziej <del datetime="2009-04-18T14:26:09+00:00">optymalne</del> <ins datetime="2009-04-18T14:26:09+00:00">wydajne</ins> rozwiązania (a jeśli są to tylko przypadkiem), bo jeśli chodzi o optymalizację, <del datetime="2009-04-18T14:26:09+00:00">to trzeba by używać wersji natywnych</del> <ins datetime="2009-04-18T14:26:09+00:00">to trzeba by się najpierw zastanowić i sprawdzić czy jest co optymalizować</ins>&#8230; :) <strong>A całość warto potraktować stricte jako zabawę</strong>, którą dla mnie było pisanie tego :)</p>
<p>W całym &#8220;problemie&#8221; chodziło o zastąpienie w tekście wystąpień &#8220;[userId]ID[/userId]&#8221; tym, co zostanie wyplute przez dodatkową funkcję której podajemy zawartość tego co jest między znacznikami. Użycie <code>preg_replace_callback ()</code> jest chyba najbardziej intuicyjnym rozwiązaniem, ale nie jedynym&#8230; :) Poniżej obydwie wersje: <a href="#hardcore"><em>hardcore</em></a> i <a href="#hardcore2"><em>bardziej hardcore</em></a> &#8211; enjoy ;)</p>
<h2><a name="hardcore"><em>hardcore</em></a></h2>
<pre><code>function replace_user_id ($str, $fn) {
    $tags = array ('start' => '[userId]', 'end' => '[/userId]');
    $tag_len = array (
        'start' => strlen ($tags['start']),
        'end'   => strlen ($tags['end'])
    );
    $offset = $pos_end = 0;
    $ret    = '';
    $strlen = strlen ($str);

    while ($pos_end < $strlen) {
        if (
            ($pos_start = strpos ($str, $tags['start'], $pos_end)) !== false &#038;&#038;
            ($pos_end   = strpos ($str, $tags['end'], $pos_start)) !== false
        ) {
            $ret .= substr ($str, $offset, $pos_start - $offset);
            $pos_start += $tag_len['start'];

            $ret .= $fn (substr ($str, $pos_start, $pos_end - $pos_start));

            $pos_end += $tag_len['end'];
            $offset = $pos_end;
        }
        else {
            break;
        }
    }

    return $ret;
}</code></pre>
<h2><a name="hardcore2"><em>bardziej hardcore</em></a></h2>
<pre><code>class __mstrlen__ErrH {
    private static $error = false;
    private function __construct () {}
    static public function errh ($errno, $errstr, $errfile = '', $errline = 0, $errctx = array ()) {
        if ($errno != E_NOTICE) {
            return false;
        }

        $expected = 'Uninitialized string offset';
        for ($i=0; $i<26; ++$i) {
            if ($expected[$i] != $errstr[$i]) {
                return false;
            }
        }

        self::$error = true;
    }
    public static function isError () {
        return self::$error;
    }
    public static function zero () {
        self::$error = false;
    }
}

function mstrlen ($str) {
    $str = (string) $str;

    $len = -1;
    __mstrlen__ErrH::zero ();
    set_error_handler (array ('__mstrlen__ErrH', 'errh'), E_NOTICE);
    while (__mstrlen__ErrH::isError () === false) {
        ++$len;
        $q = $str[$len];
    }

    restore_error_handler ();
    return $len < 0 ? 0 : $len;
}

function mstrpos ($str, $seek, $offset=0) {
    if (!is_int ($offset) || $offset < 0) {
        $offset = 0;
    }

    $str_len = mstrlen ($str);
    if ($offset > $str_len) {
        return false;
    }

    $seek_len = mstrlen ($seek);
    for ($i=$offset; $i < $str_len; ++$i) {
        for ($j=0; $j < $seek_len; ++$j) {
            if ($str[$i + $j] != $seek[$j]) {
                break;
            }
        }

        if ($j == $seek_len) {
            return $i;
        }
    }
    return false;
}

function msubstr ($str, $start, $length = null) {
    $str_len = mstrlen ($str);
    if (!is_int ($start)) {
        trigger_error ('Incorrect offset');
    }
    else if ($start >= $str_len) {
        return false;
    }
    else if ($start < 0) {
        $start = $str_len + $start;
    }

    if (!is_int ($length)) {
        $length = $str_len - $start;
    }
    else if ($length < 0) {
        $length = $str_len + $length - $start;
    }
    else if ($length + $start > $str_len) {
        $length = $str_len - $start;
    }

    $ret = '';
    for ($i=0; $i < $length; ++$i) {
        $ret .= $str[$i + $start];
    }

    return $ret;
}

function replace_user_id2 ($str, $fn) {
    $tags = array ('start' => '[userId]', 'end' => '[/userId]');
    $tag_len = array (
        'start' => mstrlen ($tags['start']),
        'end'   => mstrlen ($tags['end'])
    );
    $offset = $pos_end = 0;
    $ret    = '';
    $strlen = mstrlen ($str);

    while ($pos_end < $strlen) {
        if (
            ($pos_start = mstrpos ($str, $tags['start'], $pos_end)) !== false &#038;&#038;
            ($pos_end   = mstrpos ($str, $tags['end'], $pos_start)) !== false
        ) {
            $ret .= msubstr ($str, $offset, $pos_start - $offset);
            $pos_start += $tag_len['start'];

            $ret .= $fn (msubstr ($str, $pos_start, $pos_end - $pos_start));

            $pos_end += $tag_len['end'];
            $offset = $pos_end;
        }
        else {
            break;
        }
    }

    return $ret;
}</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://urzenia.net/410/phpphp/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		<feedburner:origLink>http://urzenia.net/410/phpphp/</feedburner:origLink></item>
		<item>
		<title>Useless-scripts: wwwshell.php 0.2</title>
		<link>http://feedproxy.google.com/~r/mysz/~3/6tVE3_062g4/</link>
		<comments>http://urzenia.net/381/useless-scripts-wwwshellphp-02/#comments</comments>
		<pubDate>Sun, 24 Aug 2008 10:54:32 +0000</pubDate>
		<dc:creator>MySZ</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[skrypt]]></category>
		<category><![CDATA[useless-scripts]]></category>
		<category><![CDATA[wwwshell]]></category>

		<guid isPermaLink="false">http://urzenia.net/?p=381</guid>
		<description><![CDATA[wwwshell.php to skrypt napisany w php, pozwalający obejść część ograniczeń związanych z brakiem shella na hostingu. Jako że w home.pl takowego nie ma, musiałem jakiś czas temu ratować się takim wynalazkiem ;) Założeniem które przyświecało od początku jego istnienia była kompaktowość (wszystko w jednym pliku), używalność, wygoda. Wydaje mi się że jak na razie spełnia [...]]]></description>
			<content:encoded><![CDATA[<p>wwwshell.php to skrypt napisany w php, pozwalający obejść część ograniczeń związanych z brakiem shella na hostingu. Jako że w <a href="http://home.pl">home.pl</a> takowego nie ma, musiałem <a href="http://urzenia.net/357/po-przeprowadzce/">jakiś czas temu</a> ratować się takim wynalazkiem ;)</p>
<p>Założeniem które przyświecało od początku jego istnienia była kompaktowość (wszystko w jednym pliku), używalność, wygoda. Wydaje mi się że jak na razie spełnia wszystkie wymienione ;) Ograniczeniami są PHP >= 4.3.0 i nie zablokowane wykonywanie funkcji <code>proc_open ()</code> i <code>proc_close ()</code>.</p>
<p>Zalety (z mojego punku widzenia ;) ):</p>
<ul>
<li>wszystko w jednym pliku (biblioteki jQuery pobierane są bezpośrednio z serwera <a href="http://jquery.com/">jQuery.com</a></li>
<li>obsługa aliasów</li>
<li>prostota użytkowania</li>
<li>historia poleceń</li>
</ul>
<p>Wady:</p>
<ul>
<li>no cóż, to jednak nie prawdziwy shell&#8230; </li>
<li>brak uzupełniania</li>
<li>uprzyjemniacze typu historia wymagają połączenia z netem lub modyfikacji skryptu i używania lokalnych kopii bibioteki jQuery</li>
</ul>
<p>Znane błędy:</p>
<ul>
<li>nie zapamiętuje ustawionego rozmiaru czcionki w okienku wyjścia</li>
<li>czasem z jakiegoś powodu historia nie działa, trzeba np. otworzyć okienko konsoli w ff i je zamknąć, wtedy jest ok :/</li>
</ul>
<p>Nie sprawdzałem też (ani nawet nie zamierzam jak na razie) sprawdzać jak wygląda i działa pod IE. Może się coś sypać :)</p>
<p>Jeśli ktoś jest zainteresowany tą zabawką, to zapraszam do pobierania na <a href="http://code.google.com/p/useless-scripts/downloads/list">GoogleCode</a>, i komentowania/krytykowania pod tą notką ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://urzenia.net/381/useless-scripts-wwwshellphp-02/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://urzenia.net/381/useless-scripts-wwwshellphp-02/</feedburner:origLink></item>
		<item>
		<title>WP-Blip! 0.3.2</title>
		<link>http://feedproxy.google.com/~r/mysz/~3/rcmKYP0EX9Q/</link>
		<comments>http://urzenia.net/378/wp-blip-032/#comments</comments>
		<pubDate>Fri, 22 Aug 2008 23:01:37 +0000</pubDate>
		<dc:creator>MySZ</dc:creator>
				<category><![CDATA[blip]]></category>
		<category><![CDATA[bliposfera]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://urzenia.net/?p=378</guid>
		<description><![CDATA[Mały bugfix release (zgłoszony przez WPNinja): W przypadku gdy nie można zapisać pliku z cache do katalogu ustawionego jako zmienna $wp_blip_cacheroot, próbuje zapisać do systemowego katalogu tymczasowego (o ile się uda takowy znaleźć). Gdy także i ta operacja się nie powiedzie, zostanie rzucony E_USER_NOTICE z informacją o problemie, a wtyczka po prostu nie będzie korzystała [...]]]></description>
			<content:encoded><![CDATA[<p>Mały bugfix release (zgłoszony przez <a href="http://wpninja.pl/blip-i-wordpress/">WPNinja</a>): W przypadku gdy nie można zapisać pliku z cache do katalogu ustawionego jako zmienna <code>$wp_blip_cacheroot</code>, próbuje zapisać do systemowego katalogu tymczasowego (o ile się uda takowy znaleźć). Gdy także i ta operacja się nie powiedzie, zostanie rzucony <code>E_USER_NOTICE</code> z informacją o problemie, a wtyczka po prostu nie będzie korzystała z funkcji cacheowania wpisów.</p>
<p>Do pobrania z <a href="http://code.google.com/p/wp-blip/downloads/list">GoogleCode</a>. Jak zawsze proszę o informacje i uwagi nt działania wtyczki, a także ucieszyłbym się z informacji że ktoś gdzieś moich wypocin używa :)</p>
]]></content:encoded>
			<wfw:commentRss>http://urzenia.net/378/wp-blip-032/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://urzenia.net/378/wp-blip-032/</feedburner:origLink></item>
		<item>
		<title>SBLAM! Blacklist Update v.0.4</title>
		<link>http://feedproxy.google.com/~r/mysz/~3/ckO4pm9AL7A/</link>
		<comments>http://urzenia.net/372/sblam-blacklist-update-v04/#comments</comments>
		<pubDate>Fri, 08 Aug 2008 01:03:44 +0000</pubDate>
		<dc:creator>MySZ</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[sblam]]></category>
		<category><![CDATA[sblam blacklist update]]></category>
		<category><![CDATA[skrypt]]></category>

		<guid isPermaLink="false">http://urzenia.net/?p=372</guid>
		<description><![CDATA[Mały update do SBLAM! Blacklist Update: jako że czasem (jak obecnie) pojawiają się błędy w generowanej black liście, do naszego .htaccess dodawane są tylko poprawne linie zawierające adres IP, oraz komentarze. Wszystko inne jest ignorowane, i nie spowoduje problemu w działaniu naszego serwisu :) Skrypt jak ciągle dostępny do pobrania z adresu: urzenia.net/wp-content/sblam_blacklist_update.txt. Podziękowania dla [...]]]></description>
			<content:encoded><![CDATA[<p>Mały update do SBLAM! Blacklist Update: jako że czasem (jak obecnie) pojawiają się błędy w generowanej black liście, do naszego .htaccess dodawane są tylko poprawne linie zawierające adres IP, oraz komentarze. Wszystko inne jest ignorowane, i nie spowoduje problemu w działaniu naszego serwisu :)</p>
<p>Skrypt jak ciągle dostępny do pobrania z adresu: <a href="http://urzenia.net/wp-content/sblam_blacklist_update.txt">urzenia.net/wp-content/sblam_blacklist_update.txt</a>.</p>
<p>Podziękowania dla <a href="http://geekspace.pl">Elus</a>ia za <a href="http://geekspace.pl/2008/8/7/sblam-blacklist">zwrócenie uwagi</a> :)</p>
]]></content:encoded>
			<wfw:commentRss>http://urzenia.net/372/sblam-blacklist-update-v04/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://urzenia.net/372/sblam-blacklist-update-v04/</feedburner:origLink></item>
		<item>
		<title>WP-Blip! 0.3</title>
		<link>http://feedproxy.google.com/~r/mysz/~3/jPB3qsaoD8o/</link>
		<comments>http://urzenia.net/371/wp-blip-03/#comments</comments>
		<pubDate>Thu, 10 Jul 2008 18:38:03 +0000</pubDate>
		<dc:creator>MySZ</dc:creator>
				<category><![CDATA[blip]]></category>
		<category><![CDATA[bliposfera]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://urzenia.net/?p=371</guid>
		<description><![CDATA[Kolejna odsłona WP-Blip!a :) Tym razem jeden bugfix (no, powiedzmy że fix), i jedna zmiana: możliwość formatowania daty dodania statusu (via komentarz Julka) naprawione linkowanie tagów i userów &#8211; teraz łapie poprawnie polskie znaczki. Może nie do końca poprawnie działać jeśli kodowanie znaków jest inne niż UTF-8, proszę wtedy dać znać, mam wrażenie że coś [...]]]></description>
			<content:encoded><![CDATA[<p>Kolejna odsłona WP-Blip!a :) Tym razem jeden bugfix (no, powiedzmy że fix), i jedna zmiana:</p>
<ul>
<li>możliwość formatowania daty dodania statusu (via <a href="http://urzenia.net/370/wp-blip-02/#comment-33358">komentarz Julka</a>)</li>
<li>naprawione linkowanie tagów i userów &#8211; teraz łapie poprawnie polskie znaczki. Może nie do końca poprawnie działać jeśli kodowanie znaków jest inne niż UTF-8, proszę wtedy dać znać, mam wrażenie że coś źle przemyślałem ;)</li>
</ul>
<p>Standardowo proszę o komentarze pod tym wpisem, lub na <a href="http://urzenia.net/email">email</a> :) A nowa wersja pluginu jest do <a href="http://code.google.com/p/wp-blip/downloads/list?can=2&#038;q=0.3&#038;colspec=Filename+Summary+Uploaded+Size+DownloadCount">pobrania na Google Code</a>.</p>
<p><ins datetime="2008-07-10T18:58:21+00:00">UPDATE:</ins></p>
<p>Już nowa wersja &#8211; 0.3.1 ;)</p>
<ul>
<li>fix: pliterki w tagach teraz działają lepiej</li>
<li>fix: myślnik w tagach też działa lepiej</li>
<li>add: linki we wpisach są obejmowana tagiem &lt;a /&gt;</li>
</ul>
<p>Do pobrania tradycyjnie na <a href="http://code.google.com/p/wp-blip/downloads/list?can=2&#038;q=0.3.1&#038;colspec=Filename+Summary+Uploaded+Size+DownloadCount">GoogleCode</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://urzenia.net/371/wp-blip-03/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://urzenia.net/371/wp-blip-03/</feedburner:origLink></item>
		<item>
		<title>WP-Blip! 0.2</title>
		<link>http://feedproxy.google.com/~r/mysz/~3/rgKsC5qFzn0/</link>
		<comments>http://urzenia.net/370/wp-blip-02/#comments</comments>
		<pubDate>Mon, 07 Jul 2008 05:54:52 +0000</pubDate>
		<dc:creator>MySZ</dc:creator>
				<category><![CDATA[blip]]></category>
		<category><![CDATA[bliposfera]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://urzenia.net/?p=370</guid>
		<description><![CDATA[Nowa wersja plugina do WordPressa pokazującego statusy z Blip!a. Zmiany: update BlipApi.php do nowej wersji linkowanie tagów i użytkowników dodanie pliku README z podstawową dokumentacją Zainteresowanych zapraszam ściągania i aktualizowania :)]]></description>
			<content:encoded><![CDATA[<p>Nowa wersja plugina do <a href="http://wordpress.org/">WordPress</a>a pokazującego statusy z <a href="http://blip.pl">Blip!</a>a. Zmiany:</p>
<ul>
<li>update BlipApi.php do nowej wersji</li>
<li>linkowanie tagów i użytkowników</li>
<li>dodanie pliku README z podstawową dokumentacją</li>
</ul>
<p>Zainteresowanych zapraszam <a href="http://code.google.com/p/wp-blip/downloads/list">ściągania i aktualizowania</a> :)</p>
]]></content:encoded>
			<wfw:commentRss>http://urzenia.net/370/wp-blip-02/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://urzenia.net/370/wp-blip-02/</feedburner:origLink></item>
		<item>
		<title>BlipApi.php 0.02.5</title>
		<link>http://feedproxy.google.com/~r/mysz/~3/uEX4jU2YLCQ/</link>
		<comments>http://urzenia.net/368/blipapiphp-0025/#comments</comments>
		<pubDate>Sun, 25 May 2008 12:46:20 +0000</pubDate>
		<dc:creator>MySZ</dc:creator>
				<category><![CDATA[blip]]></category>
		<category><![CDATA[blipapi]]></category>
		<category><![CDATA[bliposfera]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://urzenia.net/?p=368</guid>
		<description><![CDATA[Kilka dni temu Tomasz Tybulewicz (http://tybulewicz.com/) podesłał mi wersję BlipApi.php z dodaną obsługą operacji na obrazkach, jakie zaczęło oferować Blip!owe API :) Tomek równocześnie dołączył do &#8220;zespołu&#8221; tworzącego i rozwijającego BlipApi, które obecnie jest tylko w wersji PHP, a docelowo, o ile czas pozwoli, pojawi się w jeszcze kilku językach. Nie będę na razie mówił [...]]]></description>
			<content:encoded><![CDATA[<p>Kilka dni temu Tomasz Tybulewicz (<a href="http://tybulewicz.com/">http://tybulewicz.com/</a>) podesłał mi wersję BlipApi.php z dodaną obsługą operacji na obrazkach, jakie zaczęło oferować <a href="http://blip.pl">Blip!</a>owe API :) Tomek równocześnie dołączył do &#8220;zespołu&#8221; tworzącego i rozwijającego BlipApi, które obecnie jest tylko w wersji PHP, a docelowo, o ile czas pozwoli, pojawi się w jeszcze kilku językach. Nie będę na razie mówił w jakich, bo to dość niepewna przyszłość ;)</p>
<p>Nową wersję można pobrać ze specjalnie utworzonego w tym celu projektu na <a href="googlecode.com">Google Code</a>: <a href="http://blipapi.googlecode.com">blipapi.googlecode.com</a> (jeśli ktoś kojarzy projekt blipapi-php na Google Code, to niech wymaże go ze swoich bookmarków, został usunięty).</p>
]]></content:encoded>
			<wfw:commentRss>http://urzenia.net/368/blipapiphp-0025/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://urzenia.net/368/blipapiphp-0025/</feedburner:origLink></item>
		<item>
		<title>Słówko o PHP6</title>
		<link>http://feedproxy.google.com/~r/mysz/~3/O0KPcGvj60E/</link>
		<comments>http://urzenia.net/366/slowko-o-php6/#comments</comments>
		<pubDate>Fri, 11 Apr 2008 07:51:34 +0000</pubDate>
		<dc:creator>MySZ</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[php6]]></category>

		<guid isPermaLink="false">http://urzenia.net/?p=366</guid>
		<description><![CDATA[Dokopałem się właśnie do pewnego wpisu na PeHaPowym Wiki omawiającego status i różne ciekawostki dotyczące PHP6. Można się dowiedzieć fajnych rzeczy&#8230; Ale po kolei. Czego nie ma, a być powinno Co mi się nie podoba: w &#8220;odrzuconych&#8221; są takie kwiatki jak add named parameters, czyli parametry nazwane w funkcjach. Jestem dość mocno skażony Pythonem, więc [...]]]></description>
			<content:encoded><![CDATA[<p>Dokopałem się właśnie do pewnego wpisu na <a href="http://wiki.php.net/">PeHaPowym Wiki</a> omawiającego <a href="http://wiki.php.net/todo/php60">status i różne ciekawostki dotyczące PHP6</a>. Można się dowiedzieć fajnych rzeczy&#8230; Ale po kolei.</p>
<h2>Czego nie ma, a być powinno</h2>
<p>Co mi się nie podoba: w &#8220;odrzuconych&#8221; są takie kwiatki jak <cite>add named parameters</cite>, czyli parametry nazwane w funkcjach. Jestem dość mocno skażony Pythonem, więc ten wynalazek uważam za świetny pomysł, niestety został odrzucony :(</p>
<p>O ile parametry nazwane to kwestia gustu, i da się to przeżyć, o tyle gorzej że ten sam los spotkał wpis oznaczony jako <cite>all fatal errors to become exceptions</cite> Chodzi tutaj o zamianę chorego systemu błędów (które potrafią ot tak zatrzymać działanie skryptu i nie pozwalające zrobić z tym faktem niczego) na wyjątki. Dziwna sprawa jak dla mnie, jako że ogólnie PHP5 już ma na tyle zaawansowaną obsługę wyjątków i obiektów w ogólności, że nie powinien to być problem. Tym bardziej, że to ma być zupełnie nowa <strong>wersja</strong> interpretera (nie <strong>podwersja</strong>), więc taka zmiana powinna być w pełni akcpetowalna :(</p>
<p><cite>make function names match CS and unify parameter order</cite> &#8211; o ile zmiana akurat na <em>camel case</em> mnie nie bawi, bo wolę wersję z podkreśleniami, o tyle lepsze to niż obecna ruletka. A już druga część podpunktu (czyli unifikacja kolejności parametrów w funkcjach wbudowanych) to jak dla mnie takie &#8220;musiszmieć&#8221;, a oni to tak po prostu odrzucają. Porażka :( Co za problem, skoro i tak jest śmietnik, zostawić stare funkcje jako aliasy na nowe, dorzucając errora typu <em>deprecated</em>, i zrobić wreszcie jakiś porządek? :/</p>
<p><cite>add support for <code>&lt;?php="foo" ?&gt;</code></cite> &#8211; cóż, szkoda. Pozostanie pisać mi dalej w <a href="http://wordpress.org">WordPress</a>ie <code>&lt;?php echo "foo"; ?&gt;</code> :) Ale nadmiernie z tego powodu nie rozpaczam :)</p>
<p>Nieco bardziej ruszył mnie punkt dotyczący <a href="http://urzenia.net/361/cechy-w-php-traits/">wielokrotnego dziedziczenia</a>, ale płakał też nie będę. Cóż, tak samo jak z punktem poprzednim, da się żyć bez tego.</p>
<p>Natomiast zupełnie nie rozumiem dlaczego odrzucono pomysł bloku <code>finally</code> (<cite>a &#8216;finally&#8217; block for exception handling</cite>, bez którego system wyjątków jest, teges, upośledzony :(</p>
<h2>O czym nie chciało im się jeszcze rozmawiać</h2>
<p>Jednym z ciekawszych elementów nad którym nie przeprowadzono jeszcze dyskusji, jest dostarczenie globalnej funkcji <code>__call ()</code>, wywoływanej w momencie gdy zostanie użyta nieistniejąca funkcja. Coś, czym jest <code>__autoload ()</code> dla klas. Fajna sprawa, imho jak najbardziej powinno mieć to miejsce.</p>
<p>Ciekawostką jak dla mnie jest używanie wyrażeń regularnych w bloku <code>switch ()</code>. Jeśli przepchną coś takiego, to pójdą w stronę perla, gdzie w wersji 5.10 dodano tenże blok (nazywając go <code>given ()</code>), który wykorzystuje magiczny, specjalnie dla niego stworzony operator <code>~~</code>. Magiczny dlatego, że sposób jego działania (porównywania) jest zależny od tego jakie operandy są porównywane. Bez <a href="http://perldoc.perl.org/perlsyn.html">specjalnej tabeli</a> (szukaj podpunktu <em>Smart matching in detail</em>) nie podchodź.</p>
<p>Za to dwa inne podpunkty mi się nawet podobają: <cite>&#8220;ext/pimpmydate&#8221;, new date/time features, real OO interface</cite> (obiektowe podejście do operowania na datach) i <cite>being able to use array() when defining constants</cite> (możliwość definiowania stałych jako tablice). Byłoby miło gdyby to zostało wprowadzone :)</p>
<h2>Nad czym pracują i co na pewno będzie wykonane</h2>
<p>Standardowo &#8211; pełne wsparcie dla Unicode. W końcu. Co prawda, podobnie jak <a href="http://pornel.net/php6#sec10">porneL</a> nie rozumiem czemu wybór padł akurat na UTF-16, ale lepsze to niż obecne zabawy z niepełnym modułem <em>mb</em>. Trwają jeszcze prace nad pełną implenetacją tego (np. w <a href="http://php.net/pdo">PDO</a>), ale ważne że będzie ;)</p>
<p><strong>Nie ma już <code>register_globals</code> i <code>safe_mode</code></strong>. Te dwa zabytki, do spółki z <code>magic_quotes</code> są baaaardzo wkurzającymi, i często niebezpiecznymi ustawieniami dotyczącymi PHP. Na szczęście zmiany z tego podpunktu dotyczą także <a href="http://urzenia.net/349/php-53/">PHP 5.3</a>. Hip hip, hurra! :D</p>
<p>Zostanie wyrzucone z głównego drzewa rozszerzenie <code>ereg</code>, za to <code>pcre</code> zostanie jego stałą częścią bez możliwości wyłączenia.</p>
<p>Do PHP wprowadzono <code>goto</code>. Na razie działa <code>break</code>owanie do konkretnej etykiety (<code>label</code>), a niedługo dojdzie też <code>goto</code> jako takie&#8230; O ile <code>break</code> rozumiem, o tyle <code>goto</code> niespecjalnie.</p>
<p>Podoba mi się wprowadzenie rozwijania tablic do <code>foreach</code>. Wykorzystywałoby się w tym celu funkcję <code>list ()</code>, a całość wyglądałaby tak:</p>
<pre><code>
$a = array (
  array (1, 2),
  array (3,4)
);
foreach ($a as $k =&gt; list ($b, $c)) {
  echo $b .':'. $c;
}</code></pre>
<p>Przestrzenie nazw.</p>
<p>Wbudowane zabezpieczenie przeciwko <a href="http://en.wikipedia.org/wiki/Http_response_splitting">HTTP Response Splitting</a> (funkcją <code>header ()</code> będzie można wysłać tylko jeden nagłówek naraz, czyli wstrzyknięcie &#8220;Header1: Value\nHeader2:Value&#8221; nie będzie już możliwe).</p>
<h2>I co z tego?</h2>
<p>Jako podsumowanie napiszę tylko, że wprowadzane zmiany są tak jakby&#8230; chaotyczne. Z jednej strony próba wyprowadzenia różnych zaszłości, które strasznie denerwują ludzi nieco bardziej obeznanych z programowaniem. Z drugiej zostawianie rzeczy i śmietnika które denerwują nie mniej. Teoretycznie, wersja piąta jest na tyle dobrą wersją tego języka, że dałoby się z nią przeżyć jeden rok więcej. Dzięki temu można by wprowadzić znacznie więcej zmian które oczyściłyby ten jeden wielki śmietnik, jakim jest PHP.</p>
]]></content:encoded>
			<wfw:commentRss>http://urzenia.net/366/slowko-o-php6/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://urzenia.net/366/slowko-o-php6/</feedburner:origLink></item>
		<item>
		<title>Skryptowanie Vima w Pythonie – cz.2</title>
		<link>http://feedproxy.google.com/~r/mysz/~3/HiHdAj-mFec/</link>
		<comments>http://urzenia.net/365/skryptowanie-vima-w-pythonie-cz2/#comments</comments>
		<pubDate>Sun, 06 Apr 2008 00:12:16 +0000</pubDate>
		<dc:creator>MySZ</dc:creator>
				<category><![CDATA[programowanie]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[vim]]></category>
		<category><![CDATA[vimtips]]></category>

		<guid isPermaLink="false">http://urzenia.net/?p=365</guid>
		<description><![CDATA[Od jakiegoś czasu wymyślam sobie różne udoskonalenia dla Vima, i piszę je zazwyczaj w Pythonie :) Niedawno opisywałem jak wyświetlić listę funkcji z edytowanego pliku, później zrobiłem sobie wygodne komentowanie kodu (wersje które znalazłem na sieci nie satysfakcjonowały mnie), teraz przyszedł czas na sprytne (w sensie: wygodne) uruchamianie właśnie edytowanego skryptu/programu :) Do niedawna używałem [...]]]></description>
			<content:encoded><![CDATA[<p>Od jakiegoś czasu wymyślam sobie różne udoskonalenia dla Vima, i piszę je zazwyczaj w Pythonie :) Niedawno opisywałem jak <a href="http://urzenia.net/359/skrypty-pythona-w-vimie/">wyświetlić listę funkcji z edytowanego pliku</a>, później zrobiłem sobie wygodne komentowanie kodu (wersje które znalazłem na sieci nie satysfakcjonowały mnie), teraz przyszedł czas na sprytne (w sensie: wygodne) uruchamianie właśnie edytowanego skryptu/programu :)</p>
<p>Do niedawna używałem prostego Pythonowego skryptu, który wywoływem z Vima:</p>
<pre><code>!$ %</code></pre>
<p>Wykrzyknik to polecenie wywołania programu z shella, <code>$</code> to nazwa skryptu, a <code>%</code> jest rozwijany przez Vima do pełnej ścieżki bieżącego pliku. Było to o tyle wygodne, że nieważne w jakim języku pisałny był skrypt/program, <code>$</code> uruchamiał odpowiedni interpreter, ze skonfigurowanymi parametrami i wyświetlał wyjście. Tą funkcjonalność oczywiście potrzebowałem zachować, ale wykonywanie zewnętrznego programu jest strasznie niewygodne ;) Więc zrobiłem sobie wygodniejszą, i nieco bardziej rozbudowaną wersję. Inne założenia to możliwość przekazywania parametrów do wykonywanego programu, oraz dla niektórych języków możliwość wcześniejszej, automatycznej kompilacji.</p>
<p>Założyłem taki format konfiguracji poszczególnych typów plików:</p>
<pre><code>[wywolanie interpretera, przeksztalcenie pliku wykonywalnego]</code></pre>
<p>Gdzie <code>wywolanie interpretera</code> może być tuplą/listą wywołań lub zwykłym napisem z kluczami:</p>
<dl>
<dt>fname</dt>
<dd>nazwa biezacego pliku</dd>
<dt>exe</dt>
<dd>nazwa wersji wykonywalnej (nie jest wymagane)</dd>
<dt>params</dt>
<dd>dodatkowe parametry</dd>
</dl>
<p>Klucze te są zastępowane oczywiście właściwymi danymi z wykorzystaniem skłądni &#8220;procentowej&#8221;. Przykład takiej konfiguracji:</p>
<pre><code>'java':     [('javac -Xlint %(fname)s', 'java %(exe)s %(params)s'), lambda f: os.path.splitext (os.path.basename (f))[0], ],</code></pre>
<p>W takim przypadku zostanie najpierw zostanie uruchomione polecenie <code>javac -Xlint %(fname)s</code>, następnie <code>java %(exe)s %(params)s</code>, gdzie <code>%(fname)s</code> zostanie zastąpione pełną ścieżką do bieżącego pliku, <code>%(exe)s</code> rezultatem działania funkcji <code>lambda f: os.path.splitext (os.path.basename (f))[0]</code> (która zwróci samą nazwę pliku bez ścieżki i rozszerzenia), a <code>%(params)s</code> &#8211; dodatkowymi opcjami. Zamiast funkcji generującej wersję <code>exe</code> można podać napis którym ma zostać zastąpione rozszerzenie pliku, lub <code>None</code> jeśli nie ma być w ogóle zmieniane.</p>
<p>Największym problemem było wygodne uruchamianie zbudowanej funkcji &#8211; lepiej mi używać już zewnętrznego skryptu niż pisanie na przykład:</p>
<pre><code>python MDP_Execute ('arg1', 'arg2', 'arg3')</code></pre>
<p>W tym celu stworzyłem sobie funkcję Vimową (nie pythonową!) o tej samej nazwie (czyli <code>MDP_Execute ()</code>), a do tego dorzuciłem komendę którą nazwałem <code>Exe</code>. Domyślnie komendy w Vimie nie pozwalają na używanie dodatkowych argumentów. Można jednak zmienić to zachowanie poprzez dodatkowy parametr <code>-nargs</code>, który może przyjąć wartości:</p>
<dl>
<dt>0</dt>
<dd>wartość domyślna, nie pozwalająca na argumenty</dd>
<dt>1</dt>
<dd>musi być dokładnie jeden argument (może to być oczywiście inna cyfra/liczba)</dd>
<dt>*</dt>
<dd>dowolna ilość argumentów</dd>
<dt>?</dt>
<dd>0 lub 1 argument</dd>
<dt>+</dt>
<dd>1 lub więcej argumentów</dd>
</dl>
<p>W moim przypadku odpowiednim parametrem była gwiazdka:</p>
<pre><code>-nargs=*</code></pre>
<p>Problemem jeszcze było odebranie tych parametrów wewnątrz funkcji, a także przekazanie ich do funkcji pythonowej. Rozwiązaniem była najpierw definicja funkcji Vimowej z &#8220;trzykropkiem&#8221;:</p>
<pre><code>function! MDP_Execute (...)</code></pre>
<p>dzięki czemu funkcja może przyjąć dowolną ilość argumentów (ale mniejszą lub równą 20 &#8211; ograniczenie Vima), a odbiera się je wewnątrz funkcji jako zmienne funkcyjne (tzn. takie które istnieją tylko wewnątrz funkcji) o nazwie takiej samej jak index tej funkcji. Jest to mało jasne wyjaśnienie, więc może przykład:</p>
<pre><code>function! MDP_Execute (...)
    echo a:1 " wydrukuje pierwszy z parametrów wywołania
    echo a:2 " wydrukuje drugi z parametrów, etc
endfunction</code></pre>
<p>Specjalne znaczenie mają dwie zmienne: <code>a:0</code> i <code>a:000</code> &#8211; pierwszy zawiera liczbę podanych (nienazwanych) parametrów, drugi zawiera listę tychże (wygodne gdy musimy po tym przeiterować).</p>
<p>Następnie trzeba było przekazać argumenty podane do komendy do funkcji. Robi się to za pomocą argumentu <code>&lt;args&gt;</code>, a konkretnie jego odmiany <code>&lt;q-args&gt;</code>, który automatycznie przekształca parametry komendy na odpowiednio sformatowaną wersję (czyli nie musimy sami wkładać poszczególnych parametrów w cudzysłowia jakby trzeba to było robic z wersją <code>&lt;args&gt;</code>). W tym momencie można już w funkcji Vimowej <code>MDP_Execute ()</code> odebrać wywołanie komendy:</p>
<pre><code>Exe arg1 arg2 "long arg3"</code></pre>
<p>Pozostaje przekazanie tych samych argumentów do funkcji Pythonowej, ale tutaj po części wyręcza nas sam Vim &#8211; po prostu z wewnątrz funkcji pobierzemy sobie wartość zmiennej <code>a:000</code> za pomocą wbudowanej w moduł <code>vim</code> funkcji <code>eval ()</code>:</p>
<pre><code>data['params'] = ' '.join (vim.eval ('a:000'))</code></pre>
<p>Całość skrypciku wygląda tak:</p>
<pre><code>
if !has('python')
    echo "Error: Required vim compiled with +python"
    finish
endif

python &lt;&lt; EOF
import os.path
import subprocess
import types

import vim

def MDP_System (cmd):
    p   = subprocess.Popen (cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    ret = list (p.communicate ())
    ret.insert (0, p.returncode)
    return ret

def MDP_GetFileType (default=None):
    ft = vim.eval ('&#038;ft')
    if not ft:
        ft = os.path.splitext (vim.current.buffer.name)
        if len (ft) > 1:
            ft = ft[1][1:].lower ()
        else:
            ft = default

    return ft

MDP_Run_Script_ftypes = {
    'python':   ['python -tt %(fname)s %(params)s', ],
    'perl':     ['perl %(fname)s %(params)s', ],
    'sh':       ['bash %(fname)s %(params)s', ],
    'txt':      ['bash %(fname)s %(params)s', ],
    'php':      ['php -f %(fname)s %(params)s', ],
    'cs':       [('mcs %(fname)s', 'mono %(exe)s %(params)s'), '.exe', ],
    'd':        [('rebuild -oqobj %(fname)s', '%(exe)s %(params)s'), '', ],
    'java':     [('javac -Xlint %(fname)s', 'java %(exe)s %(params)s'), lambda f: os.path.splitext (os.path.basename (f))[0], ],
}

def MDP_Execute ():
    cmd_data = MDP_Run_Script_ftypes.get (MDP_GetFileType (), '')
    if not cmd_data:
        print 'Unknown filetype to execute'
        return

    if not isinstance (cmd_data[0], (list, tuple)):
        cmd_data[0] = ( cmd_data[0], )

    data = dict (
        fname   = vim.current.buffer.name,
        params  = ' '.join (vim.eval ('a:000')),
        exe     = vim.current.buffer.name,
    )

    # jesli trzeba, to wyszukujemy wersje exe
    if len (cmd_data) &gt;= 2:
        if isinstance (cmd_data[1], str):
            tmp = os.path.splitext (data['fname'])[0]
            if cmd_data[1]:
                tmp += '.' + cmd_data[1]
            data['exe'] = tmp
        elif isinstance (cmd_data[1], types.FunctionType):
            data['exe'] = cmd_data[1] (data['fname'])

    for c in cmd_data[0]:
        res = MDP_System (c % data)
        print res[1]
        if res[0]:
            print 'Błąd:'
            print res[2]

EOF
function! MDP_Execute (...)
    python MDP_Execute ()
endfunction
command! -nargs=* Exe call MDP_Execute (&lt;q-args&gt;)
map &lt;C-e&gt; &lt;Esc&gt;:call MDP_Execute ()&lt;cr&gt;
</code></pre>
<p>Ostatnia linijka odpowiada za wykonanie skryptu (bez żadnych parametrów) po wciśnięciu kombinacji klawiszy <code>Ctrl+e</code>. Jeśli wymagane są jakiekolwiek parametry, trzeba ręcznie wywołać komendę <code>Exe</code> podając po niej wymagane do poprawnego działania naszego programu argumenty :)</p>
]]></content:encoded>
			<wfw:commentRss>http://urzenia.net/365/skryptowanie-vima-w-pythonie-cz2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://urzenia.net/365/skryptowanie-vima-w-pythonie-cz2/</feedburner:origLink></item>
		<item>
		<title>Settery, gettery i inna magia – Python</title>
		<link>http://feedproxy.google.com/~r/mysz/~3/Tt05Ha8zHZY/</link>
		<comments>http://urzenia.net/364/settery-gettery-i-inna-magia-python/#comments</comments>
		<pubDate>Thu, 20 Mar 2008 23:29:22 +0000</pubDate>
		<dc:creator>MySZ</dc:creator>
				<category><![CDATA[kod]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[php5]]></category>
		<category><![CDATA[programowanie]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://urzenia.net/?p=364</guid>
		<description><![CDATA[Jakiś czas temu napisałem artykuł o setterach i getterach w PHP5. Może warto poruszyć podobny temat dotyczący Pythona? :) Przede wszystkim, model obiektowy Pythona jest zupełnie inny niż PHP. Nie będę go tu omawiał, ponieważ to temat na dość obszerną książkę :) Generalnie obiektówka Pythona jest pełniejsza, ma większe możliwości przeciążania zarówno metod, jak i [...]]]></description>
			<content:encoded><![CDATA[<p>Jakiś czas temu <a href="http://urzenia.net/339/settery-gettery-i-inna-magia/">napisałem artykuł o setterach i getterach</a> w PHP5. Może warto poruszyć podobny temat dotyczący Pythona? :)</p>
<p>Przede wszystkim, model obiektowy Pythona jest zupełnie inny niż PHP. Nie będę go tu omawiał, ponieważ to temat na dość obszerną książkę :) Generalnie obiektówka Pythona jest pełniejsza, ma większe możliwości przeciążania zarówno metod, jak i operatorów (których w PHP przeciążyć nie można).</p>
<p>Podstawą do pisania własnych setterów i getterów są w Pythonie dwie metody <em>magiczne</em>: <code>__getattr__()</code> i <code>__setattr__()</code>. Istnieje także metoda <code>__delattr__()</code> służąca do implementacji usuwania konkretnego atrybutu. Dobra, koniec smęcenia, może jakiś przykład:</p>
<pre><code>class Test (object):
  x = 1
  def __init__ (self):
    super (Test, self).__setattr__ ('data', dict ())
  def __setattr__ (self, var, value):
    self.data[var] = value
  def __getattr__ (self, var):
    return self.data[var]
</code></pre>
<p>Wtrącę jednak małe omówienie obiektówki Pythonowej: w Pythonie 2.x są dwa modele klas: nowy i stary. Deklaracja klasy nowego typu oznacza jawne dziedziczenie z obiektu <code>object</code>, co zobrazowane jest w linii pierwszej (zalecane jest korzystanie z nowego typu klas).</p>
<p>Inną ciekawostką jest deklarowanie właściwości obiektu (które są współdzielone między instancjami &#8211; zmiana jej wartości w jednej instancji powoduje też jej zmianę w drugiej instancji) i właściwości instancji (które są indywidualne dla każdej instancji): pierwsze deklaruje się w ciele klasy, co pokazane jest w linii drugiej. Drugie &#8220;dodaje się&#8221; w konstruktorze czy też dowolnej innej metodzie (z konwencji robi się to w konstruktorze, który w Pythonie nazywa się <code>__init__ ()</code>). W naszym przykładzie sytuacja się nieco komplikuje, jako że my nadpisujemy wbudowaną metodą <code>__setattr__ ()</code>. Aby dodać sobie właściwość instancji, musimy skorzystać z metody <code>__setattr__ ()</code> superklasy klasy <code>Test</code> (czyli <code>object</code>), co pokazuje nam linia czwarta. W linii tej deklarujemy sobie jakiś <em>słownik</em> (w PHP nazywa się tą strukturę <em>tablicą asocjacyjną</em>), w którym będziemy przechowywać nasze dane. Tutaj występuje pewna różnica w stosunku do PHP, gdzie metoda <code>__set</code> wykonywana jest w momencie gdy właściwość którą próbujemy ustawić nie jest zadeklarowana w obiekcie, lub gdy jest do niej ograniczony dostęp za pomocą akcesora <code>private</code>. W Pythonie metoda <code>__setattr__ ()</code> używana jest przy dostępie do <strong>jakiejkolwiek</strong> właściwości (zadeklarowanej wcześniej lub też nie). Jeśli sam sobie w definicji <code>__setattr__ ()</code> nie zapewnisz dostępu do jakiejś właściwości, to nie będziesz jej miał. Trzeba pamiętać przy tym, że sama metoda <code>__setattr__ ()</code> nie korzysta z samej siebie, czyli wewnątrz niej mamy dostęp do zadeklarowanych wcześniej właściwości.</p>
<p>Wróćmy do przykładu. Nasz setter dodaje do słownika <code>data</code> (lub zmienia wartość) klucz <code>var</code>, przypisując mu wartośc <code>value</code>. Getter po prostu zwraca szukaną właściwość, lub też, jeśli nie została jeszcze zdefiniowana, rzuci wyjątkiem (przydałoby się przechwycenie go i rzucenie właściwego wyjątku, ale to już inna kwestia).</p>
<p>A co jeśli trzeba dorobić sprawdzanie poprawności niektórych własności? No cóż, trzeba to zrobić podobnie jak w PHP, czyli zadeklarować dla nich konkretne metody sprawdzające.</p>
<pre><code>class Test2 (object):
  def __init__ (self):
    super (Test2, self).__setattr__ ('data', dict ())
  def __setattr__ (self, var, value):
    if hasattr (self, '_check__' + var):
      self.data[var] = getattr (self, '_check__' + var) (value):
    self.data[var] = value
  def __getattr__ (self, var):
    return self.data[var]
  def _check__X (self, value):
    if isinstance (value, int) or (isinstance (value, str) and value.isdigit ()):
      return int (value)
    raise ValueError (u'Podana wartość nie jest liczbą!')</code></pre>
<p>Ten kod pozwoli na przypisanie dowolnej wartości wszystkim własnościwościom poza <code>X</code>, której jedyną możliwą wartością do przypisania jest <code>integer</code>, lub napis zawierający same cyfry. W przypadku podania innej wartości zostanie rzucony wyjątek <code>ValueError</code>.</p>
<p>Powyżej została opisana jedna z możliwości stosowania własnych setterów i getterów. W Pythonie 2.2 została dodana jeszcze jedna możliwość, ta bardziej lubiana przeze mnie: funkcja (którą od wersji Pythona 2.4 można użyć jako <em>dekorator</em>) <code>property ()</code>. Funkcja ta bierze od jednego do czterech parametrów. Pierwszym z nich jest metoda pełniąca funkcję gettera, druga &#8211; settera, trzecia &#8211; funkcji usuwającej właściwość, a czwarta &#8211; napis dokumentujący. Jeden ze sposobów użycia:</p>
<pre><code>class Test3 (object):
  def __init__ (self):
    self.data = dict ()
  def _set__X (self, value):
    if isinstance (value, int) or (isinstance (value, str) and value.isdigit ()):
      self.data['X'] = int (value)
      return
    raise ValueError (u'Niewłaściwa wartość')
  def _get__X (self):
    return self.data['X']
  X = property (_get__X, _set__X)</code></pre>
<p>Powyższy przykład robi dokładnie to samo co wcześniejszy <code>Test2</code>, z wyjątkiem umieszczania <em>wszystkich</em> własności w słowniku <code>data</code>. Różnice widoczne sa tylko w implementacji, dla użytkownika klasy różnice nie występują.</p>
<p>Funkcja <code>property</code> pozwala także na stworzenie atrybutu tylko do odczytu:</p>
<pre><code>class Test4 (object):
  def __init__ (self, x):
    self.__x = x
  @property
  def x (self):
    return self.__x
t = Test4 (5)
print t.x
t.x = 6</code></pre>
<p>Wykonanie kodu z ostatniego przykładu spowoduje rzucenie wyjątku <code>AttributeError</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://urzenia.net/364/settery-gettery-i-inna-magia-python/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://urzenia.net/364/settery-gettery-i-inna-magia-python/</feedburner:origLink></item>
		<item>
		<title>Python 3000 – print, format</title>
		<link>http://feedproxy.google.com/~r/mysz/~3/AX_K85xAmlM/</link>
		<comments>http://urzenia.net/363/python-3000-print-format/#comments</comments>
		<pubDate>Mon, 03 Mar 2008 22:59:12 +0000</pubDate>
		<dc:creator>MySZ</dc:creator>
				<category><![CDATA[programowanie]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[python3k]]></category>

		<guid isPermaLink="false">http://urzenia.net/?p=363</guid>
		<description><![CDATA[Już od jakiegoś czasu deweloperzy Pythona przygotowują nową, niekompatybilną z poprzednimi, wersję Pythona. Python, gdyby ktoś nie wiedział, to jeden z najfajniejszych języków jakie wymyślono ;) (oczywiście to mocno subiektywne uczucie, ale może kogoś zachęci ;) ). Napiszę tutaj o dwóch ważnych zmianach, co do których nie byłem zupełnie przekonany (a konkretnie: w ogóle nie [...]]]></description>
			<content:encoded><![CDATA[<p>Już od jakiegoś czasu deweloperzy <a href="http://python.org">Python</a>a przygotowują nową, niekompatybilną z poprzednimi, wersję Pythona. Python, gdyby ktoś nie wiedział, to jeden z najfajniejszych języków jakie wymyślono ;) (oczywiście to mocno subiektywne uczucie, ale może kogoś zachęci ;) ). Napiszę tutaj o dwóch ważnych zmianach, co do których nie byłem zupełnie przekonany (a konkretnie: w ogóle nie byłem przekonany), a które spodobały mi się po dzisiejszej krótkiej zabawie z wersją alpha3 Pythona 3000 :)</p>
<p>Jedną z tych zmian jest wycofanie konstrukcji językowej, jaką był <code>print</code>. Został on zastąpiony funkcją o dość nietypowej, zaskakującej nazwie, jaką jest <code>print()</code> ;) Czym się różnią?</p>
<p>Konstrukcja <code>print</code> była zupełnie niekonfigurowalna. Zawsze łączył podane elementy znakiem spacji, prawie zawsze na końcu sam dodawał znak nowej linii&#8230; Jedyną sensowną metodą naprawy tego było ręczne pisanie do <code>sys.stdout</code>, co do ładnych rozwiązań nie należało. Funkcja <code>print()</code> rozwiązuje ten problem za pomocą parametrów nazwanych, do których należą m.in. <code>sep</code> i <code>end</code>. Pierwszy odpowiada za separator parametrów, a drugi za znak dodawany na końcu konstrukcji. Czyli jeśli mamy do wyświetlenia 3 elementy, które chcemy rozdzielić znakiem wykrzyknika, a zakończyć znakiem hasza, w Pythonie 2.x zrobilibyśmy np.:</p>
<pre><code>print '!'.join ('a', 's', 'd')+'#',</code></pre>
<p>lub:</p>
<pre><code>print 'a' + '!' + 's' + '!' + 'd' + '#',</code></pre>
<p>W Pythonie 3000 będzie to wyglądało nieco ładniej:</p>
<pre><code>print ('a', 's', 'd', sep='!', end='#')</code></pre>
<p>W Pythonie 2.x można było także skorzystać z alternatywnej składni, która pozwalała nam pisać do dowolnego &#8216;uchwytu&#8217; (np. otworzonego pliku, ja często z tego korzystałem przy wypisywaniu błędów na STDERR):</p>
<pre><code>print &gt;&gt;sys.stderr, "komunikat błędu"</code></pre>
<p>W nowej wersji składnia tego typu jest niedostępna, zamiast tego jest inny parametr nazwany: <code>file</code>:</p>
<pre><code>print ("komunikat błędu", file=sys.stderr)</code></pre>
<p>Druga z rzeczy które chciałbym pokazać to formatowanie tekstu. Do tej pory można było korzystać ze składni &#8220;z procentem&#8221;:</p>
<pre><code>print 'liczba całkowita: %d, liczba zmiennoprzecinkowa: %0.1f' % (3.14, 3.14)</code></pre>
<p>Ta składnia w Pythonie 3000 nie będzie już obsługiwana, zamiast tego wszystkie obiekty typu <code>string</code> dostały nową metodę: <code>.format()</code>. Metoda ta umożliwia znacznie bardziej rozbudowane formatowanie i konwersję podawanych parametrów, niż do tej pory było to możliwe za pomocą składni &#8220;procentowej&#8221;. Dajmy na to taki przykład:</p>
<pre><code>class mysz:
  def __init__ (self):
    self.fname = 'Marcin'
    self.lname = 'Sztolcman'
    self.nname = 'MySZ'
    self.age = 28
    self.city = 'Szczecin'
  def __str__ (self):
    return '{0.fname} {0.nname:_^10} {0.lname}'.format (self)

print ('Jestem {0}, mam {0.age} lat, i mieszkam w mieście {0.city}.'.format (mysz ()))</code></pre>
<p>Przykład jest może nieco infantylny ;) ale pokazuje to co chciałem pokazać: zaawansowane możliwości formatowania tekstu, jakich użycza nam metoda <code>.format()</code>. Powyższy przykład powinien nam wyświetlić:</p>
<pre><samp>Jestem Marcin ___MySZ___ Sztolcman, mam 28 lat, i mieszkam w mieście Szczecin.</samp></pre>
<p>Pełna składnia i format napisów formatujących opisany jest w Pythonowym manualu: <a href="http://docs.python.org/dev/3.0/library/string.html#format-string-syntax">docs.python.org/dev/3.0/library/string.html#format-string-syntax</a>. Ja powiem tylko że po tym jak troszę się tym pobawiłem, zrozumiałem powody rezygnacji z mojej naprawdę bardzo lubianej składni, jak ją nazwałem, &#8220;procentowej&#8221; na rzecz <code>.format()</code> :)</p>
<p>Oczywiście Python 3000 wprowadza znacznie więcej zmian i nowości, być może jeszcze kilka z nich opiszę niedługo na łamach tegoż bloga (obiecuję że się postaram ;) ).</p>
]]></content:encoded>
			<wfw:commentRss>http://urzenia.net/363/python-3000-print-format/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://urzenia.net/363/python-3000-print-format/</feedburner:origLink></item>
		<item>
		<title>Cechy w PHP (Traits)</title>
		<link>http://feedproxy.google.com/~r/mysz/~3/HX8FKZu2S1E/</link>
		<comments>http://urzenia.net/361/cechy-w-php-traits/#comments</comments>
		<pubDate>Sat, 23 Feb 2008 21:43:15 +0000</pubDate>
		<dc:creator>MySZ</dc:creator>
				<category><![CDATA[php5]]></category>
		<category><![CDATA[programowanie]]></category>
		<category><![CDATA[traits]]></category>

		<guid isPermaLink="false">http://urzenia.net/?p=361</guid>
		<description><![CDATA[Developerzy PHP, projektując &#8220;nową&#8221; implementację OOP (nową w cudzysłowiu, bo raz że to było już kilka lat temu, a dwa, że dotyczy tylko i wyłącznie samego PHP), dość mocno wzorowali się na Javie. Czy to dobrze czy to źle to kwestia gustu, jednak wynika z tego kilka znaczących drobiazgów. Jednym z nich jest jednodziedziczenie (czyli [...]]]></description>
			<content:encoded><![CDATA[<p>Developerzy <a href="http://php.net">PHP</a>, projektując &#8220;nową&#8221; implementację <a href="http://pl.wikipedia.org/wiki/OOP">OOP</a> (nową w cudzysłowiu, bo raz że to było już kilka lat temu, a dwa, że dotyczy tylko i wyłącznie samego PHP), dość mocno wzorowali się na <a href="http://java.sun.com">Javie</a>. Czy to dobrze czy to źle to kwestia gustu, jednak wynika z tego kilka znaczących drobiazgów. Jednym z nich jest <em>jednodziedziczenie</em> (czyli że jedna klasa w PHP może mieć tylko jedną klasę bazową). Od zawsze uważałem to za dużą niewygodę ;) Jak widać, nie tylko ja.</p>
<p>Padła propozycja dołączenia systemu &#8220;Cech&#8221; (ang. Traits) do PHP (podejrzewam że do wersji 6, ale to tylko moje zgadywanie &#8211; w każdym bądź razie są gotowe łatki m.in. do 5.2 i 5.3). Do czego służą Traitsy? W sumie&#8230; do obejście problemu jednodziedziczenia, czyli do wprowadzenia <em>wielodziedziczenia</em>.</p>
<p>Trzeba pamiętać, że ten mechanizm został podobno (nie sprawdzałem osobiście) sportowany także do Javy i <a href="http://msdn2.microsoft.com/en-us/vcsharp/aa336809.aspx">C#</a>, natomiast nie istnieje jeszcze ofiacjalna wersja dla PHP. Sam &#8220;wygląd&#8221; kodu, słowa kluczowe etc nie są jeszcze ustalone, ale to tylko szczegóły.</p>
<p>Szczegóły są dostępne w oficjalnym RFC: <a href="http://www.stefan-marr.de/artikel/rfc-traits-for-php.html">stefan-marr.de/artikel/rfc-traits-for-php.html</a>. Ja tylko powiem, że da się często <a href="http://stronger.jogger.pl/2008/02/22/traits-w-php/">obejść</a> niedogodność wynikajacą z braku <em>wielodziedziczenia</em>, ale problem leży właśnie w konieczności <strong>obchodzenia</strong> braków w języku (tak, wiem, to akurat jedna z typowych wojen wyższości jednych świąt nad drugimi ;) ale to akurat moje zdanie ;) ). Prostszym wyjściem byłoby wprowadzenie po prostu możliwości posiadania kilku klas bazowych, ale w to nie wnikam. Ja ogólnie jestem na tak.</p>
]]></content:encoded>
			<wfw:commentRss>http://urzenia.net/361/cechy-w-php-traits/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://urzenia.net/361/cechy-w-php-traits/</feedburner:origLink></item>
		<item>
		<title>Truecrypt 5.0</title>
		<link>http://feedproxy.google.com/~r/mysz/~3/ehQqP32Tlg4/</link>
		<comments>http://urzenia.net/360/truecrypt-50/#comments</comments>
		<pubDate>Tue, 12 Feb 2008 12:25:17 +0000</pubDate>
		<dc:creator>MySZ</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[truecrypt 5]]></category>

		<guid isPermaLink="false">http://urzenia.net/?p=360</guid>
		<description><![CDATA[Już od jakiegoś czasu używałem TrueCrypta, do przechowywania dość wrażliwych danych. Niedawno wyszła wersja 5.0, więc trzeba było się przesiąść ;) Jakkolwiek pierwsze odczucie nie było zbyt pozytywne, o tyle później już mniej więcej wróciło do normy. Domyślnie, TrueCrypt dla linuksa potrafi sformatować nowy wolumen tylko jako FAT32. Można to nieco obejść, samemu formatując wolumen, [...]]]></description>
			<content:encoded><![CDATA[<p>Już od jakiegoś czasu używałem <a href="http://www.truecrypt.org/">TrueCrypt</a>a, do przechowywania dość wrażliwych danych. Niedawno wyszła wersja 5.0, więc trzeba było się przesiąść ;) Jakkolwiek pierwsze odczucie nie było zbyt pozytywne, o tyle później już mniej więcej wróciło do normy.</p>
<p>Domyślnie, TrueCrypt dla linuksa potrafi sformatować nowy wolumen tylko jako FAT32. Można to nieco obejść, samemu formatując wolumen, a w oknie wyboru typu systemu plików, wybrać <code>None</code> (cały proces tworzenia wolumenu wraz ze zrzutami obrazów na <a href="http://www.jarzebski.pl/read/nowy-truecrypt-5.so">jarzebski.pl</a>). Następnie trzeba zamontować stworzony wolumen, ale zaznaczając opcję w oknie dialogowym &#8216;Do not mount&#8217;. Teraz pozostaje sformatować urządzenie loopbackowe (w moim przypdku było to /dev/loop0 &#8211; można podejrzeć wynik polecenia <code>mount</code>) na wybrany system plików (ext3 w moim wypadku), odmontować, zamontować ponownie już bindując pod wybrany katalog, i zacząć używać tak stworzonego wolumenu.</p>
<p>Problemy także występują przy próbie użycia kluczy. Jeśli wybrałem dowolny klucz (klucze teraz działają nieco inaczej niż w poprzedniej wersji TrueCrypta &#8211; do wersji 4.3 były generowane przez sam program, w tej chwili wskazuje mu się dowolną ilość plików i te pliki są traktowane jako klucze) przy tworzeniu wolumenu, to nie dało się podmontować go &#8211; krzyczał że niewłaściwy klucz. Okazało się, że klucze zostały olane, i montować trzeba bez nich ;) Za to po dodaniu kluczy do już stworzonego wolumenu wszystko działa jak powinno.</p>
<p>Od długiego czasu używałem swojego skryptu do montowania zaszyfrowanych wolumenów TrueCrypta. Oczywiście, jako zatwardziały zwolennik konsoli, działa on w trybie tekstowym :) Mam stworzony mały pliczek mapujący konkretną nazwę (alias) na plik zaszyfrowanego wolumenu, klucz użyty do zaszyfrowania go, i katalog pod który należy podmontować wolumen. Tutaj wyszedł problem &#8211; po każdym wywołaniu truecrypta z wybranymi opcjami, otwierało mi się okienko GUIowe i kazało klikać :/ Tutaj pomogło dodanie parametru <code>-t</code> do wywołania TrueCrypta.</p>
<p>Pozostał jeszcze jeden kłopot. Teoretycznie, nie można pod linuksem stworzyć &#8220;ukrytego wolumenu&#8221; &#8211; na etapie tworzenia wyskakuje monit &#8220;The selected feature is currently not supported on your platform.&#8221;. Więc, niech mi ktoś wyjaśni, dlaczego po próbie zamontowania zaszyfrowanego pliku w trybie tekstowym, dostaję jeszcze pytanie o włączenie ochrony ukrytego wolumenu? :/ I nie da się tego wyłączyć (OK, ja nie znalazłem, jeśli komuś się udało to proszę o info).</p>
<p>No dobra, powyżej skłamałem. Obeszłem problem brzydkim hackiem &#8211; w swoim skrypcie po prostu pobieram hasło samodzielnie, a następnie przekazuję je do odpowiednio wywołanej instancji TrueCrypta poprzez STDIN. Brzydkie, brudne, i źle działa przy błędnie wpisanym haśle, ale to akurat szczegół. Ważne że chwilowo działa&#8230;</p>
<p>To by było na tyle moich bojów z nową wersją programu. Zainteresowanych tematem odsyłam do dwóch artykułów:</p>
<ul>
<li>wspomniany wcześniej artykuł na <a href="http://www.jarzebski.pl/read/nowy-truecrypt-5.so">jarzebski.pl</a></li>
<li>bardzo ciekawy artykuł na temat starszej wersji TrueCrypta na <a href="http://jakilinux.org/howto/truecrypt-prawdziwe-szyfrowanie/">jakilinux.org</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://urzenia.net/360/truecrypt-50/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://urzenia.net/360/truecrypt-50/</feedburner:origLink></item>
		<item>
		<title>Skrypty Pythona w Vimie</title>
		<link>http://feedproxy.google.com/~r/mysz/~3/fkW2PqkI4RI/</link>
		<comments>http://urzenia.net/359/skrypty-pythona-w-vimie/#comments</comments>
		<pubDate>Sun, 27 Jan 2008 00:06:25 +0000</pubDate>
		<dc:creator>MySZ</dc:creator>
				<category><![CDATA[programowanie]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[vim]]></category>
		<category><![CDATA[vimtips]]></category>

		<guid isPermaLink="false">http://urzenia.net/?p=359</guid>
		<description><![CDATA[Stwierdziłem niedawno, że brakuje mi w Vimie takiego drobiazgu jak wyświetlanie listy funkcji z edytowanego właśnie pliku. Można z jednej strony wykorzystać ctags, ale (pewien nie jestem, nie jestem znawcą tagsów ani ich obsługi w Vimie) po dodaniu funkcji/metody/czegokolwiek innego co można by nazwać tagiem trzeba by od nowa generować listę tagów. Nie jest to [...]]]></description>
			<content:encoded><![CDATA[<p>Stwierdziłem niedawno, że brakuje mi w Vimie takiego drobiazgu jak wyświetlanie listy funkcji z edytowanego właśnie pliku.  Można z jednej strony wykorzystać <a href="http://ctags.sourceforge.net">ctags</a>, ale (pewien nie jestem, nie jestem znawcą <code>tags</code>ów ani ich obsługi w Vimie) po dodaniu funkcji/metody/czegokolwiek innego co można by nazwać tagiem trzeba by od nowa generować listę tagów. Nie jest to problemem takim bardzo dużym, do momentu gdy ciągle pracuje się nad różnymi projektami, z czego sporej części nie mam na dysku (tylko wykorzystując plugin netrw pracuję via ftp). W tym momencie moja znajomość systemu ctags podpowiada mi że robi się ciężko&#8230;</p>
<p>Postanowiłem więc napisać sobie prosty skrypt do tego, a że język wewnętrzny Vima mnie nieco odrzuca, postawiłem na Pythona ;) Żeby jakikolwiek skrypt pythona (jak ktoś lubi, można użyć też np perla) mógł zadziałać w Vimie, ten ostatni musi być skompilowany z jego obsługą. W Ubuntu wystarczy zainstalować pakiet vim-full. Łatwo sprawdzić czy Vim ma wkompilowaną obsługę pythona:</p>
<pre><code>vim --version|gi '+python'</code></pre>
<p>Jeśli wyświetliła Ci się podobna linijka:</p>
<pre><samp>+python +quickfix +reltime +rightleft +ruby +scrollbind +signs +smartindent</samp></pre>
<p>to znaczy że możesz śmiało używać pythona do oskryptowania Vima :)</p>
<p>Skrypty Pythona w Vimie przekazywane są do funkcji Vimowej o zaskakującej, nietypowej nazwie <code>python</code>. Tradycyjne <samp>Hello world</samp> wyglądałoby tak:</p>
<pre><code>:python print "Hello world"</code></pre>
<p>Interakcję z samym Vimem umożliwia nam moduł o kolejnej zaskakującej nazwie: <code>vim</code>, który powinniśmy zaimportować na początku funkcji/skryptu. Szczegółowa jego dokumentacja jest na stronach Vima: <a href="http://www.vim.org/htmldoc/if_pyth.html">vim.org/htmldoc/if_pyth.html</a>.</p>
<p>Pierwszym krokiem jest wczytanie zawartości całego bufora. Do jego zawartości dostajemy się poprzez obiekt <code>vim.current.buffer</code>:</p>
<pre><code>fc = "\n".join (line for line in vim.current.buffer)</code></pre>
<p>Samo wyszukanie deklaracji funkcji w plikach pythona można by zrobić mniej więcej tak:</p>
<pre><code>re.findall (r'^\s*def\s+(\w+)', fc, re.M)</code></pre>
<p>Jednak nam najwygodniej pobrać będzie jednocześnie z nazwą funkcji, także całą linijkę w której ta została zdefiniowana. Przyda to się przy przechodzeniu do miejsca w kodzie w którym funkcja jest zdefiniowana. Ja końcowo zrobiłem to tak:</p>
<pre><code>re.findall (r'^(\s*def\s+(\w+\s*\(.*?\))\s*:)', fc, re.M)</code></pre>
<p>Teraz, gdy mamy listę funkcji, trzeba je wyświetlić userowi, a następnie pobrać informację do deklaracji jakiej funkcji w kodzie chcemy się przenieść. Najpierw chciałem skorzystać ze standardowego pythonowego <code>raw_input ()</code>, ale ta funkcja w Vimie nie działa. Użyłem wobec tego Vimowego <code>input ()</code>. Aby skorzystać z funkcji Vimowych, moduł <code>vim</code> udostępnia nam dwie funkcje: <code>vim.eval ()</code> i <code>vim.command ()</code>. Tutaj odpowiedni będzie <code>vim.eval ()</code>:</p>
<pre><code>choice = vim.eval ('input ("Which one: ")')</code></pre>
<p>W tej chwili mamy już praktycznie napisany cały skrypt. Pozostało tylko znalezienie offsetu w jakim się zaczyna deklaracja wybranej przez usera funkcji w buforze, a następnie za pomocą  <code>vim.command ()</code> przenieść kursor w wybrane miejsce:</p>
<pre><code>vim.command ('goto '+str (pos+1))</code></pre>
<p>Całość w moim wykonaniu jest nieco bardziej rozbudowana (minimalnie), jako że staram się zrobić sobie mały framework do skryptowania Vima. Wycinek realizujący odpowiednią funkcjonalnośc w moim przypadku wygląda tak:</p>
<pre><code>" importy ogólne, przydatne funkcje, etc
python &lt;&lt; EOF
import re
import sys

import vim

def MyDevPlugins_GetFileType (default=None):
	ft = vim.eval ('synIDattr(synID(line("."), col("."), 1), "name")')
	if ft:
		m = re.findall (r'^([a-z]+)', ft)
		if m:
			return m[0]
	if not ft:
		ft = default

	return ft

EOF

" FindSubs - wyszukiwanie funkcji
python &lt;&lt; EOF
FindSubs_ftypes = {
	'perl':		r'^(\s*sub\s+(\w+(?:\s*\(.*?\))?))',
	'python':	r'^(\s*def\s+(\w+\s*\(.*?\))\s*:)',
	'php':		r'^(\s*function\s+(\w+\s*\(.*?\)))',
}
FindSubs_ftypes['java'] = FindSubs_ftypes['html'] = FindSubs_ftypes['php']

def FindSubs_Find (ft='perl'):
	try:
		rxp = FindSubs_ftypes[ft]
	except KeyError:
		print 'Unknown filetype: "%s"' % ft
		return

	# read buffer content
	fc = "\n".join (line for line in vim.current.buffer)

	# find all functions names
	m = re.findall (rxp, fc, re.M)
	if not m:
		print 'Not found'
		return

	# print them for user
	for i, sub in enumerate (m):
		print '%d. %s' % (i+1, sub[1])

	# ask for function he want to go
	choice = vim.eval ('input ("Which one: ")')
	try:
		choice = int (choice) - 1
	except:
		print 'Incorrect value'
		return

	# find file offset
	pos = fc.find (m[choice][0].strip ())
	if pos &lt; 0:
		print &gt;&gt;sys.stderr, "Some error occured."
		return

	# and go there
	vim.command ('goto '+str (pos+1))

def FindSubs_Main ():
	FindSubs_Find (MyDevPlugins_GetFileType ())

EOF

function! FindSubs()
	python FindSubs_Main()
endfunction
map &lt;F5&gt; :call FindSubs ()&lt;CR&gt;</code></pre>
<p>Ostatnia linijka odpowiada za podmapowanie wywołania funkcji pod klawisz F5.</p>
<p>Natomiast problemy sprawia opcja rozpoznawania typu pliku. Nie doszukałem się nigdzie w dokumentacji lepszego sposobu, a ten czasem zawodzi :( Nic na to chwilowo nie poradzę. Oczywiście przydałoby się rozpoznawanie większej ilości języków, ale to co jest obecnie wystarcza mi w  zupełności, w razie czego można sobie dorobić odpowiednie regexpy do słownika <code>FindSubs_ftypes</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://urzenia.net/359/skrypty-pythona-w-vimie/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://urzenia.net/359/skrypty-pythona-w-vimie/</feedburner:origLink></item>
		<item>
		<title>“Geneza powstania perla”</title>
		<link>http://feedproxy.google.com/~r/mysz/~3/OuMmhQ_p1y8/</link>
		<comments>http://urzenia.net/358/geneza-powstania-perla/#comments</comments>
		<pubDate>Sat, 26 Jan 2008 22:14:28 +0000</pubDate>
		<dc:creator>MySZ</dc:creator>
				<category><![CDATA[humor]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://urzenia.net/?p=358</guid>
		<description><![CDATA[Słyszeliście historyjkę, jak to kot wskoczył na klawiaturę, wklepując losowe znaki, a Larry stwierdził że to musi dać &#8220;Hello world&#8221; ? Znalazł się spec który odtworzył ten ciąg znaków: perl -e 's^^i6(!@*^+s;\*; Wo\$_\;~;.s![(_\!]!l!g+y"i\$@"Hro"+tr-6;~-ed\012-;print' Ja leżę i kwiczę :) Źródło: goldenline.pl/forum/perl/127239]]></description>
			<content:encoded><![CDATA[<p>Słyszeliście historyjkę, jak to kot wskoczył na klawiaturę, wklepując losowe znaki, a Larry stwierdził że to musi dać &#8220;Hello world&#8221; ? Znalazł się spec który odtworzył ten ciąg znaków:</p>
<pre><code>perl -e 's^^i6(!@*^+s;\*; Wo\$_\;~;.s![(_\!]!l!g+y"i\$@"Hro"+tr-6;~-ed\012-;print'</code></pre>
<p>Ja leżę i kwiczę :)</p>
<p>Źródło: <a href="http://www.goldenline.pl/forum/perl/127239">goldenline.pl/forum/perl/127239</p>
]]></content:encoded>
			<wfw:commentRss>http://urzenia.net/358/geneza-powstania-perla/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://urzenia.net/358/geneza-powstania-perla/</feedburner:origLink></item>
	</channel>
</rss>
