26 дек. 2009 г.

Буги с косой

Буги с косой
(В. Бутусов - Д.Умецкий)

буги-вуги такой жестокий танец
буги-вуги такой нерусский танец
он падает как град на голову мне
бреду в темноте словно во сне
буги шепчет в уши буги лезет в душу мне

буги-вуги - это образ жизни
буги-вуги - это образ мыслей
отлепляю наушники от головы
каким же дерьмом набиты наши мозги
буги слепит глаза но не видно ни зги

и с какой же стати я должен все это терпеть
я хочу жить как все и хочу как все умереть
но дэнс буги-вуги дэнс - еще...

буги-вуги живет у меня в волосах
буги-вуги сидит у меня на плечах
о буги-вуги, буги с косой
буги-вуги...

24 дек. 2009 г.

Шумахер вернулся!

http://www.formula1.com/news/headlines/2009/12/10301.html

Ура! Можно будет снова смотреть гонки. :-)

Stack Overflow: Бесплатные баннеры для open source

Сайт StackOverflow.com запустил программу бесплатной ротации баннеров для проектов с открытым исходным кодом.

Подробности здесь.

Every Day the Same Dream


Психоделично. Эту игру, кстати, можно пройти.

Canon 1D MKIV 1080p HD video

Nocturne from Vincent Laforet on Vimeo.

Снято без специального освещения.

22 дек. 2009 г.

Хабраинвайт

Да, за 50 кармы, похоже, инвайт всё-таки не дают. Хабрапомощь опять врёт.

Придётся ещё статью писать. :-)

20 дек. 2009 г.

Dwarf Fortress


Шикарная игра-песочница: Dwarf Fortress. Evil Genuis meets Falling Sand Game.

Без туториала не запускать. Играть с мануалом в руках.

Update: Стёр. Оторваться невозможно.

К вопросу о скриптовых языках

Паттерн: Alternate Hard and Soft Layers.

11 дек. 2009 г.

LuaJIT 2 x64 Sponsorship Program


Теперь в наших силах сделать так, чтобы скорее вышла 64-х битная версия!

(Есть возможность принимать спонсорскую помощь и от частных лиц.)

Новый датацентр Linode.com в Лондоне

Linode.com открыли датацентр в Лондоне.

Пинг на 50 мс лучше чем до Штатов.

http://www.linode.com/speedtest/

Рекомендую.

6 дек. 2009 г.

Sketch2Photo

Китайцы жгут!

Sketch2Photo: Internet Image Montage from Tao Chen on Vimeo.

Ещё ссылки:

Тестирование белым стихом

Функционал: Сложение чисел

Чтобы не складывать в уме
Все, у кого с этим туго
Хотят автоматическое сложение целых чисел

Сценарий: Сложение двух целых чисел
Допустим я ввожу число 50
И затем ввожу число 70
Если я нажимаю "+"
То результатом должно быть число 120

Cucumber / addition.feature

Расцветка target'а через CSS

Оказывается, в CSS можно расцвечивать элементы по target'у из URL'а.

http://www.twisty.com/misc/tests/css/target-trick.html#b

(См. исходный код страницы по ссылке.)

Основы декларативного программирования на Lua

Написал ещё одну статью для Хабра:

http://habrahabr.ru/blogs/development/77413/

Локальные переменные в луашной консоли

Всегда огорчался тем, что в луашной консоли тяжело использовать код с локальными переменными:
$ lua
Lua 5.1.3 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> local v = 5
> print(v)
nil
Переменная ушла из области видимости.

Теперь, наконец-то дошло, что нужно использовать do...end:
> do
>> local v = 5
>> print(v)
>> end
5
Примеры в статьях теперь будут корректнее. :-)

5 дек. 2009 г.

Parsing HTML with regular expressions

...Asking regexes to parse arbitrary HTML is like asking Paris Hilton to write an operating system...
StackOverflow.com
See also:

Best. StackOverflow. Answer. Ever!

Comments on Reddit.

1 дек. 2009 г.

HTML: мягкий перенос

Всё время забываю.

­

Мягкий (необязательный) перенос в HTML. Полезно при выравнивании по ширине.

29 нояб. 2009 г.

Lua 5.2

Альфа — уже "через несколько месяцев"!

27 нояб. 2009 г.

Уникальная фича Google Wave

Благодаря тому, что в GW в реальном времени видно, что печатает собеседник, GW — это первое электронное неголосовое средство общения в котором я могу его перебить!

Зря они эту фичу сделали :-)

26 нояб. 2009 г.

Google Wave

Мммм, вэээйв!..

24 нояб. 2009 г.

luamarca

Наконец-то слегка привёл в чувство и выложил луашную бенчмаркилку.


Надо теперь в бенчмарках порядок навести.

22 нояб. 2009 г.

Хабрастатьи

Хабранаписал хабрадве хабрастатьи.

Хабраплюсуйте:

Оформление кода для Хабра

Оформление код для хабрастатей:
  • Расцветить код на highlight.hohli.com со включённой галочкой "Use tag (for Habrahabr)".
  • Добавить внутрь тега blockquote тэг code
  • Если код не требует расцветки, проще его обрамить в blockquote-code-pre.
Список существующих редакторов — здесь.

21 нояб. 2009 г.

Lua vs. C++ for large programs

Mature C++ programmers often argue against intense Lua usage in the large programs.

They say that C++ is fast, Lua is slow. C++ has excellent tools to provide compile-time validation, while Lua is too dynamic and, therefore, unreliable.

Some time ago there was a related discussion on Lua mailing list. I hear these arguments so often, that I've decided to post a small essay in reply. Now I'm posting a slightly edited version of this essay here.

* * *

Several years before, when I came to Lua, my professional programming experience was almost all C++, without much of dynamic languages experience. Indeed, in C++, with careful design, compile-time validation can give very good correctness guarantees.

At first it was quite hard to write code in Lua — without compile time validation, without static types, it felt as if I try to stand on a blob of wobbly jelly instead of a good solid rock.

However, the price of such validation is quite high. Not to mention longer compile times. You need to spend much time on the design itself. Sometimes much more time than you'd spend solving the problem that you write code for. You need highly skilled and disciplined architector paying constant attention to the each part of the project all the time. You need highly-qualified programmers.

If you have a hammer, try to avoid looking on everything as a nail.

I quite understand if that amount of effort is spent on the low-level "foundation" code in the system (application, library etc.). It is usually written once, must be of high quality and work fast. But to waste it on the business logic, that mutate every day to the whim of the high command?

You want to be able to write cheap business logic code. Okay, it should be reliable enough and fast enough. But it is usually comes in huge quantities, and you should be able to change it quick. You should not need extra skilled programmers to write it — or your budget will bust.

Lua is perfect here — it is reliable, quite fast and easy to grasp.

Compile-time guarantees are not possible to achieve with pure Lua. As we know, Lua compiler is dumb (and this is a good thing — since it is also fast and simple).

I do hope that, in time, we would get Metalua-based static code validation tool, powerful enough to do something like that. But there is no such tool now.

However, there is a simple solution. Write tests.

Any static analysis tool may only catch such generic errors, that it has heuristics for. Even C++ compile-time validation will catch only so much of wrong logic — and the more it may catch, the greater the price you have to pay for the code.

To give a sense of scale: My last project had 160+ KLOC of Lua code. 80 KLOC of it were tests for our Lua and C++ code (we had 90+ KLOC of C++ in total). Most of our tests were declarative and consist of table-structured input / expected output data, they were significantly sparser than the usual code, so the price per LOC is lower.

Tests catch more (you may tune them exactly to the behaviour you expect), they cost less (you may employ less sophisticated programmers), they help refactoring at least as much as the static compile checks.

If we compare Lua with "test-time" validation and C++ with its compile-time checks, to me Lua is the winner (for the business logic at least).

* * *

Do not be afraid to use Lua in large-scale applications! It is at least as easy to write reliable code in Lua as in C++.

Of course, you have to write tests, but you should write them anyway. Lua is powerful enough and is fast enough (especially with LuaJIT 2) to make you happy. Yet it is simple enough so you don't have to force guru-level programmers to write tons of mind-numbing business-logic code.

genmakefile

Когда я писал luabins, я довольно долго возился с системой сборки проекта.

По умолчанию luabins собирается как C89. Однако, со сборкой в тестовом режиме (make test) не всё так просто.

Хорошим тоном считается, когда луашный модуль написан, как и сам Луа, на "clean ANSI C" — подмножестве C89, C98 и C++.

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

С учётом всех требований вся система получается довольно сложной.

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

Писать такой Makefile руками — тяжело. Нужен генератор.

Поскольку luabins — некоммерческий проект, мне было интересно написать такой генератор самому, в качестве развлечения.

Получился genmakefile.

Genmakefile — интересный "игрушечный" прототип мощной системы генерации текста на основе текстовых шаблонов.

Вот пример входных данных: Makefile.luabins.template.

То, что получается на выходе, мы уже видели в luabins: Makefile.luabins.out.

Вот код, который заставляет это всё работать: genmakefile.lua

Что же мы получаем из этих четырёхсот строк кода?
  • Шаблонную систему с подстановкой значений по ключам.
  • Из шаблона можно контролировать подстановочные словари.
  • Можно создавать макросы, переопределяя язык подстановок.
  • Можно использовать шаблоны и макросы неограниченной вложенности — шаблоны, генерирующие шаблоны и т.п.
  • Несколько вызовов, специфичных для генерации Makefile-ов. :-)
Недостатки — типичные для раннего прототипа:
  • Плохо продуманый синтаксис.
  • Плохо продуманное API.
  • Маловменяемые сообщения об ошибках.
Вывод: Lua rules! :-)

Есть недостатки, но получилось интересно, просто и мощно. Нужно переосмысливать и развивать систему дальше.

Дополнительное чтение:
  1. Mixlua (искать Mixlua в тексте по ссылке).
  2. Cosmo.

luabins

К вопросу о неанонсированных релизах. :-) Обнаружил, что ещё ничего не писал здесь про luabins.

Luabins — библиотека для бинарной сериализации луашных данных.
Лицензия: MIT.
Текущая версия: 0.1.1 (архив).

С библиотекой можно работать как из Луа, так и напрямую из C/C++.

Основное назначение luabins — сериализация данных для Lua-to-Lua RPC вызовов. При этом библиотека отлично подходит и для хранения простых данных.

Luabins поддерживает примитивные типы: nil, boolean, number и string. Поддерживаются нерекурсивные таблицы разумной вложенности (250 уровней по умолчанию, настраиваемо).

Luabins намеренно не поддерживает рекурсивные таблицы, функции, корутины и userdata. (Если нужна сериализация этих типов — вам к Pluto.)

Наивный пример работы на Lua:
Работа через luabins существенно быстрее чем сохранение и загрузка данных через луашный код в духе tstr и tserialize.

Размер сохранённых данных обычно больше, чем при сохранении в луашный код. (В основном из-за представления целых чисел в виде double; это та же проблема, что и при компиляции луашных исходников в байт-код.) В следующих версиях запланированы оптимизации на эту тему.

Luabins намеренно не сохраняет и не проверяет никакую мета-информацию о данных (включая версию формата!). Если нужно, эту информацию нужно подклеивать к данным руками.

Luabins пытается защищаться от враждебных (или просто неверных) данных при загрузке. Делаются проверки на переполнение и на переаллокацию.

На данный момент Luabins используется в нескольких коммерческих проектах.

Дополнительное чтение:

lua-phpserialize

Некоторое время назад я выложил v0.0.1 библиотеки lua-phpserialize.

Только теперь дошли руки написать об этом в блог. :-)

Части запланированных фичей нет (patches are welcome), но уже текущую версию библиотеки можно (и нужно) использовать для сохранения луашных данных в формат, понимаемый PHP-шным unserialize().

Очень удобно использовать для передачи данных из Lua в PHP.

Ограничения:

Как обычно, рекурсивные таблицы, функции и userdata не поддерживаются. Также, форматом PHP-шных массивов налагаются определённые ограничения на ключи.

Подробнее — здесь.

luadevtools

Слухи:

На Гитхабе появился проект luadevtools.

В проект добавлен Fabien Fleutot, автор metalua.

Проект создан от имени Sierra Wireless, работодателя Fabien'а.

Обещанное Fabien'ом наконец-то начало сбываться?

Ура!

20 нояб. 2009 г.

К вопросу о генераторах генераторов

Примечательный quine:

http://catap.ru/blog/2009/11/09/one-japan-man/

Ruby -> Python -> Erlang -> Perl -> Lua
-> OCaml -> Haskell -> C -> Java -> BrainFuck
-> Shell -> Whitespace -> Unlambda
-> Ruby

19 нояб. 2009 г.

Erlang/OTP переезжает на GitHub

Пруфлинк

100



Планка в сто постов в год преодолена!

Ура!



Paul Graham on Apple's AppStore

When you look at the famous 1984 ad now, it's easier to imagine Apple as the dictator on the screen than the woman with the hammer. In fact, if you read the dictator's speech it sounds uncannily like a prophecy of the App Store.
We have triumphed over the unprincipled dissemination of facts.

We have created, for the first time in all history, a garden of pure ideology, where each worker may bloom secure from the pests of contradictory and confusing truths.
Paul Graham, Apple's Mistake.

Gource: Визуализация истории кода

Медитативно, познавательно и, главное, крайне просто в использовании.

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

18 нояб. 2009 г.

Lua 5.1.4 полностью реализована на C#

Живёт здесь:

http://www.ppl-pilot.com/KopiLua/

Tuples in Lua

Как делать кортежи.


Всё время теряю эту ссылку.

10 нояб. 2009 г.

20 Linux System Monitoring Tools Every SysAdmin Should Know

http://www.cyberciti.biz/tips/top-linux-monitoring-tools.html

Надо уже, наконец, запомнить:
  • vmstat
  • w
  • sar
  • mpstat
  • pmap
  • ss
  • iptraf
  • ntop
Но про dstat они так и не написали...

Поддержка Unix Domain Sockets в Lua

Гугль открыл тулзы для работы с яваскриптом

Оптимизирующий компилятор, библиотека и система шаблонов.

http://code.google.com/intl/en-US/closure/

Yahoo открыл TrafficServer

TrafficServer — быстрый (до 35.000 запросов в секунду) кеш и прокси для HTTP/1.1.

Общение с ядром при помощи SysRq

Наиболее полная статья, что мне попалась по теме.

http://mydebianblog.blogspot.com/2007/07/sysrq-printscreen.html

Не только ALT + SysRq + R, S, I, U, B, но и, например, D.

ab — зло

ab considered harmful

Альтернативы:

Что Гугль знает о моём аккаунте?

Написано здесь:

https://www.google.com/dashboard

В том числе помечено, какая информация доступна публике.

9 нояб. 2009 г.

gedit

Без KDE под Ubuntu иногда сильно не хватает Kate.

Гномовский gedit в дефолтной комплектации уж очень убогий.

Вот это несколько улучшает ситуацию.

7 нояб. 2009 г.

Linode.com

Какое-то время назад перетащил свой VPS с Мастерхоста на Linode.com. Доволен как слон, отличный сервис. Цена та же (20$), и всё кроме пинга ровно в 10 раз лучше. Пинг, правда, в 10 раз хуже (200 вместо 20), но мне это не критично.

Если вдруг кто будет брать себе у них хостинг, предлагаю воспользоваться моей реферральной ссылкой. ;-)

2 нояб. 2009 г.

Веб-прокси через SSH

У Йоты проблемы с роутингом на часть сайтов.

Если есть ssh на внешний сервер с нормальным провайдером, эти проблемы легко обойти.

$ ssh -D 9999 login@server

А потом настроить в браузере SOCKS5 proxy на 9999-й порт локалхоста.

Проверить можно сравнением внешних айпишников в разных браузерах (настроенном и не настроенном).

Также можно поднять локальный HTTP-прокси перед SOCKS-прокси для пущей совместимости.

Взято отсюда.

1 нояб. 2009 г.

LuaJIT 2 beta1 is out!

Вышла долгожданная бета LuaJIT 2.0!

Анонс:


Reddit:


Бенчмарк:

LuaJIT 2 перекрывает Fortran в некоторых численных тестах!

http://shootout.alioth.debian.org/u32/benchmark.php?test=all&lang=all&d=data&gpp=on&java=on&luajit=on&v8=on&calc=calculate&box=1

24 окт. 2009 г.

Работа с XML из командной строки

Набор ссылок.

http://xmlstar.sourceforge.net/
http://www.ibm.com/developerworks/xml/library/x-starlet.html
http://bashcurescancer.com/the-best-in-command-line-xml-xmlstarlet.html
http://www.freesoftwaremagazine.com/articles/xml_starlet

Ускорение работы Firefox

Для OS X:
$ cd ~/Library/Application\ Support/Firefox/Profiles/
$ for f in */*.sqlite; do sqlite3 $f 'VACUUM;'; done
Действительно помогает.

opencv vs. iPhone

Open Computer Vision Library. Распознавание изображений на айфоне. Набор ссылок.

18 окт. 2009 г.

habrahabr.ru

Ура!

http://agladysh.habrahabr.ru/

14 окт. 2009 г.

13 окт. 2009 г.

Онлайн-детектор сломанных кодировок

Всё время забываю, что у Лебедева есть такая замечательная штука:

http://www.artlebedev.ru/tools/decoder/

В гугледоках теперь можно расшаривать папки

Ура, товарищи!

http://www.google.com/google-d-s/whatsnew.html

12 окт. 2009 г.

Флаги для GCC

Флаги компиляции для GCC 4.x от Майка Палла:
-O2 -fomit-frame-pointer -march=native
Если бинарники будут распространяться, то вместо -march=native, -march=i686

Взято отсюда.

1 окт. 2009 г.

Linus on Git по-русски

Хабравчане перевели известную презентацию Линуса о Git-е на русский.

30 сент. 2009 г.

Yota Egg


Какой, однако, забавный девайс. Автономный конвертор 4G в WiFi.

29 сент. 2009 г.

ALT+F4

...But the best part was this: No way to exit the game. Pressing Escape in the Main menu started a promotional video which after it finished went to the main menu again. Then, after thinking and clicking around a bit, I tried ALT-F4, the standard windows combination that even still some C++ developers don't know (trust me), a 'Do you really want to exit the game' menu appeared. Didn't they want people to exit their wonderful game? Strange.
http://www.irrlicht3d.org/pivot/entry.php?id=941
Выделено мной.

Дожили...

Гигабайт фотографий

Слова из известной песни про гигабайт фотографий всё больше меняют свой смысл на противоположный. Это теперь вовсе не много, а даже очень и очень мало.

Привёз из лета сотню гигабайт.

Разгребаю потихоньку.

Выложу.

P.S. Коты есть ;-)

24 сент. 2009 г.

Joel on Shipping

Shipping is a feature. A really important feature. Your product must have it.

20 сент. 2009 г.

Lua Unofficial Frequently Asked Questions

Живёт здесь: http://batbytes.com/luafaq/

lua2c

Конвертор подмножества Lua в C от Дэвида Мануры (David Manura): lua2c (исходный код доступен на GitHub'е).

Использует парсер от Metalua. Ограничения вполне ожидаемые:
lua2c does not currently support coroutines, functions that normally reject C functions (e.g. setfenv), and possibly tail call optimizations.
Более полноценное решение — llvm-lua.

lua-TestMore

Ещё одна сюита для тестирования Lua:


В дополнение к официальной:

Эмулятор NES на JavaScript

http://benfirshman.com/projects/jsnes/

Pratchett

Обнаружил ещё четыре нечитанных романа из Discworld'а. Доволен как слон.

Glidecam 4000 pro

О, какая штука! 5D Mark II туда тоже приручивается.

10 сент. 2009 г.

Луа в качестве языка конфигов Апача

Разработчики Apache обсуждают возможность использования языка Lua для конфигурирования:

http://thread.gmane.org/gmane.comp.apache.devel/37627

Здесь вправили мозг по поводу синтаксиса:

8 сент. 2009 г.

Пиксельарт

Хорошая коллекция ссылок на тему пиксельарта:

http://www.wayofthepixel.net/pixelation/index.php?topic=3467.0

7 сент. 2009 г.

The Best Way to Delete Code

Select a section of code in your editor, hit the backspace key, and be done with it.
— Ned Batchelder, Deleting Code
Рекомендуется к прочтению. Есть русский перевод.

Библиотеки для написания высокопроизводительных серверов

Маленький список библиотек для написания высокопроизводительных серверных приложений:

ОЙ!


 # source ~/.bash_history

Страшная штука! :-)

Клонирование корутин в Lua

Откопался интересный пост от Майка Палла (создателя LuaJIT), с маленьким неинтрузивным патчем для клонирования корутин:


У патча есть ещё патч:

67 терабайт за 7867$

По ссылке рассказывается как построить 67-и терабайтное хранилище за 7867 долларов. Жаль дома такое не поставишь — жужжать будет сильно...

^Z

Когда scp забивает весь скайлинковский канал, как приятно усыпить его нажатием Ctrl+Z, отправить письмо, и вернуть всё как было, сказав fg.

Всё-таки bash — отличная штука.

So what's wrong with 1975 programming?

Интересное эссе от архитектора Varnish ("Varnish is a state-of-the-art, high-performance HTTP accelerator").

Наиболее интересные куски (всё же рекомендую прочесть целиком):

<...>
Take Squid for instance, a 1975 program if I ever saw one: You tell it how much RAM it can use and how much disk it can use. It will then spend inordinate amounts of time keeping track of what HTTP objects are in RAM and which are on disk and it will move them forth and back depending on traffic patterns.

Well, today computers really only have one kind of storage, and it is usually some sort of disk, the operating system and the virtual memory management hardware has converted the RAM to a cache for the disk storage.

So what happens with squids elaborate memory management is that it gets into fights with the kernels elaborate memory management, and like any civil war, that never gets anything done.

<...>

Here is how Varnish does it:

Varnish allocate some virtual memory, it tells the operating system to back this memory with space from a disk file. When it needs to send the object to a client, it simply refers to that piece of virtual memory and leaves the rest to the kernel.

<...>

And that's it. Varnish doesn't really try to control what is cached in RAM and what is not, the kernel has code and hardware support to do a good job at that, and it does a good job.

Varnish also only has a single file on the disk whereas squid puts one object in its own separate file. The HTTP objects are not needed as filesystem objects, so there is no point in wasting time in the filesystem name space (directories, filenames and all that) for each object, all we need to have in Varnish is a pointer into virtual memory and a length, the kernel does the rest.

<...>

We also try to reuse memory which is likely to be in the caches.

The worker threads are used in "most recently busy" fashion, when a workerthread becomes free it goes to the front of the queue where it is most likely to get the next request, so that all the memory it already has cached, stack space, variables etc, can be reused while in the cache, instead of having the expensive fetches from RAM.

We also give each worker thread a private set of variables it is likely to need, all allocated on the stack of the thread. That way we are certain that they occupy a page in RAM which none of the other CPUs will ever think about touching as long as this thread runs on its own CPU. That way they will not fight about the cachelines.

<...>

— Poul-Henning Kamp, Notes from the Architect.

6 сент. 2009 г.

Разбор HTML в Markdown

Оказывается есть специальная PHP-шная библиотека для конвертации HTML-а, сгенерированного из Markdown'а обратно в Markdown: Markdownify.

Ссылки:

4 сент. 2009 г.

Внутреннее устройство графического пайплайна в айфоне

Доклад с Assembly 2009 про низкоуровневые детали устройства графического пайплайна в айфонах до 3GS от разработчиков Unity. (Слайды в PDF здесь.)

3 сент. 2009 г.

Как на самом деле нужно завязывать галстук

(Показано в районе седьмой минуты.)

1 сент. 2009 г.

GitX: git gui и gitk для OS X

GitX: замена для git gui и gitk для OS X.



Интерфейс на вид приятный. Посмотрим, как оно работает.

jhead: манипуляции с EXIF'ом из командной строки

Утилита командной строки jhead для работы с EXIF'ом в JPEG'ах.

Цитата со страницы программы:
Things jhead can extract from an Exif jpeg file
  • Time and date picture was taken
  • Camera make and model
  • Integral low-res Exif thumbnail
  • Shutter speed
  • Camera F-stop number
  • Flash used (yes/no)
  • Distance camera was focused at
  • Focal length and calculate 35 mm equivalent focal length
  • Image resolution
  • GPS info, if stored in image
  • IPTC header
  • XMP data
Things jhead can modify in an exif jpeg file
  • Up-right images according to rotation tag using jpegtran
  • Set or relative adjust internal exif timestamps
  • Fix date / time offsets in large batches of images
  • Re-name or date stamp files according to exif timestamp
  • Transfer exif headers between images
  • Replace thumbnails inside Exif headers
  • Edit jpeg comments (but not the Exif comments)
  • Delete exif or comment sections from jpeg images
  • Create new minimal exif header containing date and thumbnail

Fog: AGG без GPL

Anti-Grain Geometry (AGG) — замечательная библиотека для работы с графикой на CPU. К сожалению, начиная с версии 2.5 она распространяется под GPL.

Но, оказывается, не всё так плохо. Есть библиотека Fog, которая реализует алгоритмы из AGG (да ещё и с JIT-компиляцией растровых операций). Также в библиотеке есть поддержка других вкусностей вроде многопоточных операций с изображениями. Fog распространяется под лицензией MIT.

Библиотека, судя по всему, пока сыровата, но некоторые штуки вытащить вполне возможно. Например, улучшенную реализацию (искать "[Fog::Raster_C - StackBlur]") stack blur'а.

OProfile

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

Аналог StackOverflow.com для вебдизайнеров...

...называется doctype.com

В семействе StackOverflow есть и ещё пара полезных сайтов:

iPhone: Распознавание жестов

GLGestureRecognizer by Adam Preble (GitHub page)

Всё для котофилов...

...и фелиноманов. Магазин котосувениров:


К сожалению, доставка только по Великобритании...

В дополнение к nginx'у

HAProxy: The Reliable, High Performance TCP/HTTP Load Balancer

Slowloris HTTP DoS

Нестандартный способ ДоС-атаки, о котором нужно помнить при реализации веб-сервера:

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

Подробная статья и перловый скрипт для тестов на уязвимость здесь: http://ha.ckers.org/slowloris/

31 авг. 2009 г.

Растеризация Делоне


Автоматический поиск дубликатов в коде

Инструменты для автоматического поиска одинаковых участков кода:
  • Simian (платный, работает с любым кодом)
  • Duplo (GPL, C/C++/Java)
Интересная статья по теме:

30 авг. 2009 г.

ThinkTank: Digital Holster

ThinkTank: Digital Holster 30. По виду — приличная фотосумка, вмещающая 5D MKII с одетым объективом 70-200. У Мартина Фаулератакая же.

Нужно будет попробовать.

Wordle: облако слов из блога

Wordle: Craters of the Mind

Lua Alchemy во В Контакте

Энтузиасты доработали демо Lua Alchemy, и встроили его во В Контакте:

SSD vs. Linux

Интересная цитата на тему рискованности использования SSD-дисков (особенно под Линухом):
<...>The bug is an assumption in most standard Linux filesystems (including ext2 and ext3). They all assume that the update granularity of the underlying block device they're writing to is greater than or equal to the filesystem's granularity. (I.E. that the smallest write you can do to the block device is the same size or smaller than a filesystem block.) Oh, and also that the alignment works out, so that data you're not writing doesn't get destroyed as "collateral damage" by a failed write operation.

This isn't true for flash, which has "erase blocks" up to a couple megabytes each. As with burnable cd-roms, you have to do an "erase" pass on an area of flash memory before it can have new data written to it. You can't erase just part of an erase block, it's all or nothing.

Actual Linux flash filesystems (like jffs2) are aware of this. That's why you can't mount them on an arbitrary block device, you have to feed them actual raw flash memory hardware (or something that emulates it) so they can query extra information (erase block boundaries). They cycle through the erase blocks and keep one blank at all times, copying the old data to the blank one before making the old one the new blank one. (That's why mounting them is so slow, the filesystem has to read all the flash erase blocks to figure out which one's newest, and which order to put them in.)

But flash USB keys pretend to be normal USB hard drives, which you format FAT, or ext3 or some such. And when you write to them, what they're actually doing internally is reading a megabyte or so of data into internal memory, erasing that block of data, and then re-writing it with your modifications. Generally they'll cache some writes first so they're not rewriting a whole megabyte of flash every time you send another 512 byte sector (which would not only be insanely slow but would run through the limited number of flash write cycles pretty quickly).

This sounds fine... until you unplug one during a write and the device loses power between the internal "erase" and "rewrite". Suddenly, the sector you were writing to might be ground zero in the middle of a megabyte of zeroes. You can lose data before, after, or on both sides of the sector it was updating.

Journaling doesn't pretect you from this, because it was built on the assumption that data you weren't writing to didn't change. The "collateral damage" effect of flash erase blocks undermines what journaling is trying to do, by violating the design assumptions of conventional Linux filesystems. In fact if the journal isn't what got zeroed, the journal replay may complete happily and mount the filesystem and hide the fact anything went wrong... until you try to use the missing data, anyway. (Not that using a non-journaled filesystem would actually improve matters, but it's less likely to give you a false sense of security.)

For further reading, see Linux filesystems expert Valerie Aurora's excellent post on why she personally doesn't want a flash disk in her laptop.

Rob Landley.

22 авг. 2009 г.

Design patterns or best practices for shell scripts

Полезное обсуждение на StackOverflow.com: Design patterns or best practices for shell scripts.

Рассказывается о:
  • Command line options
  • Function calls
  • Error prone situations
  • Python-like modularization
  • OOP
  • Trapping and handling signals
И, самое главное:
If you have to use the kind of things I wrote here, it means that your problem is too complex to be solved with shell. Use another language.
Ещё ссылки:

Lua-Noise

Никто не захотел поделиться модулем для генерации шума Перлина для Lua. Пришлось сделать свой:


Осторожно: сырой код!

21 авг. 2009 г.

Альтернатива блоксхемам во Flow Based Programming

Worley Noise

Интересный "антоним" к шуму Перлина (Perlin noise) — шум Ворли (Worley noise) или клеточный шум (cell noise).

Шум Перлина характеризуется мягкими переходами:

(Не нашёл картинку на flickr'е о_О)

Переходы в Шуме Ворли же наоборот — резкие:


Интересно, что шум Ворли тесно связан с диаграммами Вороного (Voronoi diagram).

Интересные примеры (в частности) скрещивания шума Перлина с шумом Ворли можно посмотреть здесь. (Ещё интересная ссылка.)

Ссылки:

20 авг. 2009 г.

К вопросу о Lua

Who should use Lua?

<...>

Luiz: The problem is that most designers do not see this need until much later, when much code has already been written in say C or C++, and they feel that it's too late now. Application designers should consider scripting from the start. This will give them much more flexibility. It will also give them better perspective about performance, by forcing them to think where the application needs raw performance and where it does not matter at all, and so can be delegated to the easier, shorter development cycle of scripting.

— Luiz Henrique de Figueiredo,
interview for Masterminds of Programming

Цитата

И к чему всё это? Лучше бы водки выпили...
Из писем Белинского Гоголю.

Eats, shoots and leaves

Друг написал в своём блоге (пунктуация сохранена):




...На нас не капает правда...




Всего одной запятой не хватает, а какой глубокий философский эффект!

14 авг. 2009 г.

iPhone 3GS vs. VFP

В новом iPhone (как и в новых ARM-ах вообще), как оказалось, серьёзно урезан векторный сопроцессор.

Жаль.

Cсылки:

1. http://diaryofagraphicsprogrammer.blogspot.com/2008/11/iphone-arm-vfp-code.html#c7064614874794429950
2. http://lua-users.org/lists/lua-l/2009-08/msg00174.html
3. http://lua-users.org/lists/lua-l/2009-08/msg00338.html

XZ

Следующее поколение LZMA: архиватор XZ.

select() loop for X events

Оказывается, события X Window можно читать из select'а:


dis = XOpenDisplay(DISPLAY);
fd = ConnectionNumber(dis);

FD_SET(fd, &in_fds);

select(fd+1, &in_fds, NULL, NULL, NULL);

...

Automated Unit-Testing on iPhone

Несколько полезных ссылок:

Создание *.ipa для ad-hoc дистрибуции

При сборке проекта в Xcode получается папка *.app — бандл приложения.

Тестерам значительно удобнее отдавать вместо папки, один файл — *.ipa. В отличие от *.app, он устанавливаетсч в iTunes автоматически по двойному щелчку.

Приятная мелочь — в *.ipa-файле задать картинку для отображения приложения в iTunes — так, чтобы всё было совсем уж по-взрослому.

Две вещи, на которые нужно обратить внимание:

1. Тестерам вместе с *.ipa нужно отдавать *.mobileprovision, который был сгенерирован при привязке UDID-а их iPhone к аккаунту разработчика.
2. В каждом новом билде обязательно нужно увеличивать номер версии — иначе iTunes не обновит установленное приложение.

Вот скрипт для генерации *.ipa. Удобно добавить его в проект Xcode последним шагом сборки. Скрипт заточен под мои конкретные нужды, но всё должно быть понятно без комментариев.

#!/bin/bash

VER=$1

if [ "${VER}" != "lite" -a "${VER}" != "full" ]; then
echo "bad version ${VER}, exepected 'lite' or 'full'"
exit 1
fi

RES=./res
COMMON=${RES}/common
CONCRETE=${RES}/${VER}

APP=${BUILT_PRODUCTS_DIR}/${TARGET_NAME}.app
PAYLOAD=${TEMP_FILES_DIR}/Payload
IPA=${BUILT_PRODUCTS_DIR}/${TARGET_NAME}.ipa

if [ ! -d "${APP}" ]; then
echo "output .app not found: '${APP}'"
exit 1
fi

if [ "${PLATFORM_NAME}" = "iphonesimulator" ]; then
echo "Simulator detected. Skipping .ipa generation"
exit 0
fi

rm -rf ${PAYLOAD}
mkdir -p ${PAYLOAD}/Payload
cp -Rp ${APP} ${PAYLOAD}/Payload
cp ${CONCRETE}/standard/iTunesArtwork.png ${PAYLOAD}/iTunesArtwork
ditto -c -k ${PAYLOAD} ${IPA}
rm -rf ${PAYLOAD}


Пока раскапывал этот вопрос, открыл для себя команду ditto. Если сборка идёт не под OS X, ditto можно заменить на zip — *.ipa-файл — это просто zip-архив.

Причины отказа приёмки в AppStore

Несколько полезных ссылок:



Также в тему:

LibraryThing

Каталог информации по книгам и авторам: LibraryThing.com. Например, страница про Ларри Нивена.

Linux command line

Несколько ссылок на коллекции полезных трюков командной строки:

* StackOverflow.com: What is your single most favorite command-line trick using Bash?
* commandlinefu.com — сайт, подобный StackOverflow.com, но посвящённый исключительно консольным командам.
* The Definitive Guide to Bash Command Line History
* Моя личная коллекция

Xcode vs. iPhone OS 3.0.1

Текущий iPhone SDK несовместим с самой свежей прошивкой iPhone — 3.0.1.

Для того, чтобы восстановить совместимость, нужно последовать указаниям iPhone OS 3.0.1 Advisory от Apple, и выполнить команду

$ ln -s /Developer/Platforms/iPhoneOS.platform/DeviceSupport/3.0\ \(7A341\) \
/Developer/Platforms/iPhoneOS.platform/DeviceSupport/3.0.1

12 авг. 2009 г.

Unknown error

Потратил день на отлов

Failed to launch simulated application: Unknown error.

при запуске айфонного приложения в симуляторе.

Путём пошагового воссоздания проекта выяснил, что симулятор сходит с ума, если в бандле есть пользовательская папка "resources".

Нехорошо.

В очередной раз подтвердил действенность правила: если пытаешься что-то воспроизвести путём шаманских манипуляций, записывай каждый шаг отдельным коммитом в Git!

7 авг. 2009 г.

Lua Núcleo: coro.yield_outer

Обновил мастер Lua Núcleo.

Добавил модуль coro для прозрачного проброса yield'а вверх по цепочке корутин.

Корутины нередко используются для передачи управления наружу из Lua. Например, для работы по сети, когда Lua'шный стейт откладывается в пул до получения ответа, а по получении ответа делается resume. В этом случае все сетевые операции в Lua делают yield.

В обычном случае это делает невозможным использование этих сетевых операций внутри пользовательских корутин. Если же пользоваться новым модулем, это ограничение снимается. Для этого нужно:
  1. Для всех пользовательских корутин вызывать coro.resume_inner вместо coroutine.resume.
  2. Во всех сетевых операциях вызывать coro.yield_outer вместо coroutine.yield.
  3. В пользовательском коде использовать coro.pcall вместо pcall-а.
  4. Результат coroutine.resume во внешней корутине перед обработкой пропускать через функцию coro.eat_tag.
Также перетянул работу Георгия: tserialize и tdeepequals; обе функции — с поддержкой рекурсивных таблиц.

Автофотограф для вечеринок от Sony

Sony Party-shot IPT-DS1 фотографирует вечеринки в автоматическом режиме.

5 авг. 2009 г.

Mario AI competition

http://julian.togelius.com/mariocompetition2009/

Infinte Mario Bros!

http://www.mojang.com/notch/mario/

С открытым исходным кодом.

25 июл. 2009 г.

Общие приёмы повышения производительности кода на Lua 5.1

Примерно в порядке убывания эффективности.
  1. Использовать более эффективные алгоритмы. Проверять эффективность бенчмарками, а не на глазок.
  2. Помнить, что компилятор Луа не делает никаких оптимизаций (кроме constant folding'а в некоторых случаях). В прикладном коде по возможности использовать LuaJIT / llvm-lua.
  3. Минимизировать число конкатенаций строк в несколько приёмов, особенно в циклах. Строки в Луа — константные, так что конкатенации в несколько приёмов засоряют память мёртвыми объектами. Заменять на table.concat() и, в прикладном коде, rope'ы. Множественные конкатенации в один приём (a = a .. b .. c) — дают одну инструкцию виртуальной машины, не страшно.
  4. Минимизировать число создаваемых таблиц. Каждый конструктор таблицы — аллокация.
  5. Минимизировать число создаваемых функций (замыканий) и корутин. Каждое такое создание — аллокация. Избегать необоснованного создания функций внутри функций и в циклах (однако это слишком полезный приём, чтобы от него отказываться полностью).
  6. Минимизировать число операций индексации таблиц, особенно hash-части таблицы. Помнить, что обращение к глобальной переменной — также индексация (глобального окружения), операторы "." и ":" — тоже индексация. По возможности кешировать результаты индексации в локальных переменных.
  7. Предпочитать хвостовую рекурсию. Вызов function() return foo() end эффективнее function() foo() end.
  8. Numeric for от 1 до размера таблицы дешевле pairs, pairs — дешевле ipairs.
  9. Выносить (там, где это осмысленно) создание объектов (таблиц, функций, корутин, юзердат) в глобальный chunk файла (но максимально ограничивать их область видимости).
  10. При использовании LuaJIT минимизировать число вызовов из Lua в C — маршаллинг в этом случае довольно дорогой. При использовании классического интерпретатора Lua маршаллинг практически бесплатный — наоборот может иметь смысл переписать на C наиболее медленные части кода.
Дополнительное чтение:
  1. Статья Р. Иерусалимского в Lua Programming Gems "Lua Performance Tips".
  2. Lua Users Wiki: Optimization Tips
  3. Unofficial Lua FAQ 1.8: Optimization tips?
  4. A No Frills Introduction to Lua 5.1 VM Instructions
  5. The implementation of Lua 5.0
  6. Lua - an extensible extension language

23 июн. 2009 г.

Ответный удар

На попытку взрыва мозга и прочих важных частей тела — ответим адекватно но ассиметрично!

Вот вам шестьсот новых фоток из загашника.

100!

Предыдущий пост был сотым. Юбилей блога однако.

18 июн. 2009 г.

15 мая 2009 г.

Luiz Henrique de Figueiredo on Stack Overflow

Luiz Henrique de Figueiredo, один из авторов языка Lua замечен на stackoverflow.com.

15 апр. 2009 г.

Продолжаем акынствовать

Нажал на спуск
Сорок тысяч раз.
Семь лет прошло

14 апр. 2009 г.

Хокку

На улице серыми
Стали все кошки.
Снова никак не усну.

21 мар. 2009 г.

Цитата

Сквозь дымку — луна.
Замутили лапки лягушек
Небо в пруду.
Ёса Бусон.
Перевод Татьяны Соколовой-Делюсиной

Хокку

Чёрный экран,
Мерцает зелёный курсор —
Куда же ушли слова?

6 февр. 2009 г.

Golly

Колония игры «Жизнь», которая воспроизводит слово «Golly»:

Lua Alchemy v0.2

Мы с партнёром по проекту Робертом Штевином (Robert Stehwien) выпустили очередной релиз Lua Alchemy: 0.2!

http://code.google.com/p/lua-alchemy/

Демо лежит здесь.

Основная фича нового релиза — введение синтаксического сахара:

-- Says hello to the name entered in the text box on a button click

-- Create the controls
local vbox = as3.class.mx.containers.VBox.new()
local label = as3.class.mx.controls.Label.new()
local input = as3.class.mx.controls.TextInput.new()
local button = as3.class.mx.controls.Button.new()

label.text = "Name:"
button.label = "Say Hello"

-- Add a button listener to pop up an alert saying hello
button.addEventListener(as3.class.flash.events.MouseEvent.CLICK,
function (e)
as3.class.mx.controls.Alert.show("Hello " .. as3.tolua(input.text), as3.type(e))
end, false, 0, true) -- set useWeakReference=true so listener doesn't keep button reference

-- Add all the controls to the canvas in a VBox
vbox.addChild(label)
vbox.addChild(input)
vbox.addChild(button)

canvas.addChild(vbox)

Код остальных примеров можно посмотреть здесь:

Полный список изменений довольно большой, поэтому приводить не буду. Читайте здесь:

http://github.com/lua-alchemy/lua-alchemy/raw/v0.2/HISTORY

Выношу от лица разработчиков проекта благодарность коллеге E-Fir'у за помощь с узкими местами Флеша.

5 февр. 2009 г.

Нашли замечательный символ в юникоде: «☭».
Самое главное, не находится ни одним поисковиком.