Разрушающее сопоставление с образцом

В Rust используется разрушающее сопоставление с образцом, что в купе с моделью памяти Rust, иногда, дает очень занятные эффекты. Для примера возьмем структуру MyStruct и создадим две переменные типа Option в которых будет лежать наша структура, в одном случае 1 в виде стекового объекта, а во втором в виде уникального указателя 2.

struct MyStruct {
    val: int
}
let stack_data = Some(MyStruct{val:42});   // (1)
let own_data = Some(~MyStruct{val:42});    // (2)

Continue reading

Луч поноса авторам HomeBrew

Довольно давно, а если говорить точнее, то уже лет как 5 я использую MacPorts. Порты, конечно, не без багов, но все же они достаточно хорошо спроектированы и удобны в использовании. В них всегда можно найти несколько версий компиляторов и т.д. И тут, внезапно, мне понадобился HomeBrew. Да, я знаю, что писать пакеты для MacPorts трудно, а для HomeBrew легко. Да, я в курсе того, что заставить работать MacPorts через прокси не так уж и просто, а HomeBrew очень легко. Но…

КАКОГО ХЕРА HomeBrew требует что бы пользователь был Admin?! Что за жопорукий дебил это придумал?! Системное приложение ОБЯЗАНО уметь работать через sudo или каким-то иным способом повышать свои права!

Переменные окружения в OSX

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

Стандартный путь довольно прост: необходимо вписать в файл /etc/launchd.conf новые пути, следующим способом.

setenv PATH /new/path/a:/new/path/b

Собственно, я так делал всегда и все было нормально. Но, внезапно, а может и не очень, к примеру после какого-то обновления, ряд приложений (тот же Eclipse и Wireshark) перестал видеть что-либо за пределами переменных, прописанных в /etc/launchd.conf. В итоге, по мнению этого ряда приложений “исчезло” все, VJM, dir, ls да совсем-совсем все.

Гугла подсказала, что пользовательские переменные, которые должны стать доступны всем, можно добавить еще в пару файлов, например в /private/etc/paths. Формат файла прост: одна линия – один путь.

/new/path/a
/new/path/b

Слегка разочаровался в Scala

Когда-то, довольно давно, я взялся за поиск альтернативы для C++, который во все времена был и, как мне думается на данный момент, будет моим основным рабочим инструментом. Само собой, эта альтернатива мне была нужна не для того, что бы перейти в какую-то иную сферу, а для тех случаев, когда либо хочется написать что-то свое, либо нужно быстро создать какой-то прототип, проверить ту или иную концепцию. В такой ситуации JVM-based язык очень удобен и, по большому счету, безальтернативен, конкуренцию может составить разве что Python со своим простым синтаксисом и безграничным набором библиотек. Continue reading

Задачи в Rust. Подводные камни.

Все написанное в данной заметке актуально для компилятора Rust версии 0.7

Более-менее глубокой информации о задачах в Rust не много, поэтому, для того что бы разобраться в том, как же это работает, приходится экспериментировать “на кошках”. Посидев некоторое время за исходниками Rust, я открыл для себя много нового.
Самое неожиданное: на данный момент планировщиков задач аж два! Один старый, более функциональный, правда, на данный момент находящийся в довольно непотребном состоянии и новый, который еще не дописан. Подобная ситуация приводит к тому, что поведение задач, запущенных при помощи методов TaskBuilder отличаются от поведения задач, запущенных при помощи функций из модуля task.
Ну а после “оптимистичного” введения, небольшой рассказ о планировщиках Rust и том, как с ними работать на данный момент.

Старый планировщик

Если зайти на сайт Rust, то в разделе посвященном модулю Task можно найти информацию о ряде доступных типах планировщиков, заявленное поведение которых расходится с реальным: Continue reading

Сюрприз от Installd

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

/-- Library
    +--Application Suport
        +-- Company Name
            +--Product A
            +--Product B

Где Product B – директория с системными файлами нового приложения. С учетом того, что инсталляторы в Mac OS X воспринимаются исключительно как автоматизированное средство для копирования файлов, решение было предельно простым: взять уже имеющийся инсталлятор и поменять в нем “Product A” на “Product B”, не забыв поправить конфигурирующие скрипты. Но не тут то было.
Если попытаться установить два продукта параллельно, то начиналась магия: установка продукта A деинсталлировала продукт B и vice versa. Перерыл все логи инсталлятора, греша на pred- и post- install скрипты – ни малейшего намека на то, кто удаляет продукт. Хотел уже было браться за DTrace, но тут коллеги напомнили о fs_usage… Нашелся виновник: installd. Но, казалось бы, причем тут Installd?! А вот при том, что инсталлятор не только распаковывает файлы в нужные директории, но еще и делает “обновление” для пакетов с одинаковыми идентификаторами!

RB-tree в sglib

Наткнулся на довольно мерзкий баг, в когда-то уважаемой мной библиотеке sglib. Дело в том, что на определенных наборах данных у rb-tree из этой библиотеки сносит башню! В результате добавленные ранее элементы перестают находиться, хотя, количество элементов не изменяется и при обходе дерева все элементы в нем присутствуют.

#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdint.h>
#include "sglib.h"

struct rb_tree
{
    int64_t data;
    char color_field;
    struct rb_tree *left;
    struct rb_tree *right;
};
typedef struct rb_tree rb_tree;

#define CMPARATOR(x,y) ((x->data)-(y->data))

SGLIB_DEFINE_RBTREE_PROTOTYPES(rb_tree, left, right, color_field, CMPARATOR);
SGLIB_DEFINE_RBTREE_FUNCTIONS(rb_tree, left, right, color_field, CMPARATOR);

rb_tree *the_tree = 0;

int main(int argc, char *argv[])
{
    if( argc < 2 )
        return -1;

    const char *data_file_path = argv[1];
    FILE *data_file;
    data_file = fopen( data_file_path, "r" );
    if( 0 == data_file )
        return -1;

    uint64_t value;
    rb_tree *node, e;
    e.data = 6610223104;
    int added = 0;
    while( EOF != fscanf( data_file, "%llun", &value ) )
    {
        if( value == e.data )
            added = 1;
        node = malloc( sizeof(rb_tree) );
        node->data = value;
        sglib_rb_tree_add( &the_tree, node );
        if( 0 != added )
        {
            node = sglib_rb_tree_find_member( the_tree, &e );
            if( 0 == node )
                printf("ERRORn");
        }
    }

    return 0;
}

Файл с тестовыми данными.

Лучшее описание C++11

Существует довольно много статей посвященных C++11, которые в той или иной степени описывают вкусности из нового стандарта. Да что там говорить, на той же Википедии существует огромная, и вроде даже хорошая, статья посвященная C++11. Но, как известно, везде и всегда что-то не так…
Так вот, нашел я полностью устраивающее меня описание в виде презентации от Alex Sinyakov, за что ему огромное спасибо!

Кроссплатформенность в современном мире

Очередное обсуждение недостатков Nemerle на РСДНе навело меня на интересную мысль о связи между успешностью того или иного инструмента и его кроссплатформенностью.
По большому счету, Nemerle это язык с интересными концепциями и идеями, который не нужен практически никому, кроме его разработчиков. Почему я делаю такое утверждение? Тут все просто, возьмем для сравнения его ровесников Scala, Groovy и даже совсем молодежь Clojure. Для того что бы понять, нужен ли язык кому-то, кроме его авторов, можно воспользоваться следующей информацией:

  1. На каких языках присутствует информацию о языке в Википедии
  2. На какой строчке находится язык в индексе TIOBE;
  3. Участвует ли язык в индексах The Computer Language Benchmarks Game;
  4. Написал ли кто-то книги по этому языку.

Continue reading