2013-03-15 3 views
2

나는 (스크립트, 말에서)라고 모든 메소드에 의해 반환되는 값을 보려면이 같은 일부 루비 코드를 작성하고 싶습니다 :set_trace_func에서 반환 할 값을 가져올 수 있습니까?

set_trace_func proc { |event, file, line, id, binding, classname| 
    if event == "return" 
    puts "returning #{return_value} from #{classname}.#{id}" 
    end 
} 

이 가능합니까? 위 코드의 범위에서 return_value을 얻을 수 있습니까?

답변

5

Ruby 2.0에는 return_value 인스턴스 메소드가 포함 된 새로운 TracePoint 클래스가 있습니다. 당신은 다음과 같이 사용할 수 있습니다 :

trace_point = TracePoint.new(:return) do |t| # event type specification is optional 
    puts "returning #{t.return_value} from #{t.defined_class}.#{t.method_id}" 
end 

trace_point.enable 
1

사람이 여전히 1.9.3에 관심이 있다면,이 작업을 수행 할 수있는 cludgy 방법이 :

당신은 set_trace_func 내에서 호출 된 함수를 평가하기 위해 eval(code, binding)을 사용할 수 있습니다 처리기를 호출 한 다음 eval 반환 값을 메모합니다.

직접 발신자 코드를 다시 작성해야합니다. set_trace_func은 핸들러의 TEH 기간 동안 해제 되었기 때문에에만, 한 수준 아래이 작업을 수행 할 수

arg_arr = [] 
params = eval('method(__method__).parameters', binding) 
params.each do |param| 
    case param[0] 
     when :req, :opt 
      arg_arr << param[1] 
     when :rest 
      arg_arr << '*' + param[1] 
     else 
      puts "Need handler for type #{param[0]}" 
     end 
end 

call_expr = "#{id} #{arg_arr.join(',')}" 
puts "Call with <#{call_expr}>" 
res = eval(call_expr, binding) 
puts "sub-method #{id} returned #{res}" 
eval("return #{res.inspect}", binding) 

: 같은 뭔가. 더하기 arguments의 출력이 문서화되지 않은 것으로 보입니다. 또한 악을 사용합니다.

관련 문제