Архив за Сентябрь 2009

Чуть не испугался! Мне эта фича как раз нужна для проекта, и прочитав What’s New in Mac OS X 10.6, я обнаружил то, что хотел — теперь на файлы можно ссылаться по ID вместо пути. То есть, вместо /Users/dmitry/Documents/file.txt можно дать ID, который остается постоянным при перемещении или переименовании файла. Например, если я перенесу и переименую file.txt куда-нибудь в /Users/dmitry/Archive/old-file.txt, ID все равно будет на него ссылаться. Я даже про это писал в четверг.

Так вот, я нигде в документации не мог найти методы для работы с file ID. И нигде не было CFURLCreateFileIDURL, про который писали в What’s New.

Оказалось, его просто переименовали! Теперь это не “ID”, а “reference”. Логично.

NSLog(@"%@", [url absoluteURL]);

=> file://localhost/Users/dmitry/Sites/

NSLog(@"%@", [url fileReferenceURL]);

=> file:///.file/id=6571367.4787316/

Последний NSURL ссылается на ту же папку. Часть до точки — ID диска, после - ID файла/папки.

Я НЕ ЮРИСТ, Я ПРОГРАММИСТ. ДАННАЯ ЗАМЕТКА ПРЕДОСТАВЛЯЕТСЯ “КАК ЕСТЬ”, БЕЗ ЛЮБОГО ВИДА ГАРАНТИЙ, ЯВНО ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ГАРАНТИЯМИ ТОВАРНОЙ ПРИГОДНОСТИ, СООТВЕТСТВИЯ ПО ЕЕ КОНКРЕТНОМУ НАЗНАЧЕНИЮ И НЕНАРУШЕНИЯ ПРАВ. НИ В КАКОМ СЛУЧАЕ АВТОР НЕ НЕСЕТ ОТВЕТСТВЕННОСТИ ПО ИСКАМ О ВОЗМЕЩЕНИИ УЩЕРБА, УБЫТКОВ ИЛИ ДРУГИХ ТРЕБОВАНИЙ ПО ДЕЙСТВУЮЩИМ КОНТРАКТАМ, ДЕЛИКТАМ ИЛИ ИНОМУ, ВОЗНИКШИМ ИЗ, ИМЕЮЩИМ ПРИЧИНОЙ ИЛИ СВЯЗАННЫМ С ЭТОЙ ЗАМЕТКОЙ ИЛИ ИСПОЛЬЗОВАНИЕМ ЗАМЕТКИ ИЛИ ИНЫМИ ДЕЙСТВИЯМИ С ЗАМЕТКОЙ.

OK?

Я не буду рассматривать GPL/LGPL, потому что они — зло, их применение никому не понятно и они мне не нравятся (это тема для отдельного поста). Если не согласны со мной, тогда вы, скорее всего, используете их для своих проектов, а значит лицензию уже выбрали и вам нет смысла читать дальше. Мы же выберем более свободную лицензию.

Начнем с нелицензии.

Public Domain

Можно вообще отказаться от всех прав на свой код и сделать из него “всеобщее достояние”. Public domain — это не лицензия. Вы отказываетесь от всех своих прав на код, и он не будет регулироваться законами об авторском праве (естественно, вы по прежнему можете делать с ним что угодно — даже продавать лицензии). Любой может использовать ваш код как хочет, может встраивать в любые проекты без указания авторства.

Наверное, самый известный проект в public domain — SQLite. И автор SQLite не рекомендует отказываться от копирайта для проектов, потому что 1) public domain признается не во всех странах, 2) чтобы использовать код контрибьюторов, им надо отказывается от копирайта на этот код, а для некоторых работников фирм еще и делать это на бумаге и заверять ее у работодателя.

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

MIT, New BSD

Это две короткие лицензии. Я даже выложу полный текст MIT лицензии (на русском). Английскую версию можно найти тут.

Copyright (c) [год] [владельцы прав]

Данная лицензия разрешает, безвозмездно, лицам, получившим копию данного программного обеспечения и сопутствующей документации (в дальнейшем именуемыми “Программное Обеспечение”), использовать Программное Обеспечение без ограничений, включая неограниченное право на использование, копирование, изменение, добавление, публикацию, распространение, сублицензирование и/или продажу копий Программного Обеспечения, также как и лицам, которым предоставляется данное Программное Обеспечение, при соблюдении следующих условий:

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

ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ «КАК ЕСТЬ», БЕЗ ЛЮБОГО ВИДА ГАРАНТИЙ, ЯВНО ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ГАРАНТИЯМИ ТОВАРНОЙ ПРИГОДНОСТИ, СООТВЕТСТВИЯ ПО ЕГО КОНКРЕТНОМУ НАЗНАЧЕНИЮ И НЕНАРУШЕНИЯ ПРАВ. НИ В КАКОМ СЛУЧАЕ АВТОРЫ ИЛИ ПРАВООБЛАДАТЕЛИ НЕ НЕСУТ ОТВЕТСТВЕННОСТИ ПО ИСКАМ О ВОЗМЕЩЕНИИ УЩЕРБА, УБЫТКОВ ИЛИ ДРУГИХ ТРЕБОВАНИЙ ПО ДЕЙСТВУЮЩИМ КОНТРАКТАМ, ДЕЛИКТАМ ИЛИ ИНОМУ, ВОЗНИКШИМ ИЗ, ИМЕЮЩИМ ПРИЧИНОЙ ИЛИ СВЯЗАННЫМ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ ИЛИ ИСПОЛЬЗОВАНИЕМ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ ИЛИ ИНЫМИ ДЕЙСТВИЯМИ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ.

(Перевод с Википедии)

В New BSD License написано почти то же самое.

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

Основная ошибка в применении MIT/BSD-лицензий в том, что сам текст лицензии не пишут. Вместо этого упоминают, например, “Licensed under MIT-style license”, но ведь в самой лицензии написано “Вышеупомянутый копирайт и данные условия должны быть включены во все копии или значимые части данного Программного Обеспечения”. На эту лицензию нельзя ссылаться “by reference”, нужно прикладывать текст. Это, конечно, ерундовая проблема.

А самая большая проблема в том, что MIT/BSD не объясняют статус кода от контрибьюторов. “Вышеупомянутый копирайт и данные условия должны быть включены во все копии или значимые части данного Программного Обеспечения.” Патч — не копия и не всегда значимая часть продукта. А это значит что контрибьютор может сохранить за собой все авторские права на свой код. А потом, когда ваш проект станет суперпопулярным, запросить кучу денег за использование его кода. Это теория, и, еще раз, я не юрист.

Короче, есть нормальная лицензия, которая объясняет все права и обязанности, и позволяет использовать код практически так же, как под MIT/BSD лицензией:

Apache License 2.0

Полный текст занимает около 4 страниц, но зато в нем все подробно описано.

Как и в MIT/BSD:

  1. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

Кроме того, объясняются отношения с контрибьюторами: если не указано иного, контрибьюторы отдают свою работу под той же лицензией, плюс (и автор в том числе) дают лицензию на патенты, связанные с кодом.

Проекты под Apache License можно использовать в коммерческом коде, и совсем не обязательно выпускать исходники, достаточно приложить копию этой лицензии и указать авторов и контрибьюторов (если в проекте есть файл “NOTICE”).

На лицензию Apache можно ссылаться “by reference”, то есть просто включить вот такой текст вместо полной лицензии:

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Так что преимущества в краткости у BSD/MIT нет.

В общем, используйте Apache License, Version 2.0 для своих опенсорсных проектов!

Очень рекомендую блог “Пивная бутылка”. Автор почти каждый день рассказывает про разное интересное, как редкое, так и будничное пиво и выставляет оценки. Если любите пиво, читайте!

А я в последнее время пью английские эли. Рекомендую попробовать Newcastle Brown Ale и London Pride.

Кстати, сегодня 250 лет пиву Guinness.

Finder в Mac OS X 10.6 переписали на Cocoa. Какая разница, на чем он написан, если он остался почти таким же? Большая разница! ОГРОМНЕЙШАЯ.

Я уже писал, что Apple почти не делает “теоретических” фреймворков, которые сама не использует. В Apple пишут программы, под которые делаются фреймворки, которые потом публикуются для сторонних разработчиков. Именно поэтому переписка Finder на Cocoa — это большой подарок программистам.

Так как Finder был написан на Carbon, все серьезные операции с файлами были на карбоновой стороне света. В Cocoa некоторые тоже были, но NSFileManager был настолько медленный, что любой обход директорий приходилось писать с FSRef и сишным API, а то и совсем в BSD уходить. Работа с алиасами и символьными ссылками — опять туда же. Лэйблы (цвета для файлов в Finder), по-моему, то ли совсем нельзя было читать, не залезая в .DS_Store, то ли можно было, но через одно место.

С выходом Snow Leopard наступило счастье. Apple пришлось доработать библиотеки, чтобы написать Finder на Cocoa. Что нового?

  • Унифицирован доступ к файлам. Если раньше это делалось через строку с путем к файлу, через FSRef или NSURL, то теперь нам дали единый и универсальный способ — NSURL.
  • NSFileManager теперь быстро обходит директории.
  • В NSURL появились методы для запроса атрибутов файла: можно получать цвета и названия лэйблов, локализованное имя файла (какое показывается в Finder), даты, размер и иконки, а так же информацию о том, является ли директория бандлом.
  • К предыдущему пункту — если раньше иконки брались через NSWorkspace (но он не выдавал иконки с маленькими стрелочками в левом нижнем углу для алиасов и символьных ссылок), то теперь иконку можно запросить у NSURL (со всеми стрелочками для ссылок!).
  • Появились bookmarks — в них сериализуется NSURL.
  • NSURL теперь может содержать идентификатор файла вместо пути, то есть, URL будет указывать на файл даже если его переименуют или переместят.
  • и еще много всего, о чем можно почитать в Foundation Release Notes.

finder-notfinder.jpg

Я уже попробовал написать “мини Finder” используя только Cocoa. Вместо ковыряния разных API и обзывания Apple нехорошими словами, как это было раньше, я получил много удовольствия. Если каждую новую версию Mac OS X оценивать по количеству строк кода, которых не надо писать разработчикам, то 10.6 вышел отличным релизом.

PS Кстати, видите на картинке дату “Сегодня”? Если раньше это надо было делать вручную, то в Snow Leopard у NSDateFormatter есть опция setDoesRelativeDateFormatting:, которая включает выдачу локализованных “вчера”, “сегодня” и даже “позавчера” вместо цифр (и нормальную дату, если ее нельзя выразить словами). Несколько десятков строк кода можно удалять.

Очень интересный проект — Fossil. Это распределенная система контроля версий (DVCS), баг-трекалка и вики, которую пишет создатель SQLite Ричард Хипп. Все данные системы хранятся в одном файлике (база SQLite, конечно) и, что самое потрясающее, весь Fossil состоит из одного исполняемого файла. Скачал файлик и используй себе на здоровье. Кроме того, туда же встроен небольшой веб-сервер (запускающийся командой fossil ui), поэтому настраивать систему и работать с ней можно через веб-интерфейс — все это выглядит как распределенный Trac, но, подчеркну, в одном исполняемом файле. Собственно, сам сайт Fossil и есть экземпляр Fossil — можете посмотреть на интерфейс.

Я пока не собираюсь переключаться с Mercurial на Fossil, потому что лень переучиваться и не хочется бросать аккаунт в Bitbucket, но может кому-то понравится.

Частый вопрос — под какую версию Mac OS X нужно писать программу? Новые версии OS X уж очень соблазнительны для разработчиков, потому что включают кучу новых API и упрощают многие аспекты разработки. Стоит ли бросать поддержку старых систем или все еще тратить на них драгоценное время программистов?

Обычная практика — писать под текущую + предыдущую версию: когда вышла 10.5, можно было бросить 10.3 и писать под 10.4 и 10.5. Но так как 10.5 был гигантским прыжком в плане девелоперских вещей, многие даже не стали поддерживать 10.4.

В конце августа вышел Snow Leopard. Нужно ли еще писать под Leopard или можно сразу под 10.6?

Мак-юзеры, в отличие от пользователей кое-какой другой операционки, действительно обновляются до последней версии OS. Но очевидно, что чем больше продано Маков, тем меньший процент пользователей будет обновляться. (Просто потому что людям-некомпьютерщикам совершенно наплевать, что у них за OS; они даже и не знают какая версия у них стоит.)

Давайте посмотрим на статистику. В приложения Omni Group встроена хитрая система обновлений, которая отправляет на их сервер информацию о системе. Они делают полезное дело — выкладывают эту статистику на свой сайт:

Статистика Omni Group

Как видно, меньше чем за месяц с выпуска, 10.6 уже занимает 23.5% (и, как видим по графику, отнимает большую долю у Leopard, но не очень большую у Tiger).

Джон Грубер вчера опубликовал статистику посещений Daring Fireball:

daringfireball-stats.png

У него Snow Leopard уже обогнал Leopard (Intel). Его статистика, конечно, нерепрезентативна и не включает PPC, но все же — с релиза прошло меньше месяца.

Мои цифры скромнее, чем их, но своих клиентов надо знать. Посещения сайта Coding Robots по версиям Mac OS X:

codingrobots-stats.png

(Круговые диаграммы — отстой. Никогда не используйте их!)

Итак, по статистике видно, что внедрение Snow Leopard идет полным ходом.

Intel

Так как Snow Leopard не работает на PowerPC, мы можем избавиться от целой архитектуры (или двух — ppc и ppc64)! Теперь не надо иметь два макинтоша — PPC и Intel — для тестирования приложений. Это большой плюс для разработчиков.

Кстати, PowerPC, по статистике Omni (см. Hardware > CPU Type), осталось не так уж и много:

  • Intel — 89.9%
  • PowerPC — 10.1%

Последние маки на PPC были проданы в первой половине 2006 года — больше трех лет назад. Я считаю, что теперь, когда Apple сама прекратила разработку OS для PowerPC, нет смысла писать новые приложения для этой архитектуры, тем более, что эти 10% рынка скоро исчезнут совсем.

Snow Leopard

В 10.6 много улучшений и новых API. Смотрите, например, AppKit Release Notes. Кроме того, в Snow Leopard пофиксили много багов, но для совместимости многие из этих исправлений включаются только при сборке под 10.6.

Про Grand Central Dispatch и блоки в C/Objective-C уже много написано, поэтому не буду повторяться.

В Snow Leopard стал лучше Xcode (конечно, его можно использовать и для разработки хоть под 10.4).

А еще… а еще… в 10.6 появился “pane splitter” для NSSplitterView!

pane-splitter.png

В общем, мое мнение такое: новые приложения нужно писать под 10.6. Во-первых, очень много нового в API нельзя игнорировать. Во-вторых, можно скинуть целую архитектуру. В-третьих, пока вы допишете программу, Snow Leopard уже будет занимать огромную часть рынка.

А еще есть известная фраза (о правдивости судить не буду): те, кто не обновляется до свежей операционной системы, не покупает софт. (Можно тоже самое сказать и про hardware, наверное).

Примеры программ, работающих только на 10.6, уже есть — Acorn 2.

Пересказываю интересный кусочек из заметки Дерека Сиверса:

Группа продавала компакт диски со своими записями на концертах по $15. Они сообщали об этом со сцены пару раз за концерт и продавали сидюков на $300 за вечер.

Терри МакБрайд посоветовал им попробовать другой подход:

  1. Скажите аудитории: “Нам очень важно, чтобы у вас был наш сидюк. Мы усердно работали над ним и так им гордимся, что мы хотим, чтобы он был у вас по-любому. Заплатите сколько хотите. Даже если у вас нет денег, возьмите просто так”.

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

После этого продажи CD выросли до $1200 за концерт, несмотря на то, что некоторые брали его за просто так, и средняя цена получалась около $10.

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

Рекомендую, кстати, почитать блог Дерека — там есть очень интересные заметки. Дерек — основатель CD Baby, сайта, продающего CD indie-групп, который был продан в прошлом году за несколько миллионов долларов. И вообще, добрый чел.

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

MacRuby — это Ruby, портированный на Objective-C runtime и использующий ее сборщик мусора. Над проектом работают разработчики из Apple. Пока еще разработка в самом разгаре, скоро будет выпущена версия 0.5, которая построена на LLVM и может компилировать Ruby в машинный язык.

Это очень классный и важный проект.

Во-первых, Ruby известен своей плохой производительностью. Использование LLVM может улучшить ее (Google, кстати, по этому же соображению портирует Python на LLVM).

Во-вторых, использование Ruby в связке с Cocoa упростит написание десктопных приложений. Да, сейчас у Apple есть Ruby (RubyCocoa) и Python (PyObjC) bridges в Cocoa, и уже есть как опенсорсные, так и коммерческие приложения, написанные на этих двух языках. Но их производительность не так высока, как производительность откомпилированных программ, написанных на Objective-C, к тому же, их приходится распространять вместе с исходниками (код на питоне можно распространять в .pyc, но они легко декомпилируются).

Базовые классы в MacRuby построены на классах Cocoa — любой класс является наследником NSObject. Строки — NSMutableString, массивы — NSMutableArray и т.д. При этом, у них помимо методов Objective-C есть и Ruby-методы, и они являются полноценными Ruby-объектами. Например:

$ macirb
irb> s = "hello"
=> "hello"
irb> s.class
=> NSMutableString
irb> s.upcase
=> "HELLO"
irb> s.uppercaseString
=> "HELLO"

irb> a = ["one", "two"]
=> ["one", "two"]
irb> a.class
=> NSMutableArray
irb> a.is_a? Array
=> true
irb> a[0]
=> "one"
irb> a[1]
=> "two"
irb> a.objectAtIndex(0)
=> "one"

Objective-C методы состоящие из нескольких частей, например setValue:forKey: в RubyCocoa вызывались так:

obj.setValue_forKey_("hello", "greeting")

Это смотрелось не очень хорошо. В MacRuby можно делать так:

obj.setValue "hello", forKey:"greeting"

Что повышает читаемость и удобство написания.

Сравним MacRuby с Objective-C?

Objective-C:

@interface OrderedTreeController : NSTreeController
- (void)updateSortOrderForNode:(NSTreeNode *)node;
@end

@implementation OrderedTreeController

- (void)updateSortOrderForNode:(NSTreeNode *)node
{
    [[node representedObject] setValue:
        [NSNumber numberWithInteger:[[node indexPath] lastIndex]] 
        forKey:@"sortOrder"];
    for (NSTreeNode *child in [node childNodes]) {
        [self updateSortOrderForNode:child];
    }
}

@end

MacRuby:

class OrderedTreeController < NSTreeController

  def updateSortOrderForNode(node)
    node.representedObject.sortOrder = node.indexPath.lastIndex 
    node.childNodes.each { |child| updateSortOrderForNode(child) }
  end

end

Несколько замечаний. Во-первых, в MacRuby числа не надо конвертировать в NSNumber.

irb> n = 3
=> 3
irb> n.is_a? NSNumber
=> true
irb> n.is_a? Fixnum
=> true

Во-вторых, Objective-C версию можно было бы написать с setSortOrder: вместо setValue:forKey:, но тогда классу нужно было бы дать знать о setSortOrder: через включение заголовочного файла или добавление категории к NSObject. Тем не менее, разница очевидна: мы теряем проверку типов во время компиляции, но получаем легче читаемый и изменяемый код.

MacRuby можно взять с http://macruby.org, только учтите, что последний “стабильный” релиз (0.4) сделан не на LLVM, а на YARV, так что берите trunk с SVN или GitHub, либо свежий nighly build. Дистрибутив включает шаблоны проектов для Xcode, но пока со сборкой в интерпретируемом (точнее JIT-компилированном) виде, однако компилировать можно из командной строки (читайте README и рассылку, особенно это письмо с примерами). На сайте также есть небольшой туториал.

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

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

На его сайт приходят 40% виндузятников, 36% маководов и 22% линуксоидов. Это статистика посещений. А теперь статистика продаж:

  • Mac OS X: 42.72%
  • Linux: 33.98%
  • Windows: 23.30%

Мак и линукс на первых двух местах! О чем это говорит?

Рынок Mac OS X и Linux игрушек не такой большой (“под Mac и Linux нет игр”) как рынок игрушек для Windows, поэтому:

  • люди покупают игры у indie-разработчиков, а не на сидюках в магазинах;
  • разработчикам проще сделать так, чтобы о них услышали.

И, оказывается, у линуксоидов есть деньги (про маководов мы это и так знаем :) и они покупают игры.

P.S. А я уже пару недель поигрываю в New Star Grand Prix (Win/Mac).

С тех пор как я перешел на Маки фулл-тайм, я обновлял свои блоги через веб-интерфейс (странно, наверное, это слышать от автора блог-клиента… но что поделаешь, BlogJet есть только под Windows).

Ну а потом вообще перевел Sellme.ru на Webby и стал писать заметки в TextMate, обновляя блог из командной строки. (Это оказалось неудобным решением — слишком много действий).

Сегодня решил вновь попробовать блог-клиенты, а именно, MarsEdit (вернув Sellme.ru на блог-движок… Movable Type на этот раз).

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