Архив за Декабрь 2009

Сегодня мы выпустили новую бета-версию BlogJet!

Что нового:

  • Полная поддержка Юникода.
  • Новый движок и словари проверки орфографии.
  • Новая тема.

Вообще, куча всего переписано, внутри много новенького и блестящего, а разработка переведена на Delphi 2009.

Подробнее — в блоге Coding Robots (там же и ссылка на скачивание).

Репортите баги в новом разделе форума.

Unicode in BlogJet

PS Я лично не написал ни одной строчки кода для этого релиза. См. Help > About BlogJet… :-) Так что я теперь Mac-only. Ура!

Для тех, кто не видит проблемы в предыдущей заметке: давайте проведем такой эксперимент.

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

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

Microsoft добавляет Silverlight в Windows Media Components for Quick Time (это компоненты QT, позволяющие проигрывать Windows Media на маках). Он устанавливается по умолчанию.

Нигде на сайте про это не написано.

Установщик показывает вот такой экран:

flip4mac-1.png

Если ничего не сделать, Silverlight будет установлен. Чтобы его не устанавливать, надо сначала согласиться со всеми условиями нажать “Continue”, а на следующем экране нажать “Customize”:

flip4mac-2.png

и убрать галочку с “Silverlight”.

Какой дурак в Майкрософте это придумал? Какой дурак дал команду увеличить количество установок Silverlight любыми способами?


Это тема для отдельной заметки, но я хочу спросить:

  1. Сколько еще такие компании как Google, Yahoo, Яндекс (на ISDEF предлагали бандлить Яндекс.Бар), Microsoft и прочие, сующие свои тулбары, плагины и других паразитов в другие программы, будут держать пользователей за идиотов?

  2. Сколько еще разработчиков-вредителей будут включать в свои дистрибутивы паразитов от вышеперечисленных компаний в обмен на копеечку?

Обожаю “self-contained” библиотеки. Я не знаю, как правильно их назвать, но смысл в том, вместо компилирования отдельных библиотек и/или добавления зависимостей, разработчик кидает в проект один-два файлика и получает много пользы. Они как ноутбуки вместо десктопов — взял и понес, работай где хочешь.

Например, SQLite — один sqlite.c файл (amalgamation). Добавил в проект и получил полноценную SQL базу.

Сегодня обнаружил s7 (скачать) — улучшенный TinyScheme. Добавил в проект s7.h и s7.c и получил полноценный интерпретатор Scheme (который можно, например, использовать в качестве скриптового языка для программы).

Кстати, если будет время, перепишу TinySchemeObjC с s7 вместо TinyScheme, потому что в s7 можно добавлять свои типы в Scheme. Сразу отпадет надобность писать второй сборщик мусора для ObjC-объектов (который я уже, кстати, написал, но еще не закоммитил :).

RegexKitLite не соответствует критериям, потому что требует линковки с libicucore.dylib и является просто интерфейсом к ней, тем не менее, стоит его тоже упомянуть, потому как добавив два файла к проекту, получим методы в NSString для работы с регулярными выражениями, а это — пятьсот килограммов пользы.

Какие еще вы знаете self-contained полезности вроде этих? Пишите мне в твиттер (@dchest), добавлю сюда.

Сколько я продержусь без него? Делайте ставки.

3 дня.

TinyScheme Logo Пару дней назад решил поизучать лиспы (наконец-то). Естественно, первая же мысль — а можно ли их связать с Cocoa? Есть Clozure CL — Common Lisp для Мака, и я его еще не смотрел, но мне захотелось чего-нибудь очень маленькое, что можно встроить в свои приложения. И вспомнил про TinyScheme — имплементацию Scheme в ~6000 строках кода. (Кстати, Apple с 10.5 использует TinyScheme для задания правил сэндбоксинга программ.)

Исходники скаченные с сайта не компилировались, но там была инструкция как сделать так, чтобы все заработало. Впрочем, она там какая-то странная (а может не обновлялась давно) — я поменял меньше, чем там написано и получилось. Естественно, сразу выложил работающую версию на GitHub, заодно изучил, как с ним общаться из Си, написал example.c, ну и потом понеслось — захотелось общаться с Objective-C из Scheme. Одновременно учил Scheme и писал код. Получилось интересно.

Интерфейс с Scheme у нас будет классом TinyScheme.

TinyScheme *ts = [[TinyScheme alloc] init];

Та-дам! Интерпретатор готов. (Можно создавать сколько угодно объектов — у каждого будет свой интерпретатор.)

Запустим какую-нибудь ерунду:

[ts loadString:@"(log \"Hello, world!\")"];

Что выполнит (log "Hello, world!").

Или файл:

[ts loadFileWithPath:@"init.scm"];

Что интерпретирует файл init.scm.

Если интерпретатор выдаст ошибку, ts выкинет исключение, которое можно поймать в @try...@catch:

@try {
    [ts loadString:@"((we-have error here)"];
}
@catch (NSException *e) {
    NSLog(@"The exception was: %@ reason: ``%@'')", [e name], [e reason]);
}

Больше примеров тут.

Ну а теперь самое интересное: работа с Objective-C из Scheme. Если мы хотим, чтобы объект был доступен в Scheme, нужно его зарегистрировать:

NSNumber *magicNumber = [NSNumber numberWithInt:42];
[ts registerObject:magicNumber withName:@"magicNumber"];

Он будет известен Scheme под символом magicnumber (заметьте, что он оказался в нижнем регистре, потому что Scheme нечувствителен к регистру).

Теперь мы можем посылать ему сообщения, например:

(obj-send 'magicNumber "className")

вернет строку с именем класса (“NSCFNumber”), то есть сделает то же самое, что [magicNumber className] в Objective-C.

Можно и сократить:

(-> 'magicNumber "className")

потому что -> определен в objc.scm как:

(define -> objc-send)

Там еще несколько хэлперов есть.

Заметьте, что класс TinyScheme автоматически конвертирует Scheme типы в C/ObjC и обратно. Здесь мы вызвали метод className, который возвращает NSString *, а внутри Scheme он уже оказывается Scheme-типом string. Или, например, если у нас есть объект test класса Test в Objective-C с таким методом:

- (int)doSomethingWithDouble:(double)d andString:(NSString *)s
{
    NSLog(@"string was: %@", s);
    return 2 * d;
}

то мы можем его вызывать из Scheme вот так:

(-> 'test "doSomethingWithDouble:andString:" 7.40 "Hello")

и получим результат 14 (метод возвращает int), с которым можем обычным образом работать:

(+ 10 (-> 'test "doSomethingWithDouble:andString:" 7.40 "Hello"))

вернет 24.

Оки-доки, но что если мы не хотим регистрировать свои объекты через registerObject:withName:? Можно ли создавать их прямо в Scheme? Можно. Для этого всего-навсего понадобилось написать процедуру objc-class, который автоматически регистрирует класс и возвращает его.

(objc-class "NSString")

Теперь мы можем создавать объекты!

(-> (-> (objc-class "NSFileManager") "alloc") "init")

Расшифровываю: (objc-class "NSFileManager") возвращает класс NSFileManager, потом мы посылаем ему сообщение alloc, которое возвращает новый объект и этому объекту посылаем init, то есть как если бы мы сделали [[NSFileManager alloc] init].

В objc.scm есть хэлперы для упрощения этого (функция new, например). Смотрите:

(let ((fm (new "NSFileManager")))
    (log "App folder name is" (-> fm "displayNameAtPath:" "/Applications")))

покажет название папки /Applications (локализованное).

Все это пока экспериментально, многого нет (например, хотелось бы как-то забайндить Scheme-процедуры и ObjC-методы, сделать какой-нибудь нормальный memory management), но очень интересно в плане изучения… внутренностей Objective-C. И это я еще не выучил Scheme :)

Репозиторий: http://github.com/dchest/tinyscheme/

PS Пока писалась заметка, родилась идея другого синтаксиса посыла сообщений: вместо (-> object "doWithOne:andTwo:" 1 2) сделать (-> object "doWithOne:" 1 "andTwo:" 2). Надо подумать.

Сегодня удалил Flash Player с компьютера.

Оказалось, Safari без него скучно, и каждый раз при заходе, например, на GitHub, где напротив двух ссылок стоит малюсенький флэш для копирования ссылки в клипборд, он выдает модальное к окну предупреждение о том, что нужен Flash. Спасибо, Сафари, я и так знаю, что он нужен — поэтому я его и удалил. В настройках можно выключить плагины вообще, но тогда и QuickTime в браузере отключается, что нежелательно.

Выход? Все тот же ClickToFlash. Так как он заменяет собой Flash (а при клике его подгружает, если флэш установлен), в моем случае, браузер будет думать, что Flash у меня есть и перестанет показывать предупреждения.

Да здравствует веб без плагинов! ALL HAIL HTML5!

PS На всякий случай я скачал себе дистрибутив удаленного адобиевского чудовища. Вдруг в какой-нибудь поездке понадобится. Я запрятал его в самую глубокую папку и назначил вот такую иконку:

flash-dmg.png

Сколько я продержусь без него? Делайте ставки.