31 авг. 2009 г.
Автоматический поиск дубликатов в коде
Инструменты для автоматического поиска одинаковых участков кода:
Интересная статья по теме:
30 авг. 2009 г.
ThinkTank: Digital Holster
ThinkTank: Digital Holster 30. По виду — приличная фотосумка, вмещающая 5D MKII с одетым объективом 70-200. У Мартина Фаулера — такая же.
Нужно будет попробовать.
Нужно будет попробовать.
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.Ещё ссылки:
Ярлыки:
bash,
best-practices,
links,
programming,
stackoverflow.com
Lua-Noise
Никто не захотел поделиться модулем для генерации шума Перлина для Lua. Пришлось сделать свой:
Осторожно: сырой код!
21 авг. 2009 г.
Worley Noise
Интересный "антоним" к шуму Перлина (Perlin noise) — шум Ворли (Worley noise) или клеточный шум (cell noise).
Шум Перлина характеризуется мягкими переходами:
Переходы в Шуме Ворли же наоборот — резкие:
Интересно, что шум Ворли тесно связан с диаграммами Вороного (Voronoi diagram).
Интересные примеры (в частности) скрещивания шума Перлина с шумом Ворли можно посмотреть здесь. (Ещё интересная ссылка.)
Ссылки:
Шум Перлина характеризуется мягкими переходами:
(Не нашёл картинку на flickr'е о_О)
Переходы в Шуме Ворли же наоборот — резкие:
Image by Simon Strandgaard
Интересно, что шум Ворли тесно связан с диаграммами Вороного (Voronoi diagram).
Интересные примеры (в частности) скрещивания шума Перлина с шумом Ворли можно посмотреть здесь. (Ещё интересная ссылка.)
Ссылки:
- Are there any other uses for Perlin Noise besides the obvious? (StackOverflow.com)
- Improved [Perlin] Noise reference implementation
- Описание шума Перлина на русском; также см. Яндекс
- Описание клеточного Шума на русском
- Оригинальная статья про шум Ворли (математика без картинок)
- Animating Worley Noise
- Хорошие примеры шума Ворли
- Галерея примеров шума Ворли (кликать на ссылки слева)
- Making Cellular Textures
- Аппроксимация шума Перлина и шума Ворли
- Perlin Noise Math FAQ (via web.archive.org)
- Книга Перлина и Ворли Texturing and Modeling, Third Edition: A Procedural Approach.
Ярлыки:
algorithms,
noise,
perlin,
programming,
worley
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
Жаль.
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
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
Несколько полезных ссылок:
- Test Driving Your [Objective C] Code with OCUnit (Apple Developer Connection)
- iPhone Unit Testing (Google Toolbox for Mac)
- Xcode Test Automation for iPhone (StackOverflow.com)
- OCMock: Objective C implementation of mock objects
Ярлыки:
iphone,
links,
programming,
tdd,
unit-tests
Создание *.ipa для ad-hoc дистрибуции
При сборке проекта в Xcode получается папка *.app — бандл приложения.
Тестерам значительно удобнее отдавать вместо папки, один файл — *.ipa. В отличие от *.app, он устанавливаетсч в iTunes автоматически по двойному щелчку.
Приятная мелочь — в *.ipa-файле задать картинку для отображения приложения в iTunes — так, чтобы всё было совсем уж по-взрослому.
Две вещи, на которые нужно обратить внимание:
1. Тестерам вместе с *.ipa нужно отдавать *.mobileprovision, который был сгенерирован при привязке UDID-а их iPhone к аккаунту разработчика.
2. В каждом новом билде обязательно нужно увеличивать номер версии — иначе iTunes не обновит установленное приложение.
Вот скрипт для генерации *.ipa. Удобно добавить его в проект Xcode последним шагом сборки. Скрипт заточен под мои конкретные нужды, но всё должно быть понятно без комментариев.
Пока раскапывал этот вопрос, открыл для себя команду ditto. Если сборка идёт не под OS X, ditto можно заменить на zip — *.ipa-файл — это просто zip-архив.
Тестерам значительно удобнее отдавать вместо папки, один файл — *.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
Несколько полезных ссылок:
Также в тему:
- Tips for a Successful AppStore Submission (StackOverflow.com)
- Avoiding iPhone App Rejection from Apple: Part 1, Part 2
- Unofficial AppStore Rejection Criteria
- App Rejected: Why an iPhone App May Get Rejected.
Также в тему:
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
* Моя личная коллекция
* 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, и выполнить команду
Для того, чтобы восстановить совместимость, нужно последовать указаниям 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
Потратил день на отлов
Путём пошагового воссоздания проекта выяснил, что симулятор сходит с ума, если в бандле есть пользовательская папка "resources".
Нехорошо.
В очередной раз подтвердил действенность правила: если пытаешься что-то воспроизвести путём шаманских манипуляций, записывай каждый шаг отдельным коммитом в Git!
Failed to launch simulated application: Unknown error.
при запуске айфонного приложения в симуляторе.Путём пошагового воссоздания проекта выяснил, что симулятор сходит с ума, если в бандле есть пользовательская папка "resources".
Нехорошо.
В очередной раз подтвердил действенность правила: если пытаешься что-то воспроизвести путём шаманских манипуляций, записывай каждый шаг отдельным коммитом в Git!
Ярлыки:
iphone,
iphone-simulator,
programming,
unknown-error,
xcode
7 авг. 2009 г.
Lua Núcleo: coro.yield_outer
Обновил мастер Lua Núcleo.
Добавил модуль coro для прозрачного проброса yield'а вверх по цепочке корутин.
Корутины нередко используются для передачи управления наружу из Lua. Например, для работы по сети, когда Lua'шный стейт откладывается в пул до получения ответа, а по получении ответа делается resume. В этом случае все сетевые операции в Lua делают yield.
В обычном случае это делает невозможным использование этих сетевых операций внутри пользовательских корутин. Если же пользоваться новым модулем, это ограничение снимается. Для этого нужно:
Добавил модуль coro для прозрачного проброса yield'а вверх по цепочке корутин.
Корутины нередко используются для передачи управления наружу из Lua. Например, для работы по сети, когда Lua'шный стейт откладывается в пул до получения ответа, а по получении ответа делается resume. В этом случае все сетевые операции в Lua делают yield.
В обычном случае это делает невозможным использование этих сетевых операций внутри пользовательских корутин. Если же пользоваться новым модулем, это ограничение снимается. Для этого нужно:
- Для всех пользовательских корутин вызывать coro.resume_inner вместо coroutine.resume.
- Во всех сетевых операциях вызывать coro.yield_outer вместо coroutine.yield.
- В пользовательском коде использовать coro.pcall вместо pcall-а.
- Результат coroutine.resume во внешней корутине перед обработкой пропускать через функцию coro.eat_tag.
6 авг. 2009 г.
Средства автоматизации массовой работы с удалёнными машинами
- Puppet: http://reductivelabs.com/trac/puppet/
- ClusterSSH: http://sourceforge.net/projects/clusterssh/
- CFEngine: http://www.cfengine.org/manuals/cf3-reference.html
- Capistrano: http://www.capify.org/index.php/Capistrano
- BashReduce: https://github.com/erikfrey/bashreduce/tree
- DSH: http://www.netfort.gr.jp/~dancer/software/dsh.html.en
5 авг. 2009 г.
Подписаться на:
Сообщения (Atom)