Должен ли я использовать Visitor, когда мой AST - это просто массив массивов? - PullRequest
0 голосов
/ 25 февраля 2011

Я видел шаблон Visitor, используемый для прогулки по AST .Чтобы использовать этот шаблон, вы добавляете метод accept(visitor) для объектов узла AST.Этот метод вызывает visitor.visit(self), который, в свою очередь, «обрабатывает» узел для получения желаемого результата (например, довольно печатная версия AST).

Обратите внимание, что обычно вам нужно изменить узлысами добавить метод.Но что делать, если ваш AST использует встроенные объекты.Библиотека Ruby Ripper возвращает AST в виде массива массивов.Я мог бы добавить метод accept следующим образом:

class Array
  def accept(visitor)
    visitor.visit(self)
  end
end

Глядя на документацию для массива , в настоящее время нет метода accept, поэтому конфликта не будет,Но мне это не совсем подходит, особенно если я сам пишу библиотеку.Я бы не хотел «загрязнять» встроенный объект, на который могли бы полагаться другие.

Однако это не уникально для Ruby, так как я мог бы добавить метод расширения в C #, чтобы сделать подобноевещь.

Мой вопрос таков: должен ли я использовать шаблон Visitor в этом сценарии или я должен написать рекурсивную функцию, которая просто принимает тип данных, над которым я работаю, и возвращает ответ, который я хочу?

1 Ответ

1 голос
/ 07 марта 2011

Шаблон посетителя - это известное решение для обхода повторяющейся проблемы (проблема здесь может быть применена только к языкам программирования, которые не обеспечивают многократную диспетчеризацию ).

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

Как правило, у вас есть иерархия классов (дерево с различными типами узлов).Тем не менее, в этом случае я не вижу, чтобы это произошло.Поэтому мне интересно, почему вы хотите использовать шаблон посетителя в первую очередь.Не проще ли создать разные классы, которые будут использовать ваш массив в качестве входных данных и обрабатывать его?

...