> 1 <
Автор | Сообщение |
bach74
40 сообщений |
#182 2008-12-08 16:03 GMT+3 часа(ов) |
Возникла тут на java у меня проблемка... есть две группы классов (скажем А и B), где вызываются в разных методах этих классов некий метод из некого класса Server.getA() для получения некой структуры данных. Все бы хорошо, но нужно теперь с этого Server в группе B получать другую структуру, скажем через Server.getB() вместо Server.getA(). Другими словами, теперь нужно везде переписать все вызовы getA на getB. Я человек ленивый, поэтому воспользовался рефакторингом в среде eclipse со всякими там рюшечками.
Поскольку с некоторых пор я стал интересовать замечательнейшим языком Лисп, то сразу подумал, как это будет в Лисп. Я, конечно, еще во многом зеленый в нем, но сразу нашел решение, которое гораздо более элегантное, чем в java. Приведу сейчас (извиняюсь за слишком простой пример) файлы на Лиспе. файл a.lisp: (make-package :a) (in-package a) (defvar *a* 100) (defvar *b* 200) (defun getA () *a*) (defun getB () *b*) файл b.lisp (make-package :b) (in-package b) (import 'a::getA) (defun b () (getA)) теперь в REPL (я использую slime под виндой): (load "a.lisp") (load "b.lisp") (in-package b) (b) Последнее вернет 100, естественно. Теперь я хочу, чтобы вместо getA вызывалось getB (а представьте, что этих вызовов в файле сотни!) очень просто - пишем малюсенький макрос. Смотрим файл b: make-package :b) (in-package b) ;(import 'a::getA) (defmacro getA () (a::getB)) (defun b () (getA)) теперь в REPL : (load "a.lisp") (load "b.lisp") (in-package b) (b) вернется 200, как и нужно. Лисп меня просто восхитил. Будет интересно от зубров в Лиспе услышать аналогичные примеры, где Лисп превзошел другие языки и среды по своей гибкости. Думаю, это будет интересно новичкам. Правда, рефакторинг - вещь более мощная на самом деле. Было бы интересно услышать также другие решения данного вопроса в рамках Лиспа. отредактировал(а) bach74: 2008-12-08 17:26 GMT+3 часа(ов) |
|
dmitry_vk
33 сообщений |
#183 2008-12-09 00:18 GMT+3 часа(ов) |
Для рефакторинга в Slime есть функции who-calls, who-references и т.п. Они позволяют пройтись по всем функциям, где используется.
С автоматическим рефакторингом в лиспе несколько сложнее, чем с явой. Все из-за кодогенерации. Если в результирующий код вставлен вызов какой-то функции, то может быть нетривиально определить, а что же нужно изменить в исходном коде, чтобы вставить вызов другой функции. |
|
dmitry_vk
33 сообщений |
#184 2008-12-09 00:22 GMT+3 часа(ов) |
Ну и конечно, «рефакторинг» путем определения макроса, перекрывающего какой-то символ, чреват, во-первых, неудобством, а во-вторых, различными проблемами (прежде всего, в связи с появляющимися лишними зависимостями между файлами).
|
|
> 1 <