воскресенье, 24 ноября 2013 г.

ppRuby 1.0.0-beta

Итак, очередная версия ppRuby уже выложена на GitHub. На этот раз, как я полагаю, с установившимся, не экспериментальным интерфейсом. Т.е. в дальнейшем планируются только исправления и дополнения, а не перетряска всего и вся.

  • Эксперимент с классами и одновременной загрузкой разных версий признан неудачным — совершенно лишнее усложнение ради ненужной возможности.

  • Поддержки Ruby 1.8 больше нет и уже не будет. В конце концов, разработчики ее поддержку прекратили, и это уже серьезно.

    Зато работает с Ruby 2.0 и есть основания полагать, что версия 2.1 будет подключена с легкостью.

  • Внутри — удалось понять, откуда берутся сегфолты, и, соответственно, избавиться от них. Есть, правда, подозрение, что это избавление чревато утечками памяти — буду постепенно аккуратно прорабатывать тонкие места.

  • Реализован доступ к полному (ну, почти) Ruby API, а не только к нескольким используемым функциям, как раньше.

  • Начата работа над документацией. Пока — только по-русски. Крайне рекомендуется к прочтению.

четверг, 14 ноября 2013 г.

«Обернутые» функции в Free Pascal

Бывает, требуется множество подпрограмм единообразно обернуть — добавить им всем одинаковое начало и завершение или, что более интересно, выполнить их в блоке „try ... except“ с каким-нибудь фильтром на исключения... Вообще, понятно, что FPC поддерживает процедурные типы, но как раз типы тут могут быть самые разные, а нетипизированный вызов с ручной установкой стека — это потенциальный неиссякаемый источник трудноуловимых ошибок.

Тут самое время вспомнить, что FPC с некоторых пор поддерживает еще и вложенные процедурные типы, а вложенная процедура имеет доступ ко всей области видимости внешней, включая, естественно, аргументы и псевдопеременную result.

Соответственно, можно вынести все действия подпрограммы во вложенную процедуру без параметров, а в основной блок вставить вызов «оборачивателя» с этой вложенной процедурой. Пример ниже.

понедельник, 11 ноября 2013 г.

На полях: RTTI для статики

Подумалось тут: а ведь нет никакой проблемы обеспечить RTTI и передачу разнотиповых параметров при полностью статической типизации без оверхеда. Точнее, сделать так, что оверхед будет возникать только непосредственно при такой передаче, а подпрограмм, ее не использующих, никак не коснется. Всего-то надо — чтобы компилятор помечал такие подпрограммы неким флагом и добавлял скрытый параметр со ссылкой на собственно RTTI фактических аргументов. Так же и переменное число параметров решается.

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

четверг, 7 ноября 2013 г.

Slowpoke-News

Оказывается, в Ruby 2.0 введено непосредственное представление значений с плавающей точкой на 64-битной архитектуре, в связи с этим несколько констант теперь отличаются и от Ruby 1.9, и от Ruby 2.0 x32. Всё это, конечно, отражено в макросах .h-файлов, но вот при переводе на другие языки приходится учитывать... Макросы и инлайны там ужасающего вида, посему приходится радоваться, что старый формат остался доступен, правда зачем-то вместо rb_float_new() теперь rb_float_new_in_heap() с теми же параметрами. А вообще, могли бы и экспортируемую фунцию для формирования новоформатного Float сделать...

PS. Следующая версия ppRuby будет поддерживать Ruby 2.0 и не будет 1.8. Ну, и интерфейс модуля опять полностью перекурочен — возможность одновременной загрузки двух разных движков мне более не представляется сколь-нибудь ценной.

PPS. Разный стиль версионного именования файлов .so в разных дистрибутивах Linux — бесит.

среда, 30 октября 2013 г.

ppRuby — исправления

Исправил два важных бага в ppRuby. Из-за первого ничего не работало в 32-битных системах, из-за второго — под Windows. В первом случае была моя ошибка по невнимательности — забыл в трех местах cdecl (да, под 64 битами это не имеет значения); во втором не скорректировал инициализацию для Ruby 1.9, поскольку на моей рабочей машине старый способ от 1.8 продолжал работать...

четверг, 24 октября 2013 г.

RDot 1.1.1.1 — промежуточный недорелиз

Новая версия поддерживает аргументы-ключи и **kwargs у методов. Собственно новые возможности пока не введены, это скорее допиливание старых до совместимости с Ruby 2.0.

среда, 9 октября 2013 г.

Возвращаясь к размышлизму...

Или снова об оптимизации скриптовых языков. В предыдущей заметке я это всё как-то сумбурно описал. Вкратце: для условного веб-сервиса минута инициализации много «дешевле», чем секунда обработки запроса. Поэтому, проведя собственно инициализацию, имеет смысл оптимизировать с ее учетом дальнейшую работу. И для скриптовых языков это вполне возможно, в отличие от компилируемых. А вот как это мне представляется в плане практики:

  1. Составляем граф переходов для загруженной программы. Естественно, учитываем на данном этапе все возможные переходы.
  2. Выделяем самый внешние (т.е. не вложенные ни в какие другие) циклы. Получаем точки-входы и точки перед ними, в которые гарантированно не происходит возврата.

    По идее, нам надо выделить самый главный цикл, а циклы в инициализации и финализации нас уже не интересуют. Скорее всего, его таки можно выделить, но в общем случае — проблематично.

  3. Когда исполнение доходит до такой точки невозврата, включаем оптимизацию дальнейшего кода:
    1. Находим переменные, значения которых в данном цикле не меняются, фиксируем их как константы, вычисляем все константные выражения.
    2. Просматриваем условные ветвления в графе переходов, сокращаем те, условия которых стали константами в силу предыдущего пункта.
    3. Поскольку в отброшенных путях могли быть изменения переменных, повторяем итерацию. Пока изменения не закончатся.
    4. Только теперь с чистой совестью запускаем цикл.

Естественно, это всё не отменяет классической алгоритмической оптимизации, JIT-компиляции и т.д. после сокращения всего ненужного. И естественно, всё это не будет работать при «eval(string)» внутри циклов, но так делать в любом случае не стоит...

пятница, 20 сентября 2013 г.

Клонирование объекта в JavaScript, или Классика велосипедостроения...

Честно говоря, непонятно, почему до сих пор в стандарт языка ECMAScript не внесены две часто нужные вещи: клонирование объекта и «наложение» одного объекта на другой. Помимо прочего, полноценная реализация этих методов возможна только на уровне движка, но нет же — приходится довольствоваться скриптовыми велосипедами от различных библиотек или писать свой.

Ниже мой вариант с пояснениями.

понедельник, 2 сентября 2013 г.

Немного дзынь-буддизму...

Небольшая JS-функция, вроде бы и нормальная, но вызывающая стойкое ощущение упоротости.

воскресенье, 18 августа 2013 г.

Одно неловкое движение, и ты...

В общем, накосячил я немного в попытках внести мелкую правку, и теперь самый популярный пост этого блога, на который есть куча ссылок извне — http://shikhalev.blogspot.ru/2011/01/typo-keyboard-input.html — находится по адресу http://shikhalev.blogspot.ru/2011/01/blog-post.html.

Что с этим можно сделать — понятия не имею.

пятница, 16 августа 2013 г.

Сохраняем выделение

Маленький рецептик — записать, чтоб не забыть, да и вдруг кому пригодится. Когда мы используем в HTML атрибут contenteditable, может возникнуть желание (и почти наверняка возникнет) сохранять выделение редактируемого текста при кликах снаружи (например, на какие-нибудь кнопки). Сделать это можно например так:

Это, конечно, крайне примитивный пример, который, скажем, не проверяет, что выделение само по себе находится в редактируемой области, проверяет только то, что клик не в ней.

В принципе, механизм очевиден, пояснения по методу compareDocumentPosition() можно найти в документации Mozilla, или на JavaScript.ru.

В процессе довелось столкнуться с интересным моментом — при абсолютном позиционировании элементов на странице могут быть области ничем не покрытые, в т.ч. и элементом body. Соответственно, обработчик события на них не срабатывает, и выделение сбрасывается. Чтобы этого не происходило, я использовал CSS:

Демо-пример целиком можно взять по адресу: https://gist.github.com/shikhalev/6246433.

четверг, 25 июля 2013 г.

Ruby 2.0 и мои проекты

RDot работает для кода со старым синтаксисом, новые возможности требуют доработки напильником. В ветке 1.0.x такой доработки не будет, можно считать ее привязанной к Ruby 1.9, ветка 1.1–1.2 будет совместима как с 1.9, так и с 2.0, более поздние версии — только 2.0.

ppRuby на данный момент с Ruby 2.0 не работает. Судя по всему, опять поменялись внутренние константы... Предстоит бурный рефакторинг с выходом, надеюсь, на стабильную ветку.

Всякие мелкие гемы буду проверять и корректировать по ходу дела.

воскресенье, 21 июля 2013 г.

Кратко: примитивный git-сервер

Сначала немного об окружении. Во-первых, предполагается наличие доступа на сервер по SSH, причем управление доступом стандартное: через ~/.ssh/authorized_keys. Во-вторых, в моем случае на сервере уже стоит nginx; впрочем, он понадобится только для веб-отображения (см. скриншот справа), без которого вполне можно обойтись. В-третьих, как обычно, я все это делаю под Gentoo.

Теперь, что мы получим в результате. Управление репозиториями только ручное — нужно зайти на сервер под рутом, создать реп и дать на него права. Аналогично с доступом. Веб-интерфейс предназначен только для просмотра, зато обеспечивает трансляцию обновлений в RSS. Если требуется что-то большее, следует обратить внимание на GitLab, например.

среда, 10 июля 2013 г.

Лёгкая система на Qt? May be...

Тема этого поста навеяна статьями Сергея Голубева — [1] и [2]. Если кратко, там делается вывод, что в легких десктопах нет смысла, поскольку всё равно придется запускать тяжелые программы — браузер, офис, вот это всё... Однако, поскольку я уверен, что офисный пакет не нужен абсолютно, а браузеры бывают и полегче, чем жирный FireFox, увешаный плагинами, и монструозный Chrome с отдельным процессом на каждый чих, мне стало интересно, чего такого легкого удастся вытянуть на базе Razor-qt, вдруг для каких-нибудь целей оно и сгодится.

Для этого я создал виртуалку, выделив ей всего 512MB оперативки, завел там Gentoo и пошёл листать Qt-Apps.org, сразу поставив себе задачу ограничиться программами, не требующими для себя ни библиотек KDE, ни GTK+, не говоря уж о Gnome. Еще одним ограничением было наличие программы в официальном репозитории Gentoo, или хотя бы в полуофициальном оверлее Qt.

Итак, что же получилось?

среда, 19 июня 2013 г.

Откуда ждать подлянки...

... или Знаете ли вы что...

Кросспост из ЖЖ. Оригинал находится тут.

Инфоповод: Компания Oracle молча перевела man-руководства MySQL на проприетарную лицензию. О чем это нам говорит? О том, что у Oracle были права на эти руководства, несмотря на GPL. Скорее всего, так вышло, потому что документацию писали сотрудники на зарплате, а не сообщество, но я сейчас не об этом.

Гораздо интересней то, что в ряде проектов с двойным лицензированием используется практика передачи прав на код при попадании в апстрим. Так было, например, в OpenOffice.org до передачи его в Апач. Почему-то мало кто задумывается, что от закрытия кода только с одной стороны защищает GPL, а с другой — наличие множества независимых владельцев прав на этот код, которых одновременно уговорить на смену лицензии вряд ли получится. Для end-user проектов это не особо критично, поскольку уже опубликованную под GPL версию закрыть не получится, а вот для инфраструктурных, в которых важен весь жизненный цикл, обновения, вот это всё... В общем, лучше на такое не завязываться бы.

А теперь собственно, зачем этот пост. Практика отъема прав у разработчиков существует не где-нибудь, а в Проекте GNU, да благословит его Аллах и приветствует.

Можно возразить, что уж кто-кто, а FSF свободу ПО ущемлять не будет, но не всё так просто. Во-первых, где гарантия, что вместо фанатичных, но всё же вменяемых, гиков к руководству фондом не придут какие-нибудь упоротые и не забабахают неприемлемую для зависимых проектов, а главное — несовместимую с приемлемыми, новую лицензию? Во-вторых, где гарантия, что по глупости, или злому умыслу, FSF внезапно не случится банкротом, и его «интеллектуальная собственность» не пойдет с молотка?

суббота, 8 июня 2013 г.

Чего-то я не понимаю в этом вашем rb_protect...

Сначала маленькое неприятное, но понятное наблюдение: rb_eval_string_protect() в Ruby 1.9 (и, надо полагать, в 2.0 тоже) воспринимает эту самую «string» как содержащую данные в кодировке US-ASCII. Собственно, так поступают все фунции работы со строками, унаследованные из 1.8, но для обычного преобразования строки в ruby-объект String есть новые функции, позволяющие кодировку указать. А для rb_eval_string_protect() соответствующих аналогов не предусмотрено...

Отсюда логичное желание сначала строку преобразовать (с указанием правильной UTF-8), а затем уже выполнить — скормить методу Kernel.eval(). Заворачиваем этот вызов в функцию, вызываем ее через rb_protect()... И получаем странную вещь — все вроде бы отрабатывается, но если в Ruby происходит исключение, рушится стек исключений уже внешнего pascal-кода. При успешном вызове такого не происходит. Возможно, где-то косяк с соглашениями о вызове — си-паскаль переходы штука тонкая, да... Но: а) любые действия, не вызывающие исключения, проходят на ура, многократно и т.д., т.е. стек вызовов, в отличие от стека исключений, в порядке, и б) ruby-методы, мною созданные из pascal-функций, с теми же соглашениями о вызовах, работают правильно...

Причем, rb_eval_string_protect() работает прекрасно — корректно обрабатывает исключения, как и должно быть по документации. Только о кодировках ничего не знает, а так — ok. В общем, сейчас рабочий вариант такой — задаю глобальную переменную «$script_string», а затем через rb_eval_string_protect() выполняю «eval $script_string». Само по себе это решение меня устраивает, но непонятки с rb_protect() все-таки напрягают.

PS. Для иллюстрации: проблемный код vs беспроблемный код.

среда, 5 июня 2013 г.

Маленький нюанс MethodAddress

Иногда во Free Pascal / Lazarus бывает нужно динамически устанавливать обработчики событий — имеем объект и имя свойства-события и устанавливаем через SetMethodProp(). В ряде мест можно встретить инструкции делать примерно так:

var
  meth : TMethod;
. . . . .
meth.Data = MyHandlerObject;
meth.Code = MyHandlerObject.MethodAddress('HandlerMethod');
SetMethodProp(Reciever, 'onEvent', meth);

А оно не работает. Потому, например, что HandlerMethod() невиртуальный. В общем, не надо тут усложнять, если имя метода известно при компиляции. Всё просто:

SetMethodProp(Receiver, 'onEvent', TMethod(@MyHandlerObject.HandlerMethod));

понедельник, 3 июня 2013 г.

Экую интересную багофичу поймал...

Занимаясь переработкой ppRuby, напоролся на очень интересную особенность, которая стоила мне часов восьми матерной отладки...

Вкратце: в одном из определяемых методов заворачивал я объекты (дочерние компоненты) в объекты Ruby, складывал в массив, затем — преобразовывал массив в рубишный посредством “rb_ary_new4()”. При дальнейшем использовании этого массива получал AV. При этом формирование хэша, перебор этих дочерних компонентов, и т.д., и т.п. — всё проходило прекрасно. А с массивом — жопа.

В итоге выяснилось следующее: пока добавлялись последние элементы, по первым успевал пройтись сборщик мусора — у движка-то на них ссылок не было... Решение: создавать пустой массив и добавлять по одному. Работает.

среда, 29 мая 2013 г.

RDot — 1000 загрузок

Итак, RDot набрал 1000 загрузок на RubyGems. Вполне себе повод для поста с описанием текущих изменений, накопившихся со времени предыдущего.

Стабильная ветка — “fixes

v1.0.1
Исправление бага, внесенного шаловливыми ручками в версию 1.0.0 с невидимостью RDot::defaults, что вызывало падение при попытке запустить “rdot --help”.
v1.0.2
Исправлен незамеченный ранее баг с тем, что protected-методы дублировались еще и как public. Ранее же он не был замечен, видимо, из-за того, что сами эти методы редки...
v1.0.3
Улучшено отлавливание атрибутов. Теперь и в блоках.
v1.0.4
Сегодня руки дошли — в параметры командной строки добавлен ранее пропущенный (по невнимательности) “--color-module-core”.

Нестабильная ветка — 1.1.0.preX

Для установки из этой ветки нужно выполнить команду:

gem install rdot --pre

Основная функциональность, планируемая на версию 1.1, пока не готова, исправления вносятся параллельно стабильной ветке... Но один повод воспользоваться именно этой альфой есть — добавлен параметр «--graph-splines», который позволяет указать форму стрелочек на диаграмме. Возможные значения можно увидеть в документации GraphViz.

понедельник, 27 мая 2013 г.

Еще немного о контексте и блоках

Написанное мною в предыдущем посте можно понять так, что “define_method”, а точнее — блок вообще, не формирует своего контекста и области видимости локальных переменных. Это не совсем так — блок формирует собственный контекст, но этот контекст не является изолированным, в отличие от контекста, определенного “def”.

воскресенье, 19 мая 2013 г.

Отличие между def и define_method

Надо все же записать, а то сам регулярно на эти грабли наступаю...

Важное отличие между “def” и “define_method” в том, что “def” формирует свой собственный, полностью автономный контекст, а “define_method” работает с замыканием. Т.е. в примере:

a = 1

define_singleton_method :alpha do
  p a
end

def beta
  p a
end

alpha
beta

вызов “alpha” отработает нормально, а вот при вызове “beta” Ruby доложит о неопределенной переменной.

Небольшой JS-велосипед с пояснениями

Микробиблиотечка для формирования классов в JavaScript. Целиком обозреть файл можно на GitHub, а ниже я его рассмотрю по порядку фрагментов.

пятница, 17 мая 2013 г.

Об оптимизациях скриптовых языков...

Подумалось: а ведь скриптовые интерпретируемые языки вполне способны на некоторых задачах обгонять компилируемые и сильно, если программу не исполнять, а вычислять как формулу — это же совершенно не обязательно делать по-порядку. Можно «раскрыть скобки», «привести подобные», «сократить»... Соременные компиляторы, собственно, так и делают, но они могут зафиксировать только параметры, известные на этапе компиляции, а для прочих приходится учитывать все возможные комбинации значений, тогда как при каждом конкретном запуске программы их подмножество существенно ограничено. Многие вещи — такие как: переменные среды, параметры командной строки и т.д. — определяются при старте и далее могут считаться константами, соответственно, упрощаются выражения от них и т.д.

Понятно, что это упрощение дальнейших выражений не бесплатное: скорее всего, скажем, удаление неиспользуемых ветвлений будет требовать больше ресурсов, чем вычисление этих условий по ходу дела, но ежели эти условия и другие выражения должны вычисляться многократно... Скажем, для вебсервера время старта куда менее критично, чем время отклика на запрос.

Что для этого нужно? Во-первых, структурированное внутреннее представление, с которым можно манипулировать как с формулой — это не текст и не байт-код (в Ruby свежих версий именно так). Во-вторых, необходимо как-то определять наличие побочных эффектов (в Ruby это, пожалуй, может быть довольно просто реализовано для собственно ruby-методов, а вот с модулями, загружаемыми как .so и .dll будет проблема. Впрочем, достаточно к нескольким системным фунциям типа “define_method” добавить соответствующие описательные параметры). И в-третьих, желательна жесткая инкапсуляция данных, так что Ruby для этой цели подходит, а вот, скажем, JavaScript — намного хуже.

А пока такой оптимизации нет, наверное, можно подумать о том, чтобы в своих программах не только вычислять какие-то параметры один раз при старте, но формировать код в зависимости от них...

среда, 15 мая 2013 г.

Пара гемов в копилку: фиксированная точка и автонумерация билдов

is-fixed

Очередной велосипед, нужда в котором вызвана неподходящим радиусом кривизны руля у велосипедов имеющихся.

Пока реализованы только базовые операции. В планах: дореализовать все методы и сделать округление банковским (опционально, скорее всего).

is-build

Автоинкрементация номера билда для гемов.

Напомню, что версия гема состоит из четырех чисел, последнее из которых может иметь текстовый префикс. Это самое последнее число обозначает мелкие изменения, нумеровать которые вручную легко забыть, да и просто лень...

Данный гем добавляет объектам класса Gem::Specification метод «mkbuild», который вычисляет хэш включенных в гем файлов и, если тот изменился, инкрементрирует номер билда. Пример можно посмотреть в его собственной спецификации. Метод должен быть вызван после того, как уже заданы: название, список файлов и начальное значение версии (из трех чисел).

В планах: предварительная обработка номера версии (на случай, если заданы не три числа) и учет расположения .gemspec-файла (сейчас версии сохраняются в текущем каталоге, что как правило совпадает с расположением исходника, но не всегда).

Исходники всех гемов по-прежнему можно взять на GitHub.

Странности статистики

Я время от времени просматриваю статистику посещений этого блога — самую обычную, встроенную. Там, в частности, показываются источники переходов... И вот тройка запросов в Яндексе, через которые ко мне заходят:

  1. shikhalev.blogspot.com (13 за неделю)
  2. vk.com (7)
  3. ââîä ñèìâîëîâ ñ êëàâèàòóðû (4)

Вот единственное, что из этого списка мне понятно — это кракозяблы третьим пунктом. «vk.com» у меня нигде не встречается (до этого поста). Что же до п.1, понятно, что ссылки там ведут куда надо, но что же это за читатель такой, который целеустремленно раз за разом вбивает в Яндекс полный адрес блога?..

вторник, 14 мая 2013 г.

Класс — это модуль и не модуль, и что с этим делать

Есть в Ruby одно заметное нарушение LSP: класс, будучи вообще-то модулем (Class — прямой наследник Module), не может быть использован вместо модуля в качестве примеси, т.е. в “include” или “extend”. Это, в принципе, обоснованно, поскольку они не только объекты, но и конструкции языка...

вторник, 30 апреля 2013 г.

RDot v1.0 — релиз

Допинал документацию и зарелизил.

На версию 1.1–1.2 планирую связи между rb-файлами (по require), а дальше останется только жевать лавры, да послеживать за совместимостью с более лучшими новыми версиями Ruby и GraphViz... Впрочем, можно еще над гемами поизгаляться...

понедельник, 29 апреля 2013 г.

RDot: v0.10.0 ↝ v0.10.10.1

Зря я, пожалуй, мало пользуюсь четвертой цифрой версии, накручивая третью — изменений в функциональности всего два, и они неотличимы по номерам от исправлений.

Итак, история версий, исправлений и новых фишечек.

четверг, 25 апреля 2013 г.

RDot v0.10

Допинал версию RDot для Ruby 1.9. Полностью удалось отказаться от трассировки, всё делается штатными средствами интроспекции. Так что внезапных глюков должно стать намного меньше.

Заодно разделил логику и управление и оформил всю эту радость в виде гема. Теперь ожидаю лютой бешеной популярности (:смайл:).

В общем, можно брать с: RubyGems, GitHub, и традиционно до кучи —  BitBucket.

На рисунке — пример конечного результата, сформировано командной строкой:

rdot --title=Is::Command --title-size=64 is/command | dot -Tpng -oout.png

PS. Данная версия под Ruby 1.8 работать не будет. Последняя гарантированно рабочая под 1.8 версия — 0.9.4.

воскресенье, 21 апреля 2013 г.

Ruby и обезьяна с гранатом

Начал формировать гем с устоявшимися (у меня) monkey-патчами. Брать тут:

  • is-monkey — собственно гем.
  • yard-is-monkey — плагин для YARD, позволяющий учитывать в документации свойства, определенные методом property().

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

PS. Надо бы как-нибудь собраться и написать большую статью про YARD...

четверг, 18 апреля 2013 г.

Корректный nowrap

Наконец-то до меня дошло (в процессе написания предыдущего поста), как до жирафа, право слово... Итак, как же корректно (без использования устаревших и нестандартных конструкций) запретить перенос по пробелам в некоем сложносоставном (например, с маленьким рисунком) сочетании внутри строки, т.е. чтобы в ссылке вида « Иван Шихалев» никакая часть гарантированно не отрывалась от других? Ларчик просто открывался:

<span style="display : inline-block"><img src="/favicon.ico" style="vertical-align : text-bottom"> Иван Шихалев</span>

Детали оформления я, естественно, поскипал, ключевой момент выделил жирным.

Ruby: Gems и кое-что о документации

Сподобился таки оформить пару модулей как гемы и разместить на RubyGems.org:

  • is-command — DSL для написания «многокомандных» консольных приложений, т.е. таких, которые используются в виде:

    $ program ‹опции› ‹команда› ‹опции› ‹параметры›
    причем команды могут быть вложенные. Так, например, работает Git.

    На данный момент не сделана генерация справочного сообщения, посему версия 0.8, а не 0.9.

  • is-lazy — модуль для «ленивых» и многопоточных вычислений, о котором я уже писал (правда, изрядно реорганизованный).

На GitHub я поместил их в один проект — https://github.com/shikhalev/gems, куда и в дальнейшем планирую складывать всякую ruby-мелочевку.

В процессе выяснилась приятная вещь — если код документировать в комментариях посредством YARD, без каких-либо лишних телодвижений получаем онлайн-документацию на RubyDoc.info (см. [1] и [2]), на которую ведет ссылка со страницы гема. Документация появляется с некоторым запозданием порядка минут или часов, но это ж не страшно. Кроме того, с минимальными телодвижениями можно организовать такую же документацию для любого проекта на GitHub — нужно лишь включить соответствующий пункт в «Settings / Service Hooks» — см. [3].

Традиционное зеркало проекта на BitBucket — https://bitbucket.org/shikhalev/gems.

суббота, 23 марта 2013 г.

Тотальный push

Написал примитивный скрипт, чтобы push'ить из локального репозитория в несколько удаленных одной командой (лично для меня — обычное дело). Обозвал его “git-up”:

#!/bin/bash

for repo in $(git remote); do
  git push $repo $@;
done;

Чтобы git-sh начал радостно отзываться на команду “up”, в ~/.gitconfig потребовалось добавить синоним:

[alias]
 up = !git-up

Еще пара стилей

Теперь гламурненьких, с фоном и полупрозрачностью. Фон можно загрузить свой, или выбрать из двух «космических». Брать там же — http://userstyles.org/users/181685.

PS. Если ваш браузер не поддерживает указание цвета в формате rgba() — не советую эти стили сразу — уродливая фигня получится.

четверг, 21 марта 2013 г.

Stylish для Флибусты и Либрусека

Давно собирался довести до ума свои стили для чтения книг с Флибусты, наконец-то собрался. Поскольку пароль от старого логина на userstyles.org я внезапно забыл, брать здесь: http://userstyles.org/users/181685. Автоматические скриншоты чего-то не сделались — пока, или совсем, не знаю... Вкратце, там убраны лишние элементы, увеличен шрифт и добавлен пастельного оттенка фон (с пометкой «cold» — голубоватый, «warm» — коричневатый).

upd: Скриншоты появились. Правда, их автоматика не умеет расставлять переносы (см. пометку «hyphen»), а современные браузеры умеют.

четверг, 14 февраля 2013 г.

Kate Projects Plugin

Отличная штука — сабж. И наконец-то (в KDE 3.5 подобное вполне себе работало).

Правда, сырость чувствуется — чего стоит хотя бы тот факт, что из меню/диалогов никак этот самый проект не создать, и не изменить... Нужно вручную сформировать в каталоге проекта JSON-файл с именем «.kateproject» примерно такого вида:

{
  "name" : "WeRB",
  "files" : [
    {
      "git" : 1
    },
    {
      "directory" : ".",
      "filters" : [ "*.rb" ]
    }
  ]
}

Здесь у меня первый элемент массива files добавляет все, что есть в данном Git-репозитории, и именно эта возможность мне представляется наиболее значимой (вообще, инструменты разработки сейчас просто обязаны интегрироваться с системами контроля версий); а второй добавляет Ruby-файлы в корне проекта (там у меня валяется парочка файлов для быстрого тестирования чего-нибудь маловажного, в репозиторий их помещать не резон совсем). Если добавить свойство «"recursive" : 1», то будут добавлены файлы и из подкаталогов.

Открытия проекта как такового не предусмотрено — при открытии любого файла будет искаться вверх по структуре каталогов файл «.kateproject»...

За подробностями см. «Using the Projects Plugin in Kate».

Недостающее...

Очень надеюсь, что нижеописанное будет исправлено раньше, чем KDE 5.0 сломает снова всю экосистему к чертям собачачим...

  • Не помешало бы все же GUI-управление.
  • Печально, что открытые проекты не запоминаются в сеансах.
  • Насколько я понял, пока из VCS поддерживаются только Git и Subversion. Выбор хорош, но другие системы тоже имеют своих приверженцев.
  • Вот здесь описан механизм групп, которого весьма не хватает.
  • Скрытые файлы почему-то никак нельзя добавить через фильтры, только через систему контроля версий.
  • Документация, блин! Где документация?..

Тем не менее — рекомендую. Надеюсь, плагин будет развиваться.

вторник, 29 января 2013 г.

Перевод строки: трактовка Ruby vs JavaScript

Как известно, в обоих языках можно опускать точку с запятой в конце строки, однако разница есть, и она существенная: в Ruby проверяется, можно ли текущее выражение завершить, и если да — завершается, тогда как в JS — можно ли продолжить, и если да...

Парсеру, надо полагать, оба варианта равноудобны, но для человеческого восприятия гораздо удобней вариант Ruby (я, например, в JavaScript всегда использую точку с запятой, чтоб не путаться, а в Ruby — никогда). Почему в JS сделано так? Думаю, разгадка проста, как безблагодатность — обратная совместимость — когда-то же «;» пропускать было нельзя и, соответственно, простой перевод строки обязан был трактоваться как пробел. В Ruby же эта фича «by design».