30 января 2008

Старый Ruby в убунту

Принёс на воркстанцию парочку самописных плагинов к своему любимому IRC клиенту, написаны на руби. Цели при написании преследовал две - получение нужного функционала и максимальное использование всех динамических извращений фишек языка.
Где-то на 3-4 уровне вложенности вызовов функций интерпретатор валится, жалуясь на нехватку стека:

irb(main):001:0> require 'tray.rb'
=> true
irb(main):002:0> not_found_method
SystemStackError: stack level too deep
from ./tray.rb:23:in `method_missing'
from ./tray.rb:23:in `method_missing'
from (irb):2
irb(main):003:0>

Ох уж мне эти забавные животные! В дистрибутив включён руби ветки 1.9, в то же время в ветке 1.8.x там:
ruby --version
ruby 1.8.5 (2006-08-25) [i486-linux]

Более чем годичной давности...

Про оптимизацию PL/pgSQL

Довелось сегодня оптимизировать функцию, ускорив её выполнение в 400 раз.
Назначение - каскадное удаление в сложном дереве, начиная с определённого узла. Каждый узел или лист имеет внешний ключ - id прав.
Идеологически всё было в ней правильно, мысль была выражена верно: находились подузлы узла и вызывались функции их удаления. Функция удаления листа - полиморфическая, принимающая имя таблицы и id строки.
Но, с точки зрения реализации данного подхода в СУБД это совершенно неприемлемо:

1. Функция удаления листа использовала оператор EXECUTE. Из документации PostgreSQL

36.6.5. Executing Dynamic Commands
В отличие от всех других команд PL/pgSQL , команда, запущенная оператором EXECUTE не готовится и не сохраняется всего один раз в течение жизни сеанса. Вместо этого команда готовится каждый раз при запуске оператора.


2. Огромные накладные расходы в виде процессорного времени на вызов в цикле функций удаления подузлов.

Моё решение (N и способ обхода известен заранее):
select col_to_arr(distinct id узлов верхнего уровня) ,
col_to_arr(distinct id прав узлов верхнего уровня) ,
...
col_to_arr(distinct id узлов N уровня) ,
col_to_arr(distinct id прав узлов N уровня) ,
...
col_to_arr(distinct id листов) ,
col_to_arr(distinct id прав листов) ,
into имена массивов
FROM много JOIN'ов и условий.

Далее - N*2 операторов DELETE
DELETE from имя таблицы where id in (select * from arr_to_col(имя очередного массива)).

Don't be stupid(c) Scaling Twitter
1. Избегайте EXECUTE, если подразумевается многократный вызов.
2. Меньше декомпозиции работ.
3. Цикл - повод задуматься.
4. Меньше динамики.

Новая функция заняла 45 строк и выполняется в 400 раз быстрее.

26 января 2008

Holywars

Вы не любите кошек? Вы просто не умеете их готовить...

Довольно часто в последнее время появляются перед моими глазами посты в стиле "Почему я перехожу на X". И далее страницы эмоционального текста про то, что в старом Y ничего не работает, там вирусы, перезагрузки раз в день и переустановки раз в месяц. А в Z страшная чёрная консоль с шаманскими заклинаниями. И драйверов там нет.
И постоянно убеждаешься, что просто человек Y готовить толком не умеет. Другое дело, что его забота - сделать какую-то работу, а не готовить Y. Но это не даёт оснований утверждать, что Y или Z плохи.
Довольно давно я перешёл с Windows(с непременными матами, как же без этого) на Linux, долго кочевал по дистрибутивам, насчитал около десятка (залез даже в BSD семейство) и осел в Gentoo. Это именно то, что мне надо, система не для людей, а для гиков, система для меня. С другой стороны, примерно год назад мне довелось временно мигрировать обратно в Windows и прожить там месяц амптайма с интернетом 24/7. Ничего плохого сказать не могу, выключить пришлось из-за смены конфигурации.
И всё-таки статьи про переход на X роняют зёрна сомнений в душу. А вдруг - вот там настоящая жизнь? Потом вспоминаются эксперименты с Ubuntu и Gnome. И наши со Странником зачастую противоположные точки зрения в противостоянии Gnome vs. KDE.
Видимо, от добра добра не ищут. Или ищут, но с 30-ти дневным триалом :)

24 января 2008

Про DCOP в Ruby

Какой артист погибает!
Нерон


Для тех, кому мало биндингов Ruby для Qt, существуют биндинги для KDE в виде библиотеки Korundum. Вот только в этом мануале не написано, что нужно зарегистрировать клиента DCOP:

1 @dcopclient = KDE::DCOPClient.new
2 @dcopclient.attach
3 @dcopclient.registerAs("my_app_name",false)
4
5 @dcop = KDE::DCOPRef.new("other_app_name","object_identity")
6 @dcop.setDCOPClient(@dcopclient)


И точно помню, что я с этим не сталкивался в пору кодирования под КДЕ на C++ ... Как-то это для меня неожиданностью стало. В те милые сердцу времена я так и писал:

1 DCOPRef m_amarokplayer("amarok","player");
2 DCOPReply r=m_amarokplayer.call("status()");


Сейчас же без инициализации клиента получаю
DCOPRef::call(): no DCOP client or client not attached error
Но это ещё преодолимо. Есть ещё одно большое и неприятное НО - через DCOP интерфейс в руби передаются урезанные до 7 бит строки. Довольно просто это проверить с помощью Klipper:

1 @dcop = KDE::DCOPRef.new("klipper","klipper")
2 @dcop.call("setClipboardContents","строка")


Обидно.

Вот тебе, бабушка, и RPC


Everything is an Object. I mean, everything.

Ничего принципиально нового, но познавательно.
Писал к одной программе плагин на Ruby. API не предполагает вообще никакого ООП, и заворачивание функций скрипта в модуль или класс было бы пустой тратой LOC. В то же время с плагином можно было общаться через пайп, и существовала потребность вызывать функции плагина извне.
Решение:

195 def invoke(arg_procname)
196   send(:"#{arg_procname}")
198 end

А теперь помедленнее, я записываю.
1. Всё - объект. Даже не так, всё - Object, в том числе (неявно) и скрипт:

16 puts send(:class).to_s  #=>Object
17 puts inspect            #=>main 


2. У класса Object есть метод send(sym), принимающий в качестве аргумента символ с именем метода, который нужно вызвать.
3. Символы могут быть созданы с помощью синтаксиса :"symbolname"
4. "symbolname" - строка, и в ней возможны подстановки.

Итого: внешний мир пишет в именованный пайп (как вариант - в сокет) имя желаемой процедуры, объект скрипта main вызывает её как собственный метод.

22 января 2008

Gpodder-0.10.4

Вышел. И автор не забыл упомянуть меня в благодарностях на странице примечаний к релизу. Хоть моего вклада там - строк десять, остальное - раскапывание и решение проблемы, которую автор не мог бы обнаружить и воспроизвести.
Очень приятно.

18 января 2008

"Хорошая девочка Лида!

А чем же она хороша?"
Я. Смеляков
Об этом спросить остаётся лишь любителей Гнома и Убунту.
Сегодня осваивал новый воркстейшн с установленной там Ubuntu 7.04 и гномом. Первое, что бросилось в глаза - не работало колесо мыши. Сменил на гарантированно рабочую. Ничего не изменилось. Привычно полез в xorg.conf Был немало удивлён эмуляции третьей кнопки по умолчанию. Отключил. Ноль эффекта. И только открыв лог понял, что мышка считается 9-ти кнопочной. Полез в этот блог в пост про мышки за справкой, поправил конфиг, всё заработало.
А вот второй баг поправить не смог. Возможно, пока. Гном не дал мне настроить толком мои любимые хоткеи (коих у меня целая система). В частности, сочетания Alt+Ctrl+<клавиша> или Win+<клавиша> воспринимались просто как Alt+Ctrl и Win. То есть модификаторы работали просто как обычные клавиши. Что совсем не может меня порадовать. Подозрения опять же в сторону кривого конфига иксов либо в сторону оригинального косяка гнома.
Доколе! И где хвалёная дружественность?
UPD:
Доустановка KDE показала, что клавиатура с иксами настроены правильно и грабли лежали в гноме. Так что со спокойным сердцем снова предаю гном анафеме на следующий сезон. Любовь опять не состоялась, хотя все вокруг твердят, какой он хороший.

Цели и средства

Is it possible to have the performance of C and C++ and the programmer productivity of modern programming languages such as Ruby and Python in a single language? That is the question Walter Bright, the author of the Zortech C++ compiler and the Digital Mars C/C++ compiler, asked himself when creating a successor to C++: Digital Mars D, a practical programming language first released exactly one year ago that helps you get the job done quickly.

From.
Читаешь такое и сразу хочется укусить автора в глаз. Потому что сравнивается опять мягкое с тёплым, но так, что тёплое по всему выходит круче. Между тем, цели, которые ставятся перед гибкими змеюками и многогранными камнями, сильно отличаются от оных у приплюснутых языков. Равно как и пути их достижения. И такие вещи, как inline явно подчёркивают, что одно другое не заменяет.
А к вопросу о простоте - внешняя простота Ruby (как, наверняка, и Python'а) обманчива. Да, если посмотреть на книги в стиле X - мой первый язык, то Pragmatic Programmers Learn to Program от Chris Pine выгодно отличается от первых изданий Страуструпа по C (или от последних по C++). Однако при дальнейшем рассмотрении обнаруживаются штуки, которые отравленным цпп сознанием не сразу и разберёшь.

Верно и обратное. Кажущаяся сложность и дотошность C/++ при использовании всевозможных библиотек может быть весьма сглажена. А мелочи вроде обьявлений типов... давно уже стали рефлексом.

У всего есть область применения, плюсы и минусы. И, на мой взгляд, не те,  которыми автор провоцирует прочитать его  обзор, вынеся их во вступление.

15 января 2008

И вдоль и поперёк

Ещё когда только пришёл в проект, в котором предполагалось много и занудно писать на PL/pgSQL, написал две элементарные функции. И все спрашивали - да зачем оно надо... Однако сейчас используют широко и говорят спасибо.
Первая является агрегатом (как min, max, avg, sum и подобные) и собирает столбец в массив. Ну а дальше с помощью PL/pgSQL его можно обрабатывать. Используется в SELECT clause. Объявляется так:
CREATE AGGREGATE col_to_arr(BASETYPE = anyelement, SFUNC = array_append, STYPE = anyarray, INITCOND = '{}' );
Вторая решает обратную задачу - представляет массив как столбец. Используется в FROM clause.


 1 create or replace function "arr_to_col"(arr anyarray)

 2 returns setof anyelement as

 3 $$

 4 declare

 5 size int;

 6 index int;

 7 begin

 8 select array_upper(arr,1) into size;

 9 for index in 1..size loop

10     return next arr[index];

11 end loop;

12 return;

13 end

14 $$

15 language 'plpgsql';


При желании можно в одном запросе повернуть скаляр, доставшийся от какого-то другого куска кода, как вдоль так и поперёк. Что иногда приходится проделывать. Выглядит это примерно так:


113 SELECT  col_to_arr(old_id_alias)

114 INTO    new_id_array

115 FROM    table1,table2,tableN, arr_to_col(old_id_arr) old_id_alias

116 WHERE   table1.id=old_id_alias AND ...


Сначала old_id_arr представляется в виде столбца, связывается с несколькими таблицами условиями, полученная выборка преобразуется в массив для дальнейшей работы.
В общем, хозяйке на заметку.

12 января 2008

Блеск, без нищеты.

Три недели назад написал в мыслепомойку жежешечку:

Есть такой мистический класс программ. Как только где-то что-то становится возможным программировать - тут же все пишут такие программы в огромном количестве, не пишут разве что безрукие. Часы. Калькуляторы (иногда научные). Почтовики. Плеера. Напоминалки. Бэкаперы. Прогнозы погоды. Что там ещё?
Интересно в этом плане посмотреть на андроид от гугля. Новая платформа. Всяко ведь напишут всё вот это безобразие.

А теперь смотрим на второй скриншот в KDE 4.0 Visual Guide: Desktop.

Нищета, без блеска.

from
В KDE 4.0.0 размер панели можно будет менять только правкой исходников. К 4.0.1 обещают поправить


1 --------------plasma.cpp----------------

2 if (loc == BottomEdge || loc == TopEdge) {

3 setFormFactor(Plasma::Horizontal);

4

5 //FIXME: don't hardcode 48px

6 height = 48;

7 //FIXME: don't hardcode full width

8 width = r.width();

9 ------------------------------------------------


Вы всё ещё хотите KDE4?

10 января 2008

1 рукопожатие или про местных птиц

По расхожему утверждению, все люди мира находятся друг от друга на расстоянии 6 рукопожатий. С новой соведущей радио-т (это отдельная песня, которой у нас известно что зовётся) Олей aka Оляпкой я оказался знаком через одно. Это в городе-милионнике.
Кстати, слово весьма интересное - оляпка. Залез в вики - не нашёл. Вообще, это небольшая птичка, обитающая в том числе и на Урале, не улетающая на зиму в тёплые края. Патриотичная такая птичка ;) И способы выживания у неё интересные... Почитайте, поищите, это занимательно. Ещё была такая "серия детских книг, выпускаемая в свет Пермским книжным издательством на протяжении многих лет. Отмечена многочисленными наградами литературного сообщества. Издается в городе Перми." Издавалась, потому что последний виденный мной экземпляр остался в далёком детстве...
Символичный очень, в общем, ник получился. Так держать, землячка.

Ext2Fsd: 0.39 is released

Не хочется становиться этаким "новостным ресурсом", но этого я пропустить не могу. Наиболее удобный инструмент доступа к Linux разделам под windows обновился. А это очень хорошо для меня (ц), поскольку все данные хранятся именно на линукс разделах и во время вылазок в windows на тему монстров погонять они иногда бывают нужны.

09 января 2008

Подсветка синтаксиса кода в блоге

Недавно задумался - а чем же сделать эту самую подсветку? Пробегал на хабре топик про
javascript библиотеки для данных целей. Но для блога данный способ совершенно не подходит, ибо стандарт RSS ни о каком css знать не знает.
в репозитарии нашлась пара обработчиков исходного кода ( app-text/highlight и dev-util/source-highlight) разной степени паршивости. Первый почему-то не подсвечивал закрывающие круглые скобки, второй - пропускал кучу всего из коробки, а перекрывать свои настройки пользовательскими не хотел (а жаль, славная бы вышла каскадная таблица стилей...) И всё не давало покоя чувство, что кто-то же это умел красивее подсвечивать...
А лучше и полнее это умеет делать Vim. Заодно он умеет выдавать валидный html с подсветкой. Но только целиком, от DOCTYPE и до самого </html> Пришлось закатать рукава и немного изменить стандартный плагин, в результате получился у меня свой плагин (класть в ~/.vim/plugin), заточенный под тёмные темы. По комманде :TOblog формирует необходимый html, помещает его в новый буфер и копирует в буфер обмена , остаётся только вставить. Например, так


33     " change body to div vith inline style

34     :silent :%s/<body[^<]*>/<div id="code" style="background-color:#333333; color:#ffffff">/

35     :silent :%s/<\/body>/<\/div>/

36     " and delete crap around it

37     :exe "normal gg"

38     :call search("<div id=\"code\"[^>]*>")

39     :exe "normal kdgg"

40     :call search("<div id=\"code\"[^>]*>")

41     :exe "normal w%jdGygg"



А чтобы хорошо смотрелось, можно поправить fg и bg.

UPD: В комментариях jetxee развивает мою мысль и предлагает свой вариант.

The world of ghettos

Наконец-то осилил Rails is a ghetto by Zed Shaw. (Кстати, лет этак через десять я буду выглядеть именно так, если природа соизволит обременить меня усами и бородой. Гитара уже есть ;))
Что тут можно сказать, прочитать интересно, полезно, но никакого открытия он, на мой взгляд, не сделал. О том, как тяжело гулливерам в стране лиллипутов, писал ещё Джонатан Свифт. Остаётся только быть лучшим и взирать на всё свысока. И чётко разделять, что делается для денег, а что - для души. Потому что в любом сообществе можно найти и идиотов и гениев. Посмотрите на хабр, на лор, на каналы IRC. Это тоже гетто. Весь мир состоит из всевозможных гетто. Но не быть ограниченным гетто - в силах и в праве человека.
Be better. Break ghetto.

KDE 4.0.0 Release: the end of all hope

Всё больше и больше шуму вокруг "релиза" KDE4. Даже для меня, убеждённого кедофила, непонятного. Люди ждут чуда, вы посмотрите только на это:
KDE 4.0 Release counter
Я бы его переделал в when the scream becomes reality. Итак, почему я, как пользователь, не жду "чуда KDE4".

Сегодня на dot.kde.org появилась ссылка на статью, в которой описываются "наиболее ожидаемые" нововведения kde4. Почти все они мне абсолютно безразличны.
Graphics
Oxygen
Темы мы ставить умеем, спасибо.
Plasma
Ещё один ресурсоёмкий, полный багов и, что самое главное, абсолютно бесполезный набор виджетов.
KWin
А вот это хорошо, настраивать всевозможные свиристелки с трёхмерными эффектами будет проще.
Applications
Dolphin
Ещё одна ненужная сущность. Бритвой Оккама её по горлу. А я продолжу пользоваться ортодоксальными файловыми менеджерами вроде mc и krusader.
Okular
Вы знаете, мне безразлично, будет ли это 28 отдельных вьюеров или 1, я просто хочу, чтобы мои презентации в pdf открывались так же молниеносно, как это происходит в FoxItReader под Windows. Да, чёрт возьми, это пиар, программа бесплатна.
Unreleased Applications
Но ведь это ещё невыпущенные приложения, давайте не будем про шкуру неубитого медведя?

В предыдущей подобной статье, которую я грозился найти да так и не нашёл, точно так же все изменения мне показались ничего для меня, как пользователя, не меняющими. Кроме одного - убрали Kicker, заменив на Plasma.

Также есть над чем подумать в статье talking bluntly. Оттуда можно нужно прямо цитировать: "KDE 4.0.0 is our "will eat your children" release of KDE4" (KDE 4.0.0 это наш "он съест ваших детей" выпуск KDE4). Далее говорится о качестве кода. Это релиз для тестеров, не для пользователей. Для средней руки тестеров, отвыкших от компиляторов и дебаггеров. Вы хотите камлать с дебаггером? Я нет. Также это способ чётко сказать разработчикам о готовности и стабильности API, дабы они начали наконец портировать существующие горы ПО под новое окружение. Отмечается сильное улучшение качества с последней беты в связи с тем, что витающие в облаках девелоперы сосредоточились на этом.

We're at the beginning of where we can bring KDE4 into "current produce line" condition, which is to say that KDE4 is that transition period from mid-term to short-term project. И именно поэтому я подожду.

08 января 2008

Про социальные сети

I swear if someone says they’re starting a social network I’m gonna beat them with the heel of my shoe.

If you tell me that your social network will take on facebook because it includes baby pictures then I’m going to laugh in your face. They are an established player with CIA backing. You won’t wipe them out.

Ruby'ть всегда, Ruby'ть везде!

Раз уж заговорил о неочевидных применениях руби, вот ещё одно - руби на мобильных устройствах. Брать тут, ставить так. Чувствую я, что при должной страсти во взоре можно туда же и гемы воткнуть (в чём прелесть их pure-ruby реализации), а так и до рельс недалеко. И никакого апача не надо (хотя он тоже есть).

07 января 2008

then idiots come. ave idiots!

Перед тем, как окончательно засесть за прочтение статьи Rails Is A Ghetto, балую себя различными отзывами о ней, вот например один из них, весьма интересный.
Да, я люблю ruby и изучаю в первую очередь его. Да, в настоящий момент один из проектов, в которых я участвую, подразумевает программирование на уровне СУБД Postgre SQL. И да, всем популярным дистрибутивам я предпочёл Gentoo (если вы можете переварить словосочетание "Linux From Scratch on steroids" - то вы поняли, что это такое). Но сосуществование Rails & Ruby, MySQL & PostgreSQL, Ubuntu & Debian не вызывают во мне столь бурных эмоций ("Fuck you rail0rz, Ruby is not Rails"), коль скоро оно взаимовыгодно. Если развитие сущностей-сателлитов приносит пользу и основе - я за.
Так что ave, idiots!

06 января 2008

Mix it

Довольно интересная точка зрения на будущее использования различных языков. Ola Bini, как и Microsoft, идут хоть и разными, но схожими путями, в то же время недавно три года исполнилось проекту, реализующему "полиглотную разработку" в родном руби окружении.
Мне кажется, это идеальный способ послать подальше всех холиворщиков и писать на том, на чём хочется и что больше подходит. Потому что в конце концов только один остаётся лишь в фильме горец, а языки плодятся и множатся, и одного идеального не будет никогда.

Про Kicker (панель KDE)

Вот тут ЛОР поторопился протрубить о "выходе" KDE4. Пару месяцев назад проскакивала статья, в которой один из разработчиков рассказывал что и почему будет заменено в новой ветке. Если найду статью - обговорю подробнее, но самым терзающим душу пунктом стала замена Kicker'а на что-то совершенно непригодное к использованию.
К чему столько эмоций.

Дело в том, что kicker интересен не сам по себе, а как место размещения апплетов. Коих много, полезных и не очень. Которые всегда перед глазами даже на маленьком мониторе ноутбука. Которые потребляют меньше памяти и процессора, чем аналогичные решения на базе superkaramba. Которые благодаря простоте разрабатываются во множестве сторонними программистами (и автор этих строк попробовал себя на данном поприще).
Для примера -у меня из восьми апплетов на двух панелях лишь половина стандартных. Остальные - это

  • Tasty Meny (ну его-то заменят на вполне удобный вариант, известный нам по SuSE)

  • Taskbar v2, более выгодно смотрящийся на полупрозрачной панели

  • kprocessviewer для прибития особо вредных процессов в пару кликов

  • kirocker для управления akarok'ом без вызова его основного окна


Лишаться всей этой прелести как-то не с руки. И хотя я ярый поклонник KDE, ставить 4 ветку я буду разве что через полгодика, да и то "на посмотреть".

04 января 2008

Про переход на ipv6

Хорошая новость, на мой взгляд.
Пока не будет каких-то централизованных шагов в этом направлении - никто не пошевелится. И будут плакать, колоться, но жить за NAT'ами.

Информация без регистрации.

С недавних пор сайты, не поддерживающие регистрацию по OpenID резко теряют в моих глазах, а регистрироваться на них становится непреодолимо лень. Поэтому когда моя заинтересованность в концепции Test First в отношении Ruby привела меня на страничку IBM dW с учебником, регистрироваться я там не стал, а нашёл копию учебника в гугле.

03 января 2008

Подкасты и агрегатор

Довольно давно пользуюсь такой штукой как подкасты. Экономит время, которое иначе было бы потрачено на RSS ридер, и наполняет поездки информационной составляющей.
Довольно долго искал подходящий софт под никсы. Консольные варианты либо были в сильно зачаточном варианте, либо тянули за собой непозволительно большие зависимости. Графический Juice показался мне верхом нелогичности и непонятности.
А вот написанный на python+gtk gPodder управляется с подкастами именно тем путём, которого я и ожидал от подобного вида программ. И хотя некоторые части функционала пока что лежат отдельными скриптами и не интегрированы в программу и для правильной их работы пришлось ручками залезть в их код, софтина уже вполне удобная.
О том, чего можно интересного так послушать (и не только) расскажу как-нибуть в другой раз.