Кэши кода загрузки модуля ищут и по существу начинают с:
$lock.protect: {
return %loaded{$id} if %loaded{$id}:exists;
}
Таким образом, возникает вопрос: «Как загрузить модуль, а затем выгрузить его (чтобы я мог загрузить его снова)?» на что ответ: вы не можете выгрузить модуль. Однако вы можете изменить имя файла, длинное имя дистрибутива (через изменение имени, auth, api или версии) или идентификатор предварительной компоновки - независимо от того, какой конкретный CompUnit :: Repository использует для уникальной идентификации модулей - чтобы обойти кеш.
То, что кажется упущенным, - это то, что $key
предназначен для представления неизменного имени, так что оно всегда будет указывать на одно и то же содержимое. Какая версия foo.pm
должна быть загружена для модуля Used::Inside::A
, если foo.pm
загружается одновременно модулями A
и B
, модуль A
сначала загружает foo, а затем модуль B
изменяет Foo? Старая версия Module A
загружена, или (возможно, конфликтует с предыдущей версией) загруженная версия Module B? И как эта дифференциация будет работать для генерации файлов precomp (что опять может происходить параллельно)?
Конечно, если мы игнорируем вышесказанное, мы можем добавить код, чтобы сделать дорогостоящими .IO.modified
вызовы для каждой загрузки каждого модуля для всех типов CompUnit :: Repository (замедление скорости запуска), чтобы сказать «эй, эта неизменная вещь изменена». Но гранулярность измененных временных отметок файловой системы в некоторых ОС делала проверку довольно хрупкой (особенно для загрузки многопоточных модулей с генерируемыми файлами precomp), а это означает, что каждый раз требуются даже более дорогие вызовы для получения контрольной суммы.