Join Yalantis and get a $1000 sign-in bonus! React.js, React Native, Python, Java, DevOps, BА. Apply now!
×Закрыть

Поиск и замена дублированного кода, how?

Есть сайт на старом добром PHP4, сайт внутренний и написан очень давно. Часть сайта рефакторится с ПХП на Питон. В коде ПХП есть повторяющиеся куски кода, вывод каких то логов, апдейт базы и т.д., кусков таких не мало и их тяжело сверять построчно. Подскажите чем можна рефакторить куски кода, что бы выделил-нажал кнопку «новый метод» и по всему коду этот кусок заменился на вызов нового метода? Пхп-шторм и пишарм стоят.

👍НравитсяПонравилось0
В избранноеВ избранном0
LinkedIn
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Вряд ли такое умеет хоть одна IDE. Заменить одну строку на переменную в одном файле это одно, ввести новый метод, еще и по всему проекту — более сложная задача.

Но PhpStorm может помочь в данной ситуации. Там есть поиск по проекту. В том числе с поддержкой регулярных выражений. А потом ручками. Я в таких случаях так делал: писал сам метод, затем искал характерную для него строку по всему проекту и руками вставлял вызов метода. Это занимает некоторое время, но не такая уж и сложная задача.

Ах, да, важно помнить, что не всегда похожий с виду код стоит объединять в метод. Бывает такое что в каждой «копии» есть ньюанс. Из-за чего метод обрастает параметрами. И если таких параметров больше 3 — стоит подумать, «всё ли я правильно делаю».

было бы неплохо что бы ктото посоветовал тулзу которая ищет в файле кусок кода (строк 10-20) и реплейсит их не что то другое. Искать одну строку все умеют а вот 10-20 строк что бы искало я пока не нашел ничего

Emacs должен уметь. По крайней мере, замену на многострочный кусок кода я недавно делал.

любая PHPStorm / PyCharm вполне себе умеет искать многострочный код. + дополняешь код регуляркам (если вдруг один код в разных файла содержит разные отступы и прочее подобное) и норм.

Как правило, НИЧЕГО не поможет.
Повторящихся шаблонов на самом деле немного. И каждый из них содержит какую-то уникальную строчку. Например, имя лога. Вот НАХОДИШЬ каждый такой и руками меняешь.

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

Если таких кусочков не больше сотни — сделай руками и не парься, сэкономишь время. Поверь, НАЙТИ список файлов проблема небольшая. А вот ошибиться в настройке автоматики, и потом расхлёбывать её действия — гемороище редкостное, даже если всё бэкапить.

Как правило, элементарный рефакторинг даёт среда IDE в которой ты программишь. То есть поменять имя метода не проблема.

Я лично делаю полнотекстовый поиск, и замену на ТУ ЖЕ строку, но с куском кода который ТОЧНО не скомпилируется. Этим я гарантирую, что доберусь руками и доделаю запланированное, кто бы и как бы меня не отвлёк в процесс (законы Мэрфи нерушимы).

Ну и последнее: если куски кода короткие, намного выгоднее оставить их инлайном. А если не создают уязвимостей, так и вовсе не спешить, а планомерно переводить на другую платформу файл за файлом, без средств множественной автозамены. А вот СПИСОК замен просто положить себе в отдельный текстовый файлик, чтобы каждый раз когда нужно заменить что-то шаблонное, просто скопировать-вставить.
Выигрыш такого подхода — проект всегда готов, требует от тебя минимум памяти (а значит и минимальна вероятность ошибки), можно вносить любые срочные изменения на любом этапе, а это дело — откладывать в долгий ящик любой глубины. Иначе говоря, минимизировать расходы на рефакторинг.

файл уже создал ))) но так и не нашел софта который ищет в коде не одну строку а 10-20 строк, что бы задать искать и вставить туда кусок кода и реплейсмент.

Такой софт точно есть. Ключевое слово «автозамена текста». Но по факту, руками заменить быстрее чем найти эту софтину.
А вероятность ошибки с таким софтом просто таки огромна.

PS. 10-20 строк во многих местах — это кому-то точно не лень было. Неужели так сложно было написать require и вставить файлом? Небось человеку за объём кода платили.

Ну так это и вовсе элементарщина. Меняй на импорт библиотеки и дело в шляпе. Но тогда тем более руками быстрее. Искать, разумеется, по имени метода — потому что могли немного скобки подвинуть, форматирование подрихтовать, комменты подчистить — и уже хрен найдёшь.

Наиболее оптимально — искать строку «function имяМетода». Кстати говоря, если бы делал руками — ты бы давно выполнил задачу и забыл как страшный сон. Почему и говорю, что чаще всего тупую работу надо тупо сделать, и ТОЛЬКО ЕСЛИ она повторяемая в будущем — автоматизировать. А повторяется она раз в 5-10 лет :)

Отдавать другому человеку не стоит, если будешь потом вести этот код. Почему так: тебе всё равно нужно его читать и ориентироваться. И понимать, когда и где переписать будет быстрее чем понять.

)) ты оптимист, гдето 5 классов по 2000 строк в четырех, в одном 5000 строк. руками переписать ???

Всего-то? Скажи спасибо если имена переменных понимаешь что значат. Потому как одно дело спагетти распутать, другое — разобраться как оно должно работать, при том что оно НЕ работает.

На моей практике такого мегатонны встречались. Когда сам автор вместо того чтобы понять где накосячил — вставлял костыли в конечный результат. Соответственно, когда косяк исправлялся — костыли вылезали наружу, и потом долго выкорчёвывались. А потом ещё костыли, исправляющие эти костыли. И костыли которые исправляли исправление.

И каждый из них содержит какую-то уникальную строчку.
алгоритмически решаемо.
в тех же продуктах Inteliji это типа anonymize literals и anonymize subexpressions smaller then ...
то есть, тот же самый блок с «+1» и «-1» распознается как «нечеткий дубликат». разница рефакторится в виде аргументов метода и вуа-ля.

Может быть. Но факт что время на освоение этого метода и время на ручной копипаст в рамках ОДНОГО древнего проекта — соизмеримо. Однако ручной рефактор явно более защищён от ошибок.

Почему конкретно здесь советую ручной: проект не остаётся на PHP4, он мигрирует. Иначе говоря, переписать нужно ВЕСЬ код, а не только эти участки. А значит всё равно перечитывать и разбирать. И скорее всего так окажется, что есть задача более крупноблочного рефакторинга, а где-то наоборот, забивают гвозди микроскопом.

не согласен.
автоматический поиск подскажет вариации типа как с «+» и с «-».
ручной поиск такого не позволит.
потому после нечеткого поиска + рефакторинга у тебя будет куча вызовов одной функции, а после ручного способа — столько же вызовов, но разных функций.
что проще мигрировать?

ЕСЛИ эта задача стоит часто — то да. ЕСЛИ нет — то затраты на обучение и ошибки будут существенно выше. И когда это понадобится в следующий раз — не только не вспомнишь как конкретно настраивать софтину, но даже как она называется.

А вероятность вышеупомянутых вариаций крайне невысока. Я, к примеру, не встречал никогда.

не только не вспомнишь как конкретно настраивать софтину
это фича IDE автора треда. Очень странно не знать, как называется собственный инструмент.

Ну, уговаривать я точно не собираюсь.

А кто-то говорил не пользовать IDE? Но поиск регуляркой достаточно сложная процедура, а столь соблазнительная кнопка «Заменить всё» может натворить делов, о которых узнают ну слишком уж поздно.

какие регулярки? зачем?
www.jetbrains.com/...on-analysis-settings.html
anonymize variables/fnctions/literals — это настройки поиска

так научитьте — видео покажите или ссылку на где почитать

Code -> Locate Duplicates -> указать параметры anonymize * с каким-то количеством. получить блоки кода «почти полностью похожие».
Идешь в файл, выбираешь код. refactor -> extract method.
Получаешь все еще работающий код, где дублирующийся код изолирован.
После чего тебе надо добиться, чтоб все такие вот «экстрактнутые функции» имели идентичную сигнатуру(список, смысл и порядок параметров). Возможно, пригодится refactor -> extract parameter и refactor -> change signature(чтоб менять порядок аргументов).

В идеале у тебя должны получиться абсолютно идентичные методы, где вся разница передается в виде параметров.
Чтоб убедиться — запускаешь refactor -> locate duplicates без "анонимизирования"(== 0). Должно показать, что методы полностью абсолютно совпадают.

После чего остается заменить вызов локального метода, на вызов единственного инстанса, а остальные удалить.

www.sonarqube.org
Для платных опций есть тестовый период (нужно написать в суппорт, вышлют ключ). Можно продлевать при необходимости по запросу на суппорт.
Правда, есть риск, что по результатам работы тулзы повторяющиеся куски кода окажутся не самой большой проблемой...

я тоже нашел одну платную какуюто софтину — 500 баксов ))) трудно поверить что так мало рефакторят )))

Халявных валом. Просто не удивляйся что им по 10-15 лет таким программам, задача-то древняя.

Кстати говоря, проверь в своём IDE, очень вероятно сможет заменить фрагменты. Например, поле поиска однострочное, но что будет если туда Ctrl-V?

Софтина в принципе опенсорсна и бесплатна. Но платные плагины, например, под PL/SQL. По дефолту достаточно серьезный набор правил, правила можно расширять вручную. С поиском дублей в коде справляется. Давно тестировал, сейчас всех деталей не упомню, но был впечатлен результатом. Продукт достойный, но нужно обработать напильником под конкретный проект.

Рекомендую все переписать на go, там это основной паттерн.

IntelliJ тобі підсвітить сірим всі дублікати в коді. Сумніваюсь що є така кнопка як ти просиш, але можна спробувати натинути alt+enter і подивитися опції :)

по идее можна сделать что то «выделить метод», но так как код на пхп — то пичарм не хочет его реплейсить по всему коду.

оно выделяет в одном месте.
phpStorm тоже умеет.
так что, да
1. locate dulpicates
2. для каждого вхождения делаешь extract method, указывая одинаковое имя
3. удаляешь дубликаты, оставляя только вызов и передачу параметров

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

в чарм поставь расширение PHP

Подписаться на комментарии