Внедрение зависимостей перед поколением
Это дополнительный вопрос из моего предыдущего вопроса ( разница между "новым" и "общим").
Есть ли способ передать зависимости в структуру до генерации?
Я заинтересован в том, чтобы попытаться написать свой код способом, который легко проверить. В настоящее время наша кодовая база часто использует get_enclosing_unit() для получения указателей на вспомогательные структуры, такие как переводчик / params. Это приводит к тому, что в нашей кодовой базе будет много двунаправленных зависимостей. Это означает, что трудно тестировать образцы независимо от других структур.
Вот пример того, чего я пытаюсь избежать.
pregenerate() is also {
var translator : my_translator_s = get_enclosing_unit(some_enclosing_unit).get_translator_pointer();
};
Я пытаюсь избежать зависимости от some_enclosing_unit, поскольку это не относится к моей структуре и мешает юнит-тестированию
Из-за отсутствия конструктора в e, я заблудился относительно того, как передать зависимость от вызывающего модуля / структуры без использования get_enclosing_unit(). "new... with", кажется, может помочь, но, как я узнал в моем последнем вопросе, он не генерирует базовые поля, а "gen...keep" не устанавливает необходимые для моего поколения зависимости до тех пор, пока поколение было завершено.
1 ответ
Нет простого ответа, потому что ваша архитектура уже запуталась. Вы правы, подозревая эти двунаправленные вертикальные зависимости в вашем дереве экземпляров. В общем, следует следовать стратегии ограничения сверху (CFA), где вы передаете зависимости вниз по иерархии, как в
unit child_u {
p_tr: translator_s;
keep soft p_tr == NULL; // safety catch, in case you forget to constrain it
};
unit parent_u {
tr: translator_s;
child: child_u is instance;
keep child.p_tr == tr;
};
Кроме того, я рекомендую не иметь зависимости генерации между модулями. Таким образом, вы можете сохранить все ваши указатели на не генерируемые модули и соединить их в методе connect_pointers() модуля, который вызывается после генерации (см. Документацию).
extend child_u {
!p_parent: parent_u;
}
extend parent_u {
connect_pointers() is also {
child.p_parent = me;
};
};
Но тогда, конечно, вы не можете иметь ограничения в child
это указывает на parent
, В случае, когда вам абсолютно необходим сгенерированный указатель, используйте keep soft <ptr> == NULL
спровоцировать неудачу, если вы забыли ее ограничить.
Просто мои 2цента.