Сколько работы вы хотели бы сделать, чтобы создать код, который мог бы выяснить, каким должно быть исправление? И будет ли этот объем работы сопоставим или меньше с работой, необходимой для проверки кода вручную?
Теперь я пишу все это, потратив немало времени, пытаясь придумать систему проанализировать вывод программы установки CPAN, чтобы выяснить, что пошло не так (основной стимул для CPANPLUS, теперь перенесенный в историю). Легко сказать, что что-то не так, но помимо этого много страданий.
В вашем примере у вас есть ошибка по поводу необъявленной переменной. Как AutoFix узнает, должен ли это быть пакет или лексическая переменная? Вы можете угадать одно или другое, но на самом деле у вас есть две большие проблемы:
- Каков смысл кода?
- Отражает ли код действительное намерение?
Определение смысла кода зачастую очень сложно даже для опытного программиста-человека выяснить (просто прочитайте комментарии к вопросу StackOverflow). Компиляция кода часто является неправильным кодом в том смысле, что он не дает желаемого результата. Кроме того, понимает ли программист проблему? Отражает ли код, написанный программистом (здесь неправильно), фактическую работу, которую должен выполнять код? В обзоре кода людям сложно понять это. Такие инструменты, как Coverity могут догадываться о проблемах, о которых он знает, но они не смогут исправить код.
Но допустим, что программист понимает проблему. Правильно ли они это выразили? По моему опыту, чем дольше вы программируете, тем больше вы склоняетесь к «нет».
Это полностью отличается от упомянутого вами ограничения базы данных. Это узконаправленное исправление для ожидаемой и разрешенной ситуации. Рассмотрим другую параллель: если запись содержит код города Нью-Йорка, но адрес Chica go, должен ли я указать город? Когда я был младше, я делал то же самое с базой данных. Это было глупо, потому что я думал, что знаю что-то, чего не знал, и все, кто понимал ситуацию, сразу это понимали. Даже тогда, эти виды ограничений - это то, как мы моделируем то, что мы знаем о мире, а не то, чем он является на самом деле.
Теперь, чтобы сделать AutoFix, вам нужно сделать что-то, что может смотреть на код, понимать его и выяснить, что он должен делать. Вы можете делать предположения, но у вас нет оснований для воспроизведения вероятностей там.
Технические вопросы не могут решить эту проблему. AutoFix может отменить работу прагм, так что некоторые классы ошибок не отображаются, но что с того? Программа с ошибкой просто продолжается? Как это кому-нибудь поможет?
Мало того, компиляторы склонны жаловаться, когда понимают, что не могут что-то проанализировать. То, на что они жалуются, часто не является проблемой. Первое, чему я учу людей во время отладки, это то, что им нужно посмотреть на оператор, сразу после номера строки в сообщении об ошибке. Любое сообщение об ошибке, которое вы ловите, может иметь практически бесконечное число причин.
Рассмотрим этот код, который не работает так же, как ваш пример (то же сообщение об ошибке), но по совершенно другой, но распространенной причине:
use strict;
use warnings;
my $x = 5,
print $x++;
Как выяснить, каким должно быть исправление? Речь не идет о том, чтобы объявить $x
.
Итак, теперь у вас есть два случая, и вы создаете этот фиксатор. Затем вы сталкиваетесь с другим случаем, поэтому вы встраиваете его в себя. И продолжаете делать это до тех пор, пока не получите большой словарь исправлений. Может быть, вы немного сошли с ума и занялись машинным обучением (и не было бы здорово плохого кода и разрешений).
Но программа все равно не может продолжаться. Он должен начинаться сначала, потому что он должен по крайней мере вернуться туда, где он должен был что-то сделать, но не сделал этого Вы не можете просто перезапустить программу, потому что не знаете, является ли она идемпотентом. Повторный запуск программы может привести к тому, что она не будет работать, например, вставка дубликата в базы данных.
Сказав все это, подобные вещи связаны с анализом stati c и браузером рефакторинга 1038 *. Проект Адама Кеннеди Parse Perl Isolated (PPI) был первым шагом к пониманию кода Perl без его компиляции, а затем - к идеалу Smalltalk - пониманию того, какие части кода представляют одно и то же. Если бы вы знали, что две вещи с именем foo
- это одно и то же, вы могли бы изменить код, работающий с foo
. Например, если вы переименовали метод с bar
на set_bar
, вы могли бы сразу узнать, какие bar
s вы должны переименовать, а какие принадлежали к другому классу.
Адам написал Acme: : BadExample и заставил любого запустить его. Он писал, что «любой данный фрагмент источника Perl существует в причудливом псевдоквантовоподобном состоянии, в котором он демонстрирует как дуальность, так и индетерминизм».
Джос Буманс подошел и использовал некоторые изгибающие ум Perl который он затем показал в Barely Legal XXX Perl, который, я думаю, он впервые представил в 2006 году. Он был удивительно креативен в своих решениях, и я не хотел бы этого в производственном коде.
Perl даже не знает, по какому типу, что будет в переменной, или даже что метод, который вы могли бы вызвать, будет существовать. На самом деле, он настолько сильно зависит от времени выполнения, полагая, что к тому времени, когда он вам понадобится, все будет готово, и мы часто говорим: «только Perl может проанализировать perl». Вы буквально должны иметь возможность запускать код Perl для его правильной компиляции, поскольку блоки BEGIN
могут влиять на синтаксический анализ. Например, BEGIN
может определять подпрограмму с определенной арностью. Как вы анализируете foo 5, 6
? Вы должны знать, что уже было определено.
Perl имеет другие функции «действия на расстоянии», которые делают это еще более жестким. autodie
переопределяет функции CORE для добавления дополнительного поведения, но вы не сможете увидеть это в коде. Вы можете установить флаги регулярных выражений по умолчанию (и я видел множество больших ошибок, когда люди применяли /isxm
ко всем файлам без проверки).