> 1 <

Автор Сообщение

bach74

Members


Статус

40 сообщений

Где: Russia Челябинск
Род занятий: программист
Возраст: 43

#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

Members


Статус

33 сообщений
http://dmitry-vk.livejournal.com/
Где: Russia Казань
Род занятий:
Возраст: 30

#183   2008-12-09 00:18 GMT+3 часа(ов)      
Для рефакторинга в Slime есть функции who-calls, who-references и т.п. Они позволяют пройтись по всем функциям, где используется.
С автоматическим рефакторингом в лиспе несколько сложнее, чем с явой. Все из-за кодогенерации. Если в результирующий код вставлен вызов какой-то функции, то может быть нетривиально определить, а что же нужно изменить в исходном коде, чтобы вставить вызов другой функции.

dmitry_vk

Members


Статус

33 сообщений
http://dmitry-vk.livejournal.com/
Где: Russia Казань
Род занятий:
Возраст: 30

#184   2008-12-09 00:22 GMT+3 часа(ов)      
Ну и конечно, «рефакторинг» путем определения макроса, перекрывающего какой-то символ, чреват, во-первых, неудобством, а во-вторых, различными проблемами (прежде всего, в связи с появляющимися лишними зависимостями между файлами).
> 1 <


Онлайн :

0 пользователь(ей), 29 гость(ей) :




Реклама на сайте: