Я наследовал большую груду кода Ruby, который это, откровенно говоря, близко к невозможному для понимания для смертного как я. Это - на самом деле код модульного теста Rspec, но структура "очень необычна" поместить его приятно.
То, что я хотел бы иметь возможность сделать, выполняется код, и зарегистрируйте следующую информацию где-нибудь:
С этим я мог начать пытаться осуществить рефакторинг его. Без него он будет очень трудной задачей разгладить его, из-за размера кодовой базы (20k + случаи модульного теста).
Я не могу позволить себе войти и выполнить оптовые редактирования к выполняемому коду, потому что он повреждается при ровном использовании словесного оскорбления вокруг этого (т.е. часто). Вместо этого я должен быть в состоянии оснастить код в его существующем состоянии, или с минимальными изменениями в том, что существует теперь.
Существует ли способ зарегистрировать этот уровень детализации, не внося оптовые изменения в кодовую базу? Я взглянул на профилировщика Ruby, чтобы видеть, могло ли это помочь, и это, вероятно, могло; мне любопытно, если существует лучший путь (особенно регистрирующий имя файла, содержащее вызываемый метод).
Заранее спасибо
Это определенно возможно - на самом деле, есть даже способ для этого! Просто добавьте это где-нибудь в коде перед точкой, в которой вы хотите начать регистрацию:
set_trace_func proc { |event, file, line, id, binding, classname|
printf "%8s %s:%-2d %10s %8s\n", event, file, line, id, classname
}
Секретный соус, который вам нужен, исходит из Kernel # set_trace_func
, как указано выше:
- set_trace_func (proc) = > proc
- set_trace_func (nil) => nil
Устанавливает
proc
в качестве обработчика для трассировки или отключает трассировку, если параметр равенnil
.proc
принимает до шести параметров: имя события, имя файла, номер строки, идентификатор объекта, привязку и имя класса.proc
вызывается всякий раз, когда происходит событие. Событиями являются:c-call
(вызов подпрограммы языка C),c-return
(возврат из подпрограммы языка C),вызов
(вызов Ruby),class
(начало определения класса или модуля),end
(завершение определения класса или модуля),строка
(выполнение кода с новой строки ),raise
(вызов исключения) иreturn
(возврат из метода Ruby). Трассировка отключена в контексте proc.
Вот удобный пример:
class Test
def test
a = 1
b = 2
end
end
set_trace_func proc { |event, file, line, id, binding, classname|
printf "%8s %s:%-2d %10s %8s\n", event, file, line, id, classname
}
t = Test.new
t.test
(Примечание: не пытайтесь использовать это в irb
, если вам не нужен огромный экран с прокруткой текста.) В результате вы получите:
line test.rb:11 false
c-call test.rb:11 new Class
c-call test.rb:11 initialize Object
c-return test.rb:11 initialize Object
c-return test.rb:11 new Class
line test.rb:12 false
call test.rb:2 test Test
line test.rb:3 test Test
line test.rb:4 test Test
return test.rb:4 test Test
Вы можете поиграть со строкой форматирования выше, чтобы получить только те результаты, которые вы хотите зарегистрировать (например, похоже, что вас интересуют только события call
). Надеюсь, что это поможет, и удачи в разборе всех этих модульных тестов!