首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > Ruby Rails >

RUBY中保存错误现场

2012-12-19 
RUBY中保存异常现场无法接触到服务器,但有些问题需要异常的数据,虽然可以在抛出异常时把数据给手动打印到

RUBY中保存异常现场
  无法接触到服务器,但有些问题需要异常的数据,虽然可以在抛出异常时把数据给手动打印到日记,感觉太麻烦了
 
  记得有看豆瓣的架构时,有提到他们在发生异常时,会把当时的所有变量都打印到日记里,方便调试.

  在RUBY中实现这个也不难,稍微有点难的是本地变量的保存

  实例变量已经在RAILS已经有现在的实现了
# File activesupport/lib/active_support/core_ext/object/instance_variables.rb, line 12 def instance_values #:nodoc: Hash[instance_variables.map { |name| [name.to_s[1..-1], instance_variable_get(name)] }] end

  但没有找到local_values这个方法,好吧,我们自己来实现一个

    def local_values(context, black_list = [])      black_list.concat(%w[local_value_hashs])      context.eval <<-EOS     local_value_hashs = {}     local_variables.each do |var_name|       next if [#{black_list.map{|b|"'#{b}'"}.join ','}].include? var_name       local_value_hashs[var_name] = eval(var_name)     end     local_value_hashs      EOS    end


这个方法默认只需要一个参数,context参数在发生异常的rescue语句里调用binding方法,black_list参数是一个数组,当你不需要把某些本地变量给打印出来的,把它的名字写到这个数组就行了

小demo
require 'pp'class Kitty  def hello    str = "hello kitty"    raise 'test kitty'  rescue     pp local_values(binding)  end  def local_values(context, black_list = [])    black_list.concat(%w[local_value_hashs])    context.eval <<-EOS     local_value_hashs = {}     local_variables.each do |var_name|       next if [#{black_list.map{|b|"'#{b}'"}.join ','}].include? var_name       local_value_hashs[var_name] = eval(var_name)     end     local_value_hashs    EOS  endendKitty.new.hello

输出结果
引用{"str"=>"hello kitty"}

思路
通过binding方法获取异常发生的上下文调用上下文的eval方法,在eval里通过ruby自带的local_variables,获取所有本地变量的名称通过eval获取本地变量的值,把它存起来,返回结果

在Rails中,再配合exception_notification,用着就觉得很舒服了,追求完美话,可以把常量,自定的全局变量都打印出来 1 楼 ruby_windy 2011-10-24   嗯,相当好的思路.
bind与context可以用在这些好的调试的技巧中:)

热点排行