Может кому любопытно будет:
Я тут пытаюсь использовать D. Воткнулся в отсутствие нормальной
модульности (хотя она декларирована).
В частности - там нет разделения на спецификацию и реализацию модуля.
Что в некоторых случаях жутко не удобно.
То есть с этим там хуже чем в С++ (там хотя бы это более-менее
прилично эмулируется). В D с этим вообще никак.
Кроме того типы из private секции модуля и класса/структуры радостно
утекают во вне, то есть их можно использовать извне.
Примерчик:
// Implementation
module test;
public {
void foo() {foo_helper();}
struct Boo
{
public:
void boo() {S ss; foo_helper();}
private:
struct S {};
}
}
private {
struct HelperStruct {};
void foo_helper() {HelperStruct s;}
}
Specification (generated by dmd -H test.d -c) -- test.di file
// D import file generated from 'test.d'
module test;
public
{
void foo() {foo_helper();}
struct Boo
{
public
{
void boo() {S ss; foo_helper();}
private struct S{}
}
}
}
private
{
struct HelperStruct{}
void foo_helper(){HelperStruct s;}
}
Usage:
import test;
void main() {
foo(); // ok
Boo b; // ok
b.boo(); // ok
Boo.S ss; // ok (wtf?)
HelperStruct s; // ok (wtf?!)
}
Видим что сгенереная для модуля спецификация выглядит просто как
копи-паста реализации модуля. В С++ же это будет выглядеть так:
// test.hpp file
#ifndef _test_hpp_
#define _test_hpp_
void foo();
struct Boo
{
public:
void boo();
private:
struct S {};
};
#endif
// file test.cpp
#include "test.hpp"
struct HelperStruct {}; // private struct for this module only
static void foo_helper() {HelperStruct s;}
void foo() { foo_helper(); }
void Boo::boo() { S ss; foo_helper(); } // method implementation in
implementation side, not in specification!
// file main.cpp
#include "test.hpp"
int main() {
foo(); // ok
Boo b; // ok
b.boo(); // ok
Boo::S ss; // error: struct Boo::S is private
HelperStruct s; // error: HelperStruct was not declared in this scope
return 0;
}
В общем, я ожидал от D в плане модульности бОльшего... Посмотрим что
на это ответит Брайт и Александреску, ибо такая ситуация прямо
противоречит тому, что писал Александреска в своей статье case for D:
"D has a true module system that supports separate compilation and
generates and uses module summaries (highbrowspeak for "header files")
automatically from source, so you don't need to worry about
maintaining redundant files separately, unless you really wish to, in
which case you can. Yep, that stops that nag right in mid-sentence."