#ruby #parsing #code-analysis
#ruby #синтаксический анализ #анализ кода
Вопрос:
Я пишу очень простой статический анализатор кода на Ruby. Я использую Parser gem для генерации AST, а затем перехожу к анализу кода. Ниже приведен фрагмент кода.
class Processor < AST::Processor
def on_def(node)
puts node.type
end
end
parsed_code = Parser::CurrentRuby.parse(some_code) #parsing code to AST
processor = Processor.new
processor.process(parsed_code) #traversing throught the AST
Теперь проблема в том, что я могу анализировать код только внутри класса, который обработал или прошел AST. В приведенном выше случае этот класс является классом процессора. Это означает, что мне придется реализовать все мои методы анализа в классе процессора. Но я не хочу этого делать, я хочу инкапсулировать каждый метод анализатора в свой собственный класс. Например, вот так
class CheckIndentation
end
class CheckNamingConvention
end
Как я могу этого добиться?
Ответ №1:
Определите методы класса / модуля с помощью Self
Определите метод класса / модуля, а не метод экземпляра. Вы делаете это, явно используя self
в качестве получателя в определении вашего метода, чтобы он ссылался на текущий класс / модуль, когда интерпретатор выполняет определение метода. Например, следующее не проверено, потому что ваш пример кода не был полным, проверяемым примером, но должен делать то, что вы пытаетесь выполнить:
class Processor < AST::Processor
def self.on_def(node)
puts node.type
end
end
Смотрите также
Для более сложных вариантов использования также стоит упомянуть метод Module#module_function . Это копирует методы экземпляра в независимые методы модуля, которые могут вызывать метод с модулем / классом в качестве получателя. Я упоминаю это здесь только для полноты картины; ИМХО, это излишне для вашего конкретного примера.
Комментарии:
1. В моем понимании методы класса могут вызываться напрямую, без создания какого-либо экземпляра. Но я не вижу, как я могу использовать его для реализации решения, о котором я упоминал выше. Не могли бы вы немного уточнить?