Pprint w Lua
Jedną z fajniejszych rzeczy podczas nauki języka skryptowego jest możliwość korzystania z interpretera. Pozwala to na dotknięcie pisanego kodu. W Pythonie, żeby móc lepiej przyjrzeć się prostemu obiektowi wystarczy napisać
>>> obj = [1, 2, (3, 4), { 'a': 'b'}]
>>> print(obj)
[1, 2, (3, 4), {'a': 'b'}]
>>> print(dir(obj))
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__',
'__eq__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__',
'__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__',
'__setitem__', '__setslice__', '__str__', 'append', 'count', 'extend', 'index', 'insert', 'pop',
'remove', 'reverse', 'sort']
Do tego można przeciążyć odpowiednie metody klasy, żeby wyjście było jeszcze czytelniejsze. Nie mniej, już w tak podstawowej formie, każdy zorientuje się w otrzymanym tekście.
W Lua wszystko psują tablice. A ponieważ jest to podstawowy element budowy czegokolwiek w tym języku, w dużym stopniu utrudnia to oglądanie kodu
> t = { 'one', 2, '3' }
> print(t)
table: 0x8eca880
Ponieważ funkcja print(object) działa jak io.write(tostring(object) ..
'\n'), zamiast otrzymać listę wszystkich obiektów które zawiera t,
otrzymujemy adres tablicy. Można więc spróbować iterować po elementach aby je
wydrukować
> for index, value in pairs(t) do io.write(tostring(value) .. ', ') end
one, 2, 3,
Wygląda całkiem nieźle, tyle że sprawdza się jedynie dla prostych tablic
> t = { 1, {2, 3}, {'four', 5} }
> for index, value in pairs(t) do io.write(tostring(value) .. ', ') end
1, table: 0x8ecbe88, table: 0x8ecbeb0,
Tą kwestię też można rozwiązać, jeśli za pomocą type() będzie się sprawdzać
jakiego typu jest obecnie przetwarzany element i dla tablic stosować kolejną
iterację. Wszystko byłoby pięknie, gdyby nie możliwość zapętlenia i drukowania w
nieskończoność. Prosty przykład tablic w którym każda z nich trzyma adres drugiej.
> t1 = {}
> t2 = { next = t1 }
> t1.next = t2
Po rozwiązaniu ostatniego problemu, dostajemy funkcję
pprint
która w trochę dokładniejszy sposób niż podstawowe print wyświetla przekazany obiekt
> t = { 1, 'two', { value = 3, boolvalue = true }, function() end }
> pprint(t)
{1, two, {value = 3, boolvalue = true}, <function: 0x902b1a8>}
> -- zapętlenie
> t1 = { 'a' }; t2 = { 'b', next = t1 }; t1.next = t2
> pprint(t1)
{a, next = {b, next = {a, next = <table: 0x902bfd8>}}}
W miejscach gdzie tablice zaczynają się powtarzać - wykryto zapętlenie - zamiast wnętrza tablicy, drukowany jest tylko jej adres.
+ Aktualizacja
Żebym za każdym razem nie musiał ręcznie ładować wszystkich dodatkowych
bibliotek, stworzyłem sobie katalog ~/.lua w którym trzymam swoje
moduły.
Do ~/.bashrc dopisałem alias
alias Lua="lua -i ~/.lua/autoload.lua"
który uruchamia interpreter lua, załadowawszy wcześniej moduł
~/.lua/autoload.lua.
Żeby uruchamiać kod Lua z Vim, do ~/.vimrc dopisałem sobie następującą linijke
au FileType lua setlocal makeprg=lua\ -e\ \"package.path=package.path..';/home/piotrek/.lua/?.lua'\"\ -l\ autoload\ %
au FileType lua setlocal errorformat=lua:\ %f:%l:%m
gdzie /home/piotrek/.lua/ to ścieżka do wcześniej utworzonego katalogu ~/.lua. Dla wszystkich edytowanych plików rozpoznanych jako zawierające kod Lua, poleceniu :make uruchomi kod w interpreterze z załadowanymi wcześniej bibliotekami autoload.
Komentarze
Husio
2008-06-30
Już poprawiłem. Nie zauważyłem, że zmienił się sposób generowania url dla klasy Feed.
sl3dziu
2008-06-30
Coś skopałeś w rss'ach bo linki prowadzą pod adres http://example.com/blog/post/pprint-w-lua ;)