Быстрый старт с Digital Mars D

6 октября 2011 г.

Быстрый старт с Digital Mars D

Из комментариев здесь я узнал что есть люди которые перешли с С++, на некий язык D и нисколько не жалеют.
Это меня весьма заинтересовало, и захотелось узнать что же это за новый зверь такой, который совмещает в себе лучшее от целой кучи языков программирования.
Итак начинаем безобразничать и вызывать бурю негодования опытных программеров, у которых вид моих программ вызовет бурю справедливого гнева…

Гугл подсказал что искать сайт этого языка мне стоит по адресу www.digitalmars.com. Оказалось это именно то что нужно, правда сайт работает весьма отвратительно.
Начал я думать что мне может потребоваться для начала: ide, компиляторы, книжки.
IDE. Нашел я с трудом на сайте ссылочку на IDE для этого языка, но меня ожидал неудача — единственный нормальная среда, некий Poseidon, категорически отказалась запускаться на семерке, видимо идеологическое противостояние мелкомягких и опенсурса. Значит буду писать в Geany.

Компиляторы. Компиляторы встали без вопросов и проблем с помощью онлайн-инсталлятора с оффсайта.

Книжки. С этим оказалось всё гораздо хуже чем с другими языками программирования. Либо этот язык слишком новый, либо он слишком простой и понятный настолько, что книжки для него не нужны. Найти я смог только книжку Александреску «The D Programming Language». Будем работать с ней.

Digital Mars D логоИтак, компиляторы установленны и терпеливо ждут файлы для перемалывания в машинные коды, geany установлена, книжка Александреску скачана и словарь английского запущен.
Программа которая скомпилировалась вызывает у меня теплое чувство власти над компьютером и греет душу, поэтому нужно как можно скорей создать что-то компилирующееся. Не буду изобретать велосипед, будем писать классический хеллоуворлд.

Исходные файлы на D должны иметь расширение .d

c:\hello.d

import std.stdio;
 void main()
 {
 writeln("Hello, World!!!");
 }

Попробуем компилировать:


C:\>dmd h.d
h.d(5): Error: undefined identifier writeln, did you mean function writefln?
h.d(5): Error: function expected before (), not __error of type _error_

Вот как… Компилятор вполне вменяемо указал что за ошибка и где ее искать. Чем-то напомнило языки с JIT-компиляцией.
Странно что writeln он указал ошибочным именем функции, в книжечке Александреску было именно так написано. Ладно, будем верить компилятору, тем более он предложил вариант замены ошибочного имени функции. Видимо буковка ‘f’ в предложеном названии означает ‘formatted’.

writeln("Hello, World!!!"); => writefln("Hello, World!!!");

Пробуем снова:
C:\>dmd h.d
C:\>

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

C:\>h.exe
Hello, World!!!
C:\>

В папке с компиляторами есть файл rdmd, он компилирует программу куда-то себе во временную папку и запускает ее без дополнительных вопросов:
C:\>rdmd h.d
Hello, World!!!
C:\>

Шикарно, всё работает. Geany корректно подхватила компиляторы, и по нажатии «Собрать»->«Компилировать»->«Запустить» вполне нормально компилирует из запускает исходник. А если добавить в команды запуска кнопку «Выполнить» с текстом «rdmd „%f“», то можно проверять выполняемость файла без дополнительных телодвижений.

Нужно еще что-нибудь попробовать. О, можно с файлами поработать.
У меня в рейтинге первых программ на втором месте стоит «helloworld для файлов», это построчное чтение файла.
Документация и логика подсказывают что должен быть некий поток и некий вывод на консоль. это оказались std.stdio, std.stream.
c:\readfromfile.d

import std.stdio;
import std.string;
import std.stream;

void main()
{
 try
 {
 Stream fileStream = new File(r"c:\d\dmd2\license.txt",(FileMode).In); // читать будем файл лицензии на Digital Mars D
 if (fileStream.readable) // а вдруг он нечитаемый
 {
 while(!fileStream.eof()) // начинаем спамить в консоль, пока файл не покажет свой EOF
 {
 writefln(fileStream.readLine());
 }
 }
 else 
 {
 writefln("Error! File not readable!");
 }
}
catch (Exception e) // нужно схватить ошибку за яйца, если появится
{
 writefln("EXCEPTION!!! \"",e,"\"");
}
}

Попробуем это шедевр программистской мысли:

C:\>rdmd readfromfile.d
The following license applies to Software that is:

1. the executables in the bin directory
2. the libraries in the lib directory other than phobos.lib
3. the supplied source code to the dmd back end

The front end source code to the dmd D compiler is under the GPL license.

(Вырезан лишний текст)

The Software is copyrighted and comes with a single user license,
and may not be redistributed. If you wish to obtain a redistribution license,
please contact Digital Mars.

--------------------------------------------
Photo credits: Courtesy of NASA/JPL/Caltech
--------------------------------------------

C:\>

Работает, а это радует. Пишется на языке интуитивно и не сложно.

О, а как же тут передача по ссылке организована? Надо порыться в доках и писанине самого Александреску.
Тут за ссылки отвечает некое ‘ref’ ставящееся перед принимаемыми параметрами функции. Давай-ка замутит проверочку этого факта:

c:\ref.h

import std.stdio;

void main()
{
 int x = 1;
 int y = 2;
 change(x,y);
 writefln("Variable x= ",x,"; Variable y=",y,";");
}

void change(ref int x, int y)
{
 x=15;
 y=38;
}

Вроде несложно выглядит процесс использования передачи по ссылке.
Запустим, вдруг сработает:

C:\>rdmd ref.d
Variable x= 15; Variable y=2;
C:\>

Сработало.
Мне для бэкапа на работе нужен список всех расширений файлов, чтобы убрать ненужные. Попробую-ка я сделать список расширений всех файлов в каталоге.
Интернета сейчас нет, алгоритмов красивых в голову не приходит, так что буду действовать топорно.
для начала замучу список расширений файлов в массиве.

import std.stdio;
import std.file;
import std.string;
import std.path;
import std.array;

void main()
{ 
 auto array = new string[1]; //объявляем самый маленький массив, дальше он будет расширятся
 foreach (string name; dirEntries("c:\\d\\", SpanMode.breadth))// перебираем список всех каталогов, файлов внутри каталога c:\d\
 {
 if (isFile(name)) //отсекаем только файлы
 {
 array~=(extension(name));//эта запись расширяет массив на 1, и записывает туда расширение файла с точкой
 
 }
 }
 //умных мыслей не приходит, потому будем сортировать массив
 SortArray(array);
 //мысли умные до сих пор не появились, будем отбирать уникальные расширения без дубликатов
 GetExt(array);
 //выводим наш результат
 writeln("Done. Unique extensions in \"C:\\D\\\": ",array.length);

foreach(string name;array)
 {
 writefln(name);
 }

}

void GetExt(ref string[] array)//снова забираем ссылочку на массив
{
 int iterator = 0;//указатель на текущую позицию в массиве
 auto arr = new string[1];//создаем массивчик крохотный
 foreach (string ext; array)//начинаем выбирать уникальные расширения 
 {
 if (arr[iterator] != ext)
 {
 arr~=ext;
 ++iterator;
 }
 
 }
 array=arr.dup;
}
void SortArray(ref string[] array) //получаем ссылочку на массив, чтобы не возвращать значения и не создавать лишние копии массива.
{
 string tempvar, tempvar2; //пара временных переменных для хранения промежуточных значений
 //сравниваем и перемещаем со страшной силой
 for(int r=0; r< array.length; ++r)
 {
 for(int i=0; i < array.length-1; ++i)
 {
 tempvar = array[i];
 tempvar2 = array[i+1];
 if (tempvar>tempvar2)
 {
 array[i]=tempvar2;
 array[i+1]=tempvar;
 }
 }
 
 }
}

Так. Получилось что-то страшное. Дай бог что запуститься и не вылетит с каким-нибудь переполнением.
C:\>rdmd.exe c:\filelist.d
Done. Unique extensions in "C:\D\": 43

.1
.3
.5
.ASM
.DLG
.H
.ICO
.IDL
.INC
.LIB
.MAK
.MK
.ODL
.S
.TXT
.a
.asm
.bat
.c
.conf
.css
.d
.ddoc
.def
.di
.dll
.exe
.gif
.h
.hlp
.html
.ico
.ini
.jpg
.kwd
.lib
.mak
.obj
.png
.rc
.sh
.txt
C:\>

P.S. Я не специально пишу такой быдлокод, архитектура программ у меня пока хромает, не спорю что это можно было сделать гораздо короче и элегантней, добавив при этом кучу проверок.
На сегодня, наверное, хватит, ибо мозг уже кипит от чтения литературы со словарем и программирования в суровом Geany, в котором нет дьявольских приблуд типа автодополнения. Все методы приходится искать по инклудам. Хочется теперь потрогать гуй создаваемый на тулките DWT, но это в следующий раз, так много еще нужно переводить. Массивы тут оказались очень элегантно сделаны, да и всё остальное на высоте, а инструкции assert и контрактное программирование вообще шикарная штука. Буду продолжать читать Александреску со словариком, да писать статейки и программки.
Благодарю за внимание.

  • Похожие статьи
  • Предыдущие из рубрики