Perl неглубокая проверка синтаксиса? то есть. не проверять синтаксис импорта

Как я могу выполнить "мелкую" проверку синтаксиса на файлах perl. Стандарт perl -c полезно, но проверяет синтаксис импорта. Иногда это хорошо, но не очень хорошо, когда вы работаете в репозитории кода и отправляете его в работающую среду, и у вас есть функция, определенная в репозитории, но еще не переданная в работающую среду. Он не проверяет функцию, потому что импортирует пути к ссылочной системе (т. Е. Использует Custom::Project::Lib qw(foo bar baz)).

5 ответов

Решение

Это практически невозможно, потому что импорт может влиять на синтаксический анализ следующего кода. Например use strict делает так, чтобы голые слова не анализировались как строки (и изменяет правила использования имен переменных), use constant вызывает постоянные сабвуферы, которые будут определены, и use Try::Tiny изменяет синтаксический анализ выражений try, catch, или же finally (давая им & прототипы). В более общем смысле любой модуль, который экспортирует что-либо в пространство имен вызывающего, может влиять на синтаксический анализ, потому что анализатор perl разрешает неоднозначность различными способами, когда имя ссылается на существующую подпрограмму, а не когда это не так.

Есть две проблемы с этим:

  1. Как не подвести -c если необходимые модули отсутствуют?

    Есть два решения:

    A. Добавьте модуль подделки / заглушки в производство

    B. Во всех ваших модулях используйте специальную запись-ловушку @INC (используя подпрограммы в @INC объясняется здесь). Это, очевидно, имеет проблему с тем, что модуль НЕ дает сбой в реальной рабочей среде, если библиотеки отсутствуют - DoublePlusNotGood в моей книге.

  2. Даже если бы вы могли как-то пропустить сбои в отсутствующих модулях, вы бы ВСЕГДА потерпели неудачу при любом использовании идентификаторов, импортированных из отсутствующего модуля или использованных явно из пространства имен этого модуля.

    Единственное реалистичное решение - вернуться к #1a и использовать модуль-заглушку, но на этот раз с объявленным и (при необходимости) экспортированным идентификатором для каждого открытого интерфейса. Например, сабвуферы или фиктивные переменные.

    Однако даже это не удастся для некоторых расширенных модулей, которые динамически определяют, что создавать в их собственном пространстве имен и что экспортировать во время выполнения (и код вызывающей стороны может динамически определять, какие подпрограммы вызывать - хек, иногда какие модули импортировать).

    Но этот подход прекрасно подойдет для обычного "Java/C-like" ОО или процедурного кода, который вызывает только статически именованные предопределенные публичные подпрограммы, методы и обращается к экспортируемым переменным.

Я бы посоветовал включить репозиторий кода в проверку синтаксиса. perl -I/path/to/working/code/repo/local_perl/ -c или установить PERL5LIB=/path/to/working/code/repo/local_perl/ до запуска perl -c, Любой из этих вариантов должен позволять вам проверять ваш рабочий код, предполагая, что он находится в структуре каталогов, аналогичной вашему живому коду.

Вы смотрели в PPI? Я думаю, что он следует за импортом, однако, возможно, его можно было бы легче изменить, чтобы угадать, как выглядит имя функции.

Я думаю, вы могли бы сделать заглушки для отсутствующих библиотек в вашей домашней папке.

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