Возможен ли автоматический рефакторинг в динамических языках?

Возможно, я ограничен опытом работы с динамическими языками (Ruby для Netbeans и Groovy для Eclipse), но мне кажется, что природа динамических языков делает невозможным рефакторинг (переименование методов, классов, push-up, pull-down, и т. д.) автоматически.

Можно ли выполнить рефакторинг АВТОМАТИЧЕСКИ на любом динамическом языке (с помощью любой IDE/ инструмента)? Мне особенно интересны Ruby, Python и Groovy, а также то, как рефакторинг сравнивается со 100% автоматическим рефакторингом, доступным во всех Java IDE.

5 ответов

Решение

Учитывая, что автоматический рефакторинг был изобретен на динамическом языке (Smalltalk), мне пришлось бы сказать "Да".

В частности, Джон Брант, Дон Робертс и Ральф Джонсон разработали Refactoring Browser, который является одним из основных инструментов, например, в Squeak.

Мой Google-фу сегодня слаб, но вы можете попытаться найти эту статью: Дон Робертс, Джон Брант и Ральф Джонсон, Refactoring Tool для Smalltalk, "Теория и практика объектных систем", (3) 4, 1997.

Smalltalk не объявляет никаких типов. Браузер рефакторинга успешно выполнил правильные рефакторинги в коммерческом коде с 1995 года и включен почти во все текущие среды разработки Smalltalk. - Дон Робертс

Автоматический рефакторинг был изобретен в Smalltalk, очень динамичном языке. И с тех пор это работает как шарм.

Вы можете попробовать себя в бесплатной версии Smalltalk (например, http://pharo-project.org/)

На динамическом языке вы также можете самостоятельно выполнить сценарий рефакторинга или запросить систему. Простой пример, чтобы получить количество тестовых классов:

TestCase allSubclasses size

Я удивился тому же. Я не пишу компилятор / интерпретатор, но думаю, что ответом будет то, что невозможно сделать его идеальным. Тем не менее, вы можете сделать это правильно в большинстве случаев.

Во-первых, я собираюсь изменить название "динамический" язык на "интерпретируемый" язык, о котором я думаю в Ruby, Javascript и т. Д. Интерпретируемые языки, как правило, используют преимущества возможностей времени выполнения.

Например, большинство языков сценариев допускают следующее

-- pseudo-code but you get the idea
eval("echo(a)");

Я просто "запустил" строку! Вы должны также рефакторинг этой строки. И будет ли переменная или этот язык позволяет печатать символ a без кавычек, если нет переменной a?

Я хочу верить, что этот вид кодирования, вероятно, является исключением, и вы будете получать хороший рефакторинг почти все время. К сожалению, кажется, что когда я просматриваю библиотеки для языков сценариев, они обычно попадают в такие исключения и, возможно, даже основывают свою архитектуру на них.

Или немного поднять ставку:

def functionThatAssumesInputWillCreateX(input)
    eval(input)
    echo(x)


def functionWithUnknownParms( ... )
   eval(argv[1]);

По крайней мере, когда вы реорганизуете Java и меняете переменную с int на строку, вы получаете ошибки во всех местах, которые ожидали int:

String wasInt;
out = 3 + wasInt;

С интерпретированными языками вы, вероятно, не увидите этого до времени выполнения.

То же самое касается браузера Refactoring... он очень эффективен в Smalltalk. Однако я полагаю, что существуют определенные типы рефакторинга, которые были бы невозможны без информации о типах (независимо от того, получено ли это путем явной аннотации типов в языке или с помощью какой-либо формы вывода типов в динамическом языке). Один пример: при переименовании метода в Smalltalk он будет переименовывать всех разработчиков и отправителей этого метода, что чаще всего просто отлично, но иногда нежелательно. Если бы у вас была информация о типе переменных, вы могли бы охватить переименование только для разработчиков в текущей иерархии классов и всех отправителей, когда сообщение отправляется в переменную, объявленную как тип в этой иерархии (однако я мог бы представить сценарии где даже с объявлением типа это сломало бы и дало бы нежелательные результаты).

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