Zaawansowana edycja w vim II (3)

Od ponad 4 lat do edycji wszystkiego co ma litery używam Vim. Dzięki jego niesamowitym możliwościom konfiguracji, mój vimrc nie raz zmieniał się w zależności od zadań jakim musiał sprostać. Od ponad pół roku pracuje jako programista i chyba nie muszę tłumaczyć jak bardzo praca nad własnym małym projektem różni się od rozwijania aplikacji nad którą pracuje paręnaście osób.

Poniższy opis to zbiór "sztuczek" jakie odkryłem i jakich nauczyłem się używać na co dzień, w pracy nad dużą aplikacją.

Wyszukiwanie

Znalezienie odpowiedniego fragmentu kodu, to zazwyczaj połowa sukcesu. Gdyby projekt zawierał się w paru plikach, każdy byłby w stanie szybko wskazać odpowiednią linijkę. Tylko że nigdy nie wiadomo czego tak naprawdę szukamy, aż do momentu znalezienia. A wtedy i tak ...

Twisted - wprowadzenie: generatory (0)

We wpisie "reactor i deferred" przedstawiłem koncepcje programowania asynchronicznego z wykorzystaniem obiektu Deferred w którym kolejkowane były zadania. Taki sposób pisania może być jednak bardzo niewygodny, jeśli okaże się, że w swoim kodzie mamy wiele miejsc oczekujących na dane. Każdorazowe pojawienie się nowych informacji wymaga napisania nowej funkcji która je obsłuży. Drugie tyle, jeśli chcemy oprogramować możliwe wystąpienia błędów.

Generatory

Jaki jest generator, każdy widzi. Najprostszym przykładem może być generowanie kolejnych liczb:

>>> def gen_number(start):
...     while True:
...         start += 1
...         yield start
...         
>>> g = gen_number(2)
>>> g.next()
3
>>> g.next()
4
>>> g.next()
5

Jeśli chcesz dowiedzieć się o nich więcej, polecam prezentację "Generator Tricks for Systems Programmers".

Generatory, aż do Pythona 2.5 miały bardzo poważną wadę - były hermetyczne. Utworzony ...

Twisted - wprowadzenie: implementacja protokołu (0)

W poprzednim wpisie przedstawiłem obiekt reaktora oraz klasę Deferred. Kolejnym krokiem będzie napisanie serwera, który używając prostego protokołu będzie zwracał kod strony której adres został przesłany przez klienta.

Implementacja protokołu

Bazową klasą każdego protokołu, implementującą jedynie IProtocol jest internet.protocol.Protocol. Podstawową klasą dla wszystkich serwerów jest internet.protocol.ClientFactory:

>>> from twisted.internet import protocol, reactor
>>> 
>>> class WebGetProtocol(protocol.Protocol):
...     pass
... 
>>> class WebGetFactory(protocol.ServerFactory):
...     protocol = WebGetProtocol
...     
>>> reactor.listenTCP(9000, WebGetFactory())
<<class 'twisted.internet.tcp.Port'> of __main__.WebGetFactory on 9000>
>>> reactor.run()

Po utworzeniu instancji fabryki, przekazuję ją wraz z numerem portu jako parametr metody listenTCP obiektu reaktora. Wszelkie dane które pojawią się na tym porcie, obsłużone zostaną przez moją fabrykę.

Do połączenia z serwerem, można użyć na przykład ...

Twisted - wprowadzenie: reactor i deferred (0)

Śledząc portale i blogi o treści programistycznej, trudno nie zauważyć wzmożonego ostatnio zainteresowania "nowymi" asynchronicznymi frameworkami napisanymi w Pythonie. Osobiście staram się jednak nie podniecać każdą nowością i aby się przekonać do biblioteki, potrzebuję czegoś więcej niż 10 linijek kodu, wyświetlających Hello world. Okazało się, że nie ja jedyny.

Od jakiegoś czasu czytam o twisted i w miarę możliwości staram się napisać trochę działającego kodu. Niestety, oprócz tutoriala w którym opisane zostały podstawy, do dyspozycji jest jeszcze tylko dokumentacja API.

Ponieważ sam dużo czasu spędziłem na gromadzeniu informacji, postaram się w miarę przystępnie opisać podstawy twisted.

Reaktor

Ponieważ twisted jest asynchronicznym frameworkiem, posiada własny obiekt odpowiedzialny za zarządzanie główną pętlą programu i wywoływanie obsługi zdarzeń:

>>> from twisted.internet import reactor ...
txChat (0)

txChat to napisany w twisted i jQuery czat. Kiedyś, ktoś napisał w twisted podobną aplikację, której działanie polegało na wymuszaniu ciągłego przeładowywania strony. Kod miał być wydajnościowym PoC twisted. Uruchomiony na słabej maszynie, obsługiwał całkiem sporą liczbę zapytań. Pomyślałem, że napiszę coś podobnego, ale uproszczę sobie i serwerowi zadanie, używając Javascript.

YankRing (1)

YankRing.vim udostępnia funkcjonalność którą parę lat temu poznałem jeszcze jako użytkownik Emacs i polubiłem pod nazwą kill ring. Niestety, podstawowa wersja Vim podobnego mechanizmu nie posiada. Kopiowanie i wstawianie wygląda tu trochę inaczej. Upraszczając, za każdym razem gdy kopiuje się lub usuwa tekst, trafia on do rejestru. Obecnie znajdujące się tam dane są przesuwane o jedno miejsce wyżej, tak aby zwolnić przed zapełnieniem nowymi danymi "0. Zawartość rejestrów można obejrzeć po wydaniu polecenia :reg (:h registers).

Polecenie p wklei zawartość ostatnio zapisanego rejestru, "<symbol>p wstawi to co znajduje się w rejestrze oznaczonym jako <symbol>. Łącząc :reg oraz "<symbol>p można uzyskać wątpliwej wygody kill ring.

YankRing działa jednak dokładnie tak jak kill ring . Jeśli skopiujemy jakiś tekst, <C-p ...

surround.vim i django templates (0)

surround.vim to wtyczka pozwalająca na szybsze wstawianie znaczników otaczających tekst w określony sposób. Sam skrypt zawiera skróty tylko dla nawiasów oraz tagów XML (ponieważ korzysta z text-objects), ale znając wyrażenia regularne, można spróbować napisać własne definicje (:h surround-customizing).

Ponieważ wiele inclusion tagów w Django otacza fragmenty szablonu, dobrym pomysłem może być użycie do ich pisania funkcjonalności surround . Niestety nie udało mi się tego osiągnąć bez pisania paru linijek patcha. Autor w bardzo specyficzny sposób napisał ten skrypt i na pewno nie zamierzał ułatwiać jego rozszerzania, dlatego w pół godziny nie udało mi się osiągnąć niczego więcej poza obsługą wstawiania tagów. Parametrem który dostajemy po nałożeniu łatki jest d (lub D).

Ajax w Django (ver. 2) (1)

Półtora roku temu opisałem jak zastosować AJAX w aplikacji napisanej w Django. Wybrałem wtedy tworzoną w Pythonowym stylu bibliotekę mochikit i Django 0.96. Opis cieszy się dużą popularnością, ale bogatszy o ponad rok doświadczeń wiem, że teraz zrobiłbym to wszystko o wiele lepiej.

Kiedyś jako przykład użycia ajax stworzyłem proste wiki, ale nie chciało mi się tego opisać. Tym razem wyjaśnię jak napisać prymitywny blog w Django (a jakże!). Pominę jednak kwestię przyjemnego interfejsu i skupię się na jak największej ilości JavaScriptowych wodotrysków.

Wybór biblioteki JavaScript

Swój pierwszy kod w JavaScript napisałem chyba ponad trzy lata temu. Jedyne co pamiętam to biblioteka której użyłem - mootools. Potem zacząłem używać mochikit, bo wydawało mi się, że nic wygodniejszego nie znajdę.

Obecnie ...

Książka "Pro Git professional version control" (4)

Od dziś książka Pro Git professional version control dostępna w sieci za darmo jak i wersji papierowej.

Fajnie, że coraz więcej książek zostaje udostępnione publicznie w wersji elektronicznej.

Vala-fan 0.1 (0)

Nie raz już wspominałem o Vala, języku który ma w dużej mierze zastąpić ANSI C przy pisaniu aplikacji dla GNOME. Jakiś czas temu wyszła wersja 0.7.4 i nie zapowiada się aby szybko pojawiła się 1.0. Nie przeszkadza to jednak w rozwijaniu nowych programów.

To czego brakowało mi zawsze w laptopie to sensowne zarządzanie szybkością pracy wiatraka. Nie lubię jak mi się smażą kolana, ale jeszcze bardziej przeszkadza mi hałas. Do tej pory jakoś sobie radziłem dzięki kilkunasto linijkowej aplikacji napisanej w ANSI C. Ponieważ daleko jej było do doskonałości, w sobotę postanowiłem ją poprawić, a w efekcie napisałem wszystko od nowa w Vala.

Dlaczego Vala?

Algorytm obsługi wiatraka jest banalnie prosty i polega na odczycie wartości z ...

Generator zapytań dla Solra (0)

Ostatnie dni spędzam na nauce Solra i rozwijaniu Djangowego kodu wykorzystującego właśnie z ten indekser. Ponieważ tworzenie zapytań może być naprawdę męczące i generować wiele błędów, napisałem w wolnym czasie parę linijek które powinny pomóc. API jest oczywiście wzorowane na Django ORM. Komunikacją z Solr zajmuje się moduł pysolr.

Oto przykład zapytania:

q = Query()
q.filter(OR(title='Hello world!', description='Hello world!'), date__lt=dt)
q.exclude(photo=True, video=False)
q[:2]
print q.pprint()

które generuje następujący kod:

((description:"Hello world!") OR (title:"Hello world!")) 
 AND (date:"LESS_THAN(to_sorl_format)") 
 AND (NOT (contains_photo:"true") OR (contains_video:"true"))
Cscope (0)

Czytając kod który napisał ktoś inny, największym problemem jest podążanie za kolejnymi wywołaniami funkcji. Zdarza się też tak, że znam nazwę lub jej fragment i chcę znaleźć wszystkie odwołania. Jak sobie z tym poradzić? Do tej pory używałem grepa uruchamianego przez odpowiedni Vimowy plugin. Rozwiązanie sprawdza się dla projektów z niewielką ilością kodu. Gorzej jeśli na wynik trzeba czekać parę sekund, bo architektura Vima nie pozwala w tym czasie robić cokolwiek innego.

Konkurencyjnym rozwiązaniem jest ctags, który jakoś nie przypadł mi do gustu. Trafiłem jednak na narzędzie o nazwie cscope, które ponoć potrafi jeszcze więcej.

Instalacja

Miłą niespodzianką jest fakt, że aby Vim był w stanie korzystać z cscope, wystarczy skompilować go z flagą --enable-cscope.

Przygotowanie bazy

Aby móc skorzystać ...

« 2 1 /7 0 »