Внедрение зависимостей перед поколением

Это дополнительный вопрос из моего предыдущего вопроса ( разница между "новым" и "общим").

Есть ли способ передать зависимости в структуру до генерации?

Я заинтересован в том, чтобы попытаться написать свой код способом, который легко проверить. В настоящее время наша кодовая база часто использует 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цента.

Другие вопросы по тегам