@b = 2
end
def mymeth
# ...
end
protected :mymeth
end
x = SomeClass.new
def
x.newmeth
# ...
end
iv = x.instance_variables # ['@b', '@a']
p x.methods.size # 42
p x.public_methods.size # 41
p x.public_methods(false).size # 1
p x.private_methods.size # 71
p x.private_methods(false).size # 1
p x.protected_methods.size # 1
p x.singleton_methods.size # 1
Если вы работаете с Ruby уже несколько лет, то заметите, что эти методы немного изменились. Теперь параметры по умолчанию равны true
, а не false
.
11.3.9. Просмотр стека вызовов
Иногда необходимо знать, кто вызвал метод. Эта информация полезна, если, например, произошло неисправимое исключение. Метод caller
, определенный в модуле Kernel
, дает ответ на этот вопрос. Он возвращает массив строк, в котором первый элемент соответствует вызвавшему методу, следующий — методу, вызвавшему этот метод, и т.д.
def func1
puts caller[0]
end
def func2
func1
end
func2 # Печатается: somefile.rb:6:in 'func2'
Строка имеет формат «файл;строка» или «файл;строка в методе».
11.3.10. Мониторинг выполнения программы
Программа на Ruby может следить за собственным выполнением. У этой возможности есть много применений; интересующийся читатель может заглянуть в исходные тексты программ debug.rb
, profile.rb
и tracer.rb
. С ее помощью можно даже создать библиотеку для «проектирования по контракту» (design-by-contract, DBC), хотя наиболее популярная в данный момент библиотека такого рода этим средством не пользуется.
Интересно, что этот фокус реализован целиком на Ruby. Мы пользуемся методом set_trace_func
, который позволяет вызывать указанный блок при возникновении значимых событий в ходе исполнения программы. В справочном руководстве описывается последовательность вызова set_trace_func
, поэтому здесь мы ограничимся простым примером:
def meth(n)
sum = 0
for i in 1..n
sum += i
end
sum
end
set_trace_func(proc do |event, file, line,
id, binding, klass, *rest|
printf '%8s %s:%d %s/%s
', event, file, line,
klass, id
end)
meth(2)
Отметим, что здесь соблюдается стандартное соглашение о заключении многострочного блока в операторные скобки do-end
. Круглые скобки обязательны из-за особенностей синтаксического анализатора Ruby. Можно было бы, конечно, вместо этого поставить фигурные скобки.
Вот что будет напечатано в результате выполнения этого кода:
line prog.rb:13 false/
call prog.rb:1 Object/meth
line prog.rb:2 Object/meth
line prog.rb:3 Object/meth
c-call prog.rb:3 Range/each