Изменение кода программы самой программой

В прошлом году я сделал Java (Android) -programming, а С# за год до этого. Примерно через месяц я изучаю C++, и с тех пор, как я перебрал друзей, наследование и прочее, у меня появилось несколько вопросов, так как я до сих пор не работал с ним: Есть ли способ для класса определить друзей позже, потому что им нужно обмениваться информацией или чем-то еще. например, есть способ определить «случайного» друга позже? что вам нужно для этого? Имя функции или адрес класса? Или вообще есть способ изменить код из самой программы, чтобы не было необходимости перекомпилировать? например, создание новых функций, классов или так далее? Я был бы очень доволен любым ответом об этом.

blueBurningCoder 21 сен. 2014, в 11:26

Источник: overcoder.net

Какой бесплатный редактор кода выбрать для веб-разработки?

Топ-20 полезных онлайн-инструментов для рефакторинга

«Инструменты рефакторинга — это как хорошая пара обуви для плотника: они помогают нам работать более эффективно и с меньшей болью».

Мартин Фаулер
307 просмотров
Что такое инструменты рефакторинга?

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

рефакторинг исходного кода

Для программ среднего размера рефакторинг может быть выполнен вручную. Но проще и надежнее проводить рефакторинг с помощью специальных инструментов, которые могут автоматизировать анализ кода программных проектов Большинство таких инструментов доступно в Интернете.

Инструменты рефакторинга

Представляем вам подборку инструментов, которые помогут эффективно рефакторить код:

  • Stepsize. С помощью Stepsize вы можете просматривать технический долг и фрагменты кода, которые нуждаются в рефакторинге, и помечать эти данные в качестве проблемы.
  • JustCode. Благодаря быстрым рекомендациям, генерации кода, программе запуска модульных тестов и интеллектуальному рефакторингу JustCode легко вписывается в ваш естественный рабочий процесс. Другие функции JustCode включают навигацию и поиск кода, шаблоны кода и декомпиляцию для отладки.
  • Glean. Glean позволяет выполнять различные функции, такие как извлечение JSX в новые компоненты, замена компонентов класса на функциональные компоненты и наоборот, включение JSX в условия, одновременное переименование переменных состояния и их установщиков.
  • Refactoring Essentials. Рефакторинг кода C# и VB.NET становится проще с помощью этого бесплатного расширения Visual Studio с открытым исходным кодом. Ваш код становится более читабельным и качественным. Инструмент преобразует код из C# в Visual Basic и наоборот, а также предлагает предложения о том, как писать лучший код.
  • AppRefactoring. Это приложение для быстрой и безопасной проверки уникальности кода на языках Java, C#, Swift, Kotlin, JavaScript, GO, PHP, Objective-C, Typescript, Node.js. Инструмент поможет провести анализ дубликатов и пересечений, а также предоставляет отчеты для проведения рефакторинга и улучшения качества кода.

интерфейс программы

Сделал Python программу для отслеживания курса валют

  • SonaLint. В процессе написания кода SonarLint отмечает ошибки и уязвимости безопасности, подобно проверке орфографии, и предоставляет четкие инструкции по устранению уязвимостей, до публикации кода. SpotBugs. Плагин IntelliJ SpotBugs, анализирующий статический байт-код, позволяет пользователям IntelliJ IDEA находить проблемы в Java-коде. С помощью статического анализа инструмент обнаружения дефектов Java SpotBugs поможет определить типы ошибок в вашем проекте.
  • Snyk Vulnerability Scanner. Ваши проекты могут воспользоваться помощью Snyk’s Vulnerability Scanner в выявлении и устранении недостатков безопасности и проблем с качеством кода.
  • RefactorInsight. Пул-реквесты на рефакторинг могут быть идентифицированы и помечены с помощью RefatcorInsight. Также можно просмотреть историю рефакторинга для классов, методов и полей.
  • Code Style Enforcer. Code Style Enforcer предотвращает появление ошибок в определенных параметрах кода и обеспечивает немедленную визуальную обратную связь в редакторе.
  • JS Refactor. Разработчики JavaScript могут применять рефакторинг и ускорять процесс разработки с помощью этого простого, но эффективного инструмента. Вы можете легко удалить дубликаты в коде Javascript.
  • CodeRush. CodeRush предлагает быстрый рефакторинг, возможность быстрого запуска тестовых примеров, обнаружения и исправления ошибок и помогает инженерам быстрее создавать хороший код.
  • ReSharper. Что касается анализа качества кода, навигации и поиска, рефакторинга, очистки кода, обзора кодирования, модульного тестирования, инструментов редактирования XAML, кросс-языковой функциональности и Open API, ReSharper может оказать дополнительную помощь разработчикам.
  • Абракадабра. Это приложение расширяет возможности вашего редактора с помощью комбинаций, которые быстро запускают полезные компоненты и предлагают оперативные исправления, рекомендуя, при необходимости, провести рефакторинг.
  • Visual Assist. Плагин Visual Assist для Visual Studio улучшает код, предлагая инструкции по рефакторингу, выделяя общие синтаксические ошибки и поддерживая проверку орфографии. Приложение перестраивает ваш код и делает его более удобным для чтения, расширяемым и менее сложным.
Читайте также:
Как разработать визитку самому программа

инструменты рефакторинга кода

  • Rope. Rope — это легкая библиотека рефакторинга для Python. Она определяет каждую строку и функцию в коде проекта, где необходим рефакторинг.
  • OpenRewrite. Это автоматизированный инструмент для массового рефакторинга исходных кодов Java.
  • RefactorFirst. Вы можете использовать этот инструмент для кодовых баз Java, чтобы определить, какие God Classes следует рефакторить в первую очередь.
  • VIM PHP. VIM PHP — это плагин, который содержит множество инструментов рефакторинга для языка PHP. Он может переименовывать локальные переменные, переменные класса и методы, а также выявлять неиспользуемые операторы Use.
  • LiquiGraph. Liquigraph предназначен для рефакторинга баз данных. Благодаря определению и итеративному выполнению миграций, он помогает поддерживать состояние базы данных Neo4j.

Заключение

Проведение рефакторинга часто необходимо для разработчиков приложений, особенно что касается больших и масштабируемых проектов. Этот процесс помогает создавать более качественный код и совершенствовать скилы разработчиков. Преимущества использования необходимых автоматизированных инструментов для рефакторинга неоспоримы, поэтому мы составили список из 20 лучших инструментов для рефакторинга, среди которых рекомендуем к обязательному использованию инструменты Stepsize, JustCode, AppRefactoring и Glean.

Источник: vc.ru

Изменение кода программы во время ее выполнения на примере Common Lisp

По моему скромному мнению, Lisp — жемчужина среди языков функционального программирования. Несмотря на то, что это один из первых в истории (1958 год) высокоуровневых языков, он по сей день не перестает удивлять. Мне кажется, он настолько обогнал свое время, что его час еще только готовится прийти.

Так давайте попытаемся написать программу, которую проблематично будет создать на других языках. Как следует из названия статьи, эта программа будет редактировать собственный код по мере своего выполнения. Для ее создания я использую Common Lisp, а точнее его интерпретатор SBCL.

Примечание: если вы возьмете чистый SBCL , то у него есть свойство не флашить поток stdio после каждого вывода, я сам пользуюсь SBCL через Emacs и Slime, там этой проблемы нет. Адекватного решения пока не нашел.

Каким образом?

Lisp обладает замечательными свойствами, среди которых хочется отметить очень простой синтаксис и однородность кода. Самое классное то, что любой код на Lisp является данными для него же, и многие данные могут являться кодом. В частности, это дает возможность писать автоаппликативные (применимые сами к себе) и авторепликативные (воспроизводящие себя) функции. Чуть-чуть о них написано здесь; информация в свою очередь взята из книги «Мир Лиспа» (Э. Хювёнен, И. Сеппянен) том 1, страница 280. Например, квайн, который является одновременно и автоаппликативной, и авторепликативной функцией, записывается так:

((lambda (x) (list x (list ‘quote x))) ‘(lambda (x) (list x (list ‘quote x))))

При интерпретации, естественно, выводит себя же.
А почему бы не написать функцию, возвращающую не точную копию себя, а какую-то новую версию, которая в последующем будет снова исполнена, чтобы составить еще более мутировавший вариант? Так и поступим.

Командный процессор

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

Вся соль будет в том, что исходный (во всех смыслах) код будет очень минималистичен. Как только мы его скормим интерпретатору, мы более не вернемся к непосредственной работе с REPL -ом. Наша программа будет непрерывно выполняться и развиваться (или деградировать) со временем благодаря нашим командам.

Итак, начнем с функции, возвращающей s-выражение, являющееся определением лямда-функции, которая представляет собой начальный код. Эта лямда-функция принимает, как единственный параметр, свой же исходный код и отдает в качестве результата также какой-то код, которому в свою очередь предначертано быть исполненным на следующей итерации.

(defun start-program () ‘(lambda (program) (princ «$> «) (let ((input (read))) (when (listp input) (let ((command (car input))) (cond ((eq command ‘code) ; если команда = code, (setf program ; то обновим программу (funcall ; результатом того, что ввел пользовтаель (eval (list ‘lambda ‘(program input) (cadr input))) program input) ) ) (t (format t «Unknown command ~A ~%» command)) ) ) ) program ) ) )

Наш начальный код мало чего умеет. Он выводит приглашение для пользователя, считывает с клавиатуры s-выражение, если оно список, то первый элемент — имя команды, остальные — ее аргументы. Командный процессор «из коробки» умеет обрабатывать только одну единственную команду «code». Эта команда берет свой первый аргумент и создает из него лямда-функцию, применяемую к program и input.

Читайте также:
Программа управляющая только оперативной памятью компьютера это

Зачем так сложно? Потому что eval делает свои грязные делишки в нулевом лексическом окружении, а значит локальные переменные program и input нам не доступны, хотя могут потребоваться. Нужно найти способ их передать внутрь eval; ничего лучше лямды с параметрами мне в голову не пришло. Не исключаю, что есть и более изящные способы. Результат внутреннего eval присваивается переменной program.

Вообще можно было б просто присвоить program остаток от input, но в этом случае мы не сможем исполнять дополнительные функции при использовании команды code. О них чуть позже.
Следующая функция main организует цикл работы программы. Вся магия таится именно в ней.

(defun main () (let ((program (start-program))) ; задаем начальную программу ; цикл, пока программа не пустая, т.е. не nil (loop while program do ; своеобразный try — catch, увеличивает стабильность программы, ; если итерация дает ошибочный код (handler-case ; присвоим переменной program результат выполнения фукции, ; содержащейся в переменной program с параметром program (setf program (funcall (eval program) program)) ; в случае ошибки, сообщим о ней (error (c1) (format t «Error! ~A~%» c1) ) ) ) ) )

Итак, цикл идет, пока программа (переменная program) не пуста. Программа же на нулевой итерации — результат функции start-program, а на ненулевой итерации мы присваиваем ей (переменной program) результат выполнения функции, содержащейся в ней (переменная program), с параметром program (опять она же). Это не тавтология, и важно понять как оно работает, прежде чем двигаться дальше. Разобрались? Теперь запускаем в REPL -е main и видим приглашение:

CL-USER> (main) $>

Можно творить. Если надоест и захочется назад в REPL , достаточно выполнить нашу единственную пока команду code в параметром nil. Она заменит исходный текст на nil, и цикл воспримет это как условие завершения. Но мы, конечно, не будем пока этого делать. Отныне все команды вводятся уже в нашу работающую программу.

Я буду часто опускать «$> » для удобства копирования.

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

(code ‘(lambda (program) (princ «$> «) (let ((input (read))) (when (listp input) (let ((command (car input))) (cond ((eq command ‘code) (setf program (funcall (eval (list ‘lambda ‘(program input) (cadr input))) program input))) ((eq command ‘eval) (eval (cadr input))) ; НОВОЕ (t (format t «Unknown command ~A ~%» command)) ) ) ) program ) ) )

Возможно, оно выдаст STYLE-WARNING, это не страшно. Проверим:

$> (eval (print (+ 3 2))) 5 $>

Вуаля, работает!
Приправим систему с помощью трех функций (rsubs, rrem, rins). rsubs (Recursive substitution) заменяет рекурсивно старую форму (первый параметр old) на новую (второй параметр new) в форме (третий параметр form). rrem (Recursive remove) удаляет форму (первый параметр what) из формы (второй параметр form) тоже рекурсивно. Наконец, rins (Recursive insert) вставляет рядом в формой (первый параметр where) форму (второй параметр what) в форме (третий параметр form), причем если указан ключ :before t, то вставка выполняется перед формой where, иначе — после нее. Придется выполнить три команды.

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

(eval (defun rsubs (old new form) (cond ((atom form) (if (equal form old) new form)) ((equal form old) new) (t (loop for el in form collect (rsubs old new el))) ) ) ) (eval (defun rrem (what form) (cond ((atom form) (if (equal what form) nil form)) (t (loop for el in form if (not (equal what el)) collect (if (listp el) (rrem what el) el) )) ) ) ) (eval (defun rins (where what form —code—«) (print program) (terpri))) program))

Тестируем, должно получиться что-то вроде этого:

Пример вывода команды (view)

$> (view) —code— (LAMBDA (PROGRAM) (PRINC «$> «) (LET ((INPUT (READ))) (WHEN (LISTP INPUT) (LET ((COMMAND (CAR INPUT))) (COND ((EQ COMMAND ‘VIEW) (PROGN (FORMAT T «—code—«) (PRINT PROGRAM) (TERPRI))) ((EQ COMMAND ‘CODE) (SETF PROGRAM (FUNCALL (EVAL (LIST ‘LAMBDA ‘(PROGRAM INPUT) (CADR INPUT))) PROGRAM INPUT))) ((EQ COMMAND ‘EVAL) (EVAL (CADR INPUT))) (T (FORMAT T «Unknown command ~A ~%» COMMAND))))) PROGRAM)) $>

Читайте также:
Программа сохраняет скриншот экрана

Отлично! Теперь нам несложно добавить команду, которая будет добавлять команды. Ну, как иначе это назвать?

Синтаксис команды будет таков: (add-cmd имя-новой-команды что-она-будет-делать). Но тут нас ожидает пикантная ситуация. В предыдущий раз мы вставляли код новой команды после атома cond, потому что это было проще всего. Имя это распространенное, и если в тексте появится еще одно его упоминание, то вставка будет выполнена и там, что нарушит работу тех частей, которые мы не собирались трогать. Решить эту проблему можно многими способами, например, ввести уникальный маркер и вставлять новые команды после него. Маркер будет представлять собой невыполнимое условие, которое мы добавим после cond:

(code (rins ‘cond ‘((eq t nil) ‘secret-marker) program))

Готово. Теперь будем передавать в rins местоположение вставки с помощью данного маркера. Громоздкость маркера ничего не значит, ведь мы создадим команду, которая будет его знать, и нам будет уже необязательно его помнить. Кстати, нельзя, чтобы код команды add-cmd использовал определение маркера, иначе rins найдет и поломает его. Можно попытаться обмануть rins, исказив маркер, но гораздо проще просто вынести в отдельную внешнюю функцию (rins по ним не ищет). Функция add-command-to-program принимает первым параметром программу program и возвращает ее обновленной, дополнив ее новой командой command, выполняющей действие action:

(eval (defun add-command-to-program (program command action) (rins ‘((eq t nil) ‘secret-marker) ; после маркера `((eq command ‘,command) ,action) ; применим квазицитирование program ) ) )

Собственно создаем команду add-cmd.

(code (rins ‘((eq t nil) ‘secret-marker) ; вставляем после маркера следующее `((eq command ‘add-cmd) ; имя новой команды add-cmd (setf program (add-command-to-program program (cadr input) (caddr input))) ) program ) )

Замечательно! Теперь нет ничего проще, чем добавить новые команды (две последние из них лучше пока не запускать):

(add-cmd hi (princ «Hi, «)) (add-cmd quit (setf program nil)) (add-cmd reset (setf program (start-program)))

Более полезными окажутся возможности по сохранению в файл программы и последующей загрузки ее из файла. Определим соответствующие команды save и load:

(add-cmd save (with-open-file (stream (cadr input) :direction :output :if-exists :overwrite :if-does-not-exist :create) (print program stream))) (add-cmd load (setf program (with-open-file (stream (cadr input)) (read stream))))

Теперь мы можем сохранять наши наработки в любой текстовый файл и загружать их оттуда. Но следует помнить, что мы сохраняем и загружаем только содержимое program; все функции, определенные нами командой eval + defun, в этих файлах не сохраняются, они хранятся в памяти интерпретатора. Исправить это досадное недоразумение можно, но мы не будем сейчас этого касаться.

$> (save «1.txt») $> (load «1.txt»)

Кастомизация

Для разнообразия займемся кастомизацией нашего диалога. Например, добавим забавные приветствия функцией:

(eval (defun greeting () (let ((sentences (vector «My life for Ner’zhul. » «I wish only to serve. » «Thy bidding, master? » «Where shall my blood be spilled? » «I bow to your will. » ))) (elt sentences (random (length sentences))) ) ) )

Теперь применим их в командном процессоре:

(code (rsubs ‘»$> » ‘(greeting) program))

Получится нечто вроде:

I bow to your will. (hi) Hi, I wish only to serve.

Наконец, предлагаю избавиться от лишних скобок, заменив (read) на нечто посложнее: мы будем считывать строку и самостоятельно обрамлять ее скобками.

(code (rsubs ‘(read) ‘(read-from-string (concatenate ‘string «(» (read-line) «)»)) program))
Thy bidding, master? hi Hi, Where shall my blood be spilled?

Давайте напоследок еще раз взглянем на код:

Окончательный результат

Thy bidding, master? view —code— (LAMBDA (PROGRAM) (PRINC (GREETING)) (LET ((INPUT (READ-FROM-STRING (CONCATENATE ‘STRING «(» (READ-LINE) «)»)))) (WHEN (LISTP INPUT) (LET ((COMMAND (CAR INPUT))) (COND ((EQ T NIL) ‘SECRET-MARKER) ((EQ COMMAND ‘LOAD) (SETF PROGRAM (WITH-OPEN-FILE (STREAM (CADR INPUT)) (READ STREAM)))) ((EQ COMMAND ‘SAVE) (WITH-OPEN-FILE (STREAM (CADR INPUT) :DIRECTION :OUTPUT :IF-EXISTS :OVERWRITE :IF-DOES-NOT-EXIST :CREATE) (PRINT PROGRAM STREAM))) ((EQ COMMAND ‘RESET) (SETF PROGRAM (START-PROGRAM))) ((EQ COMMAND ‘QUIT) (SETF PROGRAM NIL)) ((EQ COMMAND ‘HI) (PRINC «Hi, «)) ((EQ COMMAND ‘ADD-CMD) (SETF PROGRAM (ADD-COMMAND-TO-PROGRAM PROGRAM (CADR INPUT) (CADDR INPUT)))) ((EQ COMMAND ‘VIEW) (PROGN (FORMAT T «—code—«) (PRINT PROGRAM) (TERPRI))) ((EQ COMMAND ‘CODE) (SETF PROGRAM (FUNCALL (EVAL (LIST ‘LAMBDA ‘(PROGRAM INPUT) (CADR INPUT))) PROGRAM INPUT))) ((EQ COMMAND ‘EVAL) (EVAL (CADR INPUT))) (T (FORMAT T «Unknown command ~A ~%» COMMAND))))) PROGRAM)) My life for Ner’zhul.

С этой штукой можно развлекаться сколько угодно! Но на сегодня хватит.

  • Lisp
  • искусственный интеллект
  • программирование
  • функциональное программирование
  • Ненормальное программирование
  • Lisp

Источник: habr.com

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru