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

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

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

Ответ 1

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

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

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

Ответ 2

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

Ответ 3

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

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

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

Размер TestCase allSubclasses

Ответ 4

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

Во-первых, я собираюсь изменить название "динамический" язык на "интерпретируемый" язык, что я думаю о 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;

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

Ответ 5

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